T32: FailT32 support for Cortex-M3
Currently working: - Connect/Disconnect, Read CPU info - CMM Script generation and T32 startup via cmake (make runt32) - Read/Write Register, Read Program Pointer - Read/Write Memory - Single Breakpoint - Setting Memory Breakpoint TODO: - Fix mock aspect for T32_GetRam. - Fix Thumb2 bit in function addresses from ELFReader - Evaluate memory breakpoint hit
This commit is contained in:
@ -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)
|
||||
|
||||
|
||||
@ -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."
|
||||
)
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
|
||||
58
debuggers/t32/cmm/config.t32.usb.in
Normal file
58
debuggers/t32/cmm/config.t32.usb.in
Normal file
@ -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@
|
||||
@ -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
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#include <vector>
|
||||
|
||||
#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
|
||||
|
||||
8
debuggers/t32/include/t32config.hpp.in
Normal file
8
debuggers/t32/include/t32config.hpp.in
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef __T32CONFIG_HPP__
|
||||
#define __T32CONFIG_HPP__
|
||||
|
||||
#define T32_PORTNUM "@T32_PORTNUM@"
|
||||
#define T32_PACKLEN "@T32_PACKLEN@"
|
||||
|
||||
#endif
|
||||
|
||||
@ -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<char**>(&m_cpustring), &fpu, &endian, &tmp))) { return false; }
|
||||
if(!err(T32_GetCpuInfo( reinterpret_cast<char**>(&cpuname), &fpu, &endian, &tmp))) { return false; }
|
||||
if(!err(T32_GetCpuInfo( (&cpuname), &fpu, &endian, &tmp))) { return false; }
|
||||
m_littleendian = (endian != 0);
|
||||
m_cpustring = reinterpret_cast<const char*>(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){
|
||||
|
||||
@ -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.
|
||||
|
||||
Reference in New Issue
Block a user