* IN THE SOFTWARE.
*/
+#include <cassert>
#include <sstream>
-
+#include <utility>
#include "CTFLogVisitor.h"
#include "NxMessageVisitor.h"
#include "NxMessage.h"
-using std::ostringstream;
-using std::endl;
+using std::map;
+using std::string;
+
+namespace {
+ /* Types */
+ struct bt_ctf_field_type *uint32_bin_type;
+ struct bt_ctf_field_type *uint32_oct_type;
+ struct bt_ctf_field_type *uint32_dec_type;
+ struct bt_ctf_field_type *uint32_hex_type;
+
+ struct bt_ctf_field_type *uint64_bin_type;
+ struct bt_ctf_field_type *uint64_oct_type;
+ struct bt_ctf_field_type *uint64_dec_type;
+ struct bt_ctf_field_type *uint64_hex_type;
+
+ struct bt_ctf_field_type *string_type;
+}
+
+CTFLogVisitor::CTFIntegerField::CTFIntegerField(const string &name,
+ uint32_t value,
+ enum bt_ctf_integer_base base)
+{
+ struct bt_ctf_field_type *type;
+
+ switch (base)
+ {
+ case BT_CTF_INTEGER_BASE_BINARY:
+ type = uint32_bin_type;
+ break;
+ case BT_CTF_INTEGER_BASE_OCTAL:
+ type = uint32_oct_type;
+ break;
+ case BT_CTF_INTEGER_BASE_DECIMAL:
+ type = uint32_dec_type;
+ break;
+ case BT_CTF_INTEGER_BASE_HEXADECIMAL:
+ type = uint32_hex_type;
+ break;
+ default:
+ assert(false);
+ break;
+ };
+
+ create_unsigned_field(name, type, value);
+}
+
+CTFLogVisitor::CTFIntegerField::CTFIntegerField(const string &name,
+ uint64_t value,
+ enum bt_ctf_integer_base base)
+{
+ struct bt_ctf_field_type *type;
+
+ switch (base)
+ {
+ case BT_CTF_INTEGER_BASE_BINARY:
+ type = uint64_bin_type;
+ break;
+ case BT_CTF_INTEGER_BASE_OCTAL:
+ type = uint64_oct_type;
+ break;
+ case BT_CTF_INTEGER_BASE_DECIMAL:
+ type = uint64_dec_type;
+ break;
+ case BT_CTF_INTEGER_BASE_HEXADECIMAL:
+ type = uint64_hex_type;
+ break;
+ default:
+ assert(false);
+ break;
+ };
+
+ create_unsigned_field(name, type, value);
+}
+
+void CTFLogVisitor::CTFIntegerField::create_unsigned_field(const string &name,
+ struct bt_ctf_field_type *type,
+ uint64_t value)
+{
+ int ret = 0;
+ struct bt_ctf_field *field = NULL;
+
+ assert(type);
+
+ field = bt_ctf_field_create(type);
+ assert(field);
+
+ ret = bt_ctf_field_unsigned_integer_set_value(field, value);
+ assert(!ret);
+
+ name_ = name;
+ field_ = field;
+ type_ = type;
+}
+
+CTFLogVisitor::CTFStringField::CTFStringField(const string &name,
+ const string &value)
+{
+ int ret = 0;
+ struct bt_ctf_field *field = NULL;
-CTFLogVisitor::CTFLogVisitor(const string& trace_path)
- : trace_path_(trace_path)
+ field = bt_ctf_field_create(string_type);
+ assert(field);
+
+ ret = bt_ctf_field_string_set_value(field, value.c_str());
+ assert(!ret);
+
+ name_ = name;
+ field_ = field;
+ type_ = string_type;
+}
+
+CTFLogVisitor::CTFLogVisitor(const string &trace_path)
{
- // TODO
+ int ret = 0;
+ uint64_t default_clock = 1000000000;
+
+ writer_ = bt_ctf_writer_create(trace_path.c_str());
+
+ /* TODO: How can we handle errors in the visitor? */
+ assert(writer_);
+ ret = bt_ctf_writer_add_environment_field(writer_,
+ "converter",
+ "Babeltrace Nexus to CTF");
+ assert(!ret);
+
+ /* Clock */
+
+ /*
+ * TODO: Figure out how to obtain clock frequency and precision
+ * from the traced system.
+ */
+ clock_ = bt_ctf_clock_create("system_clock");
+ assert(clock_);
+
+ ret = bt_ctf_clock_set_description(clock_, "System clock");
+ assert(!ret);
+
+ ret = bt_ctf_clock_set_frequency(clock_, default_clock);
+ assert(!ret);
+
+ ret = bt_ctf_clock_set_is_absolute(clock_, 1);
+ assert(!ret);
+
+ ret = bt_ctf_writer_add_clock(writer_, clock_);
+ assert(!ret);
+
+ /* Stream class */
+ stream_class_ = bt_ctf_stream_class_create("stream0");
+ assert(stream_class_);
+
+ ret = bt_ctf_stream_class_set_clock(stream_class_, clock_);
+ assert(!ret);
+
+ stream_ = bt_ctf_writer_create_stream(writer_, stream_class_);
+ assert(stream_);
+
+ /* Types init */
+ string_type = bt_ctf_field_type_string_create();
+
+ uint32_bin_type = bt_ctf_field_type_integer_create(32);
+ ret = bt_ctf_field_type_integer_set_base(uint32_bin_type,
+ BT_CTF_INTEGER_BASE_BINARY);
+ assert(!ret);
+
+ uint64_bin_type = bt_ctf_field_type_integer_create(64);
+ ret = bt_ctf_field_type_integer_set_base(uint64_bin_type,
+ BT_CTF_INTEGER_BASE_BINARY);
+ assert(!ret);
+
+ uint32_oct_type = bt_ctf_field_type_integer_create(32);
+ ret = bt_ctf_field_type_integer_set_base(uint32_oct_type,
+ BT_CTF_INTEGER_BASE_OCTAL);
+ assert(!ret);
+
+ uint64_oct_type = bt_ctf_field_type_integer_create(64);
+ ret = bt_ctf_field_type_integer_set_base(uint64_oct_type,
+ BT_CTF_INTEGER_BASE_OCTAL);
+ assert(!ret);
+
+ uint32_dec_type = bt_ctf_field_type_integer_create(32);
+ ret = bt_ctf_field_type_integer_set_base(uint32_dec_type,
+ BT_CTF_INTEGER_BASE_DECIMAL);
+ assert(!ret);
+
+ uint64_dec_type = bt_ctf_field_type_integer_create(64);
+ ret = bt_ctf_field_type_integer_set_base(uint64_dec_type,
+ BT_CTF_INTEGER_BASE_DECIMAL);
+ assert(!ret);
+
+ uint32_hex_type = bt_ctf_field_type_integer_create(32);
+ ret = bt_ctf_field_type_integer_set_base(uint32_hex_type,
+ BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ assert(!ret);
+
+ uint64_hex_type = bt_ctf_field_type_integer_create(64);
+ ret = bt_ctf_field_type_integer_set_base(uint64_hex_type,
+ BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ assert(!ret);
}
CTFLogVisitor::~CTFLogVisitor()
{
- // TODO
+ /* Free event classes */
+ map<const type_info *, struct bt_ctf_event_class *>::iterator it;
+ for (it = event_class_.begin(); it != event_class_.end(); ++it) {
+ bt_ctf_event_class_put(it->second);
+ }
+
+ /* Free types */
+ bt_ctf_field_type_put(uint32_bin_type);
+ bt_ctf_field_type_put(uint64_bin_type);
+
+ bt_ctf_field_type_put(uint32_oct_type);
+ bt_ctf_field_type_put(uint64_oct_type);
+
+ bt_ctf_field_type_put(uint32_dec_type);
+ bt_ctf_field_type_put(uint64_dec_type);
+
+ bt_ctf_field_type_put(uint32_hex_type);
+ bt_ctf_field_type_put(uint64_hex_type);
+
+ bt_ctf_field_type_put(string_type);
+
+ bt_ctf_clock_put(clock_);
+ bt_ctf_stream_class_put(stream_class_);
+ bt_ctf_stream_put(stream_);
+
+ /* Free writer */
+ bt_ctf_writer_put(writer_);
}
-string CTFLogVisitor::asString() const
+struct bt_ctf_event_class* CTFLogVisitor::create_event_class(const NxMessage *m,
+ const string &name,
+ const CTFFields &fields)
+{
+ int ret = 0;
+ struct bt_ctf_event_class *event_class = NULL;
+
+ event_class = bt_ctf_event_class_create(name.c_str());
+ assert(event_class);
+
+ for (CTFFields::const_iterator it = fields.begin();
+ it != fields.end();
+ ++it) {
+ const char *name = (*it)->name().c_str();
+ struct bt_ctf_field_type *type = (*it)->type();
+ assert(name);
+ assert(type);
+
+ ret = bt_ctf_event_class_add_field(event_class, type, name);
+ assert(!ret);
+ }
+
+ ret = bt_ctf_stream_class_add_event_class(stream_class_, event_class);
+ assert(!ret);
+
+ event_class_[&typeid(*m)] = event_class;
+
+ return event_class;
+}
+
+struct bt_ctf_event_class*
+CTFLogVisitor::get_event_class(const NxMessage *m) const
+{
+ struct bt_ctf_event_class *event_class = NULL;
+ map<const type_info *, struct bt_ctf_event_class *>::const_iterator it;
+
+ assert(m);
+
+ it = event_class_.find(&typeid(*m));
+
+ if (it != event_class_.end()) {
+ event_class = it->second;
+ }
+
+ return event_class;
+}
+
+
+void CTFLogVisitor::event_set_fields(struct bt_ctf_event *event,
+ const CTFFields &fields) const
+{
+ assert(event);
+
+ for (CTFFields::const_iterator it = fields.begin();
+ it != fields.end();
+ ++it) {
+ int ret = 0;
+ const char *name = (*it)->name().c_str();
+ bt_ctf_field *field = (*it)->field();
+ assert(name);
+ assert(field);
+
+ ret = bt_ctf_event_set_payload(event, name, field);
+ assert(!ret);
+ }
+}
+
+void CTFLogVisitor::append_nexus_message(NxMessage *m,
+ const string &event_name,
+ const CTFFields &fields)
{
- // TODO
- ostringstream os;
+ int ret = 0;
+ struct bt_ctf_event_class *event_class = NULL;
+ struct bt_ctf_event *event = NULL;
+
+ assert(m);
+
+ event_class = get_event_class(m);
- if (useful_visit_) {
- os << "CTFLogVisitor::asString() == TODO";
- os << endl;
- os << "CTF trace path: " << trace_path_;
- os << endl;
+ if (event_class == NULL) {
+ event_class = create_event_class(m, event_name, fields);
}
- return os.str();
+ event = bt_ctf_event_create(event_class);
+ assert(event);
+
+ event_set_fields(event, fields);
+
+ ret = bt_ctf_stream_append_event(stream_, event);
+ assert(!ret);
+
+ /*
+ * FIXME: There will only be one event per-packet
+ * if we flush for each message.
+ */
+ ret = bt_ctf_stream_flush(stream_);
+ assert(!ret);
+
+ bt_ctf_event_put(event);
+}
+
+void CTFLogVisitor::visit(NxDefaultMessage *m)
+{
+ /*
+ * These messages are treated as "unknown" and their payload
+ * won't be decoded. No need to process them.
+ */
+ useful_visit_ = false;
+}
+
+void CTFLogVisitor::visit(NxDebugStatusMessage *m)
+{
+ /* Default Nexus Message fields */
+ CTFIntegerField tcode ("TCODE", m->tcode());
+ CTFStringField tcode_desc ("TCODE_DESC", m->tcodeString());
+ CTFIntegerField src_id ("SRC_ID", m->sourceId());
+ CTFStringField src_id_desc ("SRC_ID_DESC", string(m->sourceIdString()));
+ CTFIntegerField timestamp ("TIMESTAMP", m->correctedTimestamp());
+
+ /* Nexus Debug Status fields */
+ CTFIntegerField status ("STATUS", m->status(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+ CTFFields fields;
+
+ fields.push_back(&tcode);
+ fields.push_back(&tcode_desc);
+ fields.push_back(&src_id);
+ fields.push_back(&src_id_desc);
+ fields.push_back(×tamp);
+ fields.push_back(&status);
+
+ append_nexus_message(m, "Nexus Debug Status Message", fields);
+ useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxDeviceIDMessage *m)
+{
+ /* Default Nexus Message fields */
+ CTFIntegerField tcode ("TCODE", m->tcode());
+ CTFStringField tcode_desc ("TCODE_DESC", m->tcodeString());
+ CTFIntegerField src_id ("SRC_ID", m->sourceId());
+ CTFStringField src_id_desc ("SRC_ID_DESC", string(m->sourceIdString()));
+
+ /* TODO: Confirm that Nexus Device ID Message can't have timestamp */
+ /*CTFIntegerField timestamp ("TIMESTAMP", m->correctedTimestamp());*/
+
+ CTFFields fields;
+
+ fields.push_back(&tcode);
+ fields.push_back(&tcode_desc);
+ fields.push_back(&src_id);
+ fields.push_back(&src_id_desc);
+ /*fields.push_back(×tamp);*/
+
+ append_nexus_message(m, "Nexus Device ID Message", fields);
+ useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxOwnershipTraceMessage *m)
+{
+ /* Default Nexus Message fields */
+ CTFIntegerField tcode ("TCODE", m->tcode());
+ CTFStringField tcode_desc ("TCODE_DESC", m->tcodeString());
+ CTFIntegerField src_id ("SRC_ID", m->sourceId());
+ CTFStringField src_id_desc ("SRC_ID_DESC", string(m->sourceIdString()));
+ CTFIntegerField timestamp ("TIMESTAMP", m->correctedTimestamp());
+
+ /* Nexus Ownership Trace Message fields */
+ CTFIntegerField pid_idx ("PID_INDEX", m->pidIndex(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFStringField pid_idx_desc ("PID_INDEX_DESC", string(m->pidIndexString()));
+ CTFIntegerField pid_val ("PID_VALUE", m->pidValue());
+ CTFStringField pid_val_desc ("PID_VALUE_DESC", string(m->pidValueString()));
+
+ CTFFields fields;
+
+ fields.push_back(&tcode);
+ fields.push_back(&tcode_desc);
+ fields.push_back(&src_id);
+ fields.push_back(&src_id_desc);
+ fields.push_back(×tamp);
+ fields.push_back(&pid_idx);
+ fields.push_back(&pid_idx_desc);
+ fields.push_back(&pid_val);
+ fields.push_back(&pid_val_desc);
+
+ append_nexus_message(m, "Nexus Ownership Trace Message", fields);
+ useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxDataAcquisitionMessage *m)
+{
+ /* Default Nexus Message fields */
+ CTFIntegerField tcode ("TCODE", m->tcode());
+ CTFStringField tcode_desc ("TCODE_DESC", m->tcodeString());
+ CTFIntegerField src_id ("SRC_ID", m->sourceId());
+ CTFStringField src_id_desc ("SRC_ID_DESC", string(m->sourceIdString()));
+ CTFIntegerField timestamp ("TIMESTAMP", m->correctedTimestamp());
+
+ /* Nexus Data Acquisition Message fields */
+ CTFIntegerField id_tag ("IDTAG", m->idtag(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFStringField id_tag_desc ("IDTAG_DESC", string(m->idtagString()));
+ CTFIntegerField dq_data ("DQDATA", m->dqdata());
+ CTFStringField dq_data_desc ("DQDATA_DESC", string(m->dqdataString()));
+
+ CTFFields fields;
+
+ fields.push_back(&tcode);
+ fields.push_back(&tcode_desc);
+ fields.push_back(&src_id);
+ fields.push_back(&src_id_desc);
+ fields.push_back(×tamp);
+ fields.push_back(&id_tag);
+ fields.push_back(&id_tag_desc);
+ fields.push_back(&dq_data);
+ fields.push_back(&dq_data_desc);
+
+ append_nexus_message(m, "Nexus Data Acquisition Message", fields);
+ useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxErrorMessage *m)
+{
+ /* Default Nexus Message fields */
+ CTFIntegerField tcode ("TCODE", m->tcode());
+ CTFStringField tcode_desc ("TCODE_DESC", m->tcodeString());
+ CTFIntegerField src_id ("SRC_ID", m->sourceId());
+ CTFStringField src_id_desc ("SRC_ID_DESC", string(m->sourceIdString()));
+ CTFIntegerField timestamp ("TIMESTAMP", m->correctedTimestamp());
+
+ /* Nexus Error Message fields */
+ CTFIntegerField etype ("ETYPE", m->etype(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFStringField etype_desc ("ETYPE_DESC", string(m->etypeString()));
+ CTFIntegerField ecode ("ECODE", m->ecode(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFStringField ecode_desc ("ECODE_DESC", string(m->ecodeString()));
+
+ CTFFields fields;
+
+ fields.push_back(&tcode);
+ fields.push_back(&tcode_desc);
+ fields.push_back(&src_id);
+ fields.push_back(&src_id_desc);
+ fields.push_back(×tamp);
+ fields.push_back(&etype);
+ fields.push_back(&etype_desc);
+ fields.push_back(&ecode);
+ fields.push_back(&ecode_desc);
+
+ append_nexus_message(m, "Nexus Error Message", fields);
+ useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxProgramTraceSync *m)
+{
+ /* Default Nexus Message fields */
+ CTFIntegerField tcode ("TCODE", m->tcode());
+ CTFStringField tcode_desc ("TCODE_DESC", m->tcodeString());
+ CTFIntegerField src_id ("SRC_ID", m->sourceId());
+ CTFStringField src_id_desc ("SRC_ID_DESC", string(m->sourceIdString()));
+ CTFIntegerField timestamp ("TIMESTAMP", m->correctedTimestamp());
+
+ /* Nexus Program Trace Sync fields */
+ CTFIntegerField map ("MAP", m->map(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFIntegerField icnt ("ICNT", m->icnt());
+ CTFIntegerField hist ("HIST", m->hist(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFIntegerField pc64 ("PC", m->address().address64(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFIntegerField pc32 ("PC", m->address().address32(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+ CTFFields fields;
+
+ fields.push_back(&tcode);
+ fields.push_back(&tcode_desc);
+ fields.push_back(&src_id);
+ fields.push_back(&src_id_desc);
+ fields.push_back(×tamp);
+ fields.push_back(&map);
+ fields.push_back(&icnt);
+ fields.push_back(&hist);
+
+ /*
+ * TODO: Is it possible for pc to change bitness between messages?
+ * If so, we should probably add both fields to the trace.
+ */
+ if (m->address().is64bits()) {
+ fields.push_back(&pc64);
+ } else {
+ fields.push_back(&pc32);
+ }
+
+ append_nexus_message(m, "Nexus Program Trace Sync Message", fields);
+ useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxDataTraceWrite *m)
+{
+ /* Default Nexus Message fields */
+ CTFIntegerField tcode ("TCODE", m->tcode());
+ CTFStringField tcode_desc ("TCODE_DESC", m->tcodeString());
+ CTFIntegerField src_id ("SRC_ID", m->sourceId());
+ CTFStringField src_id_desc ("SRC_ID_DESC", string(m->sourceIdString()));
+ CTFIntegerField timestamp ("TIMESTAMP", m->correctedTimestamp());
+
+ /* Nexus Data Trace Write fields */
+ CTFIntegerField dsz ("DSZ", m->dsz(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFStringField dsz_desc ("DSZ_DESC", string(m->dszString()));
+ CTFIntegerField addr ("UADDR", m->addr(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFIntegerField data ("DATA", m->data(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+ CTFFields fields;
+
+ fields.push_back(&tcode);
+ fields.push_back(&tcode_desc);
+ fields.push_back(&src_id);
+ fields.push_back(&src_id_desc);
+ fields.push_back(×tamp);
+ fields.push_back(&dsz);
+ fields.push_back(&dsz_desc);
+ fields.push_back(&addr);
+ fields.push_back(&data);
+
+ append_nexus_message(m, "Nexus Data Trace Write Message", fields);
+ useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxDataTraceRead *m)
+{
+ /* Default Nexus Message fields */
+ CTFIntegerField tcode ("TCODE", m->tcode());
+ CTFStringField tcode_desc ("TCODE_DESC", m->tcodeString());
+ CTFIntegerField src_id ("SRC_ID", m->sourceId());
+ CTFStringField src_id_desc ("SRC_ID_DESC", string(m->sourceIdString()));
+ CTFIntegerField timestamp ("TIMESTAMP", m->correctedTimestamp());
+
+ /* Nexus Data Trace Read fields */
+ CTFIntegerField dsz ("DSZ", m->dsz(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFStringField dsz_desc ("DSZ_DESC", string(m->dszString()));
+ CTFIntegerField addr ("UADDR", m->addr(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFIntegerField data ("DATA", m->data(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+ CTFFields fields;
+
+ fields.push_back(&tcode);
+ fields.push_back(&tcode_desc);
+ fields.push_back(&src_id);
+ fields.push_back(&src_id_desc);
+ fields.push_back(×tamp);
+ fields.push_back(&dsz);
+ fields.push_back(&dsz_desc);
+ fields.push_back(&addr);
+ fields.push_back(&data);
+
+ append_nexus_message(m, "Nexus Data Trace Read Message", fields);
+ useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxDataTraceWriteSync *m)
+{
+ /* Default Nexus Message fields */
+ CTFIntegerField tcode ("TCODE", m->tcode());
+ CTFStringField tcode_desc ("TCODE_DESC", m->tcodeString());
+ CTFIntegerField src_id ("SRC_ID", m->sourceId());
+ CTFStringField src_id_desc ("SRC_ID_DESC", string(m->sourceIdString()));
+ CTFIntegerField timestamp ("TIMESTAMP", m->correctedTimestamp());
+
+ /* Nexus Data Trace Write Sync fields */
+ CTFIntegerField dsz ("DSZ", m->dsz(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFStringField dsz_desc ("DSZ_DESC", string(m->dszString()));
+ CTFIntegerField addr ("FADDR", m->addr(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFIntegerField data ("DATA", m->data(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+ CTFFields fields;
+
+ fields.push_back(&tcode);
+ fields.push_back(&tcode_desc);
+ fields.push_back(&src_id);
+ fields.push_back(&src_id_desc);
+ fields.push_back(×tamp);
+ fields.push_back(&dsz);
+ fields.push_back(&dsz_desc);
+ fields.push_back(&addr);
+ fields.push_back(&data);
+
+ append_nexus_message(m, "Nexus Data Trace Write Sync Message", fields);
+ useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxDataTraceReadSync *m)
+{
+ /* Default Nexus Message fields */
+ CTFIntegerField tcode ("TCODE", m->tcode());
+ CTFStringField tcode_desc ("TCODE_DESC", m->tcodeString());
+ CTFIntegerField src_id ("SRC_ID", m->sourceId());
+ CTFStringField src_id_desc ("SRC_ID_DESC", string(m->sourceIdString()));
+ CTFIntegerField timestamp ("TIMESTAMP", m->correctedTimestamp());
+
+ /* Nexus Data Trace Read Sync fields */
+ CTFIntegerField dsz ("DSZ", m->dsz(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFStringField dsz_desc ("DSZ_DESC", string(m->dszString()));
+ CTFIntegerField addr ("FADDR", m->addr(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFIntegerField data ("DATA", m->data(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+ CTFFields fields;
+
+ fields.push_back(&tcode);
+ fields.push_back(&tcode_desc);
+ fields.push_back(&src_id);
+ fields.push_back(&src_id_desc);
+ fields.push_back(×tamp);
+ fields.push_back(&dsz);
+ fields.push_back(&dsz_desc);
+ fields.push_back(&addr);
+ fields.push_back(&data);
+
+ append_nexus_message(m, "Nexus Data Trace Read Sync Message", fields);
+ useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxWatchpointMessage *m)
+{
+ /* Default Nexus Message fields */
+ CTFIntegerField tcode ("TCODE", m->tcode());
+ CTFStringField tcode_desc ("TCODE_DESC", m->tcodeString());
+ CTFIntegerField src_id ("SRC_ID", m->sourceId());
+ CTFStringField src_id_desc ("SRC_ID_DESC", string(m->sourceIdString()));
+ CTFIntegerField timestamp ("TIMESTAMP", m->correctedTimestamp());
+
+ /* Nexus Watchpoint fields */
+ CTFIntegerField wphit ("WPHIT", m->wphit(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFStringField wphit_desc ("WPHIT_DESC", m->wphitString());
+ CTFIntegerField wphit_size ("WPHIT_SIZE", m->wphit_size(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+ CTFFields fields;
+
+ fields.push_back(&tcode);
+ fields.push_back(&tcode_desc);
+ fields.push_back(&src_id);
+ fields.push_back(&src_id_desc);
+ fields.push_back(×tamp);
+ fields.push_back(&wphit);
+ fields.push_back(&wphit_desc);
+ fields.push_back(&wphit_size);
+
+ append_nexus_message(m, "Nexus Watchpoint Message", fields);
+ useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxResourceFullMessage *m)
+{
+ /* Default Nexus Message fields */
+ CTFIntegerField tcode ("TCODE", m->tcode());
+ CTFStringField tcode_desc ("TCODE_DESC", m->tcodeString());
+ CTFIntegerField src_id ("SRC_ID", m->sourceId());
+ CTFStringField src_id_desc ("SRC_ID_DESC", string(m->sourceIdString()));
+ CTFIntegerField timestamp ("TIMESTAMP", m->correctedTimestamp());
+
+ /* Nexus Ressource Full fields */
+ CTFIntegerField rcode ("RCODE", m->rcode(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFStringField rcode_desc ("RCODE_DESC", string(m->rcodeString()));
+ CTFIntegerField rdata ("RDATA", m->rdata(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+ CTFFields fields;
+
+ fields.push_back(&tcode);
+ fields.push_back(&tcode_desc);
+ fields.push_back(&src_id);
+ fields.push_back(&src_id_desc);
+ fields.push_back(×tamp);
+ fields.push_back(&rcode);
+ fields.push_back(&rcode_desc);
+ fields.push_back(&rdata);
+
+ append_nexus_message(m, "Nexus Ressource Full Message", fields);
+ useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxProgramTraceIndirectBranch *m)
+{
+ /* Default Nexus Message fields */
+ CTFIntegerField tcode ("TCODE", m->tcode());
+ CTFStringField tcode_desc ("TCODE_DESC", m->tcodeString());
+ CTFIntegerField src_id ("SRC_ID", m->sourceId());
+ CTFStringField src_id_desc ("SRC_ID_DESC", string(m->sourceIdString()));
+ CTFIntegerField timestamp ("TIMESTAMP", m->correctedTimestamp());
+
+ /* Nexus Program Trace Indirect Branch fields */
+ CTFIntegerField btype ("BTYPE", m->btype(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFStringField btype_desc ("BTYPE_DESC", m->btypeString());
+ CTFIntegerField icnt ("ICNT", m->icnt());
+ CTFIntegerField hist ("HIST", m->hist(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFIntegerField uaddr64 ("UADDR", m->address().address64(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFIntegerField uaddr32 ("UADDR", m->address().address32(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+ CTFFields fields;
+
+ fields.push_back(&tcode);
+ fields.push_back(&tcode_desc);
+ fields.push_back(&src_id);
+ fields.push_back(&src_id_desc);
+ fields.push_back(×tamp);
+ fields.push_back(&btype);
+ fields.push_back(&btype_desc);
+ fields.push_back(&icnt);
+ fields.push_back(&hist);
+
+ /*
+ * TODO: Is it possible for uaddr to change bitness between messages?
+ * If so, we should probably add both fields to the trace.
+ */
+ if (m->address().is64bits()) {
+ fields.push_back(&uaddr64);
+ } else {
+ fields.push_back(&uaddr32);
+ }
+
+ append_nexus_message(m, "Nexus Program Trace Indirect Branch Message", fields);
+ useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxProgramTraceIndirectBranchSync *m)
+{
+ /* Default Nexus Message fields */
+ CTFIntegerField tcode ("TCODE", m->tcode());
+ CTFStringField tcode_desc ("TCODE_DESC", m->tcodeString());
+ CTFIntegerField src_id ("SRC_ID", m->sourceId());
+ CTFStringField src_id_desc ("SRC_ID_DESC", string(m->sourceIdString()));
+ CTFIntegerField timestamp ("TIMESTAMP", m->correctedTimestamp());
+
+ /* Nexus Program Trace Indirect Branch Sync fields */
+ CTFIntegerField btype ("BTYPE", m->btype(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFStringField btype_desc ("BTYPE_DESC", m->btypeString());
+ CTFIntegerField icnt ("ICNT", m->icnt());
+ CTFIntegerField hist ("HIST", m->hist(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFIntegerField faddr64 ("FADDR", m->address().address64(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFIntegerField faddr32 ("FADDR", m->address().address32(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+ CTFFields fields;
+
+ fields.push_back(&tcode);
+ fields.push_back(&tcode_desc);
+ fields.push_back(&src_id);
+ fields.push_back(&src_id_desc);
+ fields.push_back(×tamp);
+ fields.push_back(&btype);
+ fields.push_back(&btype_desc);
+ fields.push_back(&icnt);
+ fields.push_back(&hist);
+
+ /*
+ * TODO: Is it possible for faddr to change bitness between messages?
+ * If so, we should probably add both fields to the trace.
+ */
+ if (m->address().is64bits()) {
+ fields.push_back(&faddr64);
+ } else {
+ fields.push_back(&faddr32);
+ }
+
+ append_nexus_message(m, "Nexus Program Trace Indirect Branch Sync Message", fields);
+ useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxProgramTraceCorrelation *m)
+{
+ /* Default Nexus Message fields */
+ CTFIntegerField tcode ("TCODE", m->tcode());
+ CTFStringField tcode_desc ("TCODE_DESC", m->tcodeString());
+ CTFIntegerField src_id ("SRC_ID", m->sourceId());
+ CTFStringField src_id_desc ("SRC_ID_DESC", string(m->sourceIdString()));
+ CTFIntegerField timestamp ("TIMESTAMP", m->correctedTimestamp());
+
+ /* Nexus Program Trace Correlation fields */
+ CTFIntegerField evcode ("EVCODE", m->evcode(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFStringField evcode_desc ("EVCODE_DESC", m->evcodeString());
+ CTFIntegerField icnt ("ICNT", m->icnt());
+ CTFIntegerField cdata ("CDATA", m->cdata(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+ CTFFields fields;
+
+ fields.push_back(&tcode);
+ fields.push_back(&tcode_desc);
+ fields.push_back(&src_id);
+ fields.push_back(&src_id_desc);
+ fields.push_back(×tamp);
+ fields.push_back(&evcode);
+ fields.push_back(&evcode_desc);
+ fields.push_back(&icnt);
+ fields.push_back(&cdata);
+
+ append_nexus_message(m, "Nexus Program Trace Correlation Message", fields);
+ useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxDAMInCircuitTraceMessage *m)
+{
+ /* Default Nexus Message fields */
+ CTFIntegerField tcode ("TCODE", m->tcode());
+ CTFStringField tcode_desc ("TCODE_DESC", m->tcodeString());
+ CTFIntegerField src_id ("SRC_ID", m->sourceId());
+ CTFStringField src_id_desc ("SRC_ID_DESC", string(m->sourceIdString()));
+ CTFIntegerField timestamp ("TIMESTAMP", m->correctedTimestamp());
+
+ /* Nexus DAM In-Circuit Trace fields */
+ CTFStringField ict_msg_type ("ICT_MSG_TYPE", string(m->ICTMessageType()));
+ CTFIntegerField ddrmid ("DDRMID", m->ddrmid());
+ CTFIntegerField ddrsid ("DDRSID", m->ddrsid());
+ CTFIntegerField ddrtt ("DDRTT", m->ddrtt());
+ CTFStringField ddrtt_desc ("DDRTT_DESC", string(m->ddrttString()));
+ CTFIntegerField ddrsz ("DDRSZ", m->ddrsz());
+ CTFIntegerField faddr ("FADDR", (m->isSyncMessage() ? m->ddraddr() : 0), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFIntegerField uaddr ("UADDR", (m->isSyncMessage() ? 0 : m->ddraddr()), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFIntegerField dddiec ("DDDIEC", m->dddiec());
+
+ CTFFields fields;
+
+ fields.push_back(&tcode);
+ fields.push_back(&tcode_desc);
+ fields.push_back(&src_id);
+ fields.push_back(&src_id_desc);
+ fields.push_back(×tamp);
+ fields.push_back(&ict_msg_type);
+ fields.push_back(&ddrmid);
+ fields.push_back(&ddrsid);
+ fields.push_back(&ddrtt);
+ fields.push_back(&ddrtt_desc);
+ fields.push_back(&ddrsz);
+ fields.push_back(&faddr);
+ fields.push_back(&uaddr);
+ fields.push_back(&dddiec);
+
+ append_nexus_message(m, "Nexus DAM In-Circuit Trace Message", fields);
+ useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxCAMInCircuitTraceMessage *m)
+{
+ useful_visit_ = false;
+}
+
+void CTFLogVisitor::visit(NxCDMInCircuitTraceMessage *m)
+{
+ useful_visit_ = false;
+}
+
+void CTFLogVisitor::visit(NxDPQMInCircuitTraceMessage *m)
+{
+ /* Default Nexus Message fields */
+ CTFIntegerField tcode ("TCODE", m->tcode());
+ CTFStringField tcode_desc ("TCODE_DESC", m->tcodeString());
+ CTFIntegerField src_id ("SRC_ID", m->sourceId());
+ CTFStringField src_id_desc ("SRC_ID_DESC", string(m->sourceIdString()));
+ CTFIntegerField timestamp ("TIMESTAMP", m->correctedTimestamp());
+
+ /* Nexus DPQM In-Circuit Trace fields */
+ CTFStringField ict_msg_type ("ICT_MSG_TYPE", string(m->ICTMessageType()));
+ CTFIntegerField dpdm ("DBG_MARK", m->dpdm());
+ CTFIntegerField fqid ("FQ_ID", m->fqid(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFIntegerField cnum ("CH_NUM", m->cnum(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFIntegerField pnum ("PORT_NUM", m->pnum());
+ CTFIntegerField ptype ("PORT_TYPE", m->ptype());
+ CTFStringField ptype_desc ("PORT_TYPE_DESC", (m->ptype() ? "Direct Connect" : "Software"));
+ CTFIntegerField qet ("QEVNT_TYPE", m->qet());
+ CTFStringField qet_desc ("QEVNT_TYPE_DESC", string(m->queueEventTypeString()));
+ CTFIntegerField orf ("ORD_REST", m->orf());
+ /* TODO: Does the erf field indicate enqueue operation rejection? */
+ CTFIntegerField erf ("ENQ_REJCT", m->erf());
+ CTFIntegerField err ("ENQ_RESP", m->err(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFStringField err_desc ("ENQ_RESP_DESC", m->enqueueRejectionString());
+ CTFIntegerField verb ("VERBOSE", m->verb());
+ CTFIntegerField fmbpid ("FRM_BP_ID", m->fmbpid(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFIntegerField fmsc ("FRM_STAT", m->fmsc(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFIntegerField fmol ("FRM_OFFSET", m->fmol(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFIntegerField fmfmt ("FRM_FMT", m->fmfmt(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFIntegerField fmpid ("FRM_PRT_ID", m->fmpid(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFIntegerField fmaddr ("FRM_ADDR", m->fmaddr(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+ CTFFields fields;
+
+ fields.push_back(&tcode);
+ fields.push_back(&tcode_desc);
+ fields.push_back(&src_id);
+ fields.push_back(&src_id_desc);
+ fields.push_back(×tamp);
+ fields.push_back(&ict_msg_type);
+ fields.push_back(&dpdm);
+ fields.push_back(&fqid);
+ fields.push_back(&cnum);
+ fields.push_back(&pnum);
+ fields.push_back(&ptype);
+ fields.push_back(&ptype_desc);
+ fields.push_back(&qet);
+ fields.push_back(&qet_desc);
+ fields.push_back(&orf);
+ fields.push_back(&erf);
+ fields.push_back(&err);
+ fields.push_back(&err_desc);
+ fields.push_back(&verb);
+ fields.push_back(&fmbpid);
+ fields.push_back(&fmsc);
+ fields.push_back(&fmol);
+ fields.push_back(&fmfmt);
+ fields.push_back(&fmpid);
+ fields.push_back(&fmaddr);
+
+ append_nexus_message(m, "Nexus DPQM In-Circuit Trace Message", fields);
+ useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxCoreInCircuitTraceMessage *m)
+{
+ /* Default Nexus Message fields */
+ CTFIntegerField tcode ("TCODE", m->tcode());
+ CTFStringField tcode_desc ("TCODE_DESC", m->tcodeString());
+ CTFIntegerField src_id ("SRC_ID", m->sourceId());
+ CTFStringField src_id_desc ("SRC_ID_DESC", string(m->sourceIdString()));
+ CTFIntegerField timestamp ("TIMESTAMP", m->correctedTimestamp());
+
+ /* Nexus Core In-Circuit Trace fields */
+ CTFStringField ict_msg_type ("ICT_MSG_TYPE", string(m->ICTMessageType()));
+ CTFIntegerField cksrc ("CKSRC", m->cksrc());
+ CTFStringField cksrc_desc ("CKSRC_DESC", string(m->cksrcString()));
+ CTFIntegerField sync ("SYNC", m->sync());
+ CTFStringField sync_desc ("SYNC_DESC", string(m->syncString()));
+ CTFIntegerField ckdf ("CKDF", m->ckdf());
+ CTFIntegerField ckdata1 ("CKDATA1", m->ckdata1(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFIntegerField ckdata2 ("CKDATA2", m->ckdata2(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+
+ CTFFields fields;
+
+ fields.push_back(&tcode);
+ fields.push_back(&tcode_desc);
+ fields.push_back(&src_id);
+ fields.push_back(&src_id_desc);
+ fields.push_back(×tamp);
+ fields.push_back(&ict_msg_type);
+ fields.push_back(&cksrc);
+ fields.push_back(&cksrc_desc);
+ fields.push_back(&sync);
+ fields.push_back(&sync_desc);
+ fields.push_back(&ckdf);
+ fields.push_back(&ckdata1);
+ fields.push_back(&ckdata2);
+
+ append_nexus_message(m, "Nexus Core In-Circuit Trace Message", fields);
+ useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxInCircuitTraceMessage *m)
+{
+ /* Default Nexus Message fields */
+ CTFIntegerField tcode ("TCODE", m->tcode());
+ CTFStringField tcode_desc ("TCODE_DESC", m->tcodeString());
+ CTFIntegerField src_id ("SRC_ID", m->sourceId());
+ CTFStringField src_id_desc ("SRC_ID_DESC", string(m->sourceIdString()));
+ CTFIntegerField timestamp ("TIMESTAMP", m->correctedTimestamp());
+
+ /* Nexus In-Circuit Trace fields */
+ CTFStringField ict_msg_type ("ICT_MSG_TYPE", string(m->ICTMessageType()));
+
+ CTFFields fields;
+
+ fields.push_back(&tcode);
+ fields.push_back(&tcode_desc);
+ fields.push_back(&src_id);
+ fields.push_back(&src_id_desc);
+ fields.push_back(×tamp);
+ fields.push_back(&ict_msg_type);
+
+ append_nexus_message(m, "Nexus In-Circuit Trace Message", fields);
+ useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxTimeStampCorrelation *m)
+{
+ /* Default Nexus Message fields */
+ CTFIntegerField tcode ("TCODE", m->tcode());
+ CTFStringField tcode_desc ("TCODE_DESC", m->tcodeString());
+ CTFIntegerField src_id ("SRC_ID", m->sourceId());
+ CTFStringField src_id_desc ("SRC_ID_DESC", string(m->sourceIdString()));
+ CTFIntegerField timestamp ("TIMESTAMP", m->correctedTimestamp());
+
+ /* Nexus Timestamp Correlation fields */
+ CTFIntegerField tcorr ("TCORR", m->tcorr(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFIntegerField ttype ("TTYPE", m->ttype(), BT_CTF_INTEGER_BASE_HEXADECIMAL);
+ CTFStringField ttype_desc ("TTYPE_DESC", string(m->ttypeString()));
+
+ CTFFields fields;
+
+ fields.push_back(&tcode);
+ fields.push_back(&tcode_desc);
+ fields.push_back(&src_id);
+ fields.push_back(&src_id_desc);
+ fields.push_back(×tamp);
+ fields.push_back(&tcorr);
+ fields.push_back(&ttype);
+ fields.push_back(&ttype_desc);
+
+ append_nexus_message(m, "Nexus Timestamp Correlation Message", fields);
+ useful_visit_ = true;
+}
+
+void CTFLogVisitor::visit(NxDPFMInCircuitTraceMessage *m)
+{
+ /* Default Nexus Message fields */
+ CTFIntegerField tcode ("TCODE", m->tcode());
+ CTFStringField tcode_desc ("TCODE_DESC", m->tcodeString());
+ CTFIntegerField src_id ("SRC_ID", m->sourceId());
+ CTFStringField src_id_desc ("SRC_ID_DESC", string(m->sourceIdString()));
+ CTFIntegerField timestamp ("TIMESTAMP", m->correctedTimestamp());
+
+ /* Nexus DPFM In-Circuit Trace fields */
+ CTFStringField ict_msg_type ("ICT_MSG_TYPE", string(m->ICTMessageType()));
+ CTFIntegerField fmsel ("FMAN_SEL", m->getFmsel());
+ CTFIntegerField lbeat ("LAST_BEAT", m->getLbeat());
+ CTFIntegerField btcnt ("BEAT_CNT", m->getBtcnt());
+
+ /* TODO: Handle context data as CTF array */
+ /*CTFIntegerField context ("CONTEXT", m->tcode());*/
+
+ CTFFields fields;
+
+ fields.push_back(&tcode);
+ fields.push_back(&tcode_desc);
+ fields.push_back(&src_id);
+ fields.push_back(&src_id_desc);
+ fields.push_back(×tamp);
+ fields.push_back(&ict_msg_type);
+ fields.push_back(&fmsel);
+ fields.push_back(&lbeat);
+ fields.push_back(&btcnt);
+
+ append_nexus_message(m, "Nexus DPFM In-Circuit Trace Message", fields);
+ useful_visit_ = true;
+}
+
+string CTFLogVisitor::asString() const
+{
+ return "";
}