From 6ca8b5af4b6b740ed9e26503f6a375471e00c182 Mon Sep 17 00:00:00 2001 From: Martin Hoffmann Date: Sun, 17 Feb 2013 21:41:30 +0100 Subject: [PATCH] T32: Evalute memory map, RangeListener, MemAccessL --- debuggers/t32/include/T32Connector.hpp | 82 +++++++++++++++++++--- debuggers/t32/src/T32Connector.cc | 76 ++++++++++++++++++-- debuggers/t32/src/main.cc | 40 +++-------- src/core/sal/t32/T32Listener.ah | 49 ++++++++++++- src/experiments/vezs-example/experiment.cc | 22 ++++-- 5 files changed, 217 insertions(+), 52 deletions(-) diff --git a/debuggers/t32/include/T32Connector.hpp b/debuggers/t32/include/T32Connector.hpp index f8ae4e41..ce75a01a 100644 --- a/debuggers/t32/include/T32Connector.hpp +++ b/debuggers/t32/include/T32Connector.hpp @@ -1,20 +1,82 @@ #ifndef __T32CONNECTOR_HPP__ #define __T32CONNECTOR_HPP__ +#include +#include +#include + +#include "sal/SALInst.hpp" + namespace fail { -class T32Connector { - char* m_hostname; - unsigned m_port; - unsigned m_packetlength; + /** + * \class T32Connector + * + * \brief Connector to the remote T32 device. + */ + class T32Connector { + public: + T32Connector() : m_hostname("localhost"), m_port("20010"), m_packetlength("1024"), m_log("T32", false) { }; + T32Connector(const char* hostname, const char* port, const char* packlen); + ~T32Connector(); - public: - T32Connector() { }; - T32Connector(char* hostname, unsigned port, unsigned packlen); - ~T32Connector(); + // Setters/getters + void setHostname(const char* host) { m_hostname = host; }; + const char* getHostname(const char* host) const { return m_hostname; }; - -}; + void setPort(const char* port) { m_port = port; }; + const char* getPort(const char* port) const { return m_port; }; + + void setPacketlength(const char* packetlength) { m_packetlength = packetlength; }; + const char* getPacketlength(const char* packetlength) const { return m_packetlength; }; + + void setScript(const char* script) { m_script = script; }; + const char* getScript(const char* script) const { return m_script; }; + + /** + * @brief Connect and initialize T32 device + */ + bool startup(void); + + bool isRunning(void) { return getState() == RUNNING; } ; + bool isHalted(void) { return getState() == HALTED; } ; + bool isStopped(void) { return getState() == STOPPED; } ; + bool isDown(void) { return getState() == DOWN; }; + + bool isBigEndian() { return !m_littleendian; }; + bool isLittleEndian() { return m_littleendian; }; + + private: + const char* m_hostname; //!< The hostname of the T32 device + const char* m_port; //!< The port to connect as configure in config.t32. Here we use strings, as required by the API + const char* m_packetlength; //!< The packetlength of a command packet? + const char* m_script; //!< The user defined startup script to bring up the device + fail::Logger m_log; //!< Logging + + std::string m_cpustring; + + typedef std::vector< std::pair< address_t, address_t > > memory_map_t; + memory_map_t m_data_memory_map; + memory_map_t m_program_memory_map; + + bool m_littleendian; //!< Big endian: 0, little endian != 0 + + /** + * @brief Internal error handling + */ + bool err(int); + bool scriptRunning(void); + enum ICE_state_t { + DOWN = 0, + HALTED = 1, + STOPPED = 2, + RUNNING = 3, + }; + + enum { DISCOVER_PROGRAM_RAM = 2, DISCOVER_DATA_RAM = 1, DISCOVER_END = 0, }; + int getState(void); + void discoverMemory(int discovertype, memory_map_t & map); + }; } // end-of-namespace fail #endif // __T32CONNECTOR_HPP__ diff --git a/debuggers/t32/src/T32Connector.cc b/debuggers/t32/src/T32Connector.cc index 2f97b975..7f405d68 100644 --- a/debuggers/t32/src/T32Connector.cc +++ b/debuggers/t32/src/T32Connector.cc @@ -1,17 +1,83 @@ #include "T32Connector.hpp" #include -namespace fail { +#include + +using namespace fail; + +T32Connector::T32Connector(const char *hostname, const char* port, const char* packlen) + : m_hostname(hostname), m_port(port), m_packetlength(packlen), m_log("T32", false) +{ -T32Connector::T32Connector(char *hostname, unsigned port, unsigned packlen) : m_hostname(hostname), m_port(port), m_packetlength(packlen) { } T32Connector::~T32Connector() { // Close Connection to T32 on object deletion. Also works, on simulator.terminate -> global object. - std::cout << "[T32] Closing connection." << std::endl; + m_log << "Closing connection." << std::endl; +} + +bool T32Connector::startup(){ + // Setup connection to Lauterbach + m_log << "Remote connection: " << m_hostname << ":" << m_port << " - Packet length: " << m_packetlength << std::endl; + T32_Config("NODE=", m_hostname); + T32_Config("PACKLEN=", m_packetlength); + T32_Config("PORT=", m_port); + + m_log << "Init." << std::endl; + if(!err(T32_Init()) ) { return false; } + + m_log << "Attach." << std::endl; + if(!err(T32_Attach(T32_DEV_ICD)) ) { return false; } + + word tmp, fpu, endian; + char* cpuname[128]; + //if(!err(T32_GetCpuInfo( reinterpret_cast(&m_cpustring), &fpu, &endian, &tmp))) { return false; } + if(!err(T32_GetCpuInfo( reinterpret_cast(&cpuname), &fpu, &endian, &tmp))) { return false; } + m_littleendian = (endian != 0); + m_cpustring = reinterpret_cast(cpuname); + + m_log << "Attached to: " << m_cpustring << std::endl; + + // discoverMemory(DISCOVER_PROGRAM_RAM, m_program_memory_map); + // discoverMemory(DISCOVER_DATA_RAM, m_data_memory_map); + + // TODO send init script. + return true; +} + +void T32Connector::discoverMemory(int access, memory_map_t& map) { + dword pstart = 0, pend; + word paccess; + do { + paccess = access; + err(T32_GetRam(&pstart, &pend, &paccess)); + if(paccess != DISCOVER_END){ + map.push_back(std::make_pair( pstart, pend )); + } + } while(paccess != DISCOVER_END); +} + +bool T32Connector::scriptRunning() { + int retval = 0; + err(T32_GetPracticeState( &retval )); + return (retval == 1); +} + +int T32Connector::getState() { + int retval = 0; + err(T32_GetState( &retval )); + return retval; +} + + +/* Default T32 error handler */ +bool T32Connector::err(int ernum){ + if(ernum != 0){ + m_log << "Error: " << ernum << std::endl; + return false; + } + return true; } -} - diff --git a/debuggers/t32/src/main.cc b/debuggers/t32/src/main.cc index 3577ad0a..6adb332c 100644 --- a/debuggers/t32/src/main.cc +++ b/debuggers/t32/src/main.cc @@ -15,7 +15,7 @@ #include #include #include - +#include #include "config/VariantConfig.hpp" #include "sal/SALInst.hpp" #include "optionparser.h" @@ -24,14 +24,6 @@ #include "T32Connector.hpp" using namespace std; -/* Default T32 error handler */ -void err(int ernum){ - if(err != 0){ - cerr << "Error: " << err << endl; - //exit(-1); - } -} - static fail::T32Connector t32; //!< Program options @@ -62,7 +54,7 @@ int main(int argc, char** argv){ return 1; } - if ( options[HELP] ) // || argc == 0 || options[RUN].count() == 0) // to enforce -s + if ( options[HELP] ) // || argc == 0 || options[RUN].count() == 0) // to enforce -s { int columns = getenv("COLUMNS")? atoi(getenv("COLUMNS")) : 80; option::printUsage(fwrite, stdout, usage, columns); @@ -70,39 +62,23 @@ int main(int argc, char** argv){ } if(options[RUN].count()){ - cout << "Script: " << options[RUN].first()->arg << endl; + t32.setScript(options[RUN].first()->arg); } - char hostname[] = "localhost"; if(options[T32HOST].count()){ - cout << "T32 Hostname: " << options[T32HOST].first()->arg << endl; + t32.setHostname(options[T32HOST].first()->arg); } - char port[] = "20010"; if(options[PORT].count()){ - cout << "T32 Port: " << options[PORT].first()->arg << endl; + t32.setPort(options[PORT].first()->arg); } - char packlen[] = "1024"; if(options[PACKLEN].count()){ - cout << "T32 Packet Length: " << options[PACKLEN].first()->arg << endl; + t32.setPacketlength(options[PACKLEN].first()->arg); } - - // Setup connection to Lauterbach - cout << "Lauterbach remote connection" << endl; - int error; - - cout << "[T32] Connecting to " << hostname << ":" << port << " Packlen: " << packlen << endl; - T32_Config("NODE=", hostname); - T32_Config("PACKLEN=", packlen); - T32_Config("PORT=", port); - - cout << "[T32] Init." << endl; - err(T32_Init()); - - cout << "[T32] Attach." << endl; - err(T32_Attach(T32_DEV_ICD)); + // Initialize T32 + t32.startup(); // Let the SimulatorController do the dirty work. diff --git a/src/core/sal/t32/T32Listener.ah b/src/core/sal/t32/T32Listener.ah index 802c1589..e37a4a37 100644 --- a/src/core/sal/t32/T32Listener.ah +++ b/src/core/sal/t32/T32Listener.ah @@ -17,7 +17,7 @@ aspect T32Listener bool onAddition() { // Setup Breakpoint in T32 - return T32_WriteBreakpoint( m_WatchInstrPtr, T32::MEMACCESS::PROGRAM, T32::BP::EXECUTION, 1) == 0; + return T32_WriteBreakpoint( m_WatchInstrPtr, T32::MEMACCESS::PROGRAM, T32::BP::EXECUTION /* | T32::BP::READ ?? */, 1) == 0; } void onDeletion() @@ -27,6 +27,53 @@ aspect T32Listener // TODO Error handling } }; + + advice "fail::BPRangeListener" : slice class + { + public: + bool onAddition() + { + // Calculate address range + address_t range = m_WatchEndAddr - m_WatchStartAddr; // range / sizeof(address_t) ??! + // Setup Breakpoint in T32 + return T32_WriteBreakpoint( m_WatchStartAddr, T32::MEMACCESS::PROGRAM, T32::BP::EXECUTION, range) == 0; + } + + void onDeletion() + { + // Calculate address range + address_t range = m_WatchEndAddr - m_WatchStartAddr; // range / sizeof(address_t) ??! + // Setup Breakpoint in T32 + T32_WriteBreakpoint( m_WatchStartAddr, T32::MEMACCESS::PROGRAM, T32::BP::CLEAR, range); + // TODO Error handling + } + }; + + advice "fail::MemAccessListener" : slice class + { + int m_t32access; + public: + bool onAddition() + { + // Setup Breakpoint in T32 + switch(m_WatchType) { + case MemAccessEvent::MEM_READ: m_t32access = T32::BP::READ; break; + case MemAccessEvent::MEM_WRITE: m_t32access = T32::BP::WRITE; break; + case MemAccessEvent::MEM_READWRITE: m_t32access = (T32::BP::READ | T32::BP::WRITE); break; + default: return false; + } + + return T32_WriteBreakpoint( m_WatchAddr, T32::MEMACCESS::DATA, m_t32access, m_WatchWidth) == 0; + } + + void onDeletion() + { + // Setup Breakpoint in T32 + T32_WriteBreakpoint( m_WatchAddr, T32::MEMACCESS::DATA, m_t32access, m_WatchWidth); + // TODO Error handling + } + }; + }; #endif // BUILD_T32 && CONFIG_EVENT_BREAKPOINTS diff --git a/src/experiments/vezs-example/experiment.cc b/src/experiments/vezs-example/experiment.cc index bcb4262d..fc7b2700 100644 --- a/src/experiments/vezs-example/experiment.cc +++ b/src/experiments/vezs-example/experiment.cc @@ -39,19 +39,33 @@ bool VEZSExperiment::run() mm.setByte(targetaddress, 0x42); mm.getByte(targetaddress); - uint8_t tb[] = {0xaa, 0xbb, 0xcc, 0xdd}; + uint8_t tb[] = {0xab, 0xbb, 0xcc, 0xdd}; mm.setBytes(targetaddress, 4, tb); *((uint32_t*)(tb)) = 0; // clear array. // read back bytes mm.getBytes(targetaddress, 4, tb); -// Test Breakpoints - address_t address = 0x11223344; +// Test Listeners + address_t address = 0xee; BPSingleListener bp(address); simulator.addListener(&bp); - simulator.clearListeners(); + BPRangeListener rbp(0xef, 0xff); + simulator.addListener(&rbp); + MemAccessListener l_mem_w(0x1111, MemAccessEvent::MEM_WRITE); + l_mem_w.setWatchWidth(16); + simulator.addListener(&l_mem_w); + + MemAccessListener l_mem_r(0x2222, MemAccessEvent::MEM_READ); + l_mem_r.setWatchWidth(16); + simulator.addListener(&l_mem_r); + + MemAccessListener l_mem_rw(0x3333, MemAccessEvent::MEM_READWRITE); + l_mem_rw.setWatchWidth(16); + simulator.addListener(&l_mem_rw); + + simulator.clearListeners(); // resume backend. // simulator.resume();