From 96bc39c05d85a8d4b0e409c17dd30fc05cd11894 Mon Sep 17 00:00:00 2001 From: Martin Hoffmann Date: Wed, 20 Mar 2013 17:17:38 +0100 Subject: [PATCH] T32 Simulator: Basic Instruction set sim for ARMM3 The T32 can simulate bare instruction sets without periphery. For the Cortex-M3 we have complete NVIC model including Systick Timer. Currently a simple CiAO can run on the simulator. TODO: - Let memlogger log all memory accesses. - Interact with FailT32 for a complete simulation/FI --- debuggers/t32/CMakeLists.txt | 5 +- debuggers/t32/api/hremote.cc | 5 +- debuggers/t32/cmm/armm3/init.cmm | 29 - debuggers/t32/sim/CMakeLists.txt | 4 + debuggers/t32/sim/armm3/CMakeLists.txt | 1 + debuggers/t32/sim/armm3/nvic/CMakeLists.txt | 17 + debuggers/t32/sim/armm3/nvic/nvic.c | 625 +++++++++++++ debuggers/t32/sim/armm3/nvic/nvic.def | 3 + debuggers/t32/sim/armm3/nvic/nvic.h | 412 ++++++++ debuggers/t32/sim/armm3/nvic/nvic_id_space.c | 75 ++ .../t32/sim/armm3/nvic/nvic_interrupt_type.c | 47 + debuggers/t32/sim/armm3/nvic/nvic_nvic.c | 263 ++++++ .../sim/armm3/nvic/nvic_software_trigger.c | 25 + .../armm3/nvic/nvic_system_control_block.c | 873 +++++++++++++++++ .../nvic/nvic_system_control_block_cpuid.c | 37 + .../t32/sim/armm3/nvic/nvic_system_timer.c | 118 +++ debuggers/t32/sim/demo/demoport/demoport.c | 876 ++++++++++++++++++ debuggers/t32/sim/demo/demoport/demoport.cmm | 30 + debuggers/t32/sim/demo/demoport/demoport.def | 7 + debuggers/t32/sim/demo/demoport/demoport.dll | Bin 0 -> 56920 bytes debuggers/t32/sim/demo/demoport/demoport.per | 44 + debuggers/t32/sim/demo/demoport/makefile | 10 + debuggers/t32/sim/demo/demoport/makehp | 7 + debuggers/t32/sim/demo/demoport/makelinux | 7 + debuggers/t32/sim/demo/demoport/makesun | 7 + debuggers/t32/sim/demo/demoport/simul.c | 532 +++++++++++ debuggers/t32/sim/demo/demoport/simul.h | 551 +++++++++++ debuggers/t32/sim/demo/demoport/t32.cmm | 27 + debuggers/t32/sim/demo/demoport/trans.tbl | 12 + debuggers/t32/sim/include/simul.c | 532 +++++++++++ debuggers/t32/sim/include/simul.h | 553 +++++++++++ debuggers/t32/sim/memlogger/CMakeLists.txt | 10 + debuggers/t32/sim/memlogger/memlogger.c | 78 ++ debuggers/t32/src/t32cli.cc | 6 +- .../t32/cmm => scripts/t32cmm}/CMakeLists.txt | 15 +- .../t32cmm}/armm3/CMakeLists.txt | 13 +- .../t32cmm}/armm3/armm3cfg.cmm.in | 0 scripts/t32cmm/armm3/init.cmm.in | 64 ++ .../cmm => scripts/t32cmm}/armm3/loadelf.cmm | 0 .../cmm => scripts/t32cmm}/armm3/t32term.cmm | 0 .../t32cmm/config.t32.in | 4 +- .../cmm/t32.cmm => scripts/t32cmm/t32.cmm.in | 2 +- 42 files changed, 5880 insertions(+), 46 deletions(-) delete mode 100644 debuggers/t32/cmm/armm3/init.cmm create mode 100644 debuggers/t32/sim/CMakeLists.txt create mode 100644 debuggers/t32/sim/armm3/CMakeLists.txt create mode 100644 debuggers/t32/sim/armm3/nvic/CMakeLists.txt create mode 100644 debuggers/t32/sim/armm3/nvic/nvic.c create mode 100644 debuggers/t32/sim/armm3/nvic/nvic.def create mode 100644 debuggers/t32/sim/armm3/nvic/nvic.h create mode 100644 debuggers/t32/sim/armm3/nvic/nvic_id_space.c create mode 100644 debuggers/t32/sim/armm3/nvic/nvic_interrupt_type.c create mode 100644 debuggers/t32/sim/armm3/nvic/nvic_nvic.c create mode 100644 debuggers/t32/sim/armm3/nvic/nvic_software_trigger.c create mode 100644 debuggers/t32/sim/armm3/nvic/nvic_system_control_block.c create mode 100644 debuggers/t32/sim/armm3/nvic/nvic_system_control_block_cpuid.c create mode 100644 debuggers/t32/sim/armm3/nvic/nvic_system_timer.c create mode 100644 debuggers/t32/sim/demo/demoport/demoport.c create mode 100644 debuggers/t32/sim/demo/demoport/demoport.cmm create mode 100644 debuggers/t32/sim/demo/demoport/demoport.def create mode 100644 debuggers/t32/sim/demo/demoport/demoport.dll create mode 100644 debuggers/t32/sim/demo/demoport/demoport.per create mode 100644 debuggers/t32/sim/demo/demoport/makefile create mode 100644 debuggers/t32/sim/demo/demoport/makehp create mode 100644 debuggers/t32/sim/demo/demoport/makelinux create mode 100644 debuggers/t32/sim/demo/demoport/makesun create mode 100644 debuggers/t32/sim/demo/demoport/simul.c create mode 100644 debuggers/t32/sim/demo/demoport/simul.h create mode 100644 debuggers/t32/sim/demo/demoport/t32.cmm create mode 100644 debuggers/t32/sim/demo/demoport/trans.tbl create mode 100644 debuggers/t32/sim/include/simul.c create mode 100644 debuggers/t32/sim/include/simul.h create mode 100644 debuggers/t32/sim/memlogger/CMakeLists.txt create mode 100644 debuggers/t32/sim/memlogger/memlogger.c rename {debuggers/t32/cmm => scripts/t32cmm}/CMakeLists.txt (67%) rename {debuggers/t32/cmm => scripts/t32cmm}/armm3/CMakeLists.txt (71%) rename {debuggers/t32/cmm => scripts/t32cmm}/armm3/armm3cfg.cmm.in (100%) create mode 100644 scripts/t32cmm/armm3/init.cmm.in rename {debuggers/t32/cmm => scripts/t32cmm}/armm3/loadelf.cmm (100%) rename {debuggers/t32/cmm => scripts/t32cmm}/armm3/t32term.cmm (100%) rename debuggers/t32/cmm/config.t32.usb.in => scripts/t32cmm/config.t32.in (98%) rename debuggers/t32/cmm/t32.cmm => scripts/t32cmm/t32.cmm.in (79%) diff --git a/debuggers/t32/CMakeLists.txt b/debuggers/t32/CMakeLists.txt index 86000cae..ccf25464 100644 --- a/debuggers/t32/CMakeLists.txt +++ b/debuggers/t32/CMakeLists.txt @@ -9,7 +9,8 @@ include_directories(include ${CMAKE_BINARY_DIR}/include) include_directories(${CMAKE_BINARY_DIR}/src/core) + set(T32_ARCHITECTURE armm3 CACHE PATH "Setup target architecture for default cmm scripts (currently only armm3)") + add_subdirectory(api) add_subdirectory(src) -add_subdirectory(cmm) - +add_subdirectory(sim) diff --git a/debuggers/t32/api/hremote.cc b/debuggers/t32/api/hremote.cc index 252527f5..fdced808 100644 --- a/debuggers/t32/api/hremote.cc +++ b/debuggers/t32/api/hremote.cc @@ -2543,8 +2543,9 @@ int T32_CheckStateNotify(unsigned param1) case T32_E_BREAK: { - int state, err; - err = T32_GetState(&state); + int state; + //, err; + /*err =*/ T32_GetState(&state); switch (state) { case 0: break; /* system down */ case 1: break; /* system halted */ diff --git a/debuggers/t32/cmm/armm3/init.cmm b/debuggers/t32/cmm/armm3/init.cmm deleted file mode 100644 index db17a65e..00000000 --- a/debuggers/t32/cmm/armm3/init.cmm +++ /dev/null @@ -1,29 +0,0 @@ -;RESET - -&t32scriptdir=OS.PPD() - -;======================================================================== -; CPU setup - -SYStem.RESet - -if OS.FILE(&(t32scriptdir)/armm3cfg.cmm) -( - DO &(t32scriptdir)/armm3cfg.cmm -) - - -;======================================================================== -; Flash programming -; -DO &(t32scriptdir)/loadelf.cmm - - -;======================================================================== -; Optional Parts -if OS.FILE(&(t32scriptdir)/t32term.cmm) -( - DO &(t32scriptdir)/t32term.cmm -) - -ENDDO diff --git a/debuggers/t32/sim/CMakeLists.txt b/debuggers/t32/sim/CMakeLists.txt new file mode 100644 index 00000000..4677665d --- /dev/null +++ b/debuggers/t32/sim/CMakeLists.txt @@ -0,0 +1,4 @@ +include_directories(include) + +add_subdirectory(${T32_ARCHITECTURE}) +add_subdirectory(memlogger) diff --git a/debuggers/t32/sim/armm3/CMakeLists.txt b/debuggers/t32/sim/armm3/CMakeLists.txt new file mode 100644 index 00000000..bfaf8272 --- /dev/null +++ b/debuggers/t32/sim/armm3/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(nvic) diff --git a/debuggers/t32/sim/armm3/nvic/CMakeLists.txt b/debuggers/t32/sim/armm3/nvic/CMakeLists.txt new file mode 100644 index 00000000..a931041c --- /dev/null +++ b/debuggers/t32/sim/armm3/nvic/CMakeLists.txt @@ -0,0 +1,17 @@ +# NVIC simulation model for the T32 +set(SRCS + nvic.c + ../../include/simul.c # TODO we need a simul.c anywhere... + nvic_id_space.c + nvic_interrupt_type.c + nvic_nvic.c + nvic_software_trigger.c + nvic_system_control_block.c + nvic_system_control_block_cpuid.c + nvic_system_timer.c +) + +add_library(nvic SHARED ${SRCS}) +GET_TARGET_PROPERTY(__T32_NVIC_LIB nvic LOCATION) +SET(T32_NVIC_LIB "${__T32_NVIC_LIB}" CACHE INTERNAL "") + diff --git a/debuggers/t32/sim/armm3/nvic/nvic.c b/debuggers/t32/sim/armm3/nvic/nvic.c new file mode 100644 index 00000000..912163e9 --- /dev/null +++ b/debuggers/t32/sim/armm3/nvic/nvic.c @@ -0,0 +1,625 @@ +/*** +* Cortex-M3 NVIC Simulator (C) Lauterbach 2010 +* 08.03.2010 Sylwester Garncarek +***/ + +#include "nvic.h" +#include + +int setbit(simulWord32 v) +{ + int i; + for (i=0;i<32;i++) + { + if (v & (1 << i)) return i; + } + + return 0; +} + +unsigned long NVIC_reg_offsets[] = +{ +CMD_OFFSET,ICTR_OFFSET,STCSR_OFFSET,STRVR_OFFSET,STCVR_OFFSET,STCLVR_OFFSET,IRQSETENR_OFFSET,IRQCLRENR_OFFSET,IRQSETPER_OFFSET,IRQCLRPER_OFFSET, +IRQABR_OFFSET,IRQPR_OFFSET,CPUIDR_OFFSET,ICSR_OFFSET,VTOR_OFFSET,AIRCR_OFFSET,SCR_OFFSET,CCR_OFFSET,SHPR_OFFSET,SHCSR_OFFSET,CFSR_OFFSET, +HFSR_OFFSET,DFSR_OFFSET,MMAR_OFFSET,BFAR_OFFSET,AFSR_OFFSET,PFR0_OFFSET,PFR1_OFFSET,DFR0_OFFSET,AFR0_OFFSET,MMFR0_OFFSET,MMFR1_OFFSET,MMFR2_OFFSET, +MMFR3_OFFSET,ISAR0_OFFSET,ISAR1_OFFSET,ISAR2_OFFSET,ISAR3_OFFSET,ISAR4_OFFSET,STIR_OFFSET,PID4_OFFSET,PID5_OFFSET,PID6_OFFSET,PID7_OFFSET,PID0_OFFSET, +PID1_OFFSET,PID2_OFFSET,PID3_OFFSET,CID0_OFFSET,CID1_OFFSET,CID2_OFFSET,CID3_OFFSET,DHCSR_OFFSET, +#ifdef _DEBUG +GPIO_OFFSET, +#endif +}; + +unsigned long NVIC_reg_sizes[] = +{ +CMD_SIZE,ICTR_SIZE,STCSR_SIZE,STRVR_SIZE,STCVR_SIZE,STCLVR_SIZE,IRQSETENR_SIZE,IRQCLRENR_SIZE,IRQSETPER_SIZE,IRQCLRPER_SIZE,IRQABR_SIZE,IRQPR_SIZE,CPUIDR_SIZE, +ICSR_SIZE,VTOR_SIZE,AIRCR_SIZE,SCR_SIZE,CCR_SIZE,SHPR_SIZE,SHCSR_SIZE,CFSR_SIZE,HFSR_SIZE,DFSR_SIZE,MMAR_SIZE,BFAR_SIZE,AFSR_SIZE,PFR0_SIZE,PFR1_SIZE, +DFR0_SIZE,AFR0_SIZE,MMFR0_SIZE,MMFR1_SIZE,MMFR2_SIZE,MMFR3_SIZE,ISAR0_SIZE,ISAR1_SIZE,ISAR2_SIZE,ISAR3_SIZE,ISAR4_SIZE,STIR_SIZE,PID4_SIZE,PID5_SIZE, +PID6_SIZE,PID7_SIZE,PID0_SIZE,PID1_SIZE,PID2_SIZE,PID3_SIZE,CID0_SIZE,CID1_SIZE,CID2_SIZE,CID3_SIZE,DHCSR_SIZE, +#ifdef _DEBUG +GPIO_SIZE, +#endif +}; + +simulCallbackFunctionPtr NVIC_reg_read_callbacks[] = +{ +CMD_Read,ICTR_Read,STCSR_Read,STRVR_Read,STCVR_Read,STCLVR_Read,IRQSETENR_Read,IRQCLRENR_Read,IRQSETPER_Read,IRQCLRPER_Read,IRQABR_Read,IRQPR_Read,CPUIDR_Read, +ICSR_Read,VTOR_Read,AIRCR_Read,SCR_Read,CCR_Read,SHPR_Read,SHCSR_Read,CFSR_Read,HFSR_Read,DFSR_Read,MMAR_Read,BFAR_Read,AFSR_Read,/*PFR0_Read*/Feature_Read,/*PFR1_Read*/Feature_Read, +/*DFR0_Read*/Feature_Read,/*AFR0_Read*/Feature_Read,/*MMFR0_Read*/Feature_Read,/*MMFR1_Read*/Feature_Read,/*MMFR2_Read*/Feature_Read,/*MMFR3_Read*/Feature_Read,/*ISAR0_Read*/Feature_Read,/*ISAR1_Read*/Feature_Read,/*ISAR2_Read*/Feature_Read,/*ISAR3_Read*/Feature_Read,/*ISAR4_Read*/Feature_Read,/*STIR_Read*/NULL,/*PID4_Read*/ID_Read,/*PID5_Read*/ID_Read, +/*PID6_Read*/ID_Read,/*PID7_Read*/ID_Read,/*PID0_Read*/ID_Read,/*PID1_Read*/ID_Read,/*PID2_Read*/ID_Read,/*PID3_Read*/ID_Read,/*CID0_Read*/ID_Read,/*CID1_Read*/ID_Read,/*CID2_Read*/ID_Read,/*CID3_Read*/ID_Read,DHCSR_Read, +#ifdef _DEBUG +GPIO_Read, +#endif +}; + +simulCallbackFunctionPtr NVIC_reg_write_callbacks[] = +{ +CMD_Write,/*ICTR_Write*/NULL,STCSR_Write,STRVR_Write,STCVR_Write,/*STCLVR_Write*/NULL,IRQSETENR_Write,IRQCLRENR_Write,IRQSETPER_Write,IRQCLRPER_Write,/*IRQABR_Write*/NULL,IRQPR_Write,/*CPUIDR_Write*/NULL, +ICSR_Write,VTOR_Write,AIRCR_Write,SCR_Write,CCR_Write,SHPR_Write,SHCSR_Write,CFSR_Write,HFSR_Write,DFSR_Write,MMAR_Write,BFAR_Write,AFSR_Write,/*PFR0_Write*/NULL, +/*PFR1_Write*/NULL,/*DFR0_Write*/NULL,/*AFR0_Write*/NULL,/*MMFR0_Write*/NULL,/*MMFR1_Write*/NULL,/*MMFR2_Write*/NULL,/*MMFR3_Write*/NULL,/*ISAR0_Write*/NULL,/*ISAR1_Write*/NULL,/*ISAR2_Write*/NULL,/*ISAR3_Write*/NULL,/*ISAR4_Write*/NULL,STIR_Write, +/*PID4_Write*/NULL,/*PID5_Write*/NULL,/*PID6_Write*/NULL,/*PID7_Write*/NULL,/*PID0_Write*/NULL,/*PID1_Write*/NULL,/*PID2_Write*/NULL,/*PID3_Write*/NULL,/*CID0_Write*/NULL,/*CID1_Write*/NULL,/*CID2_Write*/NULL,/*CID3_Write*/NULL,DHCSR_Write, +#ifdef _DEBUG +GPIO_Write, +#endif +}; + +int NVIC_SysTick(simulProcessor processor, simulCallbackStruct *cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + + if ((IntCtrl->regs.stcvr & 0xFFFFFF) > 1) + { + IntCtrl->regs.stcvr = (IntCtrl->regs.stcvr & 0xFFFFFF) - 1; + } + else if ((IntCtrl->regs.stcvr & 0xFFFFFF) == 1) + { + IntCtrl->regs.stcsr |= REG_STCSR_COUNTFLAG; + + if (IntCtrl->regs.stcsr & REG_STCSR_TICKINT) + { + int wakeUpEvent = 0; + ChangePending(IRQNUM_SYSTICK,1); + Interrupt(processor,IntCtrl,wakeUpEvent); + } + + IntCtrl->regs.stcvr = IntCtrl->regs.strvr; + } + else + { + //nothing happens here + } + + return SIMUL_TIMER_OK; +} + +void NVIC_Init(simulProcessor processor,IntController *IntCtrl) +{ + simulWord from, to; + int i; + + for (i=0;ibaseaddress + NVIC_reg_offsets[i]; + to = IntCtrl->baseaddress + NVIC_reg_offsets[i]+ NVIC_reg_sizes[i] - 1; + if (NVIC_reg_read_callbacks[i]) SIMUL_RegisterBusReadCallback( processor, (simulCallbackFunctionPtr)NVIC_reg_read_callbacks[i], (simulPtr) IntCtrl, IntCtrl->bustype, &from, &to ); + if (NVIC_reg_write_callbacks[i]) SIMUL_RegisterBusWriteCallback( processor, (simulCallbackFunctionPtr)NVIC_reg_write_callbacks[i], (simulPtr) IntCtrl, IntCtrl->bustype, &from, &to ); + } +} + +static int SIMULAPI NVIC_Reset(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + + memset(&IntCtrl->regs, 0x00, sizeof(IntCtrl->regs)); + + IntCtrl->regs.ictr = 0; + IntCtrl->regs.stclvr = 0xC0000000; + IntCtrl->regs.stcsr = REG_STCSR_CLKSOURCE; + IntCtrl->regs.cpuidr = 0x411FC231; + IntCtrl->regs.pfr0 = 0x30; + IntCtrl->regs.pfr1 = 0x200; + IntCtrl->regs.dfr0 = 0x100000; + IntCtrl->regs.mmfr0 = 0x30; + IntCtrl->regs.isar0 = 0x01141110; + IntCtrl->regs.isar1 = 0x02111000; + IntCtrl->regs.isar2 = 0x21112231; + IntCtrl->regs.isar3 = 0x01111110; + IntCtrl->regs.isar4 = 0x01310102; + IntCtrl->regs.pid4 = 0x04; + IntCtrl->regs.pid1 = 0xB0; + IntCtrl->regs.pid2 = 0x1B; + IntCtrl->regs.cid0 = 0x0D; + IntCtrl->regs.cid1 = 0xE0; + IntCtrl->regs.cid2 = 0x05; + IntCtrl->regs.cid3 = 0xB1; + + IntCtrl->regs.dhcsr = 0x0; + + IntCtrl->regs.ccr = 0x200; + + memset(&IntCtrl->IrqActive, 0x00, sizeof(IntCtrl->IrqActive)); + memset(&IntCtrl->IrqEnable, 0x00, sizeof(IntCtrl->IrqEnable)); + memset(&IntCtrl->IrqPending, 0x00, sizeof(IntCtrl->IrqPending)); + memset(&IntCtrl->IrqPriority, 0x00, sizeof(IntCtrl->IrqPriority)); + + IntCtrl->IrqPriority[IRQNUM_RESET] = -3; + IntCtrl->IrqPriority[IRQNUM_NMI] = -2; + IntCtrl->IrqPriority[IRQNUM_HARDFAULT] = -1; + + IntCtrl->IrqEnable[IRQNUM_RESET] = 1; + IntCtrl->IrqEnable[IRQNUM_NMI] = 1; + IntCtrl->IrqEnable[IRQNUM_HARDFAULT] = 1; + IntCtrl->IrqEnable[IRQNUM_MEMFAULT] = 0; + IntCtrl->IrqEnable[IRQNUM_BUSFAULT] = 0; + IntCtrl->IrqEnable[IRQNUM_USAGEFAULT] = 0; + IntCtrl->IrqEnable[IRQNUM_SVCALL] = 1; + IntCtrl->IrqEnable[IRQNUM_DEBUG] = 1; + IntCtrl->IrqEnable[IRQNUM_PENDSV] = 1; + IntCtrl->IrqEnable[IRQNUM_SYSTICK] = 1; + + IntCtrl->CurrentIrqNum = 0; + + if (IntCtrl->timerrun) + { + SIMUL_StopTimer(processor, IntCtrl->timer); + IntCtrl->timerrun = 0; + } + + return SIMUL_RESET_OK; +} + +static int NVIC_PortChangeInternal(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 port_set, value = 0; + int wakeUpEvent = 0; + + port_set = cbs->x.port.newdata & (~cbs->x.port.olddata); + + if (port_set & 0x0001) + {/* RXEV */ + SIMUL_SetPort(processor, 0, 1, &value); + WakeUpFromWFE(processor,IntCtrl); + wakeUpEvent = 1; + } + + if (port_set & 0x0004) + {/* IRQNUM_NMI 2 */ + SIMUL_SetPort(processor, IRQNUM_NMI, 1, &value); + IntCtrl->IrqPending[IRQNUM_NMI]=1; + } + + if (port_set & 0x0008) + {/* IRQNUM_HARDFAULT 3 */ + SIMUL_SetPort(processor, IRQNUM_HARDFAULT, 1, &value); + IntCtrl->IrqPending[IRQNUM_HARDFAULT]=1; + } + + if (port_set & 0x0010) + {/* IRQNUM_MEMFAULT 4 */ + SIMUL_SetPort(processor, IRQNUM_MEMFAULT, 1, &value); + IntCtrl->IrqPending[IRQNUM_MEMFAULT]=1; + } + + if (port_set & 0x0020) + {/* IRQNUM_BUSFAULT 5 */ + SIMUL_SetPort(processor, IRQNUM_BUSFAULT, 1, &value); + IntCtrl->IrqPending[IRQNUM_BUSFAULT]=1; + } + + if (port_set & 0x0040) + {/* IRQNUM_USAGEFAULT 6 */ + SIMUL_SetPort(processor, IRQNUM_USAGEFAULT, 1, &value); + IntCtrl->IrqPending[IRQNUM_USAGEFAULT]=1; + } + + if (port_set & 0x0800) + {/* IRQNUM_SVCALL 11 */ + SIMUL_SetPort(processor, IRQNUM_SVCALL, 1, &value); + IntCtrl->IrqPending[IRQNUM_SVCALL]=1; + } + + if (port_set & 0x1000) + {/* IRQNUM_DEBUG 12 */ + SIMUL_SetPort(processor, IRQNUM_DEBUG, 1, &value); + IntCtrl->IrqPending[IRQNUM_DEBUG]=1; + } + + if (port_set & 0x4000) + {/* IRQNUM_PENDSV 14 */ + SIMUL_SetPort(processor, IRQNUM_PENDSV, 1, &value); + IntCtrl->IrqPending[IRQNUM_PENDSV]=1; + } + + if (port_set & 0x8000) + {/* IRQNUM_SYSTICK 15 */ + SIMUL_SetPort(processor, IRQNUM_SYSTICK, 1, &value); + IntCtrl->IrqPending[IRQNUM_SYSTICK]=1; + } + + Interrupt(processor,IntCtrl,wakeUpEvent); + + return SIMUL_PORT_OK; +} + +static int NVIC_PortChangeFault(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 port_set, value = 0; + + port_set = cbs->x.port.newdata & (~cbs->x.port.olddata); + + if (port_set) + { + int wakeUpEvent = 0; + + if (port_set & REG_CFSR_MMFSR_MASK) + { + IntCtrl->regs.cfsr |= (port_set & REG_CFSR_MMFSR_MASK); + ChangePending(IRQNUM_MEMFAULT,1); + while (port_set & REG_CFSR_MMFSR_MASK) + { + SIMUL_SetPort(processor, 16 + setbit(port_set & REG_CFSR_MMFSR_MASK), 1, &value); + port_set &= ~(1 << setbit(port_set)); + } + } + + if (port_set & REG_CFSR_BFSR_MASK) + { + IntCtrl->regs.cfsr |= (port_set & REG_CFSR_BFSR_MASK); + ChangePending(IRQNUM_BUSFAULT,1); + while (port_set & REG_CFSR_BFSR_MASK) + { + SIMUL_SetPort(processor, 16 + setbit(port_set & REG_CFSR_BFSR_MASK), 1, &value); + port_set &= ~(1 << setbit(port_set)); + } + } + + if (port_set & REG_CFSR_UFSR_MASK) + { + IntCtrl->regs.cfsr |= (port_set & REG_CFSR_UFSR_MASK); + ChangePending(IRQNUM_USAGEFAULT,1); + while (port_set & REG_CFSR_UFSR_MASK) + { + SIMUL_SetPort(processor, 16 + setbit(port_set & REG_CFSR_UFSR_MASK), 1, &value); + port_set &= ~(1 << setbit(port_set)); + } + } + + Interrupt(processor,IntCtrl,wakeUpEvent); + } + + return SIMUL_PORT_OK; +} + +static int NVIC_PortChangeHardFault(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 port_set, value = 0; + + port_set = cbs->x.port.newdata & (~cbs->x.port.olddata); + + if (port_set) + { + int wakeUpEvent = 0; + + if (port_set & REG_HFSR_MASK) + { + IntCtrl->regs.hfsr |= (port_set & REG_HFSR_MASK); + ChangePending(IRQNUM_DEBUG,1); + while (port_set & REG_HFSR_MASK) + { + SIMUL_SetPort(processor, 48 + setbit(port_set & REG_HFSR_MASK), 1, &value); + port_set &= ~(1 << setbit(port_set)); + } + } + + Interrupt(processor,IntCtrl,wakeUpEvent); + } + + return SIMUL_PORT_OK; +} + +static int NVIC_PortChangeDebugFault(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 port_set, value = 0; + + port_set = cbs->x.port.newdata & (~cbs->x.port.olddata); + + if (port_set) + { + int wakeUpEvent = 0; + + if (port_set & REG_DFSR_MASK) + { + IntCtrl->regs.dfsr |= (port_set & REG_DFSR_MASK); + ChangePending(IRQNUM_DEBUG,1); + while (port_set & REG_DFSR_MASK) + { + SIMUL_SetPort(processor, 80 + setbit(port_set & REG_DFSR_MASK), 1, &value); + port_set &= ~(1 << setbit(port_set)); + } + } + + Interrupt(processor,IntCtrl,wakeUpEvent); + } + + return SIMUL_PORT_OK; +} + +static int NVIC_ExternalIrqChange(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private, int offset, int len) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 port_set, port_clr, value = 0; + int wakeUpEvent = 0; + int i; + + port_set = cbs->x.port.newdata & (~cbs->x.port.olddata); + + if (port_set) + { + for (i=0;iIrqPending[16 + offset + i] && (_changePendingValue)) + { + if (IntCtrl->regs.scr & REG_SCR_SEVONPEND) WakeUpFromWFE(processor,IntCtrl); + } + + IntCtrl->IrqPending[16 + offset + i] = !!(_changePendingValue); + + + + SIMUL_SetPort(processor, offset + i, 1, &value); + } + } + } + + port_clr = ~cbs->x.port.newdata & cbs->x.port.olddata; + + if (port_clr) + { + for (i=0;iregs.dhcsr & REG_DHCSR_S_SLEEP) + { + simulWord port = 1; + IntCtrl->regs.dhcsr &= ~REG_DHCSR_S_SLEEP; + SIMUL_SetPort(processor, SIMUL_PORT_INTERRUPT, 1, &port); + } +} + +void RequestReset(simulProcessor processor) +{ + simulWord port = 1; + SIMUL_SetPort(processor, SIMUL_PORT_RESET, 1, &port); +} + +int SIMULAPI SIMUL_Init(simulProcessor processor, simulCallbackStruct *cbs) +{ + IntController *IntCtrl; + int i; + int (* ExternalIrqsCallbacks[8])(simulProcessor, simulCallbackStruct *, simulPtr); + + strcpy(cbs->x.init.modelname, __DATE__ " Cortex-M3 Interrupt Ctrl"); + IntCtrl = (IntController*) SIMUL_Alloc(processor, sizeof(IntController)); + IntCtrl->baseaddress = BASE_ADDRESS; + + if (cbs->x.init.argc == 1) + { + IntCtrl->bustype = cbs->x.init.argpbustype[0]; + IntCtrl->ExternalIrqPortsFirst = 112; + IntCtrl->ExternalIrqPortsCount = 240; + } + else if ((cbs->x.init.argc == 2) && (strcmp(cbs->x.init.argp[1], "noport") == 0)) + { + IntCtrl->bustype = cbs->x.init.argpbustype[0]; + IntCtrl->ExternalIrqPortsFirst = 0; + IntCtrl->ExternalIrqPortsCount = 0; + } + else if (cbs->x.init.argc == 3) + { + IntCtrl->bustype = cbs->x.init.argpbustype[0]; + if (cbs->x.init.argpport[1] < 112) + { + IntCtrl->ExternalIrqPortsFirst = 112; + SIMUL_Warning(processor, "First external interrupt port cannot be lower than 112"); + return SIMUL_INIT_FAIL; + } + else + { + IntCtrl->ExternalIrqPortsFirst = cbs->x.init.argpport[1]; + } + + IntCtrl->ExternalIrqPortsCount = cbs->x.init.argpport[2]; + } + else + { + SIMUL_Warning(processor, "Usage parameters: [( ) | noport]"); + return SIMUL_INIT_FAIL; + } + + if (IntCtrl->ExternalIrqPortsCount < 0) + { + SIMUL_Warning(processor, "Number of external interrupts cannot be less than zero"); + return SIMUL_INIT_FAIL; + } + + if (IntCtrl->ExternalIrqPortsCount > 240) + { + SIMUL_Warning(processor, "Maximum number of external interrupts is 240"); + return SIMUL_INIT_FAIL; + } + + SIMUL_RegisterResetCallback(processor, NVIC_Reset, (simulPtr)IntCtrl); + + SIMUL_RegisterPortChangeCallback(processor, NVIC_PortChangeInternal, (simulPtr)IntCtrl, 0, 16); + SIMUL_RegisterPortChangeCallback(processor, NVIC_PortChangeFault, (simulPtr)IntCtrl, 16, 32); + SIMUL_RegisterPortChangeCallback(processor, NVIC_PortChangeHardFault, (simulPtr)IntCtrl, 48, 32); + SIMUL_RegisterPortChangeCallback(processor, NVIC_PortChangeDebugFault, (simulPtr)IntCtrl, 80, 32); + + IntCtrl->timer = SIMUL_RegisterTimerCallback(processor, NVIC_SysTick, (simulPtr) IntCtrl); + IntCtrl->timerrun = 0; + + ExternalIrqsCallbacks[0] = NVIC_ExternalIrqChange_0_31; + ExternalIrqsCallbacks[1] = NVIC_ExternalIrqChange_32_63; + ExternalIrqsCallbacks[2] = NVIC_ExternalIrqChange_64_95; + ExternalIrqsCallbacks[3] = NVIC_ExternalIrqChange_96_127; + ExternalIrqsCallbacks[4] = NVIC_ExternalIrqChange_128_159; + ExternalIrqsCallbacks[5] = NVIC_ExternalIrqChange_160_191; + ExternalIrqsCallbacks[6] = NVIC_ExternalIrqChange_192_223; + ExternalIrqsCallbacks[7] = NVIC_ExternalIrqChange_224_240; + + for (i=0;iExternalIrqPortsCount;i+=32) + { + int width = ((i + 31) < IntCtrl->ExternalIrqPortsCount)?(32):(IntCtrl->ExternalIrqPortsCount - i); + SIMUL_RegisterPortChangeCallback(processor, ExternalIrqsCallbacks[i >> 5], (simulPtr)IntCtrl, i + IntCtrl->ExternalIrqPortsFirst, width); + } + + NVIC_Init(processor,IntCtrl); + NVIC_Reset(processor,cbs,IntCtrl); + + return SIMUL_INIT_OK; +} + +/************************* Bus Read, Write ************************/ +int BusRead(simulBusCallbackStruct * bus, simulWord32 * reg) +{ + switch (bus->width) + { + case 8: + *reg = (*reg & ~(0xff << ((bus->address & 0x3) << 3))) | ((bus->data&0xFF) << ((bus->address & 0x3) << 3)); + break; + case 16: + if (bus->address & 0x1) return SIMUL_MEMORY_FAIL; + *reg = (*reg & ~(0xffff << ((bus->address & 0x3) << 3))) | ((bus->data&0xFFFF) << ((bus->address & 0x3) << 3)); + break; + case 32: + if (bus->address & 0x3) return SIMUL_MEMORY_FAIL; + *reg = bus->data; + break; + default: + return SIMUL_MEMORY_FAIL; + } + return SIMUL_MEMORY_OK; +} + +int BusWrite(simulBusCallbackStruct * bus, simulWord32 * reg) +{ + switch (bus->width) + { + case 8: + bus->data = (*reg >> ((bus->address & 0x3) << 3)) & 0xff; + break; + case 16: + if (bus->address & 0x1) return SIMUL_MEMORY_FAIL; + bus->data = (*reg >> ((bus->address & 0x3) << 3)) & 0xffff; + break; + case 32: + if (bus->address & 0x3) return SIMUL_MEMORY_FAIL; + bus->data = *reg; + break; + default: + return SIMUL_MEMORY_FAIL; + } + return SIMUL_MEMORY_OK; +} + +void Interrupt(simulProcessor processor, simulPtr _private,int wakeUpEvent) +{ + IntController *IntCtrl = (IntController*) _private; + int i; + int pending = 0; + simulWord port; + + if (wakeUpEvent) return; + + if (IntCtrl->IrqPending[IRQNUM_USAGEFAULT] && !IntCtrl->IrqEnable[IRQNUM_USAGEFAULT]) + { + IntCtrl->IrqPending[IRQNUM_USAGEFAULT] = 0; + IntCtrl->IrqPending[IRQNUM_HARDFAULT] = 1; + IntCtrl->regs.hfsr |= REG_HFSR_FORCED; + } + + if (IntCtrl->IrqPending[IRQNUM_MEMFAULT] && !IntCtrl->IrqEnable[IRQNUM_MEMFAULT]) + { + IntCtrl->IrqPending[IRQNUM_MEMFAULT] = 0; + IntCtrl->IrqPending[IRQNUM_HARDFAULT] = 1; + IntCtrl->regs.hfsr |= REG_HFSR_FORCED; + } + + if (IntCtrl->IrqPending[IRQNUM_BUSFAULT] && !IntCtrl->IrqEnable[IRQNUM_BUSFAULT]) + { + IntCtrl->IrqPending[IRQNUM_BUSFAULT] = 0; + IntCtrl->IrqPending[IRQNUM_HARDFAULT] = 1; + IntCtrl->regs.hfsr |= REG_HFSR_FORCED; + } + + for (i=0;i<256;i++) + { + if (IntCtrl->IrqPending[i] & IntCtrl->IrqEnable[i]) pending++; + } + + port = pending > 0; + + SIMUL_SetPort(processor, SIMUL_PORT_INTERRUPT, 1, &port); +} + diff --git a/debuggers/t32/sim/armm3/nvic/nvic.def b/debuggers/t32/sim/armm3/nvic/nvic.def new file mode 100644 index 00000000..b479f51e --- /dev/null +++ b/debuggers/t32/sim/armm3/nvic/nvic.def @@ -0,0 +1,3 @@ +LIBRARY nvic +DESCRIPTION 'TRACE32 Hardware Simulation Model' +EXPORTS SIMUL_Interface diff --git a/debuggers/t32/sim/armm3/nvic/nvic.h b/debuggers/t32/sim/armm3/nvic/nvic.h new file mode 100644 index 00000000..7ca33a75 --- /dev/null +++ b/debuggers/t32/sim/armm3/nvic/nvic.h @@ -0,0 +1,412 @@ +//#pragma warning (disable : 4100) + +#include "simul.h" + +/* Definitions */ +#define BASE_ADDRESS 0xE000E000 /* base address of controller */ + +#define CMD_OFFSET 0x0000 /* Commands from ARM Simulator */ +#define ICTR_OFFSET 0x0004 /* Interrupt Control Type Register */ +#define STCSR_OFFSET 0x0010 /* SysTick Control and Status Register */ +#define STRVR_OFFSET 0x0014 /* SysTick Reload Value Register */ +#define STCVR_OFFSET 0x0018 /* SysTick Current Value Register */ +#define STCLVR_OFFSET 0x001C /* SysTick Calibration Value Register */ +#define IRQSETENR_OFFSET 0x0100 /* Irq x Set Enable Register */ +#define IRQCLRENR_OFFSET 0x0180 /* Irq x Clear Enable Register */ +#define IRQSETPER_OFFSET 0x0200 /* Irq x Set Pending Register */ +#define IRQCLRPER_OFFSET 0x0280 /* Irq x Clear Pending Register */ +#define IRQABR_OFFSET 0x0300 /* Irq x Active Bit Register */ +#define IRQPR_OFFSET 0x0400 /* Irq x Priority Register */ +#define CPUIDR_OFFSET 0x0D00 /* CPUID Base Register */ +#define ICSR_OFFSET 0x0D04 /* Interrupt Control State Register */ +#define VTOR_OFFSET 0x0D08 /* Vector Table Offset Register */ +#define AIRCR_OFFSET 0x0D0C /* Application Interrupt/Reset Control Register */ +#define SCR_OFFSET 0x0D10 /* System Control Register */ +#define CCR_OFFSET 0x0D14 /* Configuration Control Register */ +#define SHPR_OFFSET 0x0D18 /* System Handlers x Priority Register */ +#define SHCSR_OFFSET 0x0D24 /* System Handler Control and State Register */ +#define CFSR_OFFSET 0x0D28 /* Configurable Fault Status Register */ +#define HFSR_OFFSET 0x0D2C /* Hard Fault Status Register */ +#define DFSR_OFFSET 0x0D30 /* Debug Fault Status Register */ +#define MMAR_OFFSET 0x0D34 /* Memory Manage Address Register */ +#define BFAR_OFFSET 0x0D38 /* Bus Fault Address Register */ +#define AFSR_OFFSET 0x0D3C /* Auxiliary Fault Status Register */ +#define PFR0_OFFSET 0x0D40 /* Processor Feature Register 0 */ +#define PFR1_OFFSET 0x0D44 /* Processor Feature Register 1 */ +#define DFR0_OFFSET 0x0D48 /* Debug Feature Register 0 */ +#define AFR0_OFFSET 0x0D4C /* Auxiliary Feature Register 0 */ +#define MMFR0_OFFSET 0x0D50 /* Memory Model Feature Register 0 */ +#define MMFR1_OFFSET 0x0D54 /* Memory Model Feature Register 1 */ +#define MMFR2_OFFSET 0x0D58 /* Memory Model Feature Register 2 */ +#define MMFR3_OFFSET 0x0D5C /* Memory Model Feature Register 3 */ +#define ISAR0_OFFSET 0x0D60 /* ISA Feature Register 0 */ +#define ISAR1_OFFSET 0x0D64 /* ISA Feature Register 1 */ +#define ISAR2_OFFSET 0x0D68 /* ISA Feature Register 2 */ +#define ISAR3_OFFSET 0x0D6C /* ISA Feature Register 3 */ +#define ISAR4_OFFSET 0x0D70 /* ISA Feature Register 4 */ +#define STIR_OFFSET 0x0F00 /* Software Trigger Interrupt Register */ +#define PID4_OFFSET 0x0FD0 /* Peripheral Identification Register 4 */ +#define PID5_OFFSET 0x0FD4 /* Peripheral Identification Register 5 */ +#define PID6_OFFSET 0x0FD8 /* Peripheral Identification Register 6 */ +#define PID7_OFFSET 0x0FDC /* Peripheral Identification Register 7 */ +#define PID0_OFFSET 0x0FE0 /* Peripheral Identification Register 0 */ +#define PID1_OFFSET 0x0FE4 /* Peripheral Identification Register 1 */ +#define PID2_OFFSET 0x0FE8 /* Peripheral Identification Register 2 */ +#define PID3_OFFSET 0x0FEC /* Peripheral Identification Register 3 */ +#define CID0_OFFSET 0x0FF0 /* Component Identification Register 0 */ +#define CID1_OFFSET 0x0FF4 /* Component Identification Register 1 */ +#define CID2_OFFSET 0x0FF8 /* Component Identification Register 2 */ +#define CID3_OFFSET 0x0FFC /* Component Identification Register 3 */ +#define DHCSR_OFFSET 0x0DF0 /* Debug Halting Control and Status Register */ +#ifdef _DEBUG +#define GPIO_OFFSET 0x6000340C +#endif + + +#define CMD_SIZE 4 /* Commands Register */ +#define ICTR_SIZE 4 /* Interrupt Control Type Register */ +#define STCSR_SIZE 4 /* SysTick Control and Status Register */ +#define STRVR_SIZE 4 /* SysTick Reload Value Register */ +#define STCVR_SIZE 4 /* SysTick Current Value Register */ +#define STCLVR_SIZE 4 /* SysTick Calibration Value Register */ +#define IRQSETENR_SIZE 32 /* Irq x Set Enable Register */ +#define IRQCLRENR_SIZE 32 /* Irq x Clear Enable Register */ +#define IRQSETPER_SIZE 32 /* Irq x Set Pending Register */ +#define IRQCLRPER_SIZE 32 /* Irq x Clear Pending Register */ +#define IRQABR_SIZE 32 /* Irq x Active Bit Register */ +#define IRQPR_SIZE 240 /* Irq x Priority Register */ +#define CPUIDR_SIZE 4 /* CPUID Base Register */ +#define ICSR_SIZE 4 /* Interrupt Control State Register */ +#define VTOR_SIZE 4 /* Vector Table Offset Register */ +#define AIRCR_SIZE 4 /* Application Interrupt/Reset Control Register */ +#define SCR_SIZE 4 /* System Control Register */ +#define CCR_SIZE 4 /* Configuration Control Register */ +#define SHPR_SIZE 12 /* System Handlers x Priority Register */ +#define SHCSR_SIZE 4 /* System Handler Control and State Register */ +#define CFSR_SIZE 4 /* Configurable Fault Status Register */ +#define HFSR_SIZE 4 /* Hard Fault Status Register */ +#define DFSR_SIZE 4 /* Debug Fault Status Register */ +#define MMAR_SIZE 4 /* Memory Manage Address Register */ +#define BFAR_SIZE 4 /* Bus Fault Address Register */ +#define AFSR_SIZE 4 /* Auxiliary Fault Status Register */ +#define PFR0_SIZE 4 /* Processor Feature Register 0 */ +#define PFR1_SIZE 4 /* Processor Feature Register 1 */ +#define DFR0_SIZE 4 /* Debug Feature Register 0 */ +#define AFR0_SIZE 4 /* Auxiliary Feature Register 0 */ +#define MMFR0_SIZE 4 /* Memory Model Feature Register 0 */ +#define MMFR1_SIZE 4 /* Memory Model Feature Register 1 */ +#define MMFR2_SIZE 4 /* Memory Model Feature Register 2 */ +#define MMFR3_SIZE 4 /* Memory Model Feature Register 3 */ +#define ISAR0_SIZE 4 /* ISA Feature Register 0 */ +#define ISAR1_SIZE 4 /* ISA Feature Register 1 */ +#define ISAR2_SIZE 4 /* ISA Feature Register 2 */ +#define ISAR3_SIZE 4 /* ISA Feature Register 3 */ +#define ISAR4_SIZE 4 /* ISA Feature Register 4 */ +#define STIR_SIZE 4 /* Software Trigger Interrupt Register */ +#define PID4_SIZE 4 /* Peripheral Identification Register 4 */ +#define PID5_SIZE 4 /* Peripheral Identification Register 5 */ +#define PID6_SIZE 4 /* Peripheral Identification Register 6 */ +#define PID7_SIZE 4 /* Peripheral Identification Register 7 */ +#define PID0_SIZE 4 /* Peripheral Identification Register 0 */ +#define PID1_SIZE 4 /* Peripheral Identification Register 1 */ +#define PID2_SIZE 4 /* Peripheral Identification Register 2 */ +#define PID3_SIZE 4 /* Peripheral Identification Register 3 */ +#define CID0_SIZE 4 /* Component Identification Register 0 */ +#define CID1_SIZE 4 /* Component Identification Register 1 */ +#define CID2_SIZE 4 /* Component Identification Register 2 */ +#define CID3_SIZE 4 /* Component Identification Register 3 */ +#define DHCSR_SIZE 4 /* Debug Halting Control and Status Register */ +#ifdef _DEBUG +#define GPIO_SIZE 12 +#endif + +int VH_Display_KKEY_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); + + +int CMD_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int ICTR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int STCSR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int STRVR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int STCVR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int STCLVR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int IRQSETENR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int IRQCLRENR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int IRQSETPER_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int IRQCLRPER_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int IRQABR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int IRQPR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int CPUIDR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int ICSR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int VTOR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int AIRCR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int SCR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int CCR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int SHPR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int SHCSR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int CFSR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int HFSR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int DFSR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int MMAR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int BFAR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int AFSR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int Feature_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int ID_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int DHCSR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +#ifdef _DEBUG +int GPIO_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +#endif + +int CMD_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int STCSR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int STRVR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int STCVR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int IRQSETENR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int IRQCLRENR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int IRQSETPER_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int IRQCLRPER_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int IRQPR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int CPUIDR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int ICSR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int VTOR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int AIRCR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int SCR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int CCR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int SHPR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int SHCSR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int CFSR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int HFSR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int DFSR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int MMAR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int BFAR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int AFSR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int STIR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +int DHCSR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +#ifdef _DEBUG +int GPIO_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr dummy); +#endif + +int BusRead(simulBusCallbackStruct * bus, simulWord32 * reg); +int BusWrite(simulBusCallbackStruct * bus, simulWord32 * reg); +void Interrupt(simulProcessor processor, simulPtr _private,int wakeUpEvent); +void RequestReset(simulProcessor processor); + +#define ChangePending(isrnum,value) {\ + int _changePendingValue = !!(value);\ + if (!IntCtrl->IrqPending[isrnum] && (_changePendingValue))\ + {\ + if (IntCtrl->regs.scr & REG_SCR_SEVONPEND) WakeUpFromWFE(processor,IntCtrl);\ + }\ +\ + IntCtrl->IrqPending[isrnum] = !!(value);\ +} + +#define ChangeEnable(isrnum,value) {\ + IntCtrl->IrqEnable[isrnum] = !!(value);\ +} + +#define ChangeActive(isrnum,value) {\ + IntCtrl->IrqActive[isrnum] = !!(value);\ +} + +typedef struct { + simulWord cmd; + simulWord ictr,stcsr,strvr,stcvr,stclvr/*,irqsetenr[8],irqclrenr[8],irqsetper[8],irqclrper[8],irqabr[8],irqpr[8]*/; + simulWord cpuidr,icsr,vtor,aircr,scr,ccr/*,shpr[3]*/,shcsr,cfsr,hfsr,dfsr,mmar,bfar,afsr,pfr0,pfr1,dfr0,afr0,mmfr0; + simulWord mmfr1,mmfr2,mmfr3,isar0,isar1,isar2,isar3,isar4,stir,pid4,pid5,pid6,pid7,pid0,pid1,pid2,pid3,cid0,cid1,cid2,cid3,dhcsr; + simulWord gpio; +} NVIC_Regs; + +typedef struct { + int IrqNum; + int IrqPrio; +} NVIC_IrqStack; + +typedef struct { + int bustype; + simulWord baseaddress; + NVIC_Regs regs; + + int IrqPriority[256]; + int IrqActive[256]; + int IrqEnable[256]; + int IrqPending[256]; + + int CurrentIrqNum; + + int ExternalIrqPortsFirst; + int ExternalIrqPortsCount; + + int timerrun; + void *timer; + +} IntController; + +void WakeUpFromWFE(simulProcessor processor, IntController * IntCtrl); + +#define REG_ICSR_NMIPENDSET 0x80000000 +#define REG_ICSR_PENDSVSET 0x10000000 +#define REG_ICSR_PENDSVCLR 0x08000000 +#define REG_ICSR_PENDSTSET 0x04000000 +#define REG_ICSR_PENDSTCLR 0x02000000 + +#define REG_HFSR_DEBUGEVT 0x80000000 +#define REG_HFSR_FORCED 0x40000000 +#define REG_HFSR_VECTTBL 0x00000002 + +#define REG_HFSR_MASK (\ + REG_HFSR_DEBUGEVT |\ + REG_HFSR_FORCED |\ + REG_HFSR_VECTTBL\ + ) + +#define REG_SHCSR_MEMFAULTENA 0x00010000 +#define REG_SHCSR_BUSFAULTENA 0x00020000 +#define REG_SHCSR_USGFAULTENA 0x00040000 + +#define REG_SHCSR_SVCALLPENDED 0x8000 +#define REG_SHCSR_BUSFAULTPENDED 0x4000 +#define REG_SHCSR_MEMFAULTPENDED 0x2000 +#define REG_SHCSR_USGFAULTPENDED 0x1000 + +#define REG_SHCSR_SYSTICKACT 0x800 +#define REG_SHCSR_PENDSVACT 0x400 +#define REG_SHCSR_MONITORACT 0x100 +#define REG_SHCSR_SVCALLACT 0x080 +#define REG_SHCSR_USGFAULTACT 0x008 +#define REG_SHCSR_BUSFAULTACT 0x002 +#define REG_SHCSR_MEMFAULTACT 0x001 + +#define REG_CFSR_MMFSR_MMARVALID 0x00000080 +#define REG_CFSR_MMFSR_MLSPERR 0x00000020 +#define REG_CFSR_MMFSR_MSTKERR 0x00000010 +#define REG_CFSR_MMFSR_MUNSTKERR 0x00000008 +#define REG_CFSR_MMFSR_DACCVIOL 0x00000002 +#define REG_CFSR_MMFSR_IACCVIOL 0x00000001 + +#define REG_CFSR_MMFSR_MASK (\ + REG_CFSR_MMFSR_MMARVALID |\ + REG_CFSR_MMFSR_MLSPERR |\ + REG_CFSR_MMFSR_MSTKERR |\ + REG_CFSR_MMFSR_MUNSTKERR |\ + REG_CFSR_MMFSR_DACCVIOL |\ + REG_CFSR_MMFSR_IACCVIOL\ + ) + +#define REG_CFSR_BFSR_BFARVALID (0x00000080<<8) +#define REG_CFSR_BFSR_LSPERR (0x00000020<<8) +#define REG_CFSR_BFSR_STKERR (0x00000010<<8) +#define REG_CFSR_BFSR_UNSTKERR (0x00000008<<8) +#define REG_CFSR_BFSR_IMPRECISERR (0x00000004<<8) +#define REG_CFSR_BFSR_PRECISERR (0x00000002<<8) +#define REG_CFSR_BFSR_IBUSERR (0x00000001<<8) + +#define REG_CFSR_BFSR_MASK (\ + REG_CFSR_BFSR_BFARVALID |\ + REG_CFSR_BFSR_LSPERR |\ + REG_CFSR_BFSR_STKERR |\ + REG_CFSR_BFSR_UNSTKERR |\ + REG_CFSR_BFSR_IMPRECISERR |\ + REG_CFSR_BFSR_PRECISERR |\ + REG_CFSR_BFSR_IBUSERR \ + ) + +#define REG_CFSR_UFSR_DIVBYZERO (0x00000200<<16) +#define REG_CFSR_UFSR_UNALIGNED (0x00000100<<16) +#define REG_CFSR_UFSR_NOCP (0x00000008<<16) +#define REG_CFSR_UFSR_INVPC (0x00000004<<16) +#define REG_CFSR_UFSR_INVSTATE (0x00000002<<16) +#define REG_CFSR_UFSR_UNDEFINSTR (0x00000001<<16) + +#define REG_CFSR_UFSR_MASK (\ + REG_CFSR_UFSR_DIVBYZERO |\ + REG_CFSR_UFSR_UNALIGNED |\ + REG_CFSR_UFSR_NOCP |\ + REG_CFSR_UFSR_INVPC |\ + REG_CFSR_UFSR_INVSTATE |\ + REG_CFSR_UFSR_UNDEFINSTR \ + ) + +#define REG_CFSR_MASK (\ + REG_CFSR_MMFSR_MASK |\ + REG_CFSR_BFSR_MASK |\ + REG_CFSR_UFSR_MASK \ + ) + +#define REG_DFSR_EXTERNAL 0x00000010 +#define REG_DFSR_VCATCH 0x00000008 +#define REG_DFSR_DWTTRAP 0x00000004 +#define REG_DFSR_BKPT 0x00000002 +#define REG_DFSR_HALTED 0x00000001 + +#define REG_DFSR_MASK (\ + REG_DFSR_BKPT |\ + REG_DFSR_DWTTRAP |\ + REG_DFSR_EXTERNAL |\ + REG_DFSR_HALTED |\ + REG_DFSR_VCATCH\ + ) + +#define REG_STCSR_COUNTFLAG 0x00010000 +#define REG_STCSR_CLKSOURCE 0x00000004 +#define REG_STCSR_TICKINT 0x00000002 +#define REG_STCSR_ENABLE 0x00000001 + +#define REG_STCLVR_NOREF 0x80000000 +#define REG_STCLVR_SKEW 0x40000000 +#define REG_STCLVR_TENMS 0x00FFFFFF + +#define REG_AFSR_MASK 0xFFFFFFFF + +#define REG_SCR_SEVONPEND 0x00000010 +#define REG_SCR_SLEEPONEXIT 0x00000002 + +#define REG_SCR_MASK (\ + REG_SCR_SEVONPEND |\ + REG_SCR_SLEEPONEXIT\ + ) + +#define REG_DHCSR_S_SLEEP 0x00040000 + +#define REG_CCR_STKALIGN 0x00000200 +#define REG_CCR_BFHFNMIGN 0x00000100 +#define REG_CCR_DIV_0_TRP 0x00000010 +#define REG_CCR_UNALIGN_TRP 0x00000008 +#define REG_CCR_USERSETMPEND 0x00000002 +#define REG_CCR_NONBASETHRDENA 0x00000001 + +#define REG_CCR_MASK 0x0000031B + +#define REG_AIRCR_ENDIANNESS 0x00008000 +#define REG_AIRCR_PRIGROUP 0x00000700 +#define REG_AIRCR_SYSRESETREQ 0x00000004 +#define REG_AIRCR_VECTCLRACTIVE 0x00000002 +#define REG_AIRCR_VECTRESET 0x00000001 + +#define REG_AIRCR_MASK (\ + REG_AIRCR_ENDIANNESS |\ + REG_AIRCR_PRIGROUP |\ + REG_AIRCR_SYSRESETREQ |\ + REG_AIRCR_VECTCLRACTIVE |\ + REG_AIRCR_VECTRESET\ +) + +#define IRQNUM_RESET 1 +#define IRQNUM_NMI 2 +#define IRQNUM_HARDFAULT 3 +#define IRQNUM_MEMFAULT 4 +#define IRQNUM_BUSFAULT 5 +#define IRQNUM_USAGEFAULT 6 +#define IRQNUM_SVCALL 11 +#define IRQNUM_DEBUG 12 +#define IRQNUM_PENDSV 14 +#define IRQNUM_SYSTICK 15 + +#define CMD_IS_PRESENT 0x00 +#define CMD_SET_INTERRUPT_ACTIVE 0x01 +#define CMD_SET_INTERRUPT_INACTIVE 0x02 +#define CMD_GET_EXCEPTION_PRIORITY 0x03 +#define CMD_GET_HIGHEST_PRIORITY 0x04 +#define CMD_GET_ACTIVE_EXCEPTION_COUNT 0x05 +#define CMD_IS_EXCEPTION_ACTIVE 0x06 +#define CMD_ESCALATE_TO_HARD_FAULT 0x07 +#define CMD_CHANGE_ACTIVE_EXCEPTION 0x08 diff --git a/debuggers/t32/sim/armm3/nvic/nvic_id_space.c b/debuggers/t32/sim/armm3/nvic/nvic_id_space.c new file mode 100644 index 00000000..f01565f0 --- /dev/null +++ b/debuggers/t32/sim/armm3/nvic/nvic_id_space.c @@ -0,0 +1,75 @@ +#include "nvic.h" + +/*************** IDs ***************/ + +int ID_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg = 0x0; + + switch ((cbs->x.bus.address-(IntCtrl->baseaddress+PID4_OFFSET))&0xFF) + { + case 0x00: reg = IntCtrl->regs.pid4; break; + case 0x04: reg = IntCtrl->regs.pid5; break; + case 0x08: reg = IntCtrl->regs.pid6; break; + case 0x0C: reg = IntCtrl->regs.pid7; break; + case 0x10: reg = IntCtrl->regs.pid0; break; + case 0x14: reg = IntCtrl->regs.pid1; break; + case 0x18: reg = IntCtrl->regs.pid2; break; + case 0x1C: reg = IntCtrl->regs.pid3; break; + case 0x20: reg = IntCtrl->regs.cid0; break; + case 0x24: reg = IntCtrl->regs.cid1; break; + case 0x28: reg = IntCtrl->regs.cid2; break; + case 0x2C: reg = IntCtrl->regs.cid3; break; + } + cbs->x.bus.clocks = 1; + return BusWrite(&cbs->x.bus, ®); +} + + +/*************** GPIO ***************/ + +#ifdef _DEBUG +int GPIO_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg = 0x0; + + switch ((cbs->x.bus.address-(IntCtrl->baseaddress+GPIO_OFFSET))&0xF) + { + case 0x00: + reg = IntCtrl->regs.gpio; + break; + case 0x04: + reg = 0; + break; + case 0x08: + reg = 0; + break; + } + cbs->x.bus.clocks = 1; + return BusWrite(&cbs->x.bus, ®); +} + +int GPIO_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg = 0x0; + + BusRead(&cbs->x.bus, ®); + + switch ((cbs->x.bus.address-(IntCtrl->baseaddress+GPIO_OFFSET))&0xF) + { + case 0x04: + IntCtrl->regs.gpio |= reg; + break; + case 0x08: + IntCtrl->regs.gpio &= ~reg; + break; + } + cbs->x.bus.clocks = 1; + + return SIMUL_MEMORY_OK; +} + +#endif diff --git a/debuggers/t32/sim/armm3/nvic/nvic_interrupt_type.c b/debuggers/t32/sim/armm3/nvic/nvic_interrupt_type.c new file mode 100644 index 00000000..9270e54e --- /dev/null +++ b/debuggers/t32/sim/armm3/nvic/nvic_interrupt_type.c @@ -0,0 +1,47 @@ +#include "nvic.h" + +/*************** Interrupt Control Type Register ***************/ + +int ICTR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg; + cbs->x.bus.clocks = 1; + + reg = 0; + + if (IntCtrl->ExternalIrqPortsCount >= 0 && IntCtrl->ExternalIrqPortsCount <= 32) + { + reg = 0; + } + else if (IntCtrl->ExternalIrqPortsCount >= 33 && IntCtrl->ExternalIrqPortsCount <= 64) + { + reg = 1; + } + else if (IntCtrl->ExternalIrqPortsCount >= 65 && IntCtrl->ExternalIrqPortsCount <= 96) + { + reg = 2; + } + else if (IntCtrl->ExternalIrqPortsCount >= 97 && IntCtrl->ExternalIrqPortsCount <= 128) + { + reg = 3; + } + else if (IntCtrl->ExternalIrqPortsCount >= 129 && IntCtrl->ExternalIrqPortsCount <= 160) + { + reg = 4; + } + else if (IntCtrl->ExternalIrqPortsCount >= 161 && IntCtrl->ExternalIrqPortsCount <= 192) + { + reg = 5; + } + else if (IntCtrl->ExternalIrqPortsCount >= 193 && IntCtrl->ExternalIrqPortsCount <= 224) + { + reg = 6; + } + else if (IntCtrl->ExternalIrqPortsCount >= 225 && IntCtrl->ExternalIrqPortsCount <= 256) + { + reg = 7; + } + + return BusWrite(&cbs->x.bus, ®); +} diff --git a/debuggers/t32/sim/armm3/nvic/nvic_nvic.c b/debuggers/t32/sim/armm3/nvic/nvic_nvic.c new file mode 100644 index 00000000..eb13228d --- /dev/null +++ b/debuggers/t32/sim/armm3/nvic/nvic_nvic.c @@ -0,0 +1,263 @@ +#include "nvic.h" + +/*************** Irq x Set Enable Register ***************/ + +int IRQSETENR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + int idx = ((cbs->x.bus.address & ~0x3) - IntCtrl->baseaddress - IRQSETENR_OFFSET) >> 2; + int arrayidx = (idx << 5) + 16; + simulWord32 reg = 0; + int i; + + cbs->x.bus.clocks = 1; + + BusRead(&cbs->x.bus,®); + + for (i=0;i<32;i++) + { + if (reg & (1<x.bus.address & ~0x3) - IntCtrl->baseaddress - IRQCLRENR_OFFSET) >> 2; + int arrayidx = (idx << 5) + 16; + simulWord32 reg = 0; + int i; + + cbs->x.bus.clocks = 1; + + BusRead(&cbs->x.bus,®); + + for (i=0;i<32;i++) + { + if (reg & (1<x.bus.address & ~0x3) - IntCtrl->baseaddress - IRQSETPER_OFFSET) >> 2; + int arrayidx = (idx << 5) + 16; + simulWord32 reg = 0; + int wakeUpEvent = 0; + int i; + + cbs->x.bus.clocks = 1; + + BusRead(&cbs->x.bus,®); + + for (i=0;i<32;i++) + { + if (reg & (1<x.bus.address & ~0x3) - IntCtrl->baseaddress - IRQCLRPER_OFFSET) >> 2; + int arrayidx = (idx << 5) + 16; + simulWord32 reg = 0; + int wakeUpEvent = 0; + int i; + + cbs->x.bus.clocks = 1; + + BusRead(&cbs->x.bus,®); + + for (i=0;i<32;i++) + { + if (reg & (1<x.bus.address & ~0x3) - IntCtrl->baseaddress - IRQPR_OFFSET) >> 2; + int arrayidx = (idx << 2) + 16; + simulWord32 reg = 0; + int i; + + cbs->x.bus.clocks = 1; + + for (i=0;i<4;i++) reg |= IntCtrl->IrqPriority[arrayidx+i] << (i << 3); + + BusRead(&cbs->x.bus,®); + + for (i=0;i<4;i++) IntCtrl->IrqPriority[arrayidx+i] = (unsigned char)(reg >> (i << 3)); + + return SIMUL_MEMORY_OK; +} + +/*************** Irq x Set Enable Register ***************/ + +int IRQSETENR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + int idx = ((cbs->x.bus.address & ~0x3) - IntCtrl->baseaddress - IRQSETENR_OFFSET) >> 2; + int arrayidx = (idx << 5) + 16; + simulWord32 reg = 0; + int i; + + cbs->x.bus.clocks = 1; + + if (arrayidx<(7 * 32)) + { + for (i=0;i<32;i++) reg |= (IntCtrl->IrqEnable[arrayidx+i])?(1<IrqEnable[arrayidx+i])?(1<x.bus,®); + return SIMUL_MEMORY_OK; +} + +/*************** Irq x Clear Enable Register ***************/ + +int IRQCLRENR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + int idx = ((cbs->x.bus.address & ~0x3) - IntCtrl->baseaddress - IRQCLRENR_OFFSET) >> 2; + int arrayidx = (idx << 5) + 16; + simulWord32 reg = 0; + int i; + + cbs->x.bus.clocks = 1; + + if (arrayidx<(7 * 32)) + { + for (i=0;i<32;i++) reg |= (IntCtrl->IrqEnable[arrayidx+i])?(1<IrqEnable[arrayidx+i])?(1<x.bus,®); + return SIMUL_MEMORY_OK; +} + +/*************** Irq x Set Pending Register ***************/ + +int IRQSETPER_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + int idx = ((cbs->x.bus.address & ~0x3) - IntCtrl->baseaddress - IRQSETPER_OFFSET) >> 2; + int arrayidx = (idx << 5) + 16; + simulWord32 reg = 0; + int i; + + cbs->x.bus.clocks = 1; + + if (arrayidx<(7 * 32)) + { + for (i=0;i<32;i++) reg |= (IntCtrl->IrqPending[arrayidx+i])?(1<IrqPending[arrayidx+i])?(1<x.bus,®); + return SIMUL_MEMORY_OK; +} + +/*************** Irq x Clear Pending Register ***************/ + +int IRQCLRPER_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + int idx = ((cbs->x.bus.address & ~0x3) - IntCtrl->baseaddress - IRQCLRPER_OFFSET) >> 2; + int arrayidx = (idx << 5) + 16; + simulWord32 reg = 0; + int i; + + cbs->x.bus.clocks = 1; + + if (arrayidx<(7 * 32)) + { + for (i=0;i<32;i++) reg |= (IntCtrl->IrqPending[arrayidx+i])?(1<IrqPending[arrayidx+i])?(1<x.bus,®); + return SIMUL_MEMORY_OK; +} + +/*************** Irq x Active Bit Register ***************/ + +int IRQABR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + int idx = ((cbs->x.bus.address & ~0x3) - IntCtrl->baseaddress - IRQABR_OFFSET) >> 2; + int arrayidx = (idx << 5) + 16; + simulWord32 reg = 0; + int i; + + cbs->x.bus.clocks = 1; + + if (arrayidx<(7 * 32)) + { + for (i=0;i<32;i++) reg |= (IntCtrl->IrqActive[arrayidx+i])?(1<IrqActive[arrayidx+i])?(1<x.bus,®); + return SIMUL_MEMORY_OK; +} + +/*************** Irq x Priority Register ***************/ + +int IRQPR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + int idx = ((cbs->x.bus.address & ~0x3) - IntCtrl->baseaddress - IRQPR_OFFSET) >> 2; + int arrayidx = (idx << 2) + 16; + simulWord32 reg = 0; + int i; + + cbs->x.bus.clocks = 1; + + for (i=0;i<4;i++) reg |= ((simulWord32)((unsigned char)IntCtrl->IrqPriority[arrayidx+i])) << (i << 3); + + BusWrite(&cbs->x.bus,®); + return SIMUL_MEMORY_OK; +} diff --git a/debuggers/t32/sim/armm3/nvic/nvic_software_trigger.c b/debuggers/t32/sim/armm3/nvic/nvic_software_trigger.c new file mode 100644 index 00000000..54ca79f8 --- /dev/null +++ b/debuggers/t32/sim/armm3/nvic/nvic_software_trigger.c @@ -0,0 +1,25 @@ +#include "nvic.h" + +/*************** Software Trigger Interrupt Register ***************/ + +int STIR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + int arrayidx; + simulWord32 reg = 0; + int wakeUpEvent = 0; + + cbs->x.bus.clocks = 1; + + BusRead(&cbs->x.bus,®); + + arrayidx = (reg & 0x1FF) + 16; + + if (arrayidx < 256) + { + ChangePending(arrayidx,1); + Interrupt(processor,IntCtrl,wakeUpEvent); + } + + return SIMUL_MEMORY_OK; +} diff --git a/debuggers/t32/sim/armm3/nvic/nvic_system_control_block.c b/debuggers/t32/sim/armm3/nvic/nvic_system_control_block.c new file mode 100644 index 00000000..6aa9150a --- /dev/null +++ b/debuggers/t32/sim/armm3/nvic/nvic_system_control_block.c @@ -0,0 +1,873 @@ +#include "nvic.h" + +/*************** Commands from ARM Simulator ***************/ + +int CMD_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord reg; + + cbs->x.bus.clocks = 1; + + if (cbs->x.bus.cycletype==SIMUL_MEMORY_HIDDEN) + { + return BusWrite(&cbs->x.bus, &IntCtrl->regs.cmd); + } + else + { + reg = 0; + return BusWrite(&cbs->x.bus, ®); + } +} + +int CMD_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + + cbs->x.bus.clocks = 1; + + if (cbs->x.bus.cycletype==SIMUL_MEMORY_HIDDEN) + { + simulWord32 cmd; + + BusRead(&cbs->x.bus, &cmd); + + switch ((cmd>>24) & 0xFF) + { + case CMD_IS_PRESENT: + { + int i; + + IntCtrl->regs.cmd = 0; + + for (i=0;i<24;i++) + { + if ((1<regs.cmd |= 1 << (24-i); + } + } + } + break; + + case CMD_SET_INTERRUPT_ACTIVE: + { + /* command for setting interrupt to active state */ + int isrnum = cmd & 0x1FF; + + switch (isrnum) + { + case 0: + Interrupt(processor,IntCtrl,0); + break; + + case IRQNUM_RESET: + case IRQNUM_NMI: + case IRQNUM_HARDFAULT: + case IRQNUM_MEMFAULT: + case IRQNUM_BUSFAULT: + case IRQNUM_USAGEFAULT: + case IRQNUM_SVCALL: + case IRQNUM_DEBUG: + case IRQNUM_PENDSV: + case IRQNUM_SYSTICK: + IntCtrl->CurrentIrqNum = isrnum; + ChangeActive(isrnum,1); + ChangePending(isrnum,0); + Interrupt(processor,IntCtrl,0); + break; + + default: + if (isrnum > 15 && isrnum < 256) + { + IntCtrl->CurrentIrqNum = isrnum; + ChangeActive(isrnum,1); + ChangePending(isrnum,0); + Interrupt(processor,IntCtrl,0); + } + break; + } + } + break; + + case CMD_SET_INTERRUPT_INACTIVE: + { + /* command for setting interrupt inactive */ + int isrnum = cmd & 0x1FF; + + switch (isrnum) + { + case IRQNUM_RESET: + case IRQNUM_NMI: + case IRQNUM_HARDFAULT: + case IRQNUM_MEMFAULT: + case IRQNUM_BUSFAULT: + case IRQNUM_USAGEFAULT: + case IRQNUM_SVCALL: + case IRQNUM_DEBUG: + case IRQNUM_PENDSV: + case IRQNUM_SYSTICK: + IntCtrl->CurrentIrqNum = 0; + ChangeActive(isrnum,0); + Interrupt(processor,IntCtrl,0); + break; + + default: + if (isrnum > 15 && isrnum < 256) + { + IntCtrl->CurrentIrqNum = 0; + ChangeActive(isrnum,0); + Interrupt(processor,IntCtrl,0); + } + break; + } + } + break; + + case CMD_GET_EXCEPTION_PRIORITY: + { + /* command for getting priority of exception */ + int isrnum = cmd & 0x1FF; + + if (isrnum < 256) + IntCtrl->regs.cmd = IntCtrl->IrqPriority[isrnum]; + else + IntCtrl->regs.cmd = 0; + } + break; + + case CMD_GET_HIGHEST_PRIORITY: + { + /* command for computing highest priority */ + int highestpri = 256; + int groupshift = (IntCtrl->regs.aircr >> 8) & 7; /* Application Interrupt and Reset Control Register - PRIGROUP */ + int groupvalue = 2 << groupshift; + int i; + + for (i=2;i<256;i++) + { + if (IntCtrl->IrqActive[i]) + { + if (IntCtrl->IrqPriority[i] < highestpri) + { + int subgroupvalue; + + highestpri = IntCtrl->IrqPriority[i]; + + subgroupvalue = highestpri % groupvalue; + highestpri = highestpri - subgroupvalue; + } + } + } + + IntCtrl->regs.cmd = highestpri; + } + break; + + case CMD_GET_ACTIVE_EXCEPTION_COUNT: + { + /* get active exception count */ + int i,count=0; + + for (i=0;i<256;i++) + { + if (IntCtrl->IrqActive[i]) count++; + } + + IntCtrl->regs.cmd = count; + } + break; + + case CMD_IS_EXCEPTION_ACTIVE: + { + /* is exception active? */ + int isrnum = cmd & 0x1FF; + + if (isrnum < 256) + IntCtrl->regs.cmd = IntCtrl->IrqActive[isrnum]; + else + IntCtrl->regs.cmd = 0; + } + break; + + case CMD_ESCALATE_TO_HARD_FAULT: + { + /* escalate to HardFault */ + int isrnum = cmd & 0x1FF; + if (isrnum < 256) + { + IntCtrl->IrqPending[isrnum] = 0; + IntCtrl->IrqPending[IRQNUM_HARDFAULT] = 1; + IntCtrl->regs.hfsr |= REG_HFSR_FORCED; + Interrupt(processor,IntCtrl,0); + } + } + break; + + case CMD_CHANGE_ACTIVE_EXCEPTION: + { + /* change active exception */ + int active = cmd & 0x1FF; + + if ((active > 2) && (active < 256)) + { + IntCtrl->CurrentIrqNum = active; + IntCtrl->IrqActive[active] = 1; + } + } + break; + } + + + + } + + return SIMUL_MEMORY_OK; +} + + +/*************** Interrupt Control State Register ***************/ + +int ICSR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + int i; + + simulWord32 NMIPENDSET; + simulWord32 PENDSVSET; + simulWord32 PENDSTSET; + simulWord32 ISRPENDING; + simulWord32 VECTPENDING; + simulWord32 RETTOBASE; + simulWord32 VECTACTIVE; + + simulWord32 reg = 0; + + int highestPriorityPending = 256; + int groupshift = (IntCtrl->regs.aircr >> 8) & 7; /* Application Interrupt and Reset Control Register - PRIGROUP */ + int groupvalue = 2 << groupshift; + + cbs->x.bus.clocks = 1; + + NMIPENDSET = !!IntCtrl->IrqPending[IRQNUM_NMI]; + PENDSVSET = !!IntCtrl->IrqPending[IRQNUM_PENDSV]; + PENDSTSET = !!IntCtrl->IrqPending[IRQNUM_SYSTICK]; + + ISRPENDING = 0; + for (i=16;i<256;i++) + { + if (IntCtrl->IrqPending[i]) + { + ISRPENDING = 1; + break; + } + } + + RETTOBASE = 1; + for (i=0;i<256;i++) + { + if (RETTOBASE && IntCtrl->IrqActive[i]) + { + if (i != IntCtrl->CurrentIrqNum) + { + RETTOBASE = 0; + break; + } + } + } + + VECTPENDING = 0; + for (i=2;i<256;i++) + { + if (IntCtrl->IrqPending[i]) + { + if (IntCtrl->IrqPriority[i] < highestPriorityPending) + { + int subgroupvalue; + + highestPriorityPending = IntCtrl->IrqPriority[i]; + + subgroupvalue = highestPriorityPending % groupvalue; + highestPriorityPending = highestPriorityPending - subgroupvalue; + + VECTPENDING = i; + } + } + } + + VECTACTIVE = IntCtrl->CurrentIrqNum & 0x1FF; + + reg = (NMIPENDSET << 31) | (PENDSVSET << 28) | (PENDSTSET << 26) | (ISRPENDING << 22) | (VECTPENDING << 12) | (RETTOBASE << 11) | (VECTACTIVE << 0); + + return BusWrite(&cbs->x.bus, ®); +} + +int ICSR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg; + int wakeUpEvent = 0; + cbs->x.bus.clocks = 1; + + BusRead(&cbs->x.bus, ®); + + if (reg & REG_ICSR_NMIPENDSET) + { + ChangePending(IRQNUM_NMI,1); + Interrupt(processor,IntCtrl,wakeUpEvent); + } + + if (reg & REG_ICSR_PENDSVSET) + { + ChangePending(IRQNUM_PENDSV,1); + Interrupt(processor,IntCtrl,wakeUpEvent); + } + + if (reg & REG_ICSR_PENDSVCLR) + { + ChangePending(IRQNUM_PENDSV,0); + Interrupt(processor,IntCtrl,wakeUpEvent); + } + + if (reg & REG_ICSR_PENDSTSET) + { + ChangePending(IRQNUM_SYSTICK,1); + Interrupt(processor,IntCtrl,wakeUpEvent); + } + else if (reg & REG_ICSR_PENDSTCLR) + { + ChangePending(IRQNUM_SYSTICK,0); + Interrupt(processor,IntCtrl,wakeUpEvent); + } + + return SIMUL_MEMORY_OK; +} + +/*************** Vector Table Offset Register ***************/ + +int VTOR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + cbs->x.bus.clocks = 1; + return BusWrite(&cbs->x.bus, &IntCtrl->regs.vtor); +} + +int VTOR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg; + + cbs->x.bus.clocks = 1; + + reg = IntCtrl->regs.vtor; + + BusRead(&cbs->x.bus, ®); + + IntCtrl->regs.vtor = reg & 0x3FFFFF80; + + return SIMUL_MEMORY_OK; +} + +/*************** Application Interrupt/Reset Control Register ***************/ + +int AIRCR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg; + cbs->x.bus.clocks = 1; + + reg = (IntCtrl->regs.aircr & REG_AIRCR_MASK) | 0xFA050000; + + return BusWrite(&cbs->x.bus, ®); +} + +int AIRCR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg; + cbs->x.bus.clocks = 1; + + reg = IntCtrl->regs.aircr; + + BusRead(&cbs->x.bus, ®); + + if ((reg & 0xFFFF0000) == 0x05FA0000) + { + IntCtrl->regs.aircr = (IntCtrl->regs.aircr & ~REG_AIRCR_PRIGROUP) | (reg & REG_AIRCR_PRIGROUP); + + IntCtrl->regs.aircr = (IntCtrl->regs.aircr & ~REG_AIRCR_SYSRESETREQ) | (reg & REG_AIRCR_SYSRESETREQ); + + if (reg & REG_AIRCR_SYSRESETREQ) + { + RequestReset(processor); + } + + if (reg & REG_AIRCR_VECTCLRACTIVE) + { + //not imlemented + //ClearActiveState(); + } + + if (reg & REG_AIRCR_VECTRESET) + { + RequestReset(processor); + } + } + + return SIMUL_MEMORY_OK; +} + +/*************** System Control Register ***************/ + +int SCR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg; + cbs->x.bus.clocks = 1; + + reg = (IntCtrl->regs.scr & 0x00000016); + + return BusWrite(&cbs->x.bus, ®); +} + +int SCR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg = IntCtrl->regs.scr; + + cbs->x.bus.clocks = 1; + + BusRead(&cbs->x.bus, ®); + + IntCtrl->regs.scr = reg & REG_SCR_MASK; + + return SIMUL_MEMORY_OK; +} + +/*************** Configuration Control Register ***************/ + +int CCR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg; + cbs->x.bus.clocks = 1; + + reg = (IntCtrl->regs.ccr & REG_CCR_MASK); + + return BusWrite(&cbs->x.bus, ®); +} + +int CCR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg = IntCtrl->regs.ccr; + + cbs->x.bus.clocks = 1; + + BusRead(&cbs->x.bus, ®); + + IntCtrl->regs.ccr = reg & REG_CCR_MASK; + + if (IntCtrl->regs.ccr & REG_CCR_USERSETMPEND) + { + //This bit functionality cannot be implemented - NVIC model doesn't have access to CONTROL register + } + + return SIMUL_MEMORY_OK; +} + +/*************** System Handlers x Priority Register ***************/ + +int SHPR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + int idx = (cbs->x.bus.address - IntCtrl->baseaddress - SHPR_OFFSET) >> 2; + simulWord32 reg = 0; + + cbs->x.bus.clocks = 1; + + switch (idx) + { + case 0: /* PRI_4 -- PRI_7 */ + reg = ((IntCtrl->IrqPriority[IRQNUM_MEMFAULT] & 0xFF) << 0) | ((IntCtrl->IrqPriority[IRQNUM_BUSFAULT] & 0xFF) << 8) | ((IntCtrl->IrqPriority[IRQNUM_USAGEFAULT] & 0xFF) << 16); + break; + + case 1: /* PRI_8 -- PRI_11 */ + reg = ((IntCtrl->IrqPriority[IRQNUM_SVCALL] & 0xFF) << 24); + break; + + case 2: /* PRI_12 -- PRI_15 */ + reg = ((IntCtrl->IrqPriority[IRQNUM_DEBUG] & 0xFF) << 0) | ((IntCtrl->IrqPriority[IRQNUM_PENDSV] & 0xFF) << 16) | ((IntCtrl->IrqPriority[IRQNUM_SYSTICK] & 0xFF) << 24); + break; + + default: + reg = 0; + break; + } + + return BusWrite(&cbs->x.bus, ®); +} + +int SHPR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + int idx = (cbs->x.bus.address - IntCtrl->baseaddress - SHPR_OFFSET) >> 2; + simulWord32 reg = 0; +// simulWord32 regBackup; + + cbs->x.bus.clocks = 1; + + switch (idx) + { + case 0: /* PRI_4 -- PRI_7 */ + reg = ((IntCtrl->IrqPriority[IRQNUM_MEMFAULT] & 0xFF) << 0) | ((IntCtrl->IrqPriority[IRQNUM_BUSFAULT] & 0xFF) << 8) | ((IntCtrl->IrqPriority[IRQNUM_USAGEFAULT] & 0xFF) << 16); + break; + + case 1: /* PRI_8 -- PRI_11 */ + reg = ((IntCtrl->IrqPriority[IRQNUM_SVCALL] & 0xFF) << 24); + break; + + case 2: /* PRI_12 -- PRI_15 */ + reg = ((IntCtrl->IrqPriority[IRQNUM_DEBUG] & 0xFF) << 0) | ((IntCtrl->IrqPriority[IRQNUM_PENDSV] & 0xFF) << 16) | ((IntCtrl->IrqPriority[IRQNUM_SYSTICK] & 0xFF) << 24); + break; + + default: + reg = 0; + break; + } + +// regBackup = reg; + BusRead(&cbs->x.bus, ®); + + switch (idx) + { + case 0: /* PRI_4 -- PRI_7 */ + IntCtrl->IrqPriority[IRQNUM_MEMFAULT] = (reg >> 0) & 0xFF; + IntCtrl->IrqPriority[IRQNUM_BUSFAULT] = (reg >> 8) & 0xFF; + IntCtrl->IrqPriority[IRQNUM_USAGEFAULT] = (reg >> 16) & 0xFF; + break; + + case 1: /* PRI_8 -- PRI_11 */ + IntCtrl->IrqPriority[IRQNUM_SVCALL] = (reg >> 24) & 0xFF; + break; + + case 2: /* PRI_12 -- PRI_15 */ + IntCtrl->IrqPriority[IRQNUM_DEBUG] = (reg >> 0) & 0xFF; + IntCtrl->IrqPriority[IRQNUM_PENDSV] = (reg >> 16) & 0xFF; + IntCtrl->IrqPriority[IRQNUM_SYSTICK] = (reg >> 24) & 0xFF; + break; + + default: + return SIMUL_MEMORY_OK; + } + + return SIMUL_MEMORY_OK; +} + +/*************** System Handler Control and State Register ***************/ + +int SHCSR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + + simulWord32 USGFAULTENA, BUSFAULTENA, MEMFAULTENA; + simulWord32 SVCALLPENDED, BUSFAULTPENDED, MEMFAULTPENDED, USGFAULTPENDED; + simulWord32 SYSTICKACT, PENDSVACT, MONITORACT, SVCALLACT, USGFAULTACT, BUSFAULTACT, MEMFAULTACT; + + simulWord32 reg = 0; + + cbs->x.bus.clocks = 1; + + USGFAULTENA = IntCtrl->IrqEnable[IRQNUM_USAGEFAULT]; + BUSFAULTENA = IntCtrl->IrqEnable[IRQNUM_BUSFAULT]; + MEMFAULTENA = IntCtrl->IrqEnable[IRQNUM_MEMFAULT]; + + SVCALLPENDED = IntCtrl->IrqPending[IRQNUM_SVCALL]; + BUSFAULTPENDED = IntCtrl->IrqPending[IRQNUM_BUSFAULT]; + MEMFAULTPENDED = IntCtrl->IrqPending[IRQNUM_MEMFAULT]; + USGFAULTPENDED = IntCtrl->IrqPending[IRQNUM_USAGEFAULT]; + + SYSTICKACT = IntCtrl->IrqActive[IRQNUM_SYSTICK]; + PENDSVACT = IntCtrl->IrqActive[IRQNUM_PENDSV]; + MONITORACT = IntCtrl->IrqActive[IRQNUM_DEBUG]; + SVCALLACT = IntCtrl->IrqActive[IRQNUM_SVCALL]; + USGFAULTACT = IntCtrl->IrqActive[IRQNUM_USAGEFAULT]; + BUSFAULTACT = IntCtrl->IrqActive[IRQNUM_BUSFAULT]; + MEMFAULTACT = IntCtrl->IrqActive[IRQNUM_MEMFAULT]; + + reg = + ((USGFAULTENA)?(REG_SHCSR_USGFAULTENA):(0)) | + ((BUSFAULTENA)?(REG_SHCSR_BUSFAULTENA):(0)) | + ((MEMFAULTENA)?(REG_SHCSR_MEMFAULTENA):(0)) | + + ((SVCALLPENDED)?(REG_SHCSR_SVCALLPENDED):(0)) | + ((BUSFAULTPENDED)?(REG_SHCSR_BUSFAULTPENDED):(0)) | + ((MEMFAULTPENDED)?(REG_SHCSR_MEMFAULTPENDED):(0)) | + ((USGFAULTPENDED)?(REG_SHCSR_USGFAULTPENDED):(0)) | + + ((SYSTICKACT)?(REG_SHCSR_SYSTICKACT):(0)) | + ((PENDSVACT)?(REG_SHCSR_PENDSVACT):(0)) | + ((MONITORACT)?(REG_SHCSR_MONITORACT):(0)) | + ((SVCALLACT)?(REG_SHCSR_SVCALLACT):(0)) | + ((USGFAULTACT)?(REG_SHCSR_USGFAULTACT):(0)) | + ((BUSFAULTACT)?(REG_SHCSR_BUSFAULTACT):(0)) | + ((MEMFAULTACT)?(REG_SHCSR_MEMFAULTACT):(0)); + ; + + return BusWrite(&cbs->x.bus, ®); +} + +int SHCSR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + int wakeUpEvent = 0; + + simulWord32 USGFAULTENA, BUSFAULTENA, MEMFAULTENA; + simulWord32 SVCALLPENDED, BUSFAULTPENDED, MEMFAULTPENDED, USGFAULTPENDED; + simulWord32 SYSTICKACT, PENDSVACT, MONITORACT, SVCALLACT, USGFAULTACT, BUSFAULTACT, MEMFAULTACT; + + simulWord32 reg = 0; + + cbs->x.bus.clocks = 1; + + USGFAULTENA = IntCtrl->IrqEnable[IRQNUM_USAGEFAULT]; + BUSFAULTENA = IntCtrl->IrqEnable[IRQNUM_BUSFAULT]; + MEMFAULTENA = IntCtrl->IrqEnable[IRQNUM_MEMFAULT]; + + SVCALLPENDED = IntCtrl->IrqPending[IRQNUM_SVCALL]; + BUSFAULTPENDED = IntCtrl->IrqPending[IRQNUM_BUSFAULT]; + MEMFAULTPENDED = IntCtrl->IrqPending[IRQNUM_MEMFAULT]; + USGFAULTPENDED = IntCtrl->IrqPending[IRQNUM_USAGEFAULT]; + + SYSTICKACT = IntCtrl->IrqActive[IRQNUM_SYSTICK]; + PENDSVACT = IntCtrl->IrqActive[IRQNUM_PENDSV]; + MONITORACT = IntCtrl->IrqActive[IRQNUM_DEBUG]; + SVCALLACT = IntCtrl->IrqActive[IRQNUM_SVCALL]; + USGFAULTACT = IntCtrl->IrqActive[IRQNUM_USAGEFAULT]; + BUSFAULTACT = IntCtrl->IrqActive[IRQNUM_BUSFAULT]; + MEMFAULTACT = IntCtrl->IrqActive[IRQNUM_MEMFAULT]; + + reg = + ((USGFAULTENA)?(REG_SHCSR_USGFAULTENA):(0)) | + ((BUSFAULTENA)?(REG_SHCSR_BUSFAULTENA):(0)) | + ((MEMFAULTENA)?(REG_SHCSR_MEMFAULTENA):(0)) | + + ((SVCALLPENDED)?(REG_SHCSR_SVCALLPENDED):(0)) | + ((BUSFAULTPENDED)?(REG_SHCSR_BUSFAULTPENDED):(0)) | + ((MEMFAULTPENDED)?(REG_SHCSR_MEMFAULTPENDED):(0)) | + ((USGFAULTPENDED)?(REG_SHCSR_USGFAULTPENDED):(0)) | + + ((SYSTICKACT)?(REG_SHCSR_SYSTICKACT):(0)) | + ((PENDSVACT)?(REG_SHCSR_PENDSVACT):(0)) | + ((MONITORACT)?(REG_SHCSR_MONITORACT):(0)) | + ((SVCALLACT)?(REG_SHCSR_SVCALLACT):(0)) | + ((USGFAULTACT)?(REG_SHCSR_USGFAULTACT):(0)) | + ((BUSFAULTACT)?(REG_SHCSR_BUSFAULTACT):(0)) | + ((MEMFAULTACT)?(REG_SHCSR_MEMFAULTACT):(0)); + ; + + BusRead(&cbs->x.bus, ®); + + ChangeEnable(IRQNUM_USAGEFAULT,reg & REG_SHCSR_USGFAULTENA); + ChangeEnable(IRQNUM_BUSFAULT,reg & REG_SHCSR_BUSFAULTENA); + ChangeEnable(IRQNUM_MEMFAULT,reg & REG_SHCSR_MEMFAULTENA); + + ChangePending(IRQNUM_SVCALL, reg & REG_SHCSR_SVCALLPENDED); + ChangePending(IRQNUM_BUSFAULT, reg & REG_SHCSR_BUSFAULTPENDED); + ChangePending(IRQNUM_MEMFAULT, reg & REG_SHCSR_MEMFAULTPENDED); + ChangePending(IRQNUM_USAGEFAULT,reg & REG_SHCSR_USGFAULTPENDED); + + ChangeActive(IRQNUM_SYSTICK,reg & REG_SHCSR_SYSTICKACT); + ChangeActive(IRQNUM_PENDSV,reg & REG_SHCSR_PENDSVACT); + ChangeActive(IRQNUM_DEBUG,reg & REG_SHCSR_MONITORACT); + ChangeActive(IRQNUM_SVCALL,reg & REG_SHCSR_SVCALLACT); + ChangeActive(IRQNUM_USAGEFAULT,reg & REG_SHCSR_USGFAULTACT); + ChangeActive(IRQNUM_BUSFAULT,reg & REG_SHCSR_BUSFAULTACT); + ChangeActive(IRQNUM_MEMFAULT,reg & REG_SHCSR_MEMFAULTACT); + + Interrupt(processor,IntCtrl,wakeUpEvent); + + return SIMUL_MEMORY_OK; +} + +/*************** Configurable Fault Status Register ***************/ + +int CFSR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg = 0; + + cbs->x.bus.clocks = 1; + + reg = IntCtrl->regs.cfsr & REG_CFSR_MASK; + + return BusWrite(&cbs->x.bus, ®); +} + +int CFSR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg = 0; + + cbs->x.bus.clocks = 1; + + BusRead(&cbs->x.bus, ®); + + IntCtrl->regs.cfsr &= ~(reg & REG_CFSR_MASK); + + return SIMUL_MEMORY_OK; +} + +/*************** Hard Fault Status Register ***************/ + +int HFSR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg = 0; + + cbs->x.bus.clocks = 1; + + reg = IntCtrl->regs.hfsr & REG_HFSR_MASK; + + return BusWrite(&cbs->x.bus, ®); +} + +int HFSR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg = 0; + + cbs->x.bus.clocks = 1; + + BusRead(&cbs->x.bus, ®); + + IntCtrl->regs.hfsr &= ~(reg & REG_HFSR_MASK); + + return SIMUL_MEMORY_OK; +} + +/*************** Debug Fault Status Register ***************/ + +int DFSR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg = 0; + + cbs->x.bus.clocks = 1; + + reg = IntCtrl->regs.dfsr & REG_DFSR_MASK; + + return BusWrite(&cbs->x.bus, ®); +} + +int DFSR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg = 0; + + cbs->x.bus.clocks = 1; + + BusRead(&cbs->x.bus, ®); + + IntCtrl->regs.dfsr &= ~(reg & REG_DFSR_MASK); + + return SIMUL_MEMORY_OK; +} + +/*************** Memory Manage Address Register ***************/ + +int MMAR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + cbs->x.bus.clocks = 1; + return BusWrite(&cbs->x.bus, &IntCtrl->regs.mmar); +} + +int MMAR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg = IntCtrl->regs.mmar; + + cbs->x.bus.clocks = 1; + + BusRead(&cbs->x.bus, ®); + + IntCtrl->regs.mmar = reg; + + return SIMUL_MEMORY_OK; +} + +/*************** Bus Fault Address Register ***************/ + +int BFAR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + cbs->x.bus.clocks = 1; + return BusWrite(&cbs->x.bus, &IntCtrl->regs.bfar); +} + +int BFAR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg = IntCtrl->regs.bfar; + + cbs->x.bus.clocks = 1; + + BusRead(&cbs->x.bus, ®); + + IntCtrl->regs.bfar = reg; + + return SIMUL_MEMORY_OK; +} + +/*************** Auxiliary Fault Status Register ***************/ + +int AFSR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg = IntCtrl->regs.afsr; + + cbs->x.bus.clocks = 1; + + return BusWrite(&cbs->x.bus, ®); +} + +int AFSR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg = 0; + + cbs->x.bus.clocks = 1; + + BusRead(&cbs->x.bus, ®); + + IntCtrl->regs.afsr &= ~(reg & REG_AFSR_MASK); + + return SIMUL_MEMORY_OK; +} + +/*************** Debug Halting Control and Status Register ***************/ + +int DHCSR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg = IntCtrl->regs.dhcsr; + + cbs->x.bus.clocks = 1; + + return BusWrite(&cbs->x.bus, ®); +} + +int DHCSR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg = 0; + + cbs->x.bus.clocks = 1; + + BusRead(&cbs->x.bus, ®); + + IntCtrl->regs.dhcsr = reg; + + return SIMUL_MEMORY_OK; +} diff --git a/debuggers/t32/sim/armm3/nvic/nvic_system_control_block_cpuid.c b/debuggers/t32/sim/armm3/nvic/nvic_system_control_block_cpuid.c new file mode 100644 index 00000000..8898e48c --- /dev/null +++ b/debuggers/t32/sim/armm3/nvic/nvic_system_control_block_cpuid.c @@ -0,0 +1,37 @@ +#include "nvic.h" + +/*************** CPUID Base Register ***************/ + +int CPUIDR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + cbs->x.bus.clocks = 1; + return BusWrite(&cbs->x.bus, &IntCtrl->regs.cpuidr); +} + +/*************** Features ***************/ + +int Feature_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg = 0x0; + + switch ((cbs->x.bus.address-(IntCtrl->baseaddress+PFR0_OFFSET))&0xFF) + { + case 0x00: reg = IntCtrl->regs.pfr0; break; + case 0x04: reg = IntCtrl->regs.pfr1; break; + case 0x08: reg = IntCtrl->regs.dfr0; break; + case 0x0C: reg = IntCtrl->regs.afr0; break; + case 0x10: reg = IntCtrl->regs.mmfr0; break; + case 0x14: reg = IntCtrl->regs.mmfr1; break; + case 0x18: reg = IntCtrl->regs.mmfr2; break; + case 0x1C: reg = IntCtrl->regs.mmfr3; break; + case 0x20: reg = IntCtrl->regs.isar0; break; + case 0x24: reg = IntCtrl->regs.isar1; break; + case 0x28: reg = IntCtrl->regs.isar2; break; + case 0x2C: reg = IntCtrl->regs.isar3; break; + case 0x30: reg = IntCtrl->regs.isar4; break; + } + cbs->x.bus.clocks = 1; + return BusWrite(&cbs->x.bus, ®); +} diff --git a/debuggers/t32/sim/armm3/nvic/nvic_system_timer.c b/debuggers/t32/sim/armm3/nvic/nvic_system_timer.c new file mode 100644 index 00000000..52275b77 --- /dev/null +++ b/debuggers/t32/sim/armm3/nvic/nvic_system_timer.c @@ -0,0 +1,118 @@ +#include "nvic.h" + +/*************** SysTick Control and Status Register ***************/ + +int STCSR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg; + cbs->x.bus.clocks = 1; + + reg = IntCtrl->regs.stcsr & (REG_STCSR_COUNTFLAG | REG_STCSR_TICKINT | REG_STCSR_ENABLE | REG_STCSR_CLKSOURCE); + + if (cbs->x.bus.cycletype!=SIMUL_MEMORY_HIDDEN) + { + IntCtrl->regs.stcsr &= ~REG_STCSR_COUNTFLAG; + } + + return BusWrite(&cbs->x.bus, ®); +} + +int STCSR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg; + cbs->x.bus.clocks = 1; + + reg = IntCtrl->regs.stcsr; + BusRead(&cbs->x.bus,®); + + if (reg ^ IntCtrl->regs.stcsr) + { + if ((IntCtrl->regs.stcsr & REG_STCSR_ENABLE) ^ (reg & REG_STCSR_ENABLE)) + { + if (reg & REG_STCSR_ENABLE) + { + /* enable timer */ + simulTime time = 1; + SIMUL_StartTimer(processor, IntCtrl->timer, SIMUL_TIMER_REPEAT | SIMUL_TIMER_CLOCKS, &time); + IntCtrl->timerrun = 1; + + IntCtrl->regs.stcvr = IntCtrl->regs.strvr; + } + else + { + /* disable timer */ + SIMUL_StopTimer(processor, IntCtrl->timer); + IntCtrl->timerrun = 0; + } + } + + IntCtrl->regs.stcsr = (IntCtrl->regs.stcsr & ~(REG_STCSR_TICKINT | REG_STCSR_ENABLE | REG_STCSR_COUNTFLAG)) | (reg & (REG_STCSR_TICKINT | REG_STCSR_ENABLE | REG_STCSR_COUNTFLAG)) | REG_STCSR_CLKSOURCE; + } + + return SIMUL_MEMORY_OK; +} + +/*************** SysTick Reload Value Register ***************/ + +int STRVR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg; + cbs->x.bus.clocks = 1; + + reg = IntCtrl->regs.strvr & 0xFFFFFF; + + return BusWrite(&cbs->x.bus, ®); +} + +int STRVR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg; + cbs->x.bus.clocks = 1; + + BusRead(&cbs->x.bus,®); + + IntCtrl->regs.strvr = reg & 0xFFFFFF; + + return SIMUL_MEMORY_OK; +} + +/*************** SysTick Current Value Register ***************/ + +int STCVR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg; + cbs->x.bus.clocks = 1; + + reg = IntCtrl->regs.stcvr & 0xFFFFFF; + + return BusWrite(&cbs->x.bus, ®); +} + +int STCVR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + cbs->x.bus.clocks = 1; + + IntCtrl->regs.stcvr = 0; + IntCtrl->regs.stcvr &= ~REG_STCSR_COUNTFLAG; + + return SIMUL_MEMORY_OK; +} + +/*************** SysTick Calibration Value Register ***************/ + +int STCLVR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private) +{ + IntController *IntCtrl = (IntController*) _private; + simulWord32 reg; + cbs->x.bus.clocks = 1; + + reg = IntCtrl->regs.stclvr; + + return BusWrite(&cbs->x.bus, ®); +} diff --git a/debuggers/t32/sim/demo/demoport/demoport.c b/debuggers/t32/sim/demo/demoport/demoport.c new file mode 100644 index 00000000..d380bb3c --- /dev/null +++ b/debuggers/t32/sim/demo/demoport/demoport.c @@ -0,0 +1,876 @@ + +#include "simul.h" + + +/************************************************************************** + + Offsets and width of the control registers + +**************************************************************************/ + +#define DEMOPORT_WIDTH 4 +#define DEMOPORT_DATA1REG 0 +#define DEMOPORT_DATA2REG 1*DEMOPORT_WIDTH +#define DEMOPORT_DATA3REG 2*DEMOPORT_WIDTH +#define DEMOPORT_DATA5REG 3*DEMOPORT_WIDTH +#define DEMOPORT_DATA6REG 3*DEMOPORT_WIDTH+1 +#define DEMOPORT_DATA6CREG 3*DEMOPORT_WIDTH+2 +#define DEMOPORT_TIMER1REG 4*DEMOPORT_WIDTH +#define DEMOPORT_TIMER2REG 5*DEMOPORT_WIDTH +#define DEMOPORT_TIMER3REG 6*DEMOPORT_WIDTH +#define DEMOPORT_RAM1BASE 0x200 + + +/************************************************************************** + + Local port structure + +**************************************************************************/ + +typedef struct +{ + int bustype; + simulWord startaddress; + int baseport; + + simulWord port2data; + + simulWord port4data; + void * port4readcallback; + void * port4writecallback; + + void * port5readhandle; + void * port5writehandle; + simulWord port5data; + + int port6txint; + int port6rxint; + int port6txintpending; + int port6rxintpending; + + void * timer1id; + + simulWord timer2value; + + void * timer3id; + int timer3running; + simulWord timer3startvalue; + simulTime timer3startclock; +} +demoPort; + + +/************************************************************************** + + Data1 demonstrates a port which is directly connected to simulator ports. + The callback is called for reads and writes to the port. + +**************************************************************************/ + +static int SIMULAPI PortWriteData1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + demoPort *demoportptr = (demoPort *) private; + + SIMUL_SetPort(processor, demoportptr->baseport + DEMOPORT_DATA1REG * 8, cbs->x.bus.width, &cbs->x.bus.data); + cbs->x.bus.clocks += 4; /* add 4 waitstates */ + return SIMUL_MEMORY_OK; +} + + +static int SIMULAPI PortReadData1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + demoPort *demoportptr = (demoPort *) private; + + SIMUL_GetPort(processor, demoportptr->baseport + DEMOPORT_DATA1REG * 8, cbs->x.bus.width, &cbs->x.bus.data); + cbs->x.bus.clocks += 4; /* add 4 waitstates */ + return SIMUL_MEMORY_OK; +} + + +static int SIMULAPI PortResetData1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + simulWord data; + demoPort *demoportptr = (demoPort *) private; + + data = -1; + SIMUL_SetPort(processor, demoportptr->baseport + DEMOPORT_DATA1REG * 8, DEMOPORT_WIDTH * 8, &data); + + return SIMUL_RESET_OK; +} + + +static void PortInitData1(simulProcessor processor, demoPort * demoportptr) +{ + simulWord from, to; + + SIMUL_RegisterResetCallback(processor, PortResetData1, (simulPtr) demoportptr); + + from = demoportptr->startaddress + DEMOPORT_DATA1REG; + to = demoportptr->startaddress + DEMOPORT_DATA1REG + DEMOPORT_WIDTH - 1; + + SIMUL_RegisterBusWriteCallback(processor, PortWriteData1, (simulPtr) demoportptr, demoportptr->bustype, &from, &to); + + SIMUL_RegisterBusReadCallback(processor, PortReadData1, (simulPtr) demoportptr, demoportptr->bustype, &from, &to); +} + + + + +/************************************************************************** + + Data2 demonstrates a port which holds its data local. + The callback is called for reads and writes to the port. + Only the correct bussize is allowed. + +**************************************************************************/ + +static int SIMULAPI PortWriteData2(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + demoPort *demoportptr = (demoPort *) private; + + if (cbs->x.bus.width != DEMOPORT_WIDTH * 8) + return SIMUL_MEMORY_FAIL; + demoportptr->port2data = cbs->x.bus.data; + cbs->x.bus.clocks = 0; /* 0-cycle access */ + return SIMUL_MEMORY_OK; +} + + +static int SIMULAPI PortReadData2(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + demoPort *demoportptr = (demoPort *) private; + + if (cbs->x.bus.width != DEMOPORT_WIDTH * 8) + return SIMUL_MEMORY_FAIL; + cbs->x.bus.data = demoportptr->port2data; + return SIMUL_MEMORY_OK; +} + + +static int SIMULAPI PortResetData2(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + demoPort *demoportptr = (demoPort *) private; + + demoportptr->port2data = 0; + + return SIMUL_RESET_OK; +} + + +static void PortInitData2(simulProcessor processor, demoPort * demoportptr) +{ + simulWord from, to; + + demoportptr->port2data = 0; + + SIMUL_RegisterResetCallback(processor, PortResetData2, (simulPtr) demoportptr); + + from = demoportptr->startaddress + DEMOPORT_DATA2REG; + to = demoportptr->startaddress + DEMOPORT_DATA2REG + DEMOPORT_WIDTH - 1; + + SIMUL_RegisterBusWriteCallback(processor, PortWriteData2, (simulPtr) demoportptr, demoportptr->bustype, &from, &to); + + SIMUL_RegisterBusReadCallback(processor, PortReadData2, (simulPtr) demoportptr, demoportptr->bustype, &from, &to); +} + + + + +/************************************************************************** + + Data3 demonstrates a port which holds global data (same for multiple instances). + The callback is called for reads and writes to the port. + All bussizes are supported. + +**************************************************************************/ + +static simulWord Port3Data; + +static int SIMULAPI PortWriteData3(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + SIMUL_InsertWord(processor, &Port3Data, DEMOPORT_WIDTH*8, &cbs->x.bus.address, cbs->x.bus.width, &cbs->x.bus.data); + return SIMUL_MEMORY_OK; +} + + +static int SIMULAPI PortReadData3(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + SIMUL_ExtractWord(processor, &Port3Data, DEMOPORT_WIDTH*8, &cbs->x.bus.address, cbs->x.bus.width, &cbs->x.bus.data); + return SIMUL_MEMORY_OK; +} + + +static void PortInitData3(simulProcessor processor, demoPort * demoportptr) +{ + simulWord from, to; + + from = demoportptr->startaddress + DEMOPORT_DATA3REG; + to = demoportptr->startaddress + DEMOPORT_DATA3REG + DEMOPORT_WIDTH - 1; + + SIMUL_RegisterBusWriteCallback(processor, PortWriteData3, (simulPtr) demoportptr, demoportptr->bustype, &from, &to); + + SIMUL_RegisterBusReadCallback(processor, PortReadData3, (simulPtr) demoportptr, demoportptr->bustype, &from, &to); +} + + + +/************************************************************************** + + Data4 demonstrates a port with a dynamic address. + The value written to the port is the address of the port. + The lower 8 address bits of the address are zero. + The callback is called for reads and writes to the port. + +**************************************************************************/ + +static int SIMULAPI PortWriteData4(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + demoPort *demoportptr = (demoPort *) private; + simulWord from, to; + + SIMUL_InsertWord(processor, &demoportptr->port4data, DEMOPORT_WIDTH * 8, &cbs->x.bus.address, cbs->x.bus.width, &cbs->x.bus.data); + demoportptr->port4data &= ~0xff; + + from = demoportptr->port4data; + to = demoportptr->port4data + DEMOPORT_WIDTH - 1; + + SIMUL_RelocateBusCallback(processor, demoportptr->port4readcallback, demoportptr->bustype, &from, &to); + + SIMUL_RelocateBusCallback(processor, demoportptr->port4writecallback, demoportptr->bustype, &from, &to); + + return SIMUL_MEMORY_OK; +} + + +static int SIMULAPI PortReadData4(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + demoPort *demoportptr = (demoPort *) private; + + SIMUL_ExtractWord(processor, &demoportptr->port4data, DEMOPORT_WIDTH*8, &cbs->x.bus.address, cbs->x.bus.width, &cbs->x.bus.data); + return SIMUL_MEMORY_OK; +} + + +static int SIMULAPI PortResetData4(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + simulWord from, to; + demoPort *demoportptr = (demoPort *) private; + + demoportptr->port4data = (demoportptr->startaddress & ~0xff) + 0x100; /* initial address after reset */ + + from = demoportptr->port4data; + to = demoportptr->port4data + DEMOPORT_WIDTH - 1; + + SIMUL_RelocateBusCallback(processor, demoportptr->port4readcallback, demoportptr->bustype, &from, &to); + + SIMUL_RelocateBusCallback(processor, demoportptr->port4writecallback, demoportptr->bustype, &from, &to); + + return SIMUL_RESET_OK; +} + + +static void PortInitData4(simulProcessor processor, demoPort * demoportptr) +{ + simulWord from, to; + + demoportptr->port4data = (demoportptr->startaddress & ~0xff) + 0x100; /* initial address */ + + SIMUL_RegisterResetCallback(processor, PortResetData4, (simulPtr) demoportptr); + + from = demoportptr->port4data; + to = demoportptr->port4data + DEMOPORT_WIDTH - 1; + + demoportptr->port4writecallback = SIMUL_RegisterBusWriteCallback(processor, PortWriteData4, (simulPtr) demoportptr, demoportptr->bustype, &from, &to); + + demoportptr->port4readcallback = SIMUL_RegisterBusReadCallback(processor, PortReadData4, (simulPtr) demoportptr, demoportptr->bustype, &from, &to); +} + + + +/************************************************************************** + + Data5 demonstrates a port which writes or reads binary data to/from file. + The callback is called for reads and writes to the port. + All bussizes are supported. + +**************************************************************************/ + +static int SIMULAPI PortWriteData5(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + unsigned char bdata; + simulWord wdata; + demoPort *demoportptr = (demoPort *) private; + + SIMUL_InsertWord(processor, &wdata, 8, &cbs->x.bus.address, cbs->x.bus.width, &cbs->x.bus.data); + bdata = wdata & 0xff; + + if (SIMUL_WriteFile(processor, demoportptr->port5writehandle, &bdata, 1) <= 0) + return SIMUL_MEMORY_FAIL; + + return SIMUL_MEMORY_OK; +} + + +static int SIMULAPI PortReadData5(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + unsigned char bdata; + demoPort *demoportptr = (demoPort *) private; + + if (cbs->x.bus.cycletype) { /* destructive read only done when CPU/DMA makes access */ + if (!demoportptr->port5readhandle) + return SIMUL_MEMORY_FAIL; + if (SIMUL_ReadFile(processor, demoportptr->port5readhandle, &bdata, 1) <= 0) + return SIMUL_MEMORY_FAIL; + demoportptr->port5data = bdata; + } + + SIMUL_ExtractWord(processor, &demoportptr->port5data, 8, &cbs->x.bus.address, cbs->x.bus.width, &cbs->x.bus.data); + return SIMUL_MEMORY_OK; +} + + +static int SIMULAPI PortResetData5(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + demoPort *demoportptr = (demoPort *) private; + + if (demoportptr->port5readhandle) + SIMUL_SeekFile(processor, demoportptr->port5readhandle, 0l, SIMUL_FILE_SEEKABS); + demoportptr->port5data = 0; + + return SIMUL_RESET_OK; +} + + +static void PortInitData5(simulProcessor processor, demoPort * demoportptr) +{ + simulWord from, to; + + demoportptr->port5readhandle = SIMUL_OpenFile(processor, "~~~/portread.dat", SIMUL_FILE_READ); + demoportptr->port5writehandle = SIMUL_OpenFile(processor, "~~~/portwrit.dat", SIMUL_FILE_WRITE|SIMUL_FILE_CREATE); + + demoportptr->port5data = 0; + + SIMUL_RegisterResetCallback(processor, PortResetData5, (simulPtr) demoportptr); + + from = demoportptr->startaddress + DEMOPORT_DATA5REG; + to = demoportptr->startaddress + DEMOPORT_DATA5REG; + + SIMUL_RegisterBusWriteCallback(processor, PortWriteData5, (simulPtr) demoportptr, demoportptr->bustype, &from, &to); + + SIMUL_RegisterBusReadCallback(processor, PortReadData5, (simulPtr) demoportptr, demoportptr->bustype, &from, &to); +} + + + +/************************************************************************** + + Terminal1 demonstrates a port which is connected to terminal window #1. + Terminal1 is the data port, Terminal1C the status and control port. + The callback is called for reads and writes to the port. + Bits 6+7 or control enable the interrupts. + The interrupt drives directly the CPU. For normal applications this + should go thru an interrupt controller. + When unloading the model we write a message to the terminal. + +**************************************************************************/ + +static int SIMULAPI PortWriteTerminal1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + simulWord data; + demoPort *demoportptr = (demoPort *) private; + + demoportptr->port6txintpending = 0; + if (!((demoportptr->port6txintpending && demoportptr->port6txint) + || (demoportptr->port6rxintpending && demoportptr->port6rxint))) { + data = 0; + SIMUL_SetPort(processor, SIMUL_PORT_INTERRUPT, 1, &data); + } + if (SIMUL_WriteTerminal(processor, 1, (int) (cbs->x.bus.data & 0xff)) > 0) { + demoportptr->port6txintpending = 1; + if (((demoportptr->port6txintpending && demoportptr->port6txint) + || (demoportptr->port6rxintpending && demoportptr->port6rxint))) { + data = 1; + SIMUL_SetPort(processor, SIMUL_PORT_INTERRUPT, 1, &data); + } + } + return SIMUL_MEMORY_OK; +} + + +static int SIMULAPI PortReadTerminal1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + simulWord data; + demoPort *demoportptr = (demoPort *) private; + + if (cbs->x.bus.cycletype) { /* destructive read only done when CPU/DMA + * makes access */ + cbs->x.bus.data = SIMUL_ReadTerminal(processor, 1); + demoportptr->port6rxintpending = 0; + if (!((demoportptr->port6txintpending && demoportptr->port6txint) + || (demoportptr->port6rxintpending && demoportptr->port6rxint))) { + data = 0; + SIMUL_SetPort(processor, SIMUL_PORT_INTERRUPT, 1, &data); + } + return SIMUL_MEMORY_OK; + } + return SIMUL_MEMORY_FAIL; +} + + +static int SIMULAPI PortWriteTerminal1C(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + simulWord data; + demoPort *demoportptr = (demoPort *) private; + + demoportptr->port6txint = !!(cbs->x.bus.data & 0x80); + demoportptr->port6rxint = !!(cbs->x.bus.data & 0x40); + + if (((demoportptr->port6txintpending && demoportptr->port6txint) + || (demoportptr->port6rxintpending && demoportptr->port6rxint))) { + data = 1; + } else { + data = 0; + } + SIMUL_SetPort(processor, SIMUL_PORT_INTERRUPT, 1, &data); + + return SIMUL_MEMORY_OK; +} + + +static int SIMULAPI PortReadTerminal1C(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + demoPort *demoportptr = (demoPort *) private; + + cbs->x.bus.data = SIMUL_StateTerminal(processor, 1); + cbs->x.bus.data |= (demoportptr->port6txint << 7) | (demoportptr->port6rxint << 6); + + return SIMUL_MEMORY_OK; +} + + +static int SIMULAPI PortReceiveTerminal1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + simulWord data; + demoPort *demoportptr = (demoPort *) private; + + demoportptr->port6rxintpending = 1; + + if (((demoportptr->port6txintpending && demoportptr->port6txint) + || (demoportptr->port6rxintpending && demoportptr->port6rxint))) { + data = 1; + SIMUL_SetPort(processor, SIMUL_PORT_INTERRUPT, 1, &data); + } + + return SIMUL_MEMORY_OK; +} + + +static int SIMULAPI PortResetTerminal1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + demoPort *demoportptr = (demoPort *) private; + + demoportptr->port6txint = 0; + demoportptr->port6rxint = 0; + + demoportptr->port6txintpending = 0; + demoportptr->port6rxintpending = 0; + + return SIMUL_RESET_OK; +} + + +static int SIMULAPI PortExitTerminal1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + int i; + demoPort *demoportptr = (demoPort *) private; + static const char exitmessage[] = "\r\nunloaded.\r\n"; + + for (i = 0; exitmessage[i]; i++) + SIMUL_WriteTerminal(processor, 1, exitmessage[i]); + + return SIMUL_EXIT_OK; +} + + +static void PortInitTerminal1(simulProcessor processor, demoPort * demoportptr) +{ + simulWord from, to; + + demoportptr->port6txint = 0; + demoportptr->port6rxint = 0; + + demoportptr->port6txintpending = 0; + demoportptr->port6rxintpending = 0; + + SIMUL_RegisterResetCallback(processor, PortResetTerminal1, (simulPtr) demoportptr); + + SIMUL_RegisterExitCallback(processor, PortExitTerminal1, (simulPtr) demoportptr); + + from = demoportptr->startaddress + DEMOPORT_DATA6REG; + to = demoportptr->startaddress + DEMOPORT_DATA6REG; + + SIMUL_RegisterBusWriteCallback(processor, PortWriteTerminal1, (simulPtr) demoportptr, demoportptr->bustype, &from, &to); + + SIMUL_RegisterBusReadCallback(processor, PortReadTerminal1, (simulPtr) demoportptr, demoportptr->bustype, &from, &to); + + + from = demoportptr->startaddress + DEMOPORT_DATA6CREG; + to = demoportptr->startaddress + DEMOPORT_DATA6CREG; + + SIMUL_RegisterBusWriteCallback(processor, PortWriteTerminal1C, (simulPtr) demoportptr, demoportptr->bustype, &from, &to); + + SIMUL_RegisterBusReadCallback(processor, PortReadTerminal1C, (simulPtr) demoportptr, demoportptr->bustype, &from, &to); + + SIMUL_RegisterTerminalCallback(processor, PortReceiveTerminal1, (simulPtr) demoportptr, 1); +} + + + +/************************************************************************** + + Ram1 demonstrates multiport RAM between different CPUs. + The callback is called for reads and writes to the port. + All bussizes are supported. + +**************************************************************************/ + +static int SIMULAPI PortWriteRam1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + int offset, len; + unsigned char data[8]; + + len = cbs->x.bus.width / 8; + offset = cbs->x.bus.address & 0xff; + + SIMUL_SaveWord(processor, data, cbs->x.bus.width, &cbs->x.bus.data); + + if (SIMUL_WriteSharedResource(processor, offset, len, data) < 0) + return SIMUL_MEMORY_FAIL; + return SIMUL_MEMORY_OK; +} + + +static int SIMULAPI PortReadRam1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + int offset, len; + unsigned char data[8]; + + len = cbs->x.bus.width / 8; + offset = cbs->x.bus.address & 0xff; + + if (SIMUL_ReadSharedResource(processor, offset, len, data) < 0) + return SIMUL_MEMORY_FAIL; + + SIMUL_LoadWord(processor, data, cbs->x.bus.width, &cbs->x.bus.data); + return SIMUL_MEMORY_OK; +} + + +static void PortInitRam1(simulProcessor processor, demoPort * demoportptr) +{ + simulWord from, to; + + SIMUL_CreateSharedResource(processor, 256); + + from = demoportptr->startaddress + DEMOPORT_RAM1BASE; + to = demoportptr->startaddress + DEMOPORT_RAM1BASE + 0xff - 1; + + SIMUL_RegisterBusWriteCallback(processor, PortWriteRam1, (simulPtr) demoportptr, demoportptr->bustype, &from, &to); + + SIMUL_RegisterBusReadCallback(processor, PortReadRam1, (simulPtr) demoportptr, demoportptr->bustype, &from, &to); +} + + + +/************************************************************************** + + Timer1 demonstrates a timer that increments every clockticks. + The callback is called for each increment. + The timervalue is directly kept in simulated memory, no read callback. + A copy of the timer bits is also available in the ports. + Bit 0 of the timer is send to port #0xf0 (to trigger Timer2). + The command "SIM SETTIMER1 " can set the period of the timer. + +**************************************************************************/ + +static int SIMULAPI PortWriteTimer1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + demoPort *demoportptr = (demoPort *) private; + + SIMUL_SetPort(processor, demoportptr->baseport+DEMOPORT_TIMER1REG*8, cbs->x.bus.width, &cbs->x.bus.data); + SIMUL_SetPort(processor, 0xf0, 1, &cbs->x.bus.data); + + return SIMUL_MEMORY_CONTINUE; /* to update also the memory location */ +} + + +static int SIMULAPI PortIncTimer1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + demoPort *demoportptr = (demoPort *) private; + simulWord data, address; + + address = demoportptr->startaddress + DEMOPORT_TIMER1REG; + + SIMUL_ReadMemory(processor, demoportptr->bustype, &address, DEMOPORT_WIDTH*8, SIMUL_MEMORY_HIDDEN, &data); + data++; + + /* note: this write will cause the PortWriteTimer1 callback to be called */ + + SIMUL_WriteMemory(processor, demoportptr->bustype, &address, DEMOPORT_WIDTH*8, SIMUL_MEMORY_HIDDEN, &data); + + return SIMUL_TIMER_OK; +} + + +static int SIMULAPI PortCommandTimer1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + simulTime time; + demoPort *demoportptr = (demoPort *) private; + + if (!strcmp(cbs->x.command.argp[0], "SETTIMER1")) { + if (cbs->x.command.argc != 2 || cbs->x.command.argpint[1] <= 0) { + SIMUL_Warning(processor, "usage: SETTIMER1 "); + return SIMUL_COMMAND_FAIL; + } + time = cbs->x.command.argpint[1]; + SIMUL_StartTimer(processor, demoportptr->timer1id, SIMUL_TIMER_REPEAT | SIMUL_TIMER_REL | SIMUL_TIMER_CLOCKS, &time); + } + + return SIMUL_COMMAND_OK; +} + + +static int SIMULAPI PortResetTimer1(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + simulTime time; + demoPort *demoportptr = (demoPort *) private; + + time = 100; + SIMUL_StartTimer(processor, demoportptr->timer1id, SIMUL_TIMER_REPEAT | SIMUL_TIMER_REL | SIMUL_TIMER_CLOCKS, &time); + + return SIMUL_RESET_OK; +} + + +static void PortInitTimer1(simulProcessor processor, demoPort * demoportptr) +{ + simulTime time; + simulWord from, to; + + SIMUL_RegisterResetCallback(processor, PortResetTimer1, (simulPtr) demoportptr); + + SIMUL_RegisterCommandCallback(processor, PortCommandTimer1, (simulPtr) demoportptr); + + from = demoportptr->startaddress + DEMOPORT_TIMER1REG; + to = demoportptr->startaddress + DEMOPORT_TIMER1REG + DEMOPORT_WIDTH - 1; + + SIMUL_RegisterBusWriteCallback(processor, PortWriteTimer1, (simulPtr) demoportptr, demoportptr->bustype, &from, &to); + + demoportptr->timer1id = SIMUL_RegisterTimerCallback(processor, PortIncTimer1, (simulPtr) demoportptr); + + time = 100; + SIMUL_StartTimer(processor, demoportptr->timer1id, SIMUL_TIMER_REPEAT | SIMUL_TIMER_REL | SIMUL_TIMER_CLOCKS, &time); +} + + + +/************************************************************************** + + Timer2 demonstrates a timer that counts rising edges of port #0xf0. + Any write access resets the timer to 0. + The read callback does not take care about the buswidth and + will return wrong values for wrong bussizes (but it is faster). + +**************************************************************************/ + +static int SIMULAPI PortWriteTimer2(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + demoPort *demoportptr = (demoPort *) private; + + demoportptr->timer2value = 0; + return SIMUL_MEMORY_OK; +} + + +static int SIMULAPI PortReadTimer2(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + demoPort *demoportptr = (demoPort *) private; + + cbs->x.bus.data = demoportptr->timer2value; + return SIMUL_MEMORY_OK; +} + + +static int SIMULAPI PortChangeTimer2(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + demoPort *demoportptr = (demoPort *) private; + + if (cbs->x.port.newdata) + demoportptr->timer2value++; + + return SIMUL_PORT_OK; +} + + +static int SIMULAPI PortResetTimer2(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + demoPort *demoportptr = (demoPort *) private; + + demoportptr->timer2value = 0; + + return SIMUL_RESET_OK; +} + + +static void PortInitTimer2(simulProcessor processor, demoPort * demoportptr) +{ + simulWord from, to; + + demoportptr->timer2value = 0; + + SIMUL_RegisterResetCallback(processor, PortResetTimer2, (simulPtr) demoportptr); + + from = demoportptr->startaddress + DEMOPORT_TIMER2REG; + to = demoportptr->startaddress + DEMOPORT_TIMER2REG + DEMOPORT_WIDTH - 1; + + SIMUL_RegisterBusWriteCallback(processor, PortWriteTimer2, (simulPtr) demoportptr, demoportptr->bustype, &from, &to); + + SIMUL_RegisterBusReadCallback(processor, PortReadTimer2, (simulPtr) demoportptr, demoportptr->bustype, &from, &to); + + SIMUL_RegisterPortChangeCallback(processor, PortChangeTimer2, (simulPtr) demoportptr, 0xf0, 1); +} + + + +/************************************************************************** + + Timer3 demonstrates a timer that decrements every clocktick. + A write to the port starts the timer. + The timer send an interrupt to the CPU when the value reaches 0. + The callback is only called when the value reaches 0. + The read callback calculates the expected value. + +**************************************************************************/ + +static int SIMULAPI PortWriteTimer3(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + simulTime clocks; + demoPort *demoportptr = (demoPort *) private; + + if (!demoportptr->timer3id) + return SIMUL_MEMORY_FAIL; + + demoportptr->timer3running = 1; + demoportptr->timer3startvalue = cbs->x.bus.data; + SIMUL_GetClock(processor, 0, &demoportptr->timer3startclock); + + clocks = demoportptr->timer3startvalue; + + SIMUL_StartTimer(processor, demoportptr->timer3id, SIMUL_TIMER_REL | SIMUL_TIMER_CLOCKS, &clocks); + + return SIMUL_MEMORY_OK; +} + + +static int SIMULAPI PortReadTimer3(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + simulTime clocks; + demoPort *demoportptr = (demoPort *) private; + + if (!demoportptr->timer3running) { + cbs->x.bus.data = 0; + return SIMUL_MEMORY_OK; + } + + SIMUL_GetClock(processor, 0, &clocks); + clocks = clocks-demoportptr->timer3startclock; + + cbs->x.bus.data = demoportptr->timer3startvalue - (simulWord) clocks; + return SIMUL_MEMORY_OK; +} + + +static int SIMULAPI PortCallTimer3(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + simulWord data; + demoPort *demoportptr = (demoPort *) private; + + demoportptr->timer3running = 0; + + /* set the interrupt line */ + + data = 1; + SIMUL_SetPort(processor, SIMUL_PORT_INTERRUPT, 1, &data); + + return SIMUL_TIMER_OK; +} + + +static int SIMULAPI PortResetTimer3(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + demoPort *demoportptr = (demoPort *) private; + + SIMUL_StopTimer(processor, demoportptr->timer3id); + demoportptr->timer3running = 0; + + return SIMUL_RESET_OK; +} + + +static void PortInitTimer3(simulProcessor processor, demoPort * demoportptr) +{ + simulWord from, to; + + demoportptr->timer3running = 0; + + SIMUL_RegisterResetCallback(processor, PortResetTimer3, (simulPtr) demoportptr); + + from = demoportptr->startaddress + DEMOPORT_TIMER3REG; + to = demoportptr->startaddress + DEMOPORT_TIMER3REG + DEMOPORT_WIDTH - 1; + + SIMUL_RegisterBusWriteCallback(processor, PortWriteTimer3, (simulPtr) demoportptr, demoportptr->bustype, &from, &to); + + SIMUL_RegisterBusReadCallback(processor, PortReadTimer3, (simulPtr) demoportptr, demoportptr->bustype, &from, &to); + + demoportptr->timer3id = SIMUL_RegisterTimerCallback(processor, PortCallTimer3, (simulPtr) demoportptr); +} + + + +/************************************************************************** + + Entry point of the Model + +**************************************************************************/ + +int SIMULAPI SIMUL_Init(simulProcessor processor, simulCallbackStruct * cbs) +{ + demoPort *demoportptr; + + strcpy(cbs->x.init.modelname, __DATE__ " Demo Port"); + + demoportptr = (demoPort *) SIMUL_Alloc(processor, sizeof(demoPort)); + + if (cbs->x.init.argc != 3) { + SIMUL_Warning(processor, "parameters:
"); + return SIMUL_INIT_FAIL; + } + demoportptr->bustype = cbs->x.init.argpbustype[1]; + demoportptr->startaddress = cbs->x.init.argpaddress[1]; + + demoportptr->baseport = cbs->x.init.argpport[2]; + + PortInitData1(processor, demoportptr); + PortInitData2(processor, demoportptr); + PortInitData3(processor, demoportptr); + PortInitData4(processor, demoportptr); + PortInitData5(processor, demoportptr); + PortInitTerminal1(processor, demoportptr); + PortInitRam1(processor, demoportptr); + + PortInitTimer1(processor, demoportptr); + PortInitTimer2(processor, demoportptr); + PortInitTimer3(processor, demoportptr); + + return SIMUL_INIT_OK; +} diff --git a/debuggers/t32/sim/demo/demoport/demoport.cmm b/debuggers/t32/sim/demo/demoport/demoport.cmm new file mode 100644 index 00000000..68e3c70e --- /dev/null +++ b/debuggers/t32/sim/demo/demoport/demoport.cmm @@ -0,0 +1,30 @@ + wclear + + system.up + + sim.res + sim.load demoport.dll 20000 0 + + name.s p.128 timer0 + name.s p.129 timer1 + name.s p.130 timer2 + name.s p.131 timer3 + name.s p.132 timer4 + name.s p.133 timer5 + name.s p.134 timer6 + name.s p.135 timer7 + name.group g.timer p.timer0 p.timer1 p.timer2 p.timer3 p.timer4 p.timer5 p.timer6 p.timer7 + name.word w.timer g.timer + + term.protocol sim + winpos ,,,,,,, iconic + term 1 1 + + winpos ,,,,,,, iconic + port.get + + per demoport + + enddo + + diff --git a/debuggers/t32/sim/demo/demoport/demoport.def b/debuggers/t32/sim/demo/demoport/demoport.def new file mode 100644 index 00000000..b001c929 --- /dev/null +++ b/debuggers/t32/sim/demo/demoport/demoport.def @@ -0,0 +1,7 @@ +LIBRARY DEMOPORT + +DESCRIPTION 'TRACE32 Hardware Simulation Demoport' + +EXPORTS + SIMUL_Interface + diff --git a/debuggers/t32/sim/demo/demoport/demoport.dll b/debuggers/t32/sim/demo/demoport/demoport.dll new file mode 100644 index 0000000000000000000000000000000000000000..c1c84df32a4b20973a05a74ee9237620c5800613 GIT binary patch literal 56920 zcmeIb4O~>mxj%lEU2w(4T@5Nm)KxJt)mUH`SU9}HA{x;}6eRH_L@-E<7&yn51PtUr z%i*|*?aghIHchoAy=l|-rfq7CO%qluXkL9uQKYaRSvgcPnP9k~i^aEqL zXGgy}W4~_kt235YZm6|xuBpDWrtEI(y0T51ss-yE71kPYlXb%;Ywpq_>)qAm74st^ z!ejiX#Xs3Ti+f`A^Fwac^Aiy+`oogva`>f{Vck{0Fv=TCdxPHYr(cBIc^O=xo(b|L&?|t>A0v+B<>z0<(iPg6HMng?)318 z%iiY;725>Fz1oBa(MNS1tOVZivvS<+^J~h>gffnsHVP5D;f!#taKnC?=mzsOFm4WU z@fkP=+;`!I{W3YOZTduA1y#zPxmq~Cn6&tJ9aa;kVb6^yedz9XXewiGX zJroMQ{lDbEEA%@v>Uxel^Ia<*OX)3r3LfjC@py#ZYG>fFhTbGf&7oii0pCY&4^hIO z(2{3vqSOuwR#NJz$$0#pKu*)+K1y9hj|vLbOvPgbmGJ=O_&((@QtI`TZ5$;mq_{GQ z`vJW@z

O~`1@dh;{HQ^aDozWrzQ81TA{ol;DB$c@3XK}~ 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 X3sP3qZomg2H?LbYIDKp`zk~Zf?(}8O literal 0 HcmV?d00001 diff --git a/debuggers/t32/sim/demo/demoport/demoport.per b/debuggers/t32/sim/demo/demoport/demoport.per new file mode 100644 index 00000000..85aa33bc --- /dev/null +++ b/debuggers/t32/sim/demo/demoport/demoport.per @@ -0,0 +1,44 @@ + width 9. 7. + base d:20000 + + group.long 0--3 "Data1 (Simple Parallel port, available in Portanalyzer)" + line.long 0 "Data1" + + group.long 4--7 "Data2 (Simple Parallel port)" + line.long 0 "Data2" + + group.long 8--0x0b "Data3 (Parallel port, shared data)" + line.long 0 "Data3" + + group.long 100--0x10b "Data4 (Relocatable Parallel port)" + line.long 0 "Data4" + + group.byte 0x0c--0x0c "Data5 (Parallel port connected to FILE I/O)" + line.byte 0 "Data5" + + group.byte 0x0d--0x0d "Terminal1 (Serial I/O simulation to Terminal I/O)" + line.byte 0 "DATA" + group.byte 0x0e--0x0e + line.byte 0 "STAT" + bitfld 0 7 "TXIE ,TX Interrupt Enable" "no,yes" + bitfld 0 6 " RXIE ,RX Interrupt Enable" "no,yes" + bitfld 0 4 " TWAV ,Terminal Window Available" "yes,no" + bitfld 0 1 " TXR ,TX Ready" "no,yes" + bitfld 0 0 " RXR ,RX Ready" "no,yes" + + group.long 0x200--0x20f "Ram1 (Shared memory)" + line.long 0 "00" + line.long 4 "04" + line.long 8 "08" + line.long 0c "0c" + + group.long 0x10--0x13 "Timer1 (Incrementing each 100 clockticks)" + line.long 0 "Timer1" + + group.long 0x14--0x17 "Timer2 (Incrementing on each Port #0xf0 rising edge)" + line.long 0 "Timer2" + + group.long 0x18--0x1b "Timer3 (Decrementing each clockticks after activation)" + line.long 0 "Timer3" + + diff --git a/debuggers/t32/sim/demo/demoport/makefile b/debuggers/t32/sim/demo/demoport/makefile new file mode 100644 index 00000000..9784fe00 --- /dev/null +++ b/debuggers/t32/sim/demo/demoport/makefile @@ -0,0 +1,10 @@ +COPTS = -c -W3 -D_X86_=1 -DWIN32 -Z7 -Od -Gs + +all: demoport.dll + +demoport.dll: demoport.obj simul.obj + link -dll -debug:full -debugtype:cv -out:demoport.dll demoport.obj simul.obj -def:demoport.def + +.c.obj: ; cl $(COPTS) $*.c + + diff --git a/debuggers/t32/sim/demo/demoport/makehp b/debuggers/t32/sim/demo/demoport/makehp new file mode 100644 index 00000000..2096a360 --- /dev/null +++ b/debuggers/t32/sim/demo/demoport/makehp @@ -0,0 +1,7 @@ +OBJECTS = demoport.o simul.o +COPTS = +e +z -c -O + +demoport.so.1: $(OBJECTS) + ld -b -o demoport.sl $(OBJECTS) + +.c.o: ; c89 ${COPTS} $*.c diff --git a/debuggers/t32/sim/demo/demoport/makelinux b/debuggers/t32/sim/demo/demoport/makelinux new file mode 100644 index 00000000..f3784813 --- /dev/null +++ b/debuggers/t32/sim/demo/demoport/makelinux @@ -0,0 +1,7 @@ +OBJECTS = demoport.o simul.o +COPTS = -c -O + +demoport.so.1: $(OBJECTS) + cc -shared -o demoport.so.1 $(OBJECTS) + +.c.o: ; cc ${COPTS} $*.c diff --git a/debuggers/t32/sim/demo/demoport/makesun b/debuggers/t32/sim/demo/demoport/makesun new file mode 100644 index 00000000..e0ab0d3b --- /dev/null +++ b/debuggers/t32/sim/demo/demoport/makesun @@ -0,0 +1,7 @@ +OBJECTS = demoport.o simul.o +COPTS = -c -O + +demoport.so.1: $(OBJECTS) + cc -G -o demoport.so.1 $(OBJECTS) + +.c.o: ; cc ${COPTS} $*.c diff --git a/debuggers/t32/sim/demo/demoport/simul.c b/debuggers/t32/sim/demo/demoport/simul.c new file mode 100644 index 00000000..58957c81 --- /dev/null +++ b/debuggers/t32/sim/demo/demoport/simul.c @@ -0,0 +1,532 @@ + +#include "simul.h" + + +/************************************************************************** + + Model entry + +**************************************************************************/ + +int SIMULAPI SIMUL_Interface(simulProcessor processor, simulCallbackStruct * cbs) +{ + cbs->x.init.version = SIMUL_VERSION; +#if SIMUL_ARCHITECTURE_WIDTH == 8 + cbs->x.init.argpword = cbs->x.init.argpword64; + cbs->x.init.argpaddress = cbs->x.init.argpaddress64; +#else + cbs->x.init.argpword = cbs->x.init.argpword32; + cbs->x.init.argpaddress = cbs->x.init.argpaddress32; +#endif + return SIMUL_Init(processor, cbs); +} + + +/************************************************************************** + + Generic configuration functions + +**************************************************************************/ + +void SIMULAPI SIMUL_Printf(simulProcessor processor, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + (*((simulProcInfo *) processor)->printf) (processor, format, ap); + va_end(ap); +} + + +void SIMULAPI SIMUL_Warning(simulProcessor processor, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + (*((simulProcInfo *) processor)->warning) (processor, format, ap); + va_end(ap); +} + + +void SIMULAPI SIMUL_Stop(simulProcessor processor) +{ + (*((simulProcInfo *) processor)->stop) (processor); +} + + +void SIMULAPI SIMUL_Update(simulProcessor processor, int flags) +{ + (*((simulProcInfo *) processor)->update) (processor, flags); +} + + +void * SIMULAPI SIMUL_Alloc(simulProcessor processor, int size) +{ + return (*((simulProcInfo *) processor)->alloc)(processor, size); +} + + +void SIMULAPI SIMUL_Free(simulProcessor processor, void * ptr) +{ + (*((simulProcInfo *) processor)->free)(processor, ptr); +} + + +int SIMULAPI SIMUL_GetEndianess(simulProcessor processor) +{ + return ((simulProcInfo *) processor)->endianess; +} + + +void * SIMULAPI SIMUL_RegisterCommandCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private) +{ + return (*((simulProcInfo *) processor)->registerCommandCallback) (processor, func, private, SIMUL_ARCHITECTURE_WIDTH); +} + + +void * SIMULAPI SIMUL_RegisterResetCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private) +{ + return (*((simulProcInfo *) processor)->registerResetCallback)(processor, func, private); +} + + +void * SIMULAPI SIMUL_RegisterExitCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private) +{ + return (*((simulProcInfo *) processor)->registerExitCallback)(processor, func, private); +} + + +void * SIMULAPI SIMUL_RegisterGoCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private) +{ + return (*((simulProcInfo *) processor)->registerGoCallback)(processor, func, private); +} + + +void * SIMULAPI SIMUL_RegisterBreakCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private) +{ + return (*((simulProcInfo *) processor)->registerBreakCallback)(processor, func, private); +} + + +/************************************************************************** + + Clocks and Timers + +**************************************************************************/ + +void SIMULAPI SIMUL_GetClockFrequency(simulProcessor processor, int id, simulWord64 * pfrequency) +{ + (*((simulProcInfo *) processor)->getClockFrequency)(processor, id, pfrequency); +} + + +void SIMULAPI SIMUL_SetClockFrequency(simulProcessor processor, int id, simulWord64 * pfrequency) +{ + (*((simulProcInfo *) processor)->setClockFrequency)(processor, id, pfrequency); +} + + +void SIMULAPI SIMUL_GetClockCycle(simulProcessor processor, int id, simulTime * ptime) +{ + (*((simulProcInfo *) processor)->getClockCycle)(processor, id, ptime); +} + + +void SIMULAPI SIMUL_SetClockCycle(simulProcessor processor, int id, simulTime * ptime) +{ + (*((simulProcInfo *) processor)->setClockCycle)(processor, id, ptime); +} + + +void SIMULAPI SIMUL_GetTime(simulProcessor processor, simulTime * ptime) +{ + (*((simulProcInfo *) processor)->getTime)(processor, ptime); +} + + +void SIMULAPI SIMUL_GetClock(simulProcessor processor, int timerid, simulTime * ptime) +{ + (*((simulProcInfo *) processor)->getClock) (processor, timerid, ptime); +} + + +void SIMULAPI SIMUL_Stall(simulProcessor processor, int mode, simulTime * ptime) +{ + (*((simulProcInfo *) processor)->stall) (processor, mode, ptime); +} + + +void SIMULAPI SIMUL_StartTimer(simulProcessor processor, void * timerid, int mode, simulTime * ptime) +{ + (*((simulProcInfo *) processor)->startTimer)(processor, timerid, mode, ptime); +} + + +void SIMULAPI SIMUL_StopTimer(simulProcessor processor, void * timerid) +{ + (*((simulProcInfo *) processor)->stopTimer)(processor, timerid); +} + + +void SIMULAPI SIMUL_StopAllTimer(simulProcessor processor) +{ + (*((simulProcInfo *) processor)->stopTimer) (processor); +} + + +void * SIMULAPI SIMUL_RegisterTimerCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private) +{ + return (*((simulProcInfo *) processor)->registerTimerCallback)(processor, func, private); +} + + + +/************************************************************************** + + Buses and Memories + +**************************************************************************/ + +int SIMULAPI SIMUL_ReadMemory(simulProcessor processor, int bustype, simulWord * paddress, int width, int cycletype, simulWord * pdata) +{ +#if SIMUL_ARCHITECTURE_WIDTH == 8 + return (*((simulProcInfo *) processor)->readMemory64) (processor, bustype, paddress, width, cycletype, pdata); +#else + return (*((simulProcInfo *) processor)->readMemory32) (processor, bustype, paddress, width, cycletype, pdata); +#endif +} + + +int SIMULAPI SIMUL_WriteMemory(simulProcessor processor, int bustype, simulWord * paddress, int width, int cycletype, simulWord * pdata) +{ +#if SIMUL_ARCHITECTURE_WIDTH == 8 + return (*((simulProcInfo *) processor)->writeMemory64) (processor, bustype, paddress, width, cycletype, pdata); +#else + return (*((simulProcInfo *) processor)->writeMemory32) (processor, bustype, paddress, width, cycletype, pdata); +#endif +} + + +void * SIMULAPI SIMUL_RegisterBusWriteCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private, int bustype, simulWord * paddressFrom, simulWord * paddressTo) +{ + return (*((simulProcInfo *) processor)->registerBusWriteCallback)(processor, func, private, bustype, paddressFrom, paddressTo, SIMUL_ARCHITECTURE_WIDTH); +} + + +void * SIMULAPI SIMUL_RegisterBusReadCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private, int bustype, simulWord * paddressFrom, simulWord * paddressTo) +{ + return (*((simulProcInfo *) processor)->registerBusReadCallback)(processor, func, private, bustype, paddressFrom, paddressTo, SIMUL_ARCHITECTURE_WIDTH); +} + + +void SIMULAPI SIMUL_RelocateBusCallback(simulProcessor processor, void * callbackid, int bustype, simulWord * paddressFrom, simulWord * paddressTo) +{ + (*((simulProcInfo *) processor)->relocateBusCallback)(processor, callbackid, bustype, paddressFrom, paddressTo, SIMUL_ARCHITECTURE_WIDTH); +} + + +void SIMULAPI SIMUL_InsertWord(simulProcessor processor, simulWord * ptarget , int wordwidth, simulWord * paddress, int width, simulWord * pdata) +{ + int offset; + + if (width >= wordwidth) { + *ptarget = *pdata; + } else if (width == 8) { + if (((simulProcInfo *) processor)->endianess) { + offset = wordwidth - 8 - ((*paddress << 3) & (wordwidth - 1)); + } else { + offset = (*paddress << 3) & (wordwidth - 1); + } + *ptarget = (*ptarget & ~(0xff << offset)) | ((*pdata & 0xff) << offset); + } else if (width == 16) { + if (((simulProcInfo *) processor)->endianess) { + offset = wordwidth - 16 - ((*paddress << 3) & (wordwidth - 1)); + } else { + offset = (*paddress << 3) & (wordwidth - 1); + } + *ptarget = (*ptarget & ~(0xffff << offset)) | ((*pdata & 0xffff) << offset); +#if SIMUL_ARCHITECTURE_WIDTH == 8 + } else if (width == 32) { + if (((simulProcInfo *) processor)->endianess) { + offset = wordwidth - 32 - ((*paddress << 3) & (wordwidth - 1)); + } else { + offset = (*paddress << 3) & (wordwidth - 1); + } + *ptarget = (*ptarget & ~(0xffffffff << offset)) | ((*pdata & 0xffffffff) << offset); +#endif + } +} + + + +void SIMULAPI SIMUL_ExtractWord(simulProcessor processor, simulWord * psource, int wordwidth, simulWord * paddress, int width, simulWord * pdata) +{ + int offset; + + if (width >= wordwidth) { + *pdata = *psource; + } else if (width == 8) { + if (((simulProcInfo *) processor)->endianess) { + offset = wordwidth - 8 - ((*paddress << 3) & (wordwidth - 1)); + } else { + offset = (*paddress << 3) & (wordwidth - 1); + } + *pdata = (*psource >> offset) & 0xff; + } else if (width == 16) { + if (((simulProcInfo *) processor)->endianess) { + offset = wordwidth - 16 - ((*paddress << 3) & (wordwidth - 1)); + } else { + offset = (*paddress << 3) & (wordwidth - 1); + } + *pdata = (*psource >> offset) & 0xffff; +#if SIMUL_ARCHITECTURE_WIDTH == 8 + } else if (width == 32) { + if (((simulProcInfo *) processor)->endianess) { + offset = wordwidth - 32 - ((*paddress << 3) & (wordwidth - 1)); + } else { + offset = (*paddress << 3) & (wordwidth - 1); + } + *pdata = (*psource >> offset) & 0xffffffff; +#endif + } +} + + +void SIMULAPI SIMUL_SaveWord(simulProcessor processor, void * ptarget, int width, simulWord * pdata) +{ + if (((simulProcInfo *) processor)->endianess) { + switch (width>>3) { +#if SIMUL_ARCHITECTURE_WIDTH == 8 + case 8: + ((unsigned char *) ptarget)[0] = *pdata >> 56; + ((unsigned char *) ptarget)[1] = *pdata >> 48; + ((unsigned char *) ptarget)[2] = *pdata >> 40; + ((unsigned char *) ptarget)[3] = *pdata >> 32; + ((unsigned char *) ptarget)[4] = *pdata >> 24; + ((unsigned char *) ptarget)[5] = *pdata >> 16; + ((unsigned char *) ptarget)[6] = *pdata >> 8; + ((unsigned char *) ptarget)[7] = *pdata; + break; +#endif + case 4: + ((unsigned char *) ptarget)[0] = *pdata >> 24; + ((unsigned char *) ptarget)[1] = *pdata >> 16; + ((unsigned char *) ptarget)[2] = *pdata >> 8; + ((unsigned char *) ptarget)[3] = *pdata; + break; + case 2: + ((unsigned char *) ptarget)[0] = *pdata >> 8; + ((unsigned char *) ptarget)[1] = *pdata; + break; + default: + ((unsigned char *) ptarget)[0] = *pdata; + break; + } + } else { + switch (width>>3) { +#if SIMUL_ARCHITECTURE_WIDTH == 8 + case 8: + ((unsigned char *) ptarget)[7] = *pdata >> 56; + ((unsigned char *) ptarget)[6] = *pdata >> 48; + ((unsigned char *) ptarget)[5] = *pdata >> 40; + ((unsigned char *) ptarget)[4] = *pdata >> 32; +#endif + case 4: + ((unsigned char *) ptarget)[3] = *pdata >> 24; + ((unsigned char *) ptarget)[2] = *pdata >> 16; + case 2: + ((unsigned char *) ptarget)[1] = *pdata >> 8; + default: + ((unsigned char *) ptarget)[0] = *pdata; + } + } +} + + +void SIMULAPI SIMUL_LoadWord(simulProcessor processor, void * psource, int width, simulWord * pdata) +{ + if (((simulProcInfo *) processor)->endianess) { + switch (width>>3) { +#if SIMUL_ARCHITECTURE_WIDTH == 8 + case 8: + { + simulWord low, high; + low = (((unsigned char *) psource)[7]) | (((unsigned char *) psource)[6] << 8) + | (((unsigned char *) psource)[5] << 16) | (((unsigned char *) psource)[4] << 24); + high = (((unsigned char *) psource)[3]) | (((unsigned char *) psource)[2] << 8) + | (((unsigned char *) psource)[1] << 16) | (((unsigned char *) psource)[0] << 24); + *pdata = low | (high << 32); + } + break; +#endif + case 4: + *pdata = (((unsigned char *) psource)[3]) | (((unsigned char *) psource)[2] << 8) + | (((unsigned char *) psource)[1] << 16) | (((unsigned char *) psource)[0] << 24); + break; + case 2: + *pdata = (((unsigned char *) psource)[1]) | (((unsigned char *) psource)[0] << 8); + break; + default: + *pdata = ((unsigned char *) psource)[0]; + } + } else { + switch (width>>3) { +#if SIMUL_ARCHITECTURE_WIDTH == 8 + case 8: + { + simulWord low, high; + low = (((unsigned char *) psource)[0]) | (((unsigned char *) psource)[1] << 8) + | (((unsigned char *) psource)[2] << 16) | (((unsigned char *) psource)[3] << 24); + high = (((unsigned char *) psource)[4]) | (((unsigned char *) psource)[5] << 8) + | (((unsigned char *) psource)[6] << 16) | (((unsigned char *) psource)[7] << 24); + *pdata = low | (high << 32); + } + break; +#endif + case 4: + *pdata = (((unsigned char *) psource)[0]) | (((unsigned char *) psource)[1] << 8) + | (((unsigned char *) psource)[2] << 16) | (((unsigned char *) psource)[3] << 24); + break; + case 2: + *pdata = (((unsigned char *) psource)[0]) | (((unsigned char *) psource)[1] << 8); + break; + default: + *pdata = ((unsigned char *) psource)[0]; + } + } +} + + + +/************************************************************************** + + Ports + +**************************************************************************/ + +int SIMULAPI SIMUL_GetPort(simulProcessor processor, int offset, int width, simulWord * pdata) +{ +#if SIMUL_ARCHITECTURE_WIDTH == 8 + return (*((simulProcInfo *) processor)->getPort64) (processor, offset, width, pdata); +#else + return (*((simulProcInfo *) processor)->getPort32) (processor, offset, width, pdata); +#endif +} + + +int SIMULAPI SIMUL_SetPort(simulProcessor processor, int offset, int width, simulWord * pdata) +{ +#if SIMUL_ARCHITECTURE_WIDTH == 8 + return (*((simulProcInfo *) processor)->setPort64) (processor, offset, width, pdata); +#else + return (*((simulProcInfo *) processor)->setPort32) (processor, offset, width, pdata); +#endif +} + + +void * SIMULAPI SIMUL_RegisterPortChangeCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private, int offset, int width) +{ + return (*((simulProcInfo *) processor)->registerPortChangeCallback)(processor, func, private, offset, width, SIMUL_ARCHITECTURE_WIDTH); +} + + + +/************************************************************************** + + Shared Resources + +**************************************************************************/ + +int SIMULAPI SIMUL_CreateSharedResource(simulProcessor processor, int size) +{ + return (*((simulProcInfo *) processor)->createSharedResource) (processor, size); +} + + +int SIMULAPI SIMUL_ReadSharedResource(simulProcessor processor, int offset, int len, void * pdata) +{ + return (*((simulProcInfo *) processor)->readSharedResource) (processor, offset, len, pdata); +} + + +int SIMULAPI SIMUL_WriteSharedResource(simulProcessor processor, int offset, int len, void * pdata) +{ + return (*((simulProcInfo *) processor)->writeSharedResource) (processor, offset, len, pdata); +} + + + +/************************************************************************** + + File I/O + +**************************************************************************/ + +void * SIMULAPI SIMUL_OpenFile(simulProcessor processor, const char * filename, int mode) +{ + return (*((simulProcInfo *) processor)->openFile) (processor, filename, mode); +} + + +void SIMULAPI SIMUL_CloseFile(simulProcessor processor, void * file) +{ + (*((simulProcInfo *) processor)->closeFile) (processor, file); +} + + +int SIMULAPI SIMUL_ReadFile(simulProcessor processor, void * file, void * pdata, int length) +{ + return (*((simulProcInfo *) processor)->readFile) (processor, file, pdata, length); +} + +int SIMULAPI SIMUL_WriteFile(simulProcessor processor, void * file, void * pdata, int length) +{ + return (*((simulProcInfo *) processor)->writeFile) (processor, file, pdata, length); +} + + +int SIMULAPI SIMUL_ReadlineFile(simulProcessor processor, void * file, void * pdata, int length) +{ + return (*((simulProcInfo *) processor)->readlineFile) (processor, file, pdata, length); +} + +int SIMULAPI SIMUL_WritelineFile(simulProcessor processor, void * file, void * pdata) +{ + return (*((simulProcInfo *) processor)->writelineFile) (processor, file, pdata); +} + + +long SIMULAPI SIMUL_SeekFile(simulProcessor processor, void * file, long pos, int mode) +{ + return (*((simulProcInfo *) processor)->seekFile) (processor, file, pos, mode); +} + + + +/************************************************************************** + + Terminal I/O + +**************************************************************************/ + +int SIMULAPI SIMUL_StateTerminal(simulProcessor processor, int id) +{ + return (*((simulProcInfo *) processor)->stateTerminal) (processor, id); +} + +int SIMULAPI SIMUL_ReadTerminal(simulProcessor processor, int id) +{ + return (*((simulProcInfo *) processor)->readTerminal) (processor, id); +} + +int SIMULAPI SIMUL_WriteTerminal(simulProcessor processor, int id, int ch) +{ + return (*((simulProcInfo *) processor)->writeTerminal) (processor, id, ch); +} + +void * SIMUL_RegisterTerminalCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private, int id) +{ + return (*((simulProcInfo *) processor)->registerTerminalCallback) (processor, func, private, id, SIMUL_ARCHITECTURE_WIDTH); +} + + diff --git a/debuggers/t32/sim/demo/demoport/simul.h b/debuggers/t32/sim/demo/demoport/simul.h new file mode 100644 index 00000000..85c1fbe8 --- /dev/null +++ b/debuggers/t32/sim/demo/demoport/simul.h @@ -0,0 +1,551 @@ + +/************************************************************************** + + Basic types and includes + +**************************************************************************/ + +#ifdef WIN32 + +#ifndef _WINDOWS_ +#include +#endif + +typedef __int64 simulTime; +typedef unsigned __int64 simulWord64; + +#define SIMULAPI __cdecl + +#else + +#include "stdarg.h" + +#ifdef NSC32000 +typedef QUAD simulTime; +typedef QUAD simulWord64; +#else +typedef long long simulTime; +typedef unsigned long long simulWord64; +#endif + +#define SIMULAPI + +#endif + + +typedef unsigned int simulWord32; + +#define SIMUL_VERSION 1 + +#ifdef SIMUL_ARCHITECTURE_64BIT +#define SIMUL_ARCHITECTURE_WIDTH 8 +typedef simulWord64 simulWord; +#else +#define SIMUL_ARCHITECTURE_WIDTH 4 +typedef simulWord32 simulWord; +#endif + +typedef void * simulProcessor; +typedef void * simulPtr; + + +/************************************************************************** + + Internal callback structure (DO NOT ACCESS THIS STRUCTURE) + +**************************************************************************/ + +typedef struct +{ + int endianess; + int addresswidth; + int datawidth; + int processortype; + int id; + int resvd1; + int resvd2; + int resvd3; + + void (SIMULAPI *printf)(); + void (SIMULAPI *warning)(); + void (SIMULAPI *stop)(); + void (SIMULAPI *update)(); + void * (SIMULAPI *alloc)(); + void (SIMULAPI *free)(); + void * (SIMULAPI *registerCommandCallback)(); + void * (SIMULAPI *registerResetCallback)(); + void * (SIMULAPI *registerExitCallback)(); + + void (SIMULAPI *getClockFrequency)(); + void (SIMULAPI *setClockFrequency)(); + void (SIMULAPI *getClockCycle)(); + void (SIMULAPI *setClockCycle)(); + void (SIMULAPI *getTime)(); + void (SIMULAPI *getClock)(); + void (SIMULAPI *stall)(); + void (SIMULAPI *startTimer)(); + void (SIMULAPI *stopTimer)(); + void (SIMULAPI *stopAllTimer)(); + void * (SIMULAPI *registerTimerCallback)(); + + int (SIMULAPI *readMemory32)(); + int (SIMULAPI *readMemory64)(); + int (SIMULAPI *writeMemory32)(); + int (SIMULAPI *writeMemory64)(); + void * (SIMULAPI *registerBusReadCallback)(); + void * (SIMULAPI *registerBusWriteCallback)(); + void (SIMULAPI *relocateBusCallback)(); + + int (SIMULAPI *getPort32)(); + int (SIMULAPI *getPort64)(); + int (SIMULAPI *setPort32)(); + int (SIMULAPI *setPort64)(); + void * (SIMULAPI *registerPortChangeCallback)(); + + int (SIMULAPI *createSharedResource)(); + int (SIMULAPI *readSharedResource)(); + int (SIMULAPI *writeSharedResource)(); + + void * (SIMULAPI *openFile)(); + void (SIMULAPI *closeFile)(); + int (SIMULAPI *readFile)(); + int (SIMULAPI *writeFile)(); + int (SIMULAPI *readlineFile)(); + int (SIMULAPI *writelineFile)(); + long (SIMULAPI *seekFile)(); + + int (SIMULAPI *readTerminal)(); + int (SIMULAPI *writeTerminal)(); + int (SIMULAPI *stateTerminal)(); + void * (SIMULAPI *registerTerminalCallback)(); + + void * (SIMULAPI *registerGoCallback)(); + void * (SIMULAPI *registerBreakCallback)(); +} +simulProcInfo; + + +/************************************************************************** + + Callback structure + +**************************************************************************/ + +#define SIMUL_CALLBACK_INIT 0x0000 +#define SIMUL_CALLBACK_BUSREAD 0x0001 +#define SIMUL_CALLBACK_BUSWRITE 0x0002 +#define SIMUL_CALLBACK_PORTCHANGE 0x0004 +#define SIMUL_CALLBACK_TIMER 0x0010 +#define SIMUL_CALLBACK_EXIT 0x0020 +#define SIMUL_CALLBACK_RESET 0x0040 +#define SIMUL_CALLBACK_TERMINAL 0x0080 +#define SIMUL_CALLBACK_COMMAND 0x0100 +#define SIMUL_CALLBACK_GO 0x0200 +#define SIMUL_CALLBACK_BREAK 0x0400 + +typedef struct +{ + int version; + char * modelname; + char * commandline; + int argc; + char ** argp; + int * argpint; + simulWord * argpword; + simulWord32 * argpword32; + simulWord64 * argpword64; + int * argpport; + int * argpbustype; + simulWord * argpaddress; + simulWord32 * argpaddress32; + simulWord64 * argpaddress64; + simulTime * argptime; +} +simulParamCallbackStruct; + +typedef struct +{ + simulWord address; + simulWord data; + int width; + int cycletype; + int clocks; +} +simulBusCallbackStruct; + +typedef struct +{ + simulWord32 address; + simulWord32 data; + int width; + int cycletype; + int clocks; +} +simulBusCallbackStruct32; + +typedef struct +{ + simulWord64 address; + simulWord64 data; + int width; + int cycletype; + int clocks; +} +simulBusCallbackStruct64; + +typedef struct +{ + simulWord newdata; + simulWord olddata; +} +simulPortCallbackStruct; + +typedef struct +{ + simulWord32 newdata; + simulWord32 olddata; +} +simulPortCallbackStruct32; + +typedef struct +{ + simulWord64 newdata; + simulWord64 olddata; +} +simulPortCallbackStruct64; + +typedef struct +{ + int data; +} +simulTerminalCallbackStruct; + +typedef struct +{ + int type; + simulTime time; + union { + simulParamCallbackStruct init; + simulParamCallbackStruct command; + simulBusCallbackStruct bus; + simulBusCallbackStruct32 bus32; + simulBusCallbackStruct64 bus64; + simulPortCallbackStruct port; + simulPortCallbackStruct32 port32; + simulPortCallbackStruct64 port64; + simulTerminalCallbackStruct terminal; + } x; +} +simulCallbackStruct; + + +typedef int (SIMULAPI * simulCallbackFunctionPtr)(simulProcessor processor, simulCallbackStruct *, simulPtr private); + +#ifdef __cplusplus +extern "C" { +#endif + + +/************************************************************************** + + Model entry definition + +**************************************************************************/ + +#define SIMUL_INIT_OK 1 +#define SIMUL_INIT_FAIL -1 + +extern int SIMULAPI SIMUL_Init(simulProcessor processor, simulCallbackStruct * cbs); + + + +/************************************************************************** + + Generic configuration functions + +**************************************************************************/ + +extern void SIMULAPI SIMUL_Printf(simulProcessor processor, const char *format, ...); + +extern void SIMULAPI SIMUL_Warning(simulProcessor processor, const char *format, ...); + +extern void SIMULAPI SIMUL_Stop(simulProcessor processor); + +extern void SIMULAPI SIMUL_Update(simulProcessor processor, int flags); + +extern void * SIMULAPI SIMUL_Alloc(simulProcessor processor, int size); + +extern void SIMULAPI SIMUL_Free(simulProcessor processor, void * ptr); + + +#define SIMUL_ENDIANESS_LITTLE 0 +#define SIMUL_ENDIANESS_BIG 1 + +extern int SIMULAPI SIMUL_GetEndianess(simulProcessor processor); + + +#define SIMUL_COMMAND_OK 1 +#define SIMUL_COMMAND_FAIL -1 + +extern void * SIMULAPI SIMUL_RegisterCommandCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private); + + +#define SIMUL_RESET_OK 1 + +extern void * SIMULAPI SIMUL_RegisterResetCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private); + + +#define SIMUL_EXIT_OK 1 + +extern void * SIMULAPI SIMUL_RegisterExitCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private); + + +#define SIMUL_GO_OK 1 + +extern void * SIMULAPI SIMUL_RegisterGoCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private); + + +#define SIMUL_BREAK_OK 1 + +extern void * SIMULAPI SIMUL_RegisterBreakCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private); + + + +/************************************************************************** + + Clocks and Timers + +**************************************************************************/ + +#define SIMUL_TIMER_OK 1 + + +#define SIMUL_CLOCK_CORE 0 +#define SIMUL_CLOCK_BUS 1 +#define SIMUL_CLOCK_POWERPC_TIMEBASE 2 + + +extern void SIMULAPI SIMUL_GetClockFrequency(simulProcessor processor, int clockid, simulWord64 * pfrequency); + +extern void SIMULAPI SIMUL_SetClockFrequency(simulProcessor processor, int clockid, simulWord64 * pfrequency); + +extern void SIMULAPI SIMUL_GetClockCycle(simulProcessor processor, int clockid, simulTime * ptime); + +extern void SIMULAPI SIMUL_SetClockCycle(simulProcessor processor, int clockid, simulTime * ptime); + +extern void SIMULAPI SIMUL_GetTime(simulProcessor processor, simulTime * ptime); + +extern void SIMULAPI SIMUL_GetClock(simulProcessor processor, int clockid, simulTime * ptime); + +#define SIMUL_STALL_ABS 0x000 +#define SIMUL_STALL_REL 0x100 +#define SIMUL_STALL_CLOCKS 0x400 + +extern void SIMULAPI SIMUL_Stall(simulProcessor processor, int mode, simulTime * ptime); + + +/* timer modes */ + +#define SIMUL_TIMER_ABS 0x000 +#define SIMUL_TIMER_REL 0x100 +#define SIMUL_TIMER_SINGLE 0x000 +#define SIMUL_TIMER_REPEAT 0x200 +#define SIMUL_TIMER_CLOCKS 0x400 + + +extern void SIMULAPI SIMUL_StartTimer(simulProcessor processor, void * timerid, int mode, simulTime * ptime); + +extern void SIMULAPI SIMUL_StopTimer(simulProcessor processor, void * timerid); + +extern void SIMULAPI SIMUL_StopAllTimer(simulProcessor processor); + +extern void * SIMULAPI SIMUL_RegisterTimerCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private); + + + +/************************************************************************** + + Buses and Memories + +**************************************************************************/ + +/* return values for bus callback functions */ + +#define SIMUL_MEMORY_CONTINUE 0 +#define SIMUL_MEMORY_OK 1 +#define SIMUL_MEMORY_FAIL -1 + +/* cycle types */ + +#define SIMUL_MEMORY_HIDDEN 0x00 +#define SIMUL_MEMORY_FETCH 0x02 +#define SIMUL_MEMORY_DATA 0x04 +#define SIMUL_MEMORY_DMA 0x08 + + +#define SIMUL_MEMORY_DEFAULT 0 + +#define SIMUL_MEMORY_POWERPC_SPR 1 +#define SIMUL_MEMORY_POWERPC_DCR 2 + +#define SIMUL_MEMORY_ARM_CPX 1 + +#define SIMUL_MEMORY_SH_INTACK 255 +#define SIMUL_MEMORY_M68K_INTACK 255 + + +extern int SIMULAPI SIMUL_ReadMemory(simulProcessor processor, int bustype, simulWord * paddress, int width, int cycletype, simulWord * pdata); + +extern int SIMULAPI SIMUL_WriteMemory(simulProcessor processor, int bustype, simulWord * paddress, int width, int cycletype, simulWord * pdata); + + +extern void * SIMULAPI SIMUL_RegisterBusReadCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private, int bustype, simulWord * paddressFrom, simulWord * paddressTo); + +extern void * SIMULAPI SIMUL_RegisterBusWriteCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private, int bustype, simulWord * paddressFrom, simulWord * paddressTo); + +extern void SIMULAPI SIMUL_RelocateBusCallback(simulProcessor processor, void * callbackid, int bustype, simulWord * paddressFrom, simulWord * paddressTo); + + +extern void SIMULAPI SIMUL_InsertWord(simulProcessor processor, simulWord * ptarget, int wordwidth, simulWord * paddress, int width, simulWord * pdata); + +extern void SIMULAPI SIMUL_ExtractWord(simulProcessor processor, simulWord * psource, int wordwidth, simulWord * paddress, int width, simulWord * pdata); + + +extern void SIMULAPI SIMUL_SaveWord(simulProcessor processor, void * ptarget, int width, simulWord * pdata); + +extern void SIMULAPI SIMUL_LoadWord(simulProcessor processor, void * psource, int width, simulWord * pdata); + + + +/************************************************************************** + + Ports + +**************************************************************************/ + +/* predefined core ports */ + +#define SIMUL_PORT_RESET -1 +#define SIMUL_PORT_INTERRUPT -2 + +#define SIMUL_PORT_PPC_INT -2 + +#define SIMUL_PORT_ARM_IRQ -2 +#define SIMUL_PORT_ARM_FIQ -3 + +#define SIMUL_PORT_SH_IRL0 -2 +#define SIMUL_PORT_SH_IRL1 -3 +#define SIMUL_PORT_SH_IRL2 -4 +#define SIMUL_PORT_SH_IRL3 -5 + +#define SIMUL_PORT_MIPS_NMI -2 +#define SIMUL_PORT_MIPS_INT0 -3 +#define SIMUL_PORT_MIPS_INT1 -4 +#define SIMUL_PORT_MIPS_INT2 -5 +#define SIMUL_PORT_MIPS_INT3 -6 +#define SIMUL_PORT_MIPS_INT4 -7 +#define SIMUL_PORT_MIPS_INT5 -8 + +#define SIMUL_PORT_M68K_IRL0 -2 +#define SIMUL_PORT_M68K_IRL1 -3 +#define SIMUL_PORT_M68K_IRL2 -4 + +#define SIMUL_PORT_C166_IRL0 -2 +#define SIMUL_PORT_C166_IRL1 -3 +#define SIMUL_PORT_C166_IRL2 -4 +#define SIMUL_PORT_C166_IRL3 -5 +#define SIMUL_PORT_C166_NMI -6 + +/* return values for port callback functions */ + +#define SIMUL_PORT_OK 1 + + +extern int SIMULAPI SIMUL_GetPort(simulProcessor processor, int offset, int width, simulWord * pdata); + +extern int SIMULAPI SIMUL_SetPort(simulProcessor processor, int offset, int width, simulWord * pdata); + +extern void * SIMULAPI SIMUL_RegisterPortChangeCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private, int offset, int width); + + + +/************************************************************************** + + Shared Resources + +**************************************************************************/ + +extern int SIMULAPI SIMUL_CreateSharedResource(simulProcessor processor, int size); + +extern int SIMULAPI SIMUL_ReadSharedResource(simulProcessor processor, int offset, int len, void * pdata); + +extern int SIMULAPI SIMUL_WriteSharedResource(simulProcessor processor, int offset, int len, void * pdata); + + + +/************************************************************************** + + File I/O + +**************************************************************************/ + +/* file modes */ + +#define SIMUL_FILE_READ 0x001 +#define SIMUL_FILE_WRITE 0x002 +#define SIMUL_FILE_CREATE 0x010 +#define SIMUL_FILE_APPEND 0x020 +#define SIMUL_FILE_BINARY 0x000 +#define SIMUL_FILE_ASCII 0x100 + +extern void * SIMULAPI SIMUL_OpenFile(simulProcessor processor, const char * filename, int mode); + +extern void SIMULAPI SIMUL_CloseFile(simulProcessor processor, void * file); + +extern int SIMULAPI SIMUL_ReadFile(simulProcessor processor, void * file, void * pdata, int length); + +extern int SIMULAPI SIMUL_WriteFile(simulProcessor processor, void * file, void * pdata, int length); + +extern int SIMULAPI SIMUL_ReadlineFile(simulProcessor processor, void * file, void * pdata, int length); + +extern int SIMULAPI SIMUL_WritelineFile(simulProcessor processor, void * file, void * pdata); + +#define SIMUL_FILE_SEEKABS 0 +#define SIMUL_FILE_SEEKREL 1 +#define SIMUL_FILE_SEEKEND 2 + +extern long SIMULAPI SIMUL_SeekFile(simulProcessor processor, void * file, long pos, int mode); + + + + +/************************************************************************** + + Terminal I/O + +**************************************************************************/ + +/* status bits */ + +#define SIMUL_STATE_RXREADY 0x001 +#define SIMUL_STATE_TXREADY 0x002 +#define SIMUL_STATE_NOTEXISTING 0x010 + +extern int SIMULAPI SIMUL_ReadTerminal(simulProcessor processor, int id); + +extern int SIMULAPI SIMUL_WriteTerminal(simulProcessor processor, int id, int ch); + +extern int SIMULAPI SIMUL_StateTerminal(simulProcessor processor, int id); + +extern void * SIMUL_RegisterTerminalCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private, int id); + + +/************************************************************************** + + End of Include + +**************************************************************************/ + +#ifdef __cplusplus +} +#endif diff --git a/debuggers/t32/sim/demo/demoport/t32.cmm b/debuggers/t32/sim/demo/demoport/t32.cmm new file mode 100644 index 00000000..b7eed4a8 --- /dev/null +++ b/debuggers/t32/sim/demo/demoport/t32.cmm @@ -0,0 +1,27 @@ +;Add some extra buttons to the toolbar + + menu.rp + ( + add + toolbar + ( + separator + toolitem "Source/List" ":list" "Data.List" + toolitem "Memory Dump" ":dump" "Data.dump" + toolitem "Register" ":reg" "Register /SpotLight" + separator + toolitem "Watch" ":var" "Var.Watch" + toolitem "Stack" ":varframe" "Var.Frame /l /c" + toolitem "Automatic Watch" ":varref" "Var.Ref" + separator + toolitem "List Breakpoints" ":break" "Break.List" + toolitem "List Symbols" ":symbols" "sYmbol.Browse" + toolitem "List Tracebuffer" ":alist" "Analyzer.List" + separator + ) + ) + + do demoport + + enddo + diff --git a/debuggers/t32/sim/demo/demoport/trans.tbl b/debuggers/t32/sim/demo/demoport/trans.tbl new file mode 100644 index 00000000..5893a12a --- /dev/null +++ b/debuggers/t32/sim/demo/demoport/trans.tbl @@ -0,0 +1,12 @@ +F DEMOPORT.C demoport.c +F DEMOPORT.CMM demoport.cmm +F DEMOPORT.DEF demoport.def +F DEMOPORT.DLL demoport.dll +F DEMOPORT.PER demoport.per +F MAKEFILE. makefile +F MAKEHP. makehp +F MAKELINUX. makelinux +F MAKESUN. makesun +F SIMUL.C simul.c +F SIMUL.H simul.h +F T32.CMM t32.cmm diff --git a/debuggers/t32/sim/include/simul.c b/debuggers/t32/sim/include/simul.c new file mode 100644 index 00000000..58957c81 --- /dev/null +++ b/debuggers/t32/sim/include/simul.c @@ -0,0 +1,532 @@ + +#include "simul.h" + + +/************************************************************************** + + Model entry + +**************************************************************************/ + +int SIMULAPI SIMUL_Interface(simulProcessor processor, simulCallbackStruct * cbs) +{ + cbs->x.init.version = SIMUL_VERSION; +#if SIMUL_ARCHITECTURE_WIDTH == 8 + cbs->x.init.argpword = cbs->x.init.argpword64; + cbs->x.init.argpaddress = cbs->x.init.argpaddress64; +#else + cbs->x.init.argpword = cbs->x.init.argpword32; + cbs->x.init.argpaddress = cbs->x.init.argpaddress32; +#endif + return SIMUL_Init(processor, cbs); +} + + +/************************************************************************** + + Generic configuration functions + +**************************************************************************/ + +void SIMULAPI SIMUL_Printf(simulProcessor processor, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + (*((simulProcInfo *) processor)->printf) (processor, format, ap); + va_end(ap); +} + + +void SIMULAPI SIMUL_Warning(simulProcessor processor, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + (*((simulProcInfo *) processor)->warning) (processor, format, ap); + va_end(ap); +} + + +void SIMULAPI SIMUL_Stop(simulProcessor processor) +{ + (*((simulProcInfo *) processor)->stop) (processor); +} + + +void SIMULAPI SIMUL_Update(simulProcessor processor, int flags) +{ + (*((simulProcInfo *) processor)->update) (processor, flags); +} + + +void * SIMULAPI SIMUL_Alloc(simulProcessor processor, int size) +{ + return (*((simulProcInfo *) processor)->alloc)(processor, size); +} + + +void SIMULAPI SIMUL_Free(simulProcessor processor, void * ptr) +{ + (*((simulProcInfo *) processor)->free)(processor, ptr); +} + + +int SIMULAPI SIMUL_GetEndianess(simulProcessor processor) +{ + return ((simulProcInfo *) processor)->endianess; +} + + +void * SIMULAPI SIMUL_RegisterCommandCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private) +{ + return (*((simulProcInfo *) processor)->registerCommandCallback) (processor, func, private, SIMUL_ARCHITECTURE_WIDTH); +} + + +void * SIMULAPI SIMUL_RegisterResetCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private) +{ + return (*((simulProcInfo *) processor)->registerResetCallback)(processor, func, private); +} + + +void * SIMULAPI SIMUL_RegisterExitCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private) +{ + return (*((simulProcInfo *) processor)->registerExitCallback)(processor, func, private); +} + + +void * SIMULAPI SIMUL_RegisterGoCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private) +{ + return (*((simulProcInfo *) processor)->registerGoCallback)(processor, func, private); +} + + +void * SIMULAPI SIMUL_RegisterBreakCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private) +{ + return (*((simulProcInfo *) processor)->registerBreakCallback)(processor, func, private); +} + + +/************************************************************************** + + Clocks and Timers + +**************************************************************************/ + +void SIMULAPI SIMUL_GetClockFrequency(simulProcessor processor, int id, simulWord64 * pfrequency) +{ + (*((simulProcInfo *) processor)->getClockFrequency)(processor, id, pfrequency); +} + + +void SIMULAPI SIMUL_SetClockFrequency(simulProcessor processor, int id, simulWord64 * pfrequency) +{ + (*((simulProcInfo *) processor)->setClockFrequency)(processor, id, pfrequency); +} + + +void SIMULAPI SIMUL_GetClockCycle(simulProcessor processor, int id, simulTime * ptime) +{ + (*((simulProcInfo *) processor)->getClockCycle)(processor, id, ptime); +} + + +void SIMULAPI SIMUL_SetClockCycle(simulProcessor processor, int id, simulTime * ptime) +{ + (*((simulProcInfo *) processor)->setClockCycle)(processor, id, ptime); +} + + +void SIMULAPI SIMUL_GetTime(simulProcessor processor, simulTime * ptime) +{ + (*((simulProcInfo *) processor)->getTime)(processor, ptime); +} + + +void SIMULAPI SIMUL_GetClock(simulProcessor processor, int timerid, simulTime * ptime) +{ + (*((simulProcInfo *) processor)->getClock) (processor, timerid, ptime); +} + + +void SIMULAPI SIMUL_Stall(simulProcessor processor, int mode, simulTime * ptime) +{ + (*((simulProcInfo *) processor)->stall) (processor, mode, ptime); +} + + +void SIMULAPI SIMUL_StartTimer(simulProcessor processor, void * timerid, int mode, simulTime * ptime) +{ + (*((simulProcInfo *) processor)->startTimer)(processor, timerid, mode, ptime); +} + + +void SIMULAPI SIMUL_StopTimer(simulProcessor processor, void * timerid) +{ + (*((simulProcInfo *) processor)->stopTimer)(processor, timerid); +} + + +void SIMULAPI SIMUL_StopAllTimer(simulProcessor processor) +{ + (*((simulProcInfo *) processor)->stopTimer) (processor); +} + + +void * SIMULAPI SIMUL_RegisterTimerCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private) +{ + return (*((simulProcInfo *) processor)->registerTimerCallback)(processor, func, private); +} + + + +/************************************************************************** + + Buses and Memories + +**************************************************************************/ + +int SIMULAPI SIMUL_ReadMemory(simulProcessor processor, int bustype, simulWord * paddress, int width, int cycletype, simulWord * pdata) +{ +#if SIMUL_ARCHITECTURE_WIDTH == 8 + return (*((simulProcInfo *) processor)->readMemory64) (processor, bustype, paddress, width, cycletype, pdata); +#else + return (*((simulProcInfo *) processor)->readMemory32) (processor, bustype, paddress, width, cycletype, pdata); +#endif +} + + +int SIMULAPI SIMUL_WriteMemory(simulProcessor processor, int bustype, simulWord * paddress, int width, int cycletype, simulWord * pdata) +{ +#if SIMUL_ARCHITECTURE_WIDTH == 8 + return (*((simulProcInfo *) processor)->writeMemory64) (processor, bustype, paddress, width, cycletype, pdata); +#else + return (*((simulProcInfo *) processor)->writeMemory32) (processor, bustype, paddress, width, cycletype, pdata); +#endif +} + + +void * SIMULAPI SIMUL_RegisterBusWriteCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private, int bustype, simulWord * paddressFrom, simulWord * paddressTo) +{ + return (*((simulProcInfo *) processor)->registerBusWriteCallback)(processor, func, private, bustype, paddressFrom, paddressTo, SIMUL_ARCHITECTURE_WIDTH); +} + + +void * SIMULAPI SIMUL_RegisterBusReadCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private, int bustype, simulWord * paddressFrom, simulWord * paddressTo) +{ + return (*((simulProcInfo *) processor)->registerBusReadCallback)(processor, func, private, bustype, paddressFrom, paddressTo, SIMUL_ARCHITECTURE_WIDTH); +} + + +void SIMULAPI SIMUL_RelocateBusCallback(simulProcessor processor, void * callbackid, int bustype, simulWord * paddressFrom, simulWord * paddressTo) +{ + (*((simulProcInfo *) processor)->relocateBusCallback)(processor, callbackid, bustype, paddressFrom, paddressTo, SIMUL_ARCHITECTURE_WIDTH); +} + + +void SIMULAPI SIMUL_InsertWord(simulProcessor processor, simulWord * ptarget , int wordwidth, simulWord * paddress, int width, simulWord * pdata) +{ + int offset; + + if (width >= wordwidth) { + *ptarget = *pdata; + } else if (width == 8) { + if (((simulProcInfo *) processor)->endianess) { + offset = wordwidth - 8 - ((*paddress << 3) & (wordwidth - 1)); + } else { + offset = (*paddress << 3) & (wordwidth - 1); + } + *ptarget = (*ptarget & ~(0xff << offset)) | ((*pdata & 0xff) << offset); + } else if (width == 16) { + if (((simulProcInfo *) processor)->endianess) { + offset = wordwidth - 16 - ((*paddress << 3) & (wordwidth - 1)); + } else { + offset = (*paddress << 3) & (wordwidth - 1); + } + *ptarget = (*ptarget & ~(0xffff << offset)) | ((*pdata & 0xffff) << offset); +#if SIMUL_ARCHITECTURE_WIDTH == 8 + } else if (width == 32) { + if (((simulProcInfo *) processor)->endianess) { + offset = wordwidth - 32 - ((*paddress << 3) & (wordwidth - 1)); + } else { + offset = (*paddress << 3) & (wordwidth - 1); + } + *ptarget = (*ptarget & ~(0xffffffff << offset)) | ((*pdata & 0xffffffff) << offset); +#endif + } +} + + + +void SIMULAPI SIMUL_ExtractWord(simulProcessor processor, simulWord * psource, int wordwidth, simulWord * paddress, int width, simulWord * pdata) +{ + int offset; + + if (width >= wordwidth) { + *pdata = *psource; + } else if (width == 8) { + if (((simulProcInfo *) processor)->endianess) { + offset = wordwidth - 8 - ((*paddress << 3) & (wordwidth - 1)); + } else { + offset = (*paddress << 3) & (wordwidth - 1); + } + *pdata = (*psource >> offset) & 0xff; + } else if (width == 16) { + if (((simulProcInfo *) processor)->endianess) { + offset = wordwidth - 16 - ((*paddress << 3) & (wordwidth - 1)); + } else { + offset = (*paddress << 3) & (wordwidth - 1); + } + *pdata = (*psource >> offset) & 0xffff; +#if SIMUL_ARCHITECTURE_WIDTH == 8 + } else if (width == 32) { + if (((simulProcInfo *) processor)->endianess) { + offset = wordwidth - 32 - ((*paddress << 3) & (wordwidth - 1)); + } else { + offset = (*paddress << 3) & (wordwidth - 1); + } + *pdata = (*psource >> offset) & 0xffffffff; +#endif + } +} + + +void SIMULAPI SIMUL_SaveWord(simulProcessor processor, void * ptarget, int width, simulWord * pdata) +{ + if (((simulProcInfo *) processor)->endianess) { + switch (width>>3) { +#if SIMUL_ARCHITECTURE_WIDTH == 8 + case 8: + ((unsigned char *) ptarget)[0] = *pdata >> 56; + ((unsigned char *) ptarget)[1] = *pdata >> 48; + ((unsigned char *) ptarget)[2] = *pdata >> 40; + ((unsigned char *) ptarget)[3] = *pdata >> 32; + ((unsigned char *) ptarget)[4] = *pdata >> 24; + ((unsigned char *) ptarget)[5] = *pdata >> 16; + ((unsigned char *) ptarget)[6] = *pdata >> 8; + ((unsigned char *) ptarget)[7] = *pdata; + break; +#endif + case 4: + ((unsigned char *) ptarget)[0] = *pdata >> 24; + ((unsigned char *) ptarget)[1] = *pdata >> 16; + ((unsigned char *) ptarget)[2] = *pdata >> 8; + ((unsigned char *) ptarget)[3] = *pdata; + break; + case 2: + ((unsigned char *) ptarget)[0] = *pdata >> 8; + ((unsigned char *) ptarget)[1] = *pdata; + break; + default: + ((unsigned char *) ptarget)[0] = *pdata; + break; + } + } else { + switch (width>>3) { +#if SIMUL_ARCHITECTURE_WIDTH == 8 + case 8: + ((unsigned char *) ptarget)[7] = *pdata >> 56; + ((unsigned char *) ptarget)[6] = *pdata >> 48; + ((unsigned char *) ptarget)[5] = *pdata >> 40; + ((unsigned char *) ptarget)[4] = *pdata >> 32; +#endif + case 4: + ((unsigned char *) ptarget)[3] = *pdata >> 24; + ((unsigned char *) ptarget)[2] = *pdata >> 16; + case 2: + ((unsigned char *) ptarget)[1] = *pdata >> 8; + default: + ((unsigned char *) ptarget)[0] = *pdata; + } + } +} + + +void SIMULAPI SIMUL_LoadWord(simulProcessor processor, void * psource, int width, simulWord * pdata) +{ + if (((simulProcInfo *) processor)->endianess) { + switch (width>>3) { +#if SIMUL_ARCHITECTURE_WIDTH == 8 + case 8: + { + simulWord low, high; + low = (((unsigned char *) psource)[7]) | (((unsigned char *) psource)[6] << 8) + | (((unsigned char *) psource)[5] << 16) | (((unsigned char *) psource)[4] << 24); + high = (((unsigned char *) psource)[3]) | (((unsigned char *) psource)[2] << 8) + | (((unsigned char *) psource)[1] << 16) | (((unsigned char *) psource)[0] << 24); + *pdata = low | (high << 32); + } + break; +#endif + case 4: + *pdata = (((unsigned char *) psource)[3]) | (((unsigned char *) psource)[2] << 8) + | (((unsigned char *) psource)[1] << 16) | (((unsigned char *) psource)[0] << 24); + break; + case 2: + *pdata = (((unsigned char *) psource)[1]) | (((unsigned char *) psource)[0] << 8); + break; + default: + *pdata = ((unsigned char *) psource)[0]; + } + } else { + switch (width>>3) { +#if SIMUL_ARCHITECTURE_WIDTH == 8 + case 8: + { + simulWord low, high; + low = (((unsigned char *) psource)[0]) | (((unsigned char *) psource)[1] << 8) + | (((unsigned char *) psource)[2] << 16) | (((unsigned char *) psource)[3] << 24); + high = (((unsigned char *) psource)[4]) | (((unsigned char *) psource)[5] << 8) + | (((unsigned char *) psource)[6] << 16) | (((unsigned char *) psource)[7] << 24); + *pdata = low | (high << 32); + } + break; +#endif + case 4: + *pdata = (((unsigned char *) psource)[0]) | (((unsigned char *) psource)[1] << 8) + | (((unsigned char *) psource)[2] << 16) | (((unsigned char *) psource)[3] << 24); + break; + case 2: + *pdata = (((unsigned char *) psource)[0]) | (((unsigned char *) psource)[1] << 8); + break; + default: + *pdata = ((unsigned char *) psource)[0]; + } + } +} + + + +/************************************************************************** + + Ports + +**************************************************************************/ + +int SIMULAPI SIMUL_GetPort(simulProcessor processor, int offset, int width, simulWord * pdata) +{ +#if SIMUL_ARCHITECTURE_WIDTH == 8 + return (*((simulProcInfo *) processor)->getPort64) (processor, offset, width, pdata); +#else + return (*((simulProcInfo *) processor)->getPort32) (processor, offset, width, pdata); +#endif +} + + +int SIMULAPI SIMUL_SetPort(simulProcessor processor, int offset, int width, simulWord * pdata) +{ +#if SIMUL_ARCHITECTURE_WIDTH == 8 + return (*((simulProcInfo *) processor)->setPort64) (processor, offset, width, pdata); +#else + return (*((simulProcInfo *) processor)->setPort32) (processor, offset, width, pdata); +#endif +} + + +void * SIMULAPI SIMUL_RegisterPortChangeCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private, int offset, int width) +{ + return (*((simulProcInfo *) processor)->registerPortChangeCallback)(processor, func, private, offset, width, SIMUL_ARCHITECTURE_WIDTH); +} + + + +/************************************************************************** + + Shared Resources + +**************************************************************************/ + +int SIMULAPI SIMUL_CreateSharedResource(simulProcessor processor, int size) +{ + return (*((simulProcInfo *) processor)->createSharedResource) (processor, size); +} + + +int SIMULAPI SIMUL_ReadSharedResource(simulProcessor processor, int offset, int len, void * pdata) +{ + return (*((simulProcInfo *) processor)->readSharedResource) (processor, offset, len, pdata); +} + + +int SIMULAPI SIMUL_WriteSharedResource(simulProcessor processor, int offset, int len, void * pdata) +{ + return (*((simulProcInfo *) processor)->writeSharedResource) (processor, offset, len, pdata); +} + + + +/************************************************************************** + + File I/O + +**************************************************************************/ + +void * SIMULAPI SIMUL_OpenFile(simulProcessor processor, const char * filename, int mode) +{ + return (*((simulProcInfo *) processor)->openFile) (processor, filename, mode); +} + + +void SIMULAPI SIMUL_CloseFile(simulProcessor processor, void * file) +{ + (*((simulProcInfo *) processor)->closeFile) (processor, file); +} + + +int SIMULAPI SIMUL_ReadFile(simulProcessor processor, void * file, void * pdata, int length) +{ + return (*((simulProcInfo *) processor)->readFile) (processor, file, pdata, length); +} + +int SIMULAPI SIMUL_WriteFile(simulProcessor processor, void * file, void * pdata, int length) +{ + return (*((simulProcInfo *) processor)->writeFile) (processor, file, pdata, length); +} + + +int SIMULAPI SIMUL_ReadlineFile(simulProcessor processor, void * file, void * pdata, int length) +{ + return (*((simulProcInfo *) processor)->readlineFile) (processor, file, pdata, length); +} + +int SIMULAPI SIMUL_WritelineFile(simulProcessor processor, void * file, void * pdata) +{ + return (*((simulProcInfo *) processor)->writelineFile) (processor, file, pdata); +} + + +long SIMULAPI SIMUL_SeekFile(simulProcessor processor, void * file, long pos, int mode) +{ + return (*((simulProcInfo *) processor)->seekFile) (processor, file, pos, mode); +} + + + +/************************************************************************** + + Terminal I/O + +**************************************************************************/ + +int SIMULAPI SIMUL_StateTerminal(simulProcessor processor, int id) +{ + return (*((simulProcInfo *) processor)->stateTerminal) (processor, id); +} + +int SIMULAPI SIMUL_ReadTerminal(simulProcessor processor, int id) +{ + return (*((simulProcInfo *) processor)->readTerminal) (processor, id); +} + +int SIMULAPI SIMUL_WriteTerminal(simulProcessor processor, int id, int ch) +{ + return (*((simulProcInfo *) processor)->writeTerminal) (processor, id, ch); +} + +void * SIMUL_RegisterTerminalCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr private, int id) +{ + return (*((simulProcInfo *) processor)->registerTerminalCallback) (processor, func, private, id, SIMUL_ARCHITECTURE_WIDTH); +} + + diff --git a/debuggers/t32/sim/include/simul.h b/debuggers/t32/sim/include/simul.h new file mode 100644 index 00000000..feab0da9 --- /dev/null +++ b/debuggers/t32/sim/include/simul.h @@ -0,0 +1,553 @@ +#ifndef __SIMUL_H +#define __SIMUL_H +/************************************************************************** + + Basic types and includes + +**************************************************************************/ + +#ifdef WIN32 + +#ifndef _WINDOWS_ +#include +#endif + +typedef __int64 simulTime; +typedef unsigned __int64 simulWord64; + +#define SIMULAPI __cdecl + +#else + +#include "stdarg.h" + +#ifdef NSC32000 +typedef QUAD simulTime; +typedef QUAD simulWord64; +#else +typedef long long simulTime; +typedef unsigned long long simulWord64; +#endif + +#define SIMULAPI + +#endif + + +typedef unsigned int simulWord32; + +#define SIMUL_VERSION 1 + +#ifdef SIMUL_ARCHITECTURE_64BIT +#define SIMUL_ARCHITECTURE_WIDTH 8 +typedef simulWord64 simulWord; +#else +#define SIMUL_ARCHITECTURE_WIDTH 4 +typedef simulWord32 simulWord; +#endif + +typedef void * simulProcessor; +typedef void * simulPtr; + + +/************************************************************************** + + Internal callback structure (DO NOT ACCESS THIS STRUCTURE) + +**************************************************************************/ + +typedef struct +{ + int endianess; + int addresswidth; + int datawidth; + int processortype; + int id; + int resvd1; + int resvd2; + int resvd3; + + void (SIMULAPI *printf)(); + void (SIMULAPI *warning)(); + void (SIMULAPI *stop)(); + void (SIMULAPI *update)(); + void * (SIMULAPI *alloc)(); + void (SIMULAPI *free)(); + void * (SIMULAPI *registerCommandCallback)(); + void * (SIMULAPI *registerResetCallback)(); + void * (SIMULAPI *registerExitCallback)(); + + void (SIMULAPI *getClockFrequency)(); + void (SIMULAPI *setClockFrequency)(); + void (SIMULAPI *getClockCycle)(); + void (SIMULAPI *setClockCycle)(); + void (SIMULAPI *getTime)(); + void (SIMULAPI *getClock)(); + void (SIMULAPI *stall)(); + void (SIMULAPI *startTimer)(); + void (SIMULAPI *stopTimer)(); + void (SIMULAPI *stopAllTimer)(); + void * (SIMULAPI *registerTimerCallback)(); + + int (SIMULAPI *readMemory32)(); + int (SIMULAPI *readMemory64)(); + int (SIMULAPI *writeMemory32)(); + int (SIMULAPI *writeMemory64)(); + void * (SIMULAPI *registerBusReadCallback)(); + void * (SIMULAPI *registerBusWriteCallback)(); + void (SIMULAPI *relocateBusCallback)(); + + int (SIMULAPI *getPort32)(); + int (SIMULAPI *getPort64)(); + int (SIMULAPI *setPort32)(); + int (SIMULAPI *setPort64)(); + void * (SIMULAPI *registerPortChangeCallback)(); + + int (SIMULAPI *createSharedResource)(); + int (SIMULAPI *readSharedResource)(); + int (SIMULAPI *writeSharedResource)(); + + void * (SIMULAPI *openFile)(); + void (SIMULAPI *closeFile)(); + int (SIMULAPI *readFile)(); + int (SIMULAPI *writeFile)(); + int (SIMULAPI *readlineFile)(); + int (SIMULAPI *writelineFile)(); + long (SIMULAPI *seekFile)(); + + int (SIMULAPI *readTerminal)(); + int (SIMULAPI *writeTerminal)(); + int (SIMULAPI *stateTerminal)(); + void * (SIMULAPI *registerTerminalCallback)(); + + void * (SIMULAPI *registerGoCallback)(); + void * (SIMULAPI *registerBreakCallback)(); +} +simulProcInfo; + + +/************************************************************************** + + Callback structure + +**************************************************************************/ + +#define SIMUL_CALLBACK_INIT 0x0000 +#define SIMUL_CALLBACK_BUSREAD 0x0001 +#define SIMUL_CALLBACK_BUSWRITE 0x0002 +#define SIMUL_CALLBACK_PORTCHANGE 0x0004 +#define SIMUL_CALLBACK_TIMER 0x0010 +#define SIMUL_CALLBACK_EXIT 0x0020 +#define SIMUL_CALLBACK_RESET 0x0040 +#define SIMUL_CALLBACK_TERMINAL 0x0080 +#define SIMUL_CALLBACK_COMMAND 0x0100 +#define SIMUL_CALLBACK_GO 0x0200 +#define SIMUL_CALLBACK_BREAK 0x0400 + +typedef struct +{ + int version; + char * modelname; + char * commandline; + int argc; + char ** argp; + int * argpint; + simulWord * argpword; + simulWord32 * argpword32; + simulWord64 * argpword64; + int * argpport; + int * argpbustype; + simulWord * argpaddress; + simulWord32 * argpaddress32; + simulWord64 * argpaddress64; + simulTime * argptime; +} +simulParamCallbackStruct; + +typedef struct +{ + simulWord address; + simulWord data; + int width; + int cycletype; + int clocks; +} +simulBusCallbackStruct; + +typedef struct +{ + simulWord32 address; + simulWord32 data; + int width; + int cycletype; + int clocks; +} +simulBusCallbackStruct32; + +typedef struct +{ + simulWord64 address; + simulWord64 data; + int width; + int cycletype; + int clocks; +} +simulBusCallbackStruct64; + +typedef struct +{ + simulWord newdata; + simulWord olddata; +} +simulPortCallbackStruct; + +typedef struct +{ + simulWord32 newdata; + simulWord32 olddata; +} +simulPortCallbackStruct32; + +typedef struct +{ + simulWord64 newdata; + simulWord64 olddata; +} +simulPortCallbackStruct64; + +typedef struct +{ + int data; +} +simulTerminalCallbackStruct; + +typedef struct +{ + int type; + simulTime time; + union { + simulParamCallbackStruct init; + simulParamCallbackStruct command; + simulBusCallbackStruct bus; + simulBusCallbackStruct32 bus32; + simulBusCallbackStruct64 bus64; + simulPortCallbackStruct port; + simulPortCallbackStruct32 port32; + simulPortCallbackStruct64 port64; + simulTerminalCallbackStruct terminal; + } x; +} +simulCallbackStruct; + + +typedef int (SIMULAPI * simulCallbackFunctionPtr)(simulProcessor processor, simulCallbackStruct *, simulPtr priv); + +#ifdef __cplusplus +extern "C" { +#endif + + +/************************************************************************** + + Model entry definition + +**************************************************************************/ + +#define SIMUL_INIT_OK 1 +#define SIMUL_INIT_FAIL -1 + +extern int SIMULAPI SIMUL_Init(simulProcessor processor, simulCallbackStruct * cbs); + + + +/************************************************************************** + + Generic configuration functions + +**************************************************************************/ + +extern void SIMULAPI SIMUL_Printf(simulProcessor processor, const char *format, ...); + +extern void SIMULAPI SIMUL_Warning(simulProcessor processor, const char *format, ...); + +extern void SIMULAPI SIMUL_Stop(simulProcessor processor); + +extern void SIMULAPI SIMUL_Update(simulProcessor processor, int flags); + +extern void * SIMULAPI SIMUL_Alloc(simulProcessor processor, int size); + +extern void SIMULAPI SIMUL_Free(simulProcessor processor, void * ptr); + + +#define SIMUL_ENDIANESS_LITTLE 0 +#define SIMUL_ENDIANESS_BIG 1 + +extern int SIMULAPI SIMUL_GetEndianess(simulProcessor processor); + + +#define SIMUL_COMMAND_OK 1 +#define SIMUL_COMMAND_FAIL -1 + +extern void * SIMULAPI SIMUL_RegisterCommandCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr priv); + + +#define SIMUL_RESET_OK 1 + +extern void * SIMULAPI SIMUL_RegisterResetCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr priv); + + +#define SIMUL_EXIT_OK 1 + +extern void * SIMULAPI SIMUL_RegisterExitCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr priv); + + +#define SIMUL_GO_OK 1 + +extern void * SIMULAPI SIMUL_RegisterGoCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr priv); + + +#define SIMUL_BREAK_OK 1 + +extern void * SIMULAPI SIMUL_RegisterBreakCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr priv); + + + +/************************************************************************** + + Clocks and Timers + +**************************************************************************/ + +#define SIMUL_TIMER_OK 1 + + +#define SIMUL_CLOCK_CORE 0 +#define SIMUL_CLOCK_BUS 1 +#define SIMUL_CLOCK_POWERPC_TIMEBASE 2 + + +extern void SIMULAPI SIMUL_GetClockFrequency(simulProcessor processor, int clockid, simulWord64 * pfrequency); + +extern void SIMULAPI SIMUL_SetClockFrequency(simulProcessor processor, int clockid, simulWord64 * pfrequency); + +extern void SIMULAPI SIMUL_GetClockCycle(simulProcessor processor, int clockid, simulTime * ptime); + +extern void SIMULAPI SIMUL_SetClockCycle(simulProcessor processor, int clockid, simulTime * ptime); + +extern void SIMULAPI SIMUL_GetTime(simulProcessor processor, simulTime * ptime); + +extern void SIMULAPI SIMUL_GetClock(simulProcessor processor, int clockid, simulTime * ptime); + +#define SIMUL_STALL_ABS 0x000 +#define SIMUL_STALL_REL 0x100 +#define SIMUL_STALL_CLOCKS 0x400 + +extern void SIMULAPI SIMUL_Stall(simulProcessor processor, int mode, simulTime * ptime); + + +/* timer modes */ + +#define SIMUL_TIMER_ABS 0x000 +#define SIMUL_TIMER_REL 0x100 +#define SIMUL_TIMER_SINGLE 0x000 +#define SIMUL_TIMER_REPEAT 0x200 +#define SIMUL_TIMER_CLOCKS 0x400 + + +extern void SIMULAPI SIMUL_StartTimer(simulProcessor processor, void * timerid, int mode, simulTime * ptime); + +extern void SIMULAPI SIMUL_StopTimer(simulProcessor processor, void * timerid); + +extern void SIMULAPI SIMUL_StopAllTimer(simulProcessor processor); + +extern void * SIMULAPI SIMUL_RegisterTimerCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr priv); + + + +/************************************************************************** + + Buses and Memories + +**************************************************************************/ + +/* return values for bus callback functions */ + +#define SIMUL_MEMORY_CONTINUE 0 +#define SIMUL_MEMORY_OK 1 +#define SIMUL_MEMORY_FAIL -1 + +/* cycle types */ + +#define SIMUL_MEMORY_HIDDEN 0x00 +#define SIMUL_MEMORY_FETCH 0x02 +#define SIMUL_MEMORY_DATA 0x04 +#define SIMUL_MEMORY_DMA 0x08 + + +#define SIMUL_MEMORY_DEFAULT 0 + +#define SIMUL_MEMORY_POWERPC_SPR 1 +#define SIMUL_MEMORY_POWERPC_DCR 2 + +#define SIMUL_MEMORY_ARM_CPX 1 + +#define SIMUL_MEMORY_SH_INTACK 255 +#define SIMUL_MEMORY_M68K_INTACK 255 + + +extern int SIMULAPI SIMUL_ReadMemory(simulProcessor processor, int bustype, simulWord * paddress, int width, int cycletype, simulWord * pdata); + +extern int SIMULAPI SIMUL_WriteMemory(simulProcessor processor, int bustype, simulWord * paddress, int width, int cycletype, simulWord * pdata); + + +extern void * SIMULAPI SIMUL_RegisterBusReadCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr priv, int bustype, simulWord * paddressFrom, simulWord * paddressTo); + +extern void * SIMULAPI SIMUL_RegisterBusWriteCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr priv, int bustype, simulWord * paddressFrom, simulWord * paddressTo); + +extern void SIMULAPI SIMUL_RelocateBusCallback(simulProcessor processor, void * callbackid, int bustype, simulWord * paddressFrom, simulWord * paddressTo); + + +extern void SIMULAPI SIMUL_InsertWord(simulProcessor processor, simulWord * ptarget, int wordwidth, simulWord * paddress, int width, simulWord * pdata); + +extern void SIMULAPI SIMUL_ExtractWord(simulProcessor processor, simulWord * psource, int wordwidth, simulWord * paddress, int width, simulWord * pdata); + + +extern void SIMULAPI SIMUL_SaveWord(simulProcessor processor, void * ptarget, int width, simulWord * pdata); + +extern void SIMULAPI SIMUL_LoadWord(simulProcessor processor, void * psource, int width, simulWord * pdata); + + + +/************************************************************************** + + Ports + +**************************************************************************/ + +/* predefined core ports */ + +#define SIMUL_PORT_RESET -1 +#define SIMUL_PORT_INTERRUPT -2 + +#define SIMUL_PORT_PPC_INT -2 + +#define SIMUL_PORT_ARM_IRQ -2 +#define SIMUL_PORT_ARM_FIQ -3 + +#define SIMUL_PORT_SH_IRL0 -2 +#define SIMUL_PORT_SH_IRL1 -3 +#define SIMUL_PORT_SH_IRL2 -4 +#define SIMUL_PORT_SH_IRL3 -5 + +#define SIMUL_PORT_MIPS_NMI -2 +#define SIMUL_PORT_MIPS_INT0 -3 +#define SIMUL_PORT_MIPS_INT1 -4 +#define SIMUL_PORT_MIPS_INT2 -5 +#define SIMUL_PORT_MIPS_INT3 -6 +#define SIMUL_PORT_MIPS_INT4 -7 +#define SIMUL_PORT_MIPS_INT5 -8 + +#define SIMUL_PORT_M68K_IRL0 -2 +#define SIMUL_PORT_M68K_IRL1 -3 +#define SIMUL_PORT_M68K_IRL2 -4 + +#define SIMUL_PORT_C166_IRL0 -2 +#define SIMUL_PORT_C166_IRL1 -3 +#define SIMUL_PORT_C166_IRL2 -4 +#define SIMUL_PORT_C166_IRL3 -5 +#define SIMUL_PORT_C166_NMI -6 + +/* return values for port callback functions */ + +#define SIMUL_PORT_OK 1 + + +extern int SIMULAPI SIMUL_GetPort(simulProcessor processor, int offset, int width, simulWord * pdata); + +extern int SIMULAPI SIMUL_SetPort(simulProcessor processor, int offset, int width, simulWord * pdata); + +extern void * SIMULAPI SIMUL_RegisterPortChangeCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr priv, int offset, int width); + + + +/************************************************************************** + + Shared Resources + +**************************************************************************/ + +extern int SIMULAPI SIMUL_CreateSharedResource(simulProcessor processor, int size); + +extern int SIMULAPI SIMUL_ReadSharedResource(simulProcessor processor, int offset, int len, void * pdata); + +extern int SIMULAPI SIMUL_WriteSharedResource(simulProcessor processor, int offset, int len, void * pdata); + + + +/************************************************************************** + + File I/O + +**************************************************************************/ + +/* file modes */ + +#define SIMUL_FILE_READ 0x001 +#define SIMUL_FILE_WRITE 0x002 +#define SIMUL_FILE_CREATE 0x010 +#define SIMUL_FILE_APPEND 0x020 +#define SIMUL_FILE_BINARY 0x000 +#define SIMUL_FILE_ASCII 0x100 + +extern void * SIMULAPI SIMUL_OpenFile(simulProcessor processor, const char * filename, int mode); + +extern void SIMULAPI SIMUL_CloseFile(simulProcessor processor, void * file); + +extern int SIMULAPI SIMUL_ReadFile(simulProcessor processor, void * file, void * pdata, int length); + +extern int SIMULAPI SIMUL_WriteFile(simulProcessor processor, void * file, void * pdata, int length); + +extern int SIMULAPI SIMUL_ReadlineFile(simulProcessor processor, void * file, void * pdata, int length); + +extern int SIMULAPI SIMUL_WritelineFile(simulProcessor processor, void * file, void * pdata); + +#define SIMUL_FILE_SEEKABS 0 +#define SIMUL_FILE_SEEKREL 1 +#define SIMUL_FILE_SEEKEND 2 + +extern long SIMULAPI SIMUL_SeekFile(simulProcessor processor, void * file, long pos, int mode); + + + + +/************************************************************************** + + Terminal I/O + +**************************************************************************/ + +/* status bits */ + +#define SIMUL_STATE_RXREADY 0x001 +#define SIMUL_STATE_TXREADY 0x002 +#define SIMUL_STATE_NOTEXISTING 0x010 + +extern int SIMULAPI SIMUL_ReadTerminal(simulProcessor processor, int id); + +extern int SIMULAPI SIMUL_WriteTerminal(simulProcessor processor, int id, int ch); + +extern int SIMULAPI SIMUL_StateTerminal(simulProcessor processor, int id); + +extern void * SIMUL_RegisterTerminalCallback(simulProcessor processor, simulCallbackFunctionPtr func, simulPtr priv, int id); + + +/************************************************************************** + + End of Include + +**************************************************************************/ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/debuggers/t32/sim/memlogger/CMakeLists.txt b/debuggers/t32/sim/memlogger/CMakeLists.txt new file mode 100644 index 00000000..0af6a087 --- /dev/null +++ b/debuggers/t32/sim/memlogger/CMakeLists.txt @@ -0,0 +1,10 @@ +# NVIC simulation model for the T32 +set(SRCS + memlogger.c + ../include/simul.c +) + +add_library(memlogger SHARED ${SRCS}) +GET_TARGET_PROPERTY(__T32_MEMLOGGER_LIB memlogger LOCATION) +SET(T32_MEMLOGGER_LIB "${__T32_MEMLOGGER_LIB}" CACHE INTERNAL "") + diff --git a/debuggers/t32/sim/memlogger/memlogger.c b/debuggers/t32/sim/memlogger/memlogger.c new file mode 100644 index 00000000..b60cd083 --- /dev/null +++ b/debuggers/t32/sim/memlogger/memlogger.c @@ -0,0 +1,78 @@ + +#include "simul.h" +#include +/************************************************************************** + + Local port structure + +**************************************************************************/ + +typedef struct +{ + int bustype; + int data; +} +MemLog_t; + + + +static int SIMULAPI readCB(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + + // simulWord address = cbs->x.bus.address; + MemLog_t * memlog = (MemLog_t*)private; + cbs->x.bus.data = memlog->data; + //int width = cbs->x.bus.width; + SIMUL_Printf(processor, "MEM Read *0x%x - 0x%x\n", cbs->x.bus.address, memlog->data); + return SIMUL_MEMORY_OK; +} + + +static int SIMULAPI writeCB(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + simulWord data = cbs->x.bus.data; + //simulWord address = cbs->x.bus.address; + MemLog_t * memlog = (MemLog_t*)private; + memlog->data = cbs->x.bus.data; + //int width = cbs->x.bus.width; + SIMUL_Printf(processor, "MEM Write *0x%x - 0x%x\n", cbs->x.bus.address, data); + return SIMUL_MEMORY_OK; +} + + + +static int SIMULAPI PortReset(simulProcessor processor, simulCallbackStruct * cbs, simulPtr private) +{ + return SIMUL_RESET_OK; +} + + +/************************************************************************** + + Entry point of the Model + +**************************************************************************/ + +int SIMULAPI SIMUL_Init(simulProcessor processor, simulCallbackStruct * cbs) +{ + MemLog_t *pmemlog; + + strcpy(cbs->x.init.modelname, __DATE__ " MemLogger"); + + pmemlog = (MemLog_t *) SIMUL_Alloc(processor, sizeof(MemLog_t)); + +// if (cbs->x.init.argc != 3) { +// SIMUL_Warning(processor, "parameters:

"); +// return SIMUL_INIT_FAIL; +// } + pmemlog->bustype = cbs->x.init.argpbustype[1]; + + simulWord from, to; + from = 0x20002074; + to = 0x20002077; + SIMUL_RegisterResetCallback(processor, PortReset, (simulPtr) pmemlog); + + SIMUL_RegisterBusWriteCallback(processor, writeCB, (simulPtr) pmemlog, pmemlog->bustype, &from, &to); + SIMUL_RegisterBusReadCallback(processor, readCB, (simulPtr) pmemlog, pmemlog->bustype, &from, &to); + return SIMUL_INIT_OK; +} diff --git a/debuggers/t32/src/t32cli.cc b/debuggers/t32/src/t32cli.cc index 2f4f6d1d..c2360c4a 100644 --- a/debuggers/t32/src/t32cli.cc +++ b/debuggers/t32/src/t32cli.cc @@ -6,8 +6,8 @@ using namespace std; void err(int ernum){ - if(err != 0){ - cerr << "Error: " << err << endl; + if(ernum != 0){ + cerr << "Error: " << ernum << endl; //exit(-1); } } @@ -36,7 +36,7 @@ int eval_command(){ int main(void){ cout << "Lauterbach remote connection" << endl; cout << "Enter bye to exit." << endl; - int error; + char hostname[] = "localhost"; char packlen[] = "1024"; char port[] = "20010"; diff --git a/debuggers/t32/cmm/CMakeLists.txt b/scripts/t32cmm/CMakeLists.txt similarity index 67% rename from debuggers/t32/cmm/CMakeLists.txt rename to scripts/t32cmm/CMakeLists.txt index d982fee0..59e0c850 100644 --- a/debuggers/t32/cmm/CMakeLists.txt +++ b/scripts/t32cmm/CMakeLists.txt @@ -14,14 +14,21 @@ else() message(FATAL_ERROR "Please set the FAIL_ELF_PATH enviroment variable to the binary under test.") endif() +OPTION( T32_SIMULATOR "Start LAuterbach as instruction set simulator. No hardware needed." OFF) + +if(T32_SIMULATOR) + set(T32_USB_OR_SIM "SIM") +else() + set(T32_USB_OR_SIM "USB") +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) +configure_file(config.t32.in ${PROJECT_BINARY_DIR}/cmm/config.t32) +configure_file(t32.cmm.in ${PROJECT_BINARY_DIR}/cmm/t32.cmm) set(T32_ARCHITECTURE armm3 CACHE PATH "Setup target architecture for default cmm scripts (currently only armm3)") -set(T32_EXE "${T32_SYS}/bin/pc_linux/" CACHE INTERNAL "") # TODO: set pc_linux64 for 64 bit systems +set(T32_EXE "${T32_SYS}/bin/pc_linux64/" CACHE INTERNAL "") # TODO: set pc_linux64 for 64 bit systems add_subdirectory(${T32_ARCHITECTURE}) @@ -30,7 +37,7 @@ 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} & + COMMAND T32CONFIG=${PROJECT_BINARY_DIR}/cmm/config.t32 ${T32_EXE} & WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/cmm" COMMENT "Starting Lauterbach." ) diff --git a/debuggers/t32/cmm/armm3/CMakeLists.txt b/scripts/t32cmm/armm3/CMakeLists.txt similarity index 71% rename from debuggers/t32/cmm/armm3/CMakeLists.txt rename to scripts/t32cmm/armm3/CMakeLists.txt index c2a213ec..18eb0804 100644 --- a/debuggers/t32/cmm/armm3/CMakeLists.txt +++ b/scripts/t32cmm/armm3/CMakeLists.txt @@ -2,14 +2,21 @@ if(EXISTS $ENV{T32SYS}) SET(T32_SYS $ENV{T32SYS}) -else(EXISTS $ENV{KESOROOTPATH}) +else() 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 "") +if(T32_SIMULATOR) + set(T32_OFF_FOR_SIM ";") +else() + set(T32_OFF_FOR_SIM " ") +endif() + + +set(T32_EXE "${T32_EXE}/t32marm-qt" 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(init.cmm.in ${PROJECT_BINARY_DIR}/cmm/init.cmm ) 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/armm3/armm3cfg.cmm.in b/scripts/t32cmm/armm3/armm3cfg.cmm.in similarity index 100% rename from debuggers/t32/cmm/armm3/armm3cfg.cmm.in rename to scripts/t32cmm/armm3/armm3cfg.cmm.in diff --git a/scripts/t32cmm/armm3/init.cmm.in b/scripts/t32cmm/armm3/init.cmm.in new file mode 100644 index 00000000..92613b8c --- /dev/null +++ b/scripts/t32cmm/armm3/init.cmm.in @@ -0,0 +1,64 @@ +;RESET + +&t32scriptdir=OS.PPD() + +;======================================================================== +; CPU setup + +SYStem.RESet + +IF (SIMULATOR()) +( + SYS.DOWN + AREA.view + SIM.UNLOAD + SIM.LOAD @T32_MEMLOGGER_LIB@ + SIM.LOAD @T32_NVIC_LIB@ + SIM.LIST + SYS.CPU cortexm3 + SYS.UP +) +ELSE +( + if OS.FILE(&(t32scriptdir)/armm3cfg.cmm) + ( + DO &(t32scriptdir)/armm3cfg.cmm + ) +) + +IF (SIMULATOR()) +( + DATA.LOAD.ELF &appimage + ; Copy first bytes to address 0 to make simulator work + DATA.COPY 0x8000000++0x200 0x00 + ; Load Stack pointer and Instruction Pointer + REGISTER.RES + + + ; Be aware of the HACK! + ; To get over the RCC Initialisation, we have to get to the second read + ; of the RCC Register and inject some initilized looking values. + ; for STM32 + BREAK.SET 0x40021000 /Read /DISableHit /Count 2 + GO + wait !state.run() + DATA.SET 0x40021000 %long ~0 + DATA.SET 0x40021004 %long 0x8 +) +else +( + +;======================================================================== +; Flash programming +; + DO &(t32scriptdir)/loadelf.cmm +) + +;======================================================================== +; Optional Parts +if OS.FILE(&(t32scriptdir)/t32term.cmm) +( + DO &(t32scriptdir)/t32term.cmm +) + +ENDDO diff --git a/debuggers/t32/cmm/armm3/loadelf.cmm b/scripts/t32cmm/armm3/loadelf.cmm similarity index 100% rename from debuggers/t32/cmm/armm3/loadelf.cmm rename to scripts/t32cmm/armm3/loadelf.cmm diff --git a/debuggers/t32/cmm/armm3/t32term.cmm b/scripts/t32cmm/armm3/t32term.cmm similarity index 100% rename from debuggers/t32/cmm/armm3/t32term.cmm rename to scripts/t32cmm/armm3/t32term.cmm diff --git a/debuggers/t32/cmm/config.t32.usb.in b/scripts/t32cmm/config.t32.in similarity index 98% rename from debuggers/t32/cmm/config.t32.usb.in rename to scripts/t32cmm/config.t32.in index cc86d6f7..02c70ae6 100644 --- a/debuggers/t32/cmm/config.t32.usb.in +++ b/scripts/t32cmm/config.t32.in @@ -22,8 +22,8 @@ ;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 +PBI=@T32_USB_OR_SIM@ + ; ;uncomment the following 3 lines if you use an ICE or PodbusEthernetController diff --git a/debuggers/t32/cmm/t32.cmm b/scripts/t32cmm/t32.cmm.in similarity index 79% rename from debuggers/t32/cmm/t32.cmm rename to scripts/t32cmm/t32.cmm.in index ecdc50e7..f9495bf2 100644 --- a/debuggers/t32/cmm/t32.cmm +++ b/scripts/t32cmm/t32.cmm.in @@ -1,6 +1,6 @@ ;===== Cortex-M3 Lauterbach initialisation ==== -&appimage=OS.ENV(FAIL_ELF_PATH) +&appimage="@T32_ELF_PATH@" DO init.cmm