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
This commit is contained in:
Martin Hoffmann
2013-03-20 17:17:38 +01:00
parent f0e26a9b63
commit 96bc39c05d
42 changed files with 5880 additions and 46 deletions

View File

@ -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)

View File

@ -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 */

View File

@ -1,36 +0,0 @@
## Setup T32 target architecture for startup scripts
if(EXISTS $ENV{T32SYS})
SET(T32_SYS $ENV{T32SYS})
message(STATUS "[FAIL*] T32 base directory: T32SYS=${T32_SYS}")
else()
message(FATAL_ERROR "Please set env variable T32SYS to a valid T32 installation base directory.")
endif()
if(EXISTS $ENV{FAIL_ELF_PATH})
SET(T32_ELF_PATH $ENV{FAIL_ELF_PATH})
message(STATUS "[FAIL*] T32 ELF under test: ${T32_ELF_PATH}")
else()
message(FATAL_ERROR "Please set the FAIL_ELF_PATH enviroment variable to the binary under test.")
endif()
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/cmm)
configure_file(config.t32.usb.in ${PROJECT_BINARY_DIR}/cmm/config.t32.usb)
configure_file(t32.cmm ${PROJECT_BINARY_DIR}/cmm/t32.cmm COPYONLY)
set(T32_ARCHITECTURE armm3 CACHE PATH "Setup target architecture for default cmm scripts (currently only armm3)")
set(T32_EXE "${T32_SYS}/bin/pc_linux/" CACHE INTERNAL "") # TODO: set pc_linux64 for 64 bit systems
add_subdirectory(${T32_ARCHITECTURE})
message(STATUS "[FAIL*] T32 Architecture: ${T32_ARCHITECTURE}")
message(STATUS "[FAIL*] T32 CPU name: ${T32_CPUNAME}")
message(STATUS "[FAIL*] T32 Executable: ${T32_EXE}")
add_custom_target(runt32
COMMAND T32CONFIG=${PROJECT_BINARY_DIR}/cmm/config.t32.usb ${T32_EXE} &
WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/cmm"
COMMENT "Starting Lauterbach."
)

View File

@ -1,15 +0,0 @@
### Configure cmm Scripts for ARM Cortex-M3
if(EXISTS $ENV{T32SYS})
SET(T32_SYS $ENV{T32SYS})
else(EXISTS $ENV{KESOROOTPATH})
message(FATAL_ERROR "Please set env variable T32SYS to valid T32 installation base directory.")
endif(EXISTS $ENV{T32SYS})
set(T32_EXE "${T32_EXE}/t32marm" CACHE INTERNAL "")
set(T32_CPUNAME STM32F103RG CACHE PATH "CPU name for SYSTEM.CPU call. (e.g. STM32F103RG)")
configure_file(armm3cfg.cmm.in ${PROJECT_BINARY_DIR}/cmm/armm3cfg.cmm)
configure_file(init.cmm ${PROJECT_BINARY_DIR}/cmm/init.cmm COPYONLY)
configure_file(loadelf.cmm ${PROJECT_BINARY_DIR}/cmm/loadelf.cmm COPYONLY)
configure_file(t32term.cmm ${PROJECT_BINARY_DIR}/cmm/t32term.cmm COPYONLY)

View File

