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

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