diff --git a/debuggers/t32/CMakeLists.txt b/debuggers/t32/CMakeLists.txt index 841fdd65..86000cae 100644 --- a/debuggers/t32/CMakeLists.txt +++ b/debuggers/t32/CMakeLists.txt @@ -1,5 +1,11 @@ +# T32 remote specific configuration options +OPTION( T32_MOCK_API "Intercept remote calls to T32 for debugging" OFF) -include_directories(include) +set(T32_PORTNUM 20000 CACHE PATH "TCP Port number for remote access.") +set(T32_PACKLEN 1024 CACHE INTERNAL "TCP Packet size, max. 1024") +configure_file( include/t32config.hpp.in ${CMAKE_BINARY_DIR}/include/t32config.hpp) + +include_directories(include ${CMAKE_BINARY_DIR}/include) include_directories(${CMAKE_BINARY_DIR}/src/core) diff --git a/debuggers/t32/cmm/CMakeLists.txt b/debuggers/t32/cmm/CMakeLists.txt index c69fcdb6..d982fee0 100644 --- a/debuggers/t32/cmm/CMakeLists.txt +++ b/debuggers/t32/cmm/CMakeLists.txt @@ -1,11 +1,36 @@ - ## Setup T32 target architecture for startup scripts + +if(EXISTS $ENV{T32SYS}) + SET(T32_SYS $ENV{T32SYS}) + message(STATUS "[FAIL*] T32 base directory: T32SYS=${T32_SYS}") +else() + message(FATAL_ERROR "Please set env variable T32SYS to a valid T32 installation base directory.") +endif() + +if(EXISTS $ENV{FAIL_ELF_PATH}) + SET(T32_ELF_PATH $ENV{FAIL_ELF_PATH}) + message(STATUS "[FAIL*] T32 ELF under test: ${T32_ELF_PATH}") +else() + message(FATAL_ERROR "Please set the FAIL_ELF_PATH enviroment variable to the binary under test.") +endif() + + + file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/cmm) +configure_file(config.t32.usb.in ${PROJECT_BINARY_DIR}/cmm/config.t32.usb) configure_file(t32.cmm ${PROJECT_BINARY_DIR}/cmm/t32.cmm COPYONLY) set(T32_ARCHITECTURE armm3 CACHE PATH "Setup target architecture for default cmm scripts (currently only armm3)") -message(STATUS "[FAIL*] T32 Architecture: ${T32_ARCHITECTURE}") +set(T32_EXE "${T32_SYS}/bin/pc_linux/" CACHE INTERNAL "") # TODO: set pc_linux64 for 64 bit systems add_subdirectory(${T32_ARCHITECTURE}) -message(STATUS "[FAIL*] T32 CPU name: ${T32_CPUNAME}") +message(STATUS "[FAIL*] T32 Architecture: ${T32_ARCHITECTURE}") +message(STATUS "[FAIL*] T32 CPU name: ${T32_CPUNAME}") +message(STATUS "[FAIL*] T32 Executable: ${T32_EXE}") + +add_custom_target(runt32 + COMMAND T32CONFIG=${PROJECT_BINARY_DIR}/cmm/config.t32.usb ${T32_EXE} & + WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/cmm" + COMMENT "Starting Lauterbach." + ) diff --git a/debuggers/t32/cmm/armm3/CMakeLists.txt b/debuggers/t32/cmm/armm3/CMakeLists.txt index a99bf6d2..c2a213ec 100644 --- a/debuggers/t32/cmm/armm3/CMakeLists.txt +++ b/debuggers/t32/cmm/armm3/CMakeLists.txt @@ -1,9 +1,15 @@ ### Configure cmm Scripts for ARM Cortex-M3 +if(EXISTS $ENV{T32SYS}) + SET(T32_SYS $ENV{T32SYS}) +else(EXISTS $ENV{KESOROOTPATH}) + message(FATAL_ERROR "Please set env variable T32SYS to valid T32 installation base directory.") +endif(EXISTS $ENV{T32SYS}) + +set(T32_EXE "${T32_EXE}/t32marm" CACHE INTERNAL "") set(T32_CPUNAME STM32F103RG CACHE PATH "CPU name for SYSTEM.CPU call. (e.g. STM32F103RG)") configure_file(armm3cfg.cmm.in ${PROJECT_BINARY_DIR}/cmm/armm3cfg.cmm) configure_file(init.cmm ${PROJECT_BINARY_DIR}/cmm/init.cmm COPYONLY) configure_file(loadelf.cmm ${PROJECT_BINARY_DIR}/cmm/loadelf.cmm COPYONLY) configure_file(t32term.cmm ${PROJECT_BINARY_DIR}/cmm/t32term.cmm COPYONLY) - diff --git a/debuggers/t32/cmm/config.t32.usb.in b/debuggers/t32/cmm/config.t32.usb.in new file mode 100644 index 00000000..cc86d6f7 --- /dev/null +++ b/debuggers/t32/cmm/config.t32.usb.in @@ -0,0 +1,58 @@ +; +;please refer the installation guide for more information +;about your configuration +; +; +;uncomment the following 3 lines if you don't use already environment variables +;changes to the actual directory names are necessary +;OS= +;SYS=/opt/t32 +;TMP=/usr/tmp + +; +;uncomment the following 4 lines if you use PowerTrace, PowerNexus or PowerDebugEthernet +;with onhost driver executable (t32m*) via ethernet interface +;the nodename is only the default name, please replace it with the actual node name +;PBI= +;NET +;NODE=t32 +;PACKLEN=1024 + +;uncomment the following 2 lines if you use PowerTrace, PowerNexus, PowerDebugEthernet or +;PowerDebugInterface USB with onhost driver executable (t32m*) via USB interface +;please refer the installation manual (file icd_quick_installation.pdf) about more details +;concerning USB driver installation +PBI= +USB + +; +;uncomment the following 3 lines if you use an ICE or PodbusEthernetController +;with standard hostdriver executable (t32cde) via ethernet interface +;the nodename is only the default name, please replace it with the actual node name +;LINK=NET +;NODE=t32 +;PACKLEN=1024 + +;uncomment the following 1 lines if you use SCSI interface (ICE) +;LINK=SCSI + +;uncomment the following 3 lines if you want to use TRACE32 fonts +;SCREEN= +;FONT=DEC +;FONT=SMALL + +;uncomment the following 2 lines if you want to use TRACE32 bitmap fonts +;SCREEN= +;FONTMODE=3 + +;uncomment the following 2 lines if you use OPENWINDOWS +;SCREEN= +;WMGR=OW16 + +;uncomment the following 2 lines if you use MOTIF +;SCREEN= +;WMGR=MOTIF16 + +RCL=NETASSIST +PACKLEN=1024 +PORT=@T32_PORTNUM@ diff --git a/debuggers/t32/cmm/t32.cmm b/debuggers/t32/cmm/t32.cmm index 97bbf5f7..ecdc50e7 100644 --- a/debuggers/t32/cmm/t32.cmm +++ b/debuggers/t32/cmm/t32.cmm @@ -1,10 +1,10 @@ ;===== Cortex-M3 Lauterbach initialisation ==== -&appimage="OS.ENV(FAIL_ELF_PATH)" +&appimage=OS.ENV(FAIL_ELF_PATH) DO init.cmm -VAr.Frame /LOCALS /CALLER +;VAr.Frame /LOCALS /CALLER REGISTER /SPOTLIGHT -Data.ListAsm +;Data.ListAsm diff --git a/debuggers/t32/include/T32Connector.hpp b/debuggers/t32/include/T32Connector.hpp index 667122c8..27938962 100644 --- a/debuggers/t32/include/T32Connector.hpp +++ b/debuggers/t32/include/T32Connector.hpp @@ -6,6 +6,7 @@ #include #include "sal/SALInst.hpp" +#include "t32config.hpp" namespace fail { @@ -16,7 +17,7 @@ namespace fail { */ class T32Connector { public: - T32Connector() : m_hostname("localhost"), m_port("20010"), m_packetlength("1024"), m_log("T32", false), m_connection_established(false) { }; + T32Connector() : m_hostname("localhost"), m_port(T32_PORTNUM), m_packetlength(T32_PACKLEN), m_log("T32", false), m_connection_established(false) { }; T32Connector(const char* hostname, const char* port, const char* packlen) : m_hostname(hostname), m_port(port), m_packetlength(packlen), m_log("T32", false), m_connection_established(false) { }; @@ -48,6 +49,9 @@ namespace fail { bool isBigEndian(void) const { return !m_littleendian; }; bool isLittleEndian(void) const { return m_littleendian; }; + void showDataRegions(void) const { showMemoryRegions(m_data_memory_map); }; + void showProgramRegions(void) const { showMemoryRegions(m_program_memory_map); }; + 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 @@ -57,7 +61,8 @@ namespace fail { std::string m_cpustring; - typedef std::vector< std::pair< address_t, address_t > > memory_map_t; + typedef std::pair< address_t, address_t > region_t; + typedef std::vector< region_t > memory_map_t; memory_map_t m_data_memory_map; memory_map_t m_program_memory_map; @@ -78,6 +83,7 @@ namespace fail { enum MemoryDiscoverCommand_t { DISCOVER_PROGRAM_RAM = 2, DISCOVER_DATA_RAM = 1, DISCOVER_END = 0, }; void discoverMemory(int discovertype, memory_map_t & map); + void showMemoryRegions(const memory_map_t & map) const; }; } // end-of-namespace fail diff --git a/debuggers/t32/include/t32config.hpp.in b/debuggers/t32/include/t32config.hpp.in new file mode 100644 index 00000000..81bfbf3b --- /dev/null +++ b/debuggers/t32/include/t32config.hpp.in @@ -0,0 +1,8 @@ +#ifndef __T32CONFIG_HPP__ +#define __T32CONFIG_HPP__ + +#define T32_PORTNUM "@T32_PORTNUM@" +#define T32_PACKLEN "@T32_PACKLEN@" + +#endif + diff --git a/debuggers/t32/src/T32Connector.cc b/debuggers/t32/src/T32Connector.cc index 093af5f8..0ebbe10f 100644 --- a/debuggers/t32/src/T32Connector.cc +++ b/debuggers/t32/src/T32Connector.cc @@ -14,27 +14,34 @@ T32Connector::~T32Connector() { 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); + 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; } + if(!err(T32_Init()) ) { return false; } m_log << "Attach." << std::endl; - if(!err(T32_Attach(T32_DEV_ICD)) ) { return false; } + if(!err(T32_Attach(T32_DEV_ICD)) ) { return false; } word tmp, fpu, endian; - char* cpuname[128]; + char * cpuname; //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; } + if(!err(T32_GetCpuInfo( (&cpuname), &fpu, &endian, &tmp))) { return false; } m_littleendian = (endian != 0); m_cpustring = reinterpret_cast(cpuname); + m_log << "Attached to: " << m_cpustring << (isBigEndian() == true ? " (BIG-endian)" : " (little-endian)") << std::endl; - m_log << "Attached to: " << m_cpustring << std::endl; +// discoverMemory(DISCOVER_PROGRAM_RAM, m_program_memory_map); +// discoverMemory(DISCOVER_DATA_RAM, m_data_memory_map); - // discoverMemory(DISCOVER_PROGRAM_RAM, m_program_memory_map); - // discoverMemory(DISCOVER_DATA_RAM, m_data_memory_map); + if(m_data_memory_map.size() > 0) { + showDataRegions(); + } + + if(m_program_memory_map.size() > 0) { + showProgramRegions(); + } m_connection_established = true; // TODO send init script. @@ -44,7 +51,9 @@ bool T32Connector::startup(){ void T32Connector::discoverMemory(int access, memory_map_t& map) { dword pstart = 0, pend; word paccess; + int c = 1; do { + std::cout << "Discovering Memory Regions: " << c++ << std::endl; paccess = access; err(T32_GetRam(&pstart, &pend, &paccess)); if(paccess != DISCOVER_END){ @@ -66,6 +75,14 @@ int T32Connector::getState() const { } +void T32Connector::showMemoryRegions(const memory_map_t& map) const { + + for(int i = 0; i < map.size(); i++){ + std::cout << "[" << i << "] 0x" << std::hex << map[i].first << " - 0x" << std::hex << map[i].second << std::endl; + } +} + + /* Default T32 error handler */ bool T32Connector::err(int errornum) const { if(errornum != 0){ diff --git a/debuggers/t32/src/main.cc b/debuggers/t32/src/main.cc index 6adb332c..6a01c85e 100644 --- a/debuggers/t32/src/main.cc +++ b/debuggers/t32/src/main.cc @@ -78,7 +78,10 @@ int main(int argc, char** argv){ } // Initialize T32 - t32.startup(); + if(t32.startup() == false){ + cout << "Could not connect to Lauterbach :(" << endl; + return -1; + } // Let the SimulatorController do the dirty work. diff --git a/src/core/config/VariantConfig.hpp.in b/src/core/config/VariantConfig.hpp.in index 4cb980a3..54de68d8 100644 --- a/src/core/config/VariantConfig.hpp.in +++ b/src/core/config/VariantConfig.hpp.in @@ -6,6 +6,7 @@ #cmakedefine BUILD_OVP #cmakedefine BUILD_QEMU #cmakedefine BUILD_T32 +#cmakedefine T32_MOCK_API #cmakedefine BUILD_X86 #cmakedefine BUILD_ARM diff --git a/src/core/sal/t32/T32ArmCPU.cc b/src/core/sal/t32/T32ArmCPU.cc index d6704deb..1743b50a 100644 --- a/src/core/sal/t32/T32ArmCPU.cc +++ b/src/core/sal/t32/T32ArmCPU.cc @@ -22,6 +22,7 @@ regdata_t T32ArmCPU::getRegisterContent(Register* reg) const return m_regbuffer[reg->getIndex()]; } else { /// TODO Error handling! + std::cout << "could not read register :(" << std::endl; } } return 0; // we should not come here. @@ -31,12 +32,15 @@ void T32ArmCPU::setRegisterContent(Register* reg, regdata_t value) { uint64_t mask = (1 << reg->getIndex()); + // set value to be set by T32: + m_regbuffer[reg->getIndex()] = value; if(mask){ if( T32_WriteRegister(static_cast(mask & lower), static_cast(mask >> 32), m_regbuffer) == 0 ){ // No error, return value. return; } else { /// TODO Error handling! + std::cout << "could not write register :(" << std::endl; } } } diff --git a/src/core/sal/t32/T32Mock.ah b/src/core/sal/t32/T32Mock.ah index eeed5b32..f62e4182 100644 --- a/src/core/sal/t32/T32Mock.ah +++ b/src/core/sal/t32/T32Mock.ah @@ -2,12 +2,15 @@ #define __T32MOCK_AH__ #include +#include "config/VariantConfig.hpp" -#if defined(BUILD_T32) // && defined(T32MOCK) +#if defined(BUILD_T32) && defined(T32_MOCK_API) +#warning "T32 remote calls are intercepted by T32Mock aspect!" /* Mock aspect for testing without T32 HW attached. */ aspect T32Mock { + // TODO: Let T32_GetRam's third parameter set to 0. advice call("% T32_% (...)") : around () { std::cout << "[T32 MOCK] " << JoinPoint::signature() << " ("; @@ -21,6 +24,5 @@ aspect T32Mock *tjp->result() = 0; } }; - #endif // BUILD_T32 && CONFIG_EVENT_BREAKPOINTS #endif // __T32MOCK_AH__ diff --git a/src/experiments/vezs-example/experiment.cc b/src/experiments/vezs-example/experiment.cc index fc7b2700..1c29895c 100644 --- a/src/experiments/vezs-example/experiment.cc +++ b/src/experiments/vezs-example/experiment.cc @@ -26,13 +26,21 @@ bool VEZSExperiment::run() m_log << "Instruction Pointer: 0x" << hex << simulator.getCPU(0).getInstructionPointer() << endl; // Test register access Register* reg = simulator.getCPU(0).getRegister(RI_R1); - m_log << "Register R2: 0x" << hex << simulator.getCPU(0).getRegisterContent(reg) << endl; - - reg = simulator.getCPU(0).getRegister(RI_R2); m_log << "Register R1: 0x" << hex << simulator.getCPU(0).getRegisterContent(reg) << endl; + reg = simulator.getCPU(0).getRegister(RI_R2); + m_log << "Register R2: 0x" << hex << simulator.getCPU(0).getRegisterContent(reg) << endl; simulator.getCPU(0).setRegisterContent(reg, 0x23); + reg = simulator.getCPU(0).getRegister(RI_R3); + m_log << "Register R3: 0x" << hex << simulator.getCPU(0).getRegisterContent(reg) << endl; + + simulator.terminate(); + +// STOP HERE + + + // Test Memory access address_t targetaddress = 0x12345678; MemoryManager& mm = simulator.getMemoryManager();