@ -1,169 +0,0 @@
;========================================================================
; CPU setup
IF SYSTEM.MODE()<5
(
SYStem.RESet
SYStem.CPU @T32_CPUNAME@
SYStem.Up
)
;========================================================================
; Flash declaration
FLASH.RESet
GOSUB FlashDeclaration
ENDDO
;========================================================================
; Flash declaration depending on selected CPU
FlashDeclaration:
LOCAL &FlashSize
LOCAL &RAMSize
IF ((CPU()=="STM32F100C4")||(CPU()=="STM32F100R4")||(CPU()=="STM32F101C4")||(CPU()=="STM32F101R4")||(CPU()=="STM32F101T4")||(CPU()=="STM32F102C4")||(CPU()=="STM32F102R4"))
(
&FlashSize=0x4000
&RAMSize=0x1000
)
ELSE IF ((CPU()=="STM32F103C4")||(CPU()=="STM32F103R4")||(CPU()=="STM32F103T4"))
(
&FlashSize=0x4000
&RAMSize=0x1800
)
ELSE IF ((CPU()=="STM32F100C6")||(CPU()=="STM32F100R6"))
(
&FlashSize=0x8000
&RAMSize=0x1000
)
ELSE IF ((CPU()=="STM32F101C6")||(CPU()=="STM32F101R6")||(CPU()=="STM32F101T6")||(CPU()=="STM32F102C6")||(CPU()=="STM32F102R6"))
(
&FlashSize=0x8000
&RAMSize=0x1800
)
ELSE IF ((CPU()=="STM32F103C6")||(CPU()=="STM32F103R6")||(CPU()=="STM32F103T6"))
(
&FlashSize=0x8000
&RAMSize=0x2800
)
ELSE IF ((CPU()=="STM32F100C8")||(CPU()=="STM32F100R8")||(CPU()=="STM32F100V8"))
(
&FlashSize=0x10000
&RAMSize=0x2000
)
ELSE IF ((CPU()=="STM32F101C8")||(CPU()=="STM32F101R8")||(CPU()=="STM32F101T8")||(CPU()=="STM32F101V8")||(CPU()=="STM32F102C8")||(CPU()=="STM32F102R8"))
(
&FlashSize=0x10000
&RAMSize=0x2800
)
ELSE IF ((CPU()=="STM32F103C8")||(CPU()=="STM32F103R8")||(CPU()=="STM32F103T8")||(CPU()=="STM32F103V8")||(CPU()=="STM32F105R8")||(CPU()=="STM32F105V8"))
(
&FlashSize=0x10000
&RAMSize=0x2800
)
ELSE IF ((CPU()=="STM32F100CB")||(CPU()=="STM32F100RB")||(CPU()=="STM32F100VB"))
(
&FlashSize=0x20000
&RAMSize=0x2000
)
ELSE IF ((CPU()=="STM32F101CB")||(CPU()=="STM32F101RB")||(CPU()=="STM32F101VB")||(CPU()=="STM32F102CB")||(CPU()=="STM32F102RB"))
(
&FlashSize=0x20000
&RAMSize=0x4000
)
ELSE IF ((CPU()=="STM32F103CB")||(CPU()=="STM32F103RB")||(CPU()=="STM32F103VB"))
(
&FlashSize=0x20000
&RAMSize=0x5000
)
ELSE IF ((CPU()=="STM32F105RB")||(CPU()=="STM32F105VB"))
(
&FlashSize=0x20000
&RAMSize=0x8000
)
ELSE IF ((CPU()=="STM32F107RB")||(CPU()=="STM32F107VB"))
(
&FlashSize=0x20000
&RAMSize=0x8000
)
ELSE IF ((CPU()=="STM32F101RC")||(CPU()=="STM32F101VC")||(CPU()=="STM32F101ZC"))
(
&FlashSize=0x40000
&RAMSize=0x8000
)
ELSE IF ((CPU()=="STM32F103RC")||(CPU()=="STM32F103VC")||(CPU()=="STM32F103ZC"))
(
&FlashSize=0x40000
&RAMSize=0xc000
)
ELSE IF ((CPU()=="STM32F105RC")||(CPU()=="STM32F105VC")||(CPU()=="STM32F107RC")||(CPU()=="STM32F107VC"))
(
&FlashSize=0x40000
&RAMSize=0x10000
)
ELSE IF ((CPU()=="STM32F101RD")||(CPU()=="STM32F101VD")||(CPU()=="STM32F101ZD"))
(
&FlashSize=0x60000
&RAMSize=0xc000
)
ELSE IF ((CPU()=="STM32F103RD")||(CPU()=="STM32F103VD")||(CPU()=="STM32F103ZD"))
(
&FlashSize=0x60000
&RAMSize=0x10000
)
ELSE IF ((CPU()=="STM32F101RE")||(CPU()=="STM32F101VE")||(CPU()=="STM32F101ZE"))
(
&FlashSize=0x80000
&RAMSize=0xc000
)
ELSE IF ((CPU()=="STM32F103RE")||(CPU()=="STM32F103VE")||(CPU()=="STM32F103ZE"))
(
&FlashSize=0x80000
&RAMSize=0x10000
)
ELSE IF ((CPU()=="STM32F101RF")||(CPU()=="STM32F101VF")||(CPU()=="STM32F101ZF")||(CPU()=="STM32F103RF")||(CPU()=="STM32F103VF")||(CPU()=="STM32F103ZF"))
(
&FlashSize=0xc0000
&RAMSize=0x18000
)
ELSE IF ((CPU()=="STM32F101RG")||(CPU()=="STM32F101VG")||(CPU()=="STM32F101ZG")||(CPU()=="STM32F103RG")||(CPU()=="STM32F103VG")||(CPU()=="STM32F103ZG"))
(
&FlashSize=0x100000
&RAMSize=0x18000
)
ELSE
(
PRINT %ERROR "FLASH size of CPU type is unknown"
ENDDO
)
IF &FlashSize>=0x40000
(
FLASH.Create 1. 0x08000000++(&FlashSize-0x01) 0x800 TARGET Word
)
ELSE
(
FLASH.Create 1. 0x08000000++(&FlashSize-0x01) 0x400 TARGET Word
)
IF &FlashSize>0x80000
(
FLASH.TARGET 0x20000000 0x20001000 0x800 ~~/demo/arm/flash/word/stm32f100xl.bin
)
ELSE IF &RAMSize>=0x1800
(
FLASH.TARGET 0x20000000 0x20000800 0x800 ~~/demo/arm/flash/word/stm32f100.bin
)
ELSE IF &RAMSize>=0x1000
(
FLASH.TARGET 0x20000000 0x20000800 0x400 ~~/demo/arm/flash/word/stm32f100.bin
)
ELSE
(
DIALOG.OK "Not enough memory for flash algorithm."
ENDDO
)
RETURN

