T32SIM: Integrating Tracing feature of the T32SIM.

After each simulator break, T32Tracer retrieves the latest (16)
trace records from the T32. Memory address and value can now
be evaluated easily from the trace record.

TODO:Nevertheless we still have to traverse the trace to
find the instruction causing the access.
This commit is contained in:
Martin Hoffmann
2013-03-21 17:59:21 +01:00
parent 4e8098a636
commit b8e706b1a5
17 changed files with 270 additions and 26 deletions

View File

@ -0,0 +1,76 @@
#ifndef __T32TRACEFORMAT_H__
#define __T32TRACEFORMAT_H__
#include <string>
#include <stdint.h>
namespace fail {
struct T32TraceHeader {
uint8_t export_file_header_string[32];
uint8_t reserved_32;
uint8_t cpu_code;
uint8_t timestamp_available;
uint8_t prestore_mode;
uint8_t trigger_unit_available;
uint8_t port_analyzer_avaiable_mode;
uint8_t analyzer_type;
uint8_t reserved_39;
uint32_t record_length; // in bytes
uint32_t number_of_records; // in the file
uint32_t last_record;
uint32_t referenced_record;
uint8_t reserved_56_63[8];
};
struct T32TraceRecord {
struct {
uint32_t data_cycle :1; // bit 0
uint32_t program_cycle :1; // bit 1
uint32_t reserved_2_5 : 4; // bits 2-5
uint32_t write_cycle : 1; // bit 6
uint32_t reserved_7_20 : 14 ;// bits 7-20
uint32_t flow_error : 1; // bit 21
uint32_t reserved_22_24 : 3; //bits 22-24
uint32_t fifo_overflow : 1; // bit 25
uint32_t reserved_26_30 : 5; // bits 26-30
uint32_t ownership_cycle :1; // bit 31
} cycle_information;
// data byte enable mask
uint8_t data_byte_valid; // bit0 : byte0 valid, ...
struct {
uint8_t exec_signal : 1;
uint8_t thumb_mode : 1;
uint8_t arm_mode : 1;
uint8_t reserved_3_4 : 2;
uint8_t not_executed : 1;
uint8_t executed : 1;
uint8_t reserved_6_7 : 1;
} cpu_info;
uint8_t reserved_6;
uint8_t core_number; // only on SMP targets
uint32_t bus_data_address; // bus/data
uint32_t pflow_address; // or upper part
uint64_t data;
uint64_t timestamp; // relative to ZERO in ns
bool isDataAccess(void) const { return cycle_information.data_cycle == 1; };
bool isProgram(void) const { return cycle_information.program_cycle == 1; };
bool isDataRead(void) const { return cycle_information.data_cycle && !cycle_information.write_cycle; };
bool isDataWrite(void) const { return cycle_information.data_cycle && cycle_information.write_cycle; };
uint32_t getAddress(void) const { return bus_data_address; };
uint32_t getData(void) const { return data; };
};
//<! This allows to print a record via Logger or cout
std::ostream& operator <<(std::ostream & os, const fail::T32TraceRecord & r);
};
#endif // __T32TRACEFORMAT_H__

View File

@ -0,0 +1,44 @@
#ifndef __T32TRACER_HPP__
#define __T32TRACER_HPP__
#include <string>
#include <vector>
#include "T32TraceFormat.hpp"
#include "util/Logger.hpp"
namespace fail {
class T32Tracer {
private:
typedef std::vector<T32TraceRecord> record_vector_t;
bool avail;
std::string path;
std::string exportcmd;
record_vector_t rvec;
fail::Logger m_log;
public:
typedef record_vector_t::const_reverse_iterator const_record_iterator;
T32Tracer( const std::string& tracefile );
void setup(void) const;
int evaluate();
bool wasDataAccess(void) const ;
const T32TraceRecord & getLatestRecord(void) const { return rvec.back(); };
void dump(void);
bool available(void) const { return avail; };
// We return a reverse operator, as the trace list begins with the oldest record.
// We just let it look like a "normal" iterator and traverse backwards starting
// with most recent record. (Rbegin/Rend!)
const_record_iterator begin() const { return rvec.rbegin(); };
const_record_iterator end() const { return rvec.rend(); };
};
}; // end of namespace
#endif // __T32TRACER_HPP__

View File

@ -315,7 +315,7 @@ T32EXTERN int T32_SetMode(int);
T32EXTERN int T32_Go(void);
T32EXTERN int T32_Break(void);
T32EXTERN int T32_Terminate(int retval);
T32EXTERN int T32_Cmd( char * );
T32EXTERN int T32_Cmd( const char * );
T32EXTERN int T32_CmdWin( dword, char * );
T32EXTERN int T32_EvalGet ( dword * );
T32EXTERN int T32_GetMessage ( char *, word * );