View File

@ -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

View File

@ -1,15 +0,0 @@
;========================================================================
; Flash programming example
FLASH.ReProgram ALL /Erase
Data.LOAD.elf &appimage /GNU /CPP /GLOBTYPES
FLASH.ReProgram off
; Verify flash programming
Data.LOAD.ELF &appimage /ComPare
; Reset device
SYStem.Down
SYStem.Up
Symbol.Demangle ON ON

View File

@ -1,6 +0,0 @@
; This is currently output only, to support input we'd need a separate buffer
TERM.METHOD BUFFERE e:_ZN2hw3hal7T32Term9OutBufferE e:_ZN2hw3hal7T32Term9OutBufferE
TERM.MODE ASCII
TERM.GATE

View File

@ -1,58 +0,0 @@
;
;please refer the installation guide for more information
;about your configuration
;
;
;uncomment the following 3 lines if you don't use already environment variables
;changes to the actual directory names are necessary
;OS=
;SYS=/opt/t32
;TMP=/usr/tmp
;
;uncomment the following 4 lines if you use PowerTrace, PowerNexus or PowerDebugEthernet
;with onhost driver executable (t32m*) via ethernet interface
;the nodename is only the default name, please replace it with the actual node name
;PBI=
;NET
;NODE=t32
;PACKLEN=1024
;uncomment the following 2 lines if you use PowerTrace, PowerNexus, PowerDebugEthernet or
;PowerDebugInterface USB with onhost driver executable (t32m*) via USB interface
;please refer the installation manual (file icd_quick_installation.pdf) about more details
;concerning USB driver installation
PBI=
USB
;
;uncomment the following 3 lines if you use an ICE or PodbusEthernetController
;with standard hostdriver executable (t32cde) via ethernet interface
;the nodename is only the default name, please replace it with the actual node name
;LINK=NET
;NODE=t32
;PACKLEN=1024
;uncomment the following 1 lines if you use SCSI interface (ICE)
;LINK=SCSI
;uncomment the following 3 lines if you want to use TRACE32 fonts
;SCREEN=
;FONT=DEC
;FONT=SMALL
;uncomment the following 2 lines if you want to use TRACE32 bitmap fonts
;SCREEN=
;FONTMODE=3
;uncomment the following 2 lines if you use OPENWINDOWS
;SCREEN=
;WMGR=OW16
;uncomment the following 2 lines if you use MOTIF
;SCREEN=
;WMGR=MOTIF16
RCL=NETASSIST
PACKLEN=1024
PORT=@T32_PORTNUM@

View File

@ -1,10 +0,0 @@
;===== Cortex-M3 Lauterbach initialisation ====
&appimage=OS.ENV(FAIL_ELF_PATH)
DO init.cmm
;VAr.Frame /LOCALS /CALLER
REGISTER /SPOTLIGHT
;Data.ListAsm

View File

@ -0,0 +1,4 @@
include_directories(include)
add_subdirectory(${T32_ARCHITECTURE})
add_subdirectory(memlogger)

View File

@ -0,0 +1 @@
add_subdirectory(nvic)

View File

@ -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 "")

View File

@ -0,0 +1,625 @@
/***
* Cortex-M3 NVIC Simulator (C) Lauterbach 2010
* 08.03.2010 Sylwester Garncarek
***/
#include "nvic.h"
#include <string.h>
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;i<sizeof(NVIC_reg_offsets)/sizeof(unsigned long);i++)
{
from = IntCtrl->baseaddress + 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;i<len;i++)
{
if (port_set & (1 << i))
{
int _changePendingValue = !!(1);
if (!IntCtrl->IrqPending[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;i<len;i++)
{
if (port_clr & (1 << i))
{
ChangePending(16 + offset + i,0);
}
}
}
if (port_set || port_clr)
Interrupt(processor,IntCtrl,wakeUpEvent);
return SIMUL_PORT_OK;
}
static int NVIC_ExternalIrqChange_0_31(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
{
return NVIC_ExternalIrqChange(processor,cbs,_private,0,32);
}
static int NVIC_ExternalIrqChange_32_63(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
{
return NVIC_ExternalIrqChange(processor,cbs,_private,32,32);
}
static int NVIC_ExternalIrqChange_64_95(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
{
return NVIC_ExternalIrqChange(processor,cbs,_private,64,32);
}
static int NVIC_ExternalIrqChange_96_127(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
{
return NVIC_ExternalIrqChange(processor,cbs,_private,96,32);
}
static int NVIC_ExternalIrqChange_128_159(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
{
return NVIC_ExternalIrqChange(processor,cbs,_private,128,32);
}
static int NVIC_ExternalIrqChange_160_191(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
{
return NVIC_ExternalIrqChange(processor,cbs,_private,160,32);
}
static int NVIC_ExternalIrqChange_192_223(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
{
return NVIC_ExternalIrqChange(processor,cbs,_private,192,32);
}
static int NVIC_ExternalIrqChange_224_240(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
{
return NVIC_ExternalIrqChange(processor,cbs,_private,224,16);
}
void WakeUpFromWFE(simulProcessor processor, IntController * IntCtrl)
{
if (IntCtrl->regs.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: [(<first int port> <number of int ports>) | 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;i<IntCtrl->ExternalIrqPortsCount;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);
}

View File

@ -0,0 +1,3 @@
LIBRARY nvic
DESCRIPTION 'TRACE32 Hardware Simulation Model'
EXPORTS SIMUL_Interface

View File

@ -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

View File

@ -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, &reg);
}
/*************** 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, &reg);
}
int GPIO_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
{
IntController *IntCtrl = (IntController*) _private;
simulWord32 reg = 0x0;
BusRead(&cbs->x.bus, &reg);
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

View File

@ -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, &reg);
}

View File

@ -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,&reg);
for (i=0;i<32;i++)
{
if (reg & (1<<i)) ChangeEnable(arrayidx+i,1);
}
Interrupt(processor,IntCtrl,0);
return SIMUL_MEMORY_OK;
}
/*************** Irq x Clear Enable Register ***************/
int IRQCLRENR_Write(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;
BusRead(&cbs->x.bus,&reg);
for (i=0;i<32;i++)
{
if (reg & (1<<i)) ChangeEnable(arrayidx+i,0);
}
Interrupt(processor,IntCtrl,0);
return SIMUL_MEMORY_OK;
}
/*************** Irq x Set Pending Register ***************/
int IRQSETPER_Write(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 wakeUpEvent = 0;
int i;
cbs->x.bus.clocks = 1;
BusRead(&cbs->x.bus,&reg);
for (i=0;i<32;i++)
{
if (reg & (1<<i)) ChangePending(arrayidx+i,1);
}
Interrupt(processor,IntCtrl,wakeUpEvent);
return SIMUL_MEMORY_OK;
}
/*************** Irq x Clear Pending Register ***************/
int IRQCLRPER_Write(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 wakeUpEvent = 0;
int i;
cbs->x.bus.clocks = 1;
BusRead(&cbs->x.bus,&reg);
for (i=0;i<32;i++)
{
if (reg & (1<<i)) ChangePending(arrayidx+i,0);
}
Interrupt(processor,IntCtrl,wakeUpEvent);
return SIMUL_MEMORY_OK;
}
/*************** Irq x Priority Register ***************/
int IRQPR_Write(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 |= IntCtrl->IrqPriority[arrayidx+i] << (i << 3);
BusRead(&cbs->x.bus,&reg);
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<<i):(0);
}
else
{
for (i=0;i<16;i++) reg |= (IntCtrl->IrqEnable[arrayidx+i])?(1<<i):(0);
}
BusWrite(&cbs->x.bus,&reg);
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<<i):(0);
}
else
{
for (i=0;i<16;i++) reg |= (IntCtrl->IrqEnable[arrayidx+i])?(1<<i):(0);
}
BusWrite(&cbs->x.bus,&reg);
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<<i):(0);
}
else
{
for (i=0;i<16;i++) reg |= (IntCtrl->IrqPending[arrayidx+i])?(1<<i):(0);
}
BusWrite(&cbs->x.bus,&reg);
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<<i):(0);
}
else
{
for (i=0;i<16;i++) reg |= (IntCtrl->IrqPending[arrayidx+i])?(1<<i):(0);
}
BusWrite(&cbs->x.bus,&reg);
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<<i):(0);
}
else
{
for (i=0;i<16;i++) reg |= (IntCtrl->IrqActive[arrayidx+i])?(1<<i):(0);
}
BusWrite(&cbs->x.bus,&reg);
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,&reg);
return SIMUL_MEMORY_OK;
}

View File

@ -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,&reg);
arrayidx = (reg & 0x1FF) + 16;
if (arrayidx < 256)
{
ChangePending(arrayidx,1);
Interrupt(processor,IntCtrl,wakeUpEvent);
}
return SIMUL_MEMORY_OK;
}

View File

@ -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, &reg);
}
}
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<<i) & cmd)
{
IntCtrl->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, &reg);
}
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, &reg);
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, &reg);
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, &reg);
}
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, &reg);
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, &reg);
}
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, &reg);
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, &reg);
}
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, &reg);
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, &reg);
}
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, &reg);
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, &reg);
}
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, &reg);
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, &reg);
}
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, &reg);
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, &reg);
}
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, &reg);
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, &reg);
}
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, &reg);
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, &reg);
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, &reg);
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, &reg);
}
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, &reg);
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, &reg);
}
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, &reg);
IntCtrl->regs.dhcsr = reg;
return SIMUL_MEMORY_OK;
}

View File

@ -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, &reg);
}

View File

@ -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, &reg);
}
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,&reg);
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, &reg);
}
int STRVR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
{
IntController *IntCtrl = (IntController*) _private;
simulWord32 reg;
cbs->x.bus.clocks = 1;
BusRead(&cbs->x.bus,&reg);
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, &reg);
}
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, &reg);
}

View File

@ -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 <n> 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 <clocks>" 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 <clocks>");
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: <address> <portnumber>");
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;
}

View File

@ -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

View File

@ -0,0 +1,7 @@
LIBRARY DEMOPORT
DESCRIPTION 'TRACE32 Hardware Simulation Demoport'
EXPORTS
SIMUL_Interface

Binary file not shown.

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -0,0 +1,551 @@
/**************************************************************************
Basic types and includes
**************************************************************************/
#ifdef WIN32
#ifndef _WINDOWS_
#include <windows.h>
#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

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -0,0 +1,553 @@
#ifndef __SIMUL_H
#define __SIMUL_H
/**************************************************************************
Basic types and includes
**************************************************************************/
#ifdef WIN32
#ifndef _WINDOWS_
#include <windows.h>
#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

View File

@ -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 "")

View File

@ -0,0 +1,78 @@
#include "simul.h"
#include <string.h>
/**************************************************************************
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: <address> <portnumber>");
// 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;
}

View File

@ -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";