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:
873
debuggers/t32/sim/armm3/nvic/nvic_system_control_block.c
Normal file
873
debuggers/t32/sim/armm3/nvic/nvic_system_control_block.c
Normal 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, ®);
|
||||
}
|
||||
}
|
||||
|
||||
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, ®);
|
||||
}
|
||||
|
||||
int ICSR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
simulWord32 reg;
|
||||
int wakeUpEvent = 0;
|
||||
cbs->x.bus.clocks = 1;
|
||||
|
||||
BusRead(&cbs->x.bus, ®);
|
||||
|
||||
if (reg & REG_ICSR_NMIPENDSET)
|
||||
{
|
||||
ChangePending(IRQNUM_NMI,1);
|
||||
Interrupt(processor,IntCtrl,wakeUpEvent);
|
||||
}
|
||||
|
||||
if (reg & REG_ICSR_PENDSVSET)
|
||||
{
|
||||
ChangePending(IRQNUM_PENDSV,1);
|
||||
Interrupt(processor,IntCtrl,wakeUpEvent);
|
||||
}
|
||||
|
||||
if (reg & REG_ICSR_PENDSVCLR)
|
||||
{
|
||||
ChangePending(IRQNUM_PENDSV,0);
|
||||
Interrupt(processor,IntCtrl,wakeUpEvent);
|
||||
}
|
||||
|
||||
if (reg & REG_ICSR_PENDSTSET)
|
||||
{
|
||||
ChangePending(IRQNUM_SYSTICK,1);
|
||||
Interrupt(processor,IntCtrl,wakeUpEvent);
|
||||
}
|
||||
else if (reg & REG_ICSR_PENDSTCLR)
|
||||
{
|
||||
ChangePending(IRQNUM_SYSTICK,0);
|
||||
Interrupt(processor,IntCtrl,wakeUpEvent);
|
||||
}
|
||||
|
||||
return SIMUL_MEMORY_OK;
|
||||
}
|
||||
|
||||
/*************** Vector Table Offset Register ***************/
|
||||
|
||||
int VTOR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
cbs->x.bus.clocks = 1;
|
||||
return BusWrite(&cbs->x.bus, &IntCtrl->regs.vtor);
|
||||
}
|
||||
|
||||
int VTOR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
simulWord32 reg;
|
||||
|
||||
cbs->x.bus.clocks = 1;
|
||||
|
||||
reg = IntCtrl->regs.vtor;
|
||||
|
||||
BusRead(&cbs->x.bus, ®);
|
||||
|
||||
IntCtrl->regs.vtor = reg & 0x3FFFFF80;
|
||||
|
||||
return SIMUL_MEMORY_OK;
|
||||
}
|
||||
|
||||
/*************** Application Interrupt/Reset Control Register ***************/
|
||||
|
||||
int AIRCR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
simulWord32 reg;
|
||||
cbs->x.bus.clocks = 1;
|
||||
|
||||
reg = (IntCtrl->regs.aircr & REG_AIRCR_MASK) | 0xFA050000;
|
||||
|
||||
return BusWrite(&cbs->x.bus, ®);
|
||||
}
|
||||
|
||||
int AIRCR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
simulWord32 reg;
|
||||
cbs->x.bus.clocks = 1;
|
||||
|
||||
reg = IntCtrl->regs.aircr;
|
||||
|
||||
BusRead(&cbs->x.bus, ®);
|
||||
|
||||
if ((reg & 0xFFFF0000) == 0x05FA0000)
|
||||
{
|
||||
IntCtrl->regs.aircr = (IntCtrl->regs.aircr & ~REG_AIRCR_PRIGROUP) | (reg & REG_AIRCR_PRIGROUP);
|
||||
|
||||
IntCtrl->regs.aircr = (IntCtrl->regs.aircr & ~REG_AIRCR_SYSRESETREQ) | (reg & REG_AIRCR_SYSRESETREQ);
|
||||
|
||||
if (reg & REG_AIRCR_SYSRESETREQ)
|
||||
{
|
||||
RequestReset(processor);
|
||||
}
|
||||
|
||||
if (reg & REG_AIRCR_VECTCLRACTIVE)
|
||||
{
|
||||
//not imlemented
|
||||
//ClearActiveState();
|
||||
}
|
||||
|
||||
if (reg & REG_AIRCR_VECTRESET)
|
||||
{
|
||||
RequestReset(processor);
|
||||
}
|
||||
}
|
||||
|
||||
return SIMUL_MEMORY_OK;
|
||||
}
|
||||
|
||||
/*************** System Control Register ***************/
|
||||
|
||||
int SCR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
simulWord32 reg;
|
||||
cbs->x.bus.clocks = 1;
|
||||
|
||||
reg = (IntCtrl->regs.scr & 0x00000016);
|
||||
|
||||
return BusWrite(&cbs->x.bus, ®);
|
||||
}
|
||||
|
||||
int SCR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
simulWord32 reg = IntCtrl->regs.scr;
|
||||
|
||||
cbs->x.bus.clocks = 1;
|
||||
|
||||
BusRead(&cbs->x.bus, ®);
|
||||
|
||||
IntCtrl->regs.scr = reg & REG_SCR_MASK;
|
||||
|
||||
return SIMUL_MEMORY_OK;
|
||||
}
|
||||
|
||||
/*************** Configuration Control Register ***************/
|
||||
|
||||
int CCR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
simulWord32 reg;
|
||||
cbs->x.bus.clocks = 1;
|
||||
|
||||
reg = (IntCtrl->regs.ccr & REG_CCR_MASK);
|
||||
|
||||
return BusWrite(&cbs->x.bus, ®);
|
||||
}
|
||||
|
||||
int CCR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
simulWord32 reg = IntCtrl->regs.ccr;
|
||||
|
||||
cbs->x.bus.clocks = 1;
|
||||
|
||||
BusRead(&cbs->x.bus, ®);
|
||||
|
||||
IntCtrl->regs.ccr = reg & REG_CCR_MASK;
|
||||
|
||||
if (IntCtrl->regs.ccr & REG_CCR_USERSETMPEND)
|
||||
{
|
||||
//This bit functionality cannot be implemented - NVIC model doesn't have access to CONTROL register
|
||||
}
|
||||
|
||||
return SIMUL_MEMORY_OK;
|
||||
}
|
||||
|
||||
/*************** System Handlers x Priority Register ***************/
|
||||
|
||||
int SHPR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
int idx = (cbs->x.bus.address - IntCtrl->baseaddress - SHPR_OFFSET) >> 2;
|
||||
simulWord32 reg = 0;
|
||||
|
||||
cbs->x.bus.clocks = 1;
|
||||
|
||||
switch (idx)
|
||||
{
|
||||
case 0: /* PRI_4 -- PRI_7 */
|
||||
reg = ((IntCtrl->IrqPriority[IRQNUM_MEMFAULT] & 0xFF) << 0) | ((IntCtrl->IrqPriority[IRQNUM_BUSFAULT] & 0xFF) << 8) | ((IntCtrl->IrqPriority[IRQNUM_USAGEFAULT] & 0xFF) << 16);
|
||||
break;
|
||||
|
||||
case 1: /* PRI_8 -- PRI_11 */
|
||||
reg = ((IntCtrl->IrqPriority[IRQNUM_SVCALL] & 0xFF) << 24);
|
||||
break;
|
||||
|
||||
case 2: /* PRI_12 -- PRI_15 */
|
||||
reg = ((IntCtrl->IrqPriority[IRQNUM_DEBUG] & 0xFF) << 0) | ((IntCtrl->IrqPriority[IRQNUM_PENDSV] & 0xFF) << 16) | ((IntCtrl->IrqPriority[IRQNUM_SYSTICK] & 0xFF) << 24);
|
||||
break;
|
||||
|
||||
default:
|
||||
reg = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return BusWrite(&cbs->x.bus, ®);
|
||||
}
|
||||
|
||||
int SHPR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
int idx = (cbs->x.bus.address - IntCtrl->baseaddress - SHPR_OFFSET) >> 2;
|
||||
simulWord32 reg = 0;
|
||||
// simulWord32 regBackup;
|
||||
|
||||
cbs->x.bus.clocks = 1;
|
||||
|
||||
switch (idx)
|
||||
{
|
||||
case 0: /* PRI_4 -- PRI_7 */
|
||||
reg = ((IntCtrl->IrqPriority[IRQNUM_MEMFAULT] & 0xFF) << 0) | ((IntCtrl->IrqPriority[IRQNUM_BUSFAULT] & 0xFF) << 8) | ((IntCtrl->IrqPriority[IRQNUM_USAGEFAULT] & 0xFF) << 16);
|
||||
break;
|
||||
|
||||
case 1: /* PRI_8 -- PRI_11 */
|
||||
reg = ((IntCtrl->IrqPriority[IRQNUM_SVCALL] & 0xFF) << 24);
|
||||
break;
|
||||
|
||||
case 2: /* PRI_12 -- PRI_15 */
|
||||
reg = ((IntCtrl->IrqPriority[IRQNUM_DEBUG] & 0xFF) << 0) | ((IntCtrl->IrqPriority[IRQNUM_PENDSV] & 0xFF) << 16) | ((IntCtrl->IrqPriority[IRQNUM_SYSTICK] & 0xFF) << 24);
|
||||
break;
|
||||
|
||||
default:
|
||||
reg = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// regBackup = reg;
|
||||
BusRead(&cbs->x.bus, ®);
|
||||
|
||||
switch (idx)
|
||||
{
|
||||
case 0: /* PRI_4 -- PRI_7 */
|
||||
IntCtrl->IrqPriority[IRQNUM_MEMFAULT] = (reg >> 0) & 0xFF;
|
||||
IntCtrl->IrqPriority[IRQNUM_BUSFAULT] = (reg >> 8) & 0xFF;
|
||||
IntCtrl->IrqPriority[IRQNUM_USAGEFAULT] = (reg >> 16) & 0xFF;
|
||||
break;
|
||||
|
||||
case 1: /* PRI_8 -- PRI_11 */
|
||||
IntCtrl->IrqPriority[IRQNUM_SVCALL] = (reg >> 24) & 0xFF;
|
||||
break;
|
||||
|
||||
case 2: /* PRI_12 -- PRI_15 */
|
||||
IntCtrl->IrqPriority[IRQNUM_DEBUG] = (reg >> 0) & 0xFF;
|
||||
IntCtrl->IrqPriority[IRQNUM_PENDSV] = (reg >> 16) & 0xFF;
|
||||
IntCtrl->IrqPriority[IRQNUM_SYSTICK] = (reg >> 24) & 0xFF;
|
||||
break;
|
||||
|
||||
default:
|
||||
return SIMUL_MEMORY_OK;
|
||||
}
|
||||
|
||||
return SIMUL_MEMORY_OK;
|
||||
}
|
||||
|
||||
/*************** System Handler Control and State Register ***************/
|
||||
|
||||
int SHCSR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
|
||||
simulWord32 USGFAULTENA, BUSFAULTENA, MEMFAULTENA;
|
||||
simulWord32 SVCALLPENDED, BUSFAULTPENDED, MEMFAULTPENDED, USGFAULTPENDED;
|
||||
simulWord32 SYSTICKACT, PENDSVACT, MONITORACT, SVCALLACT, USGFAULTACT, BUSFAULTACT, MEMFAULTACT;
|
||||
|
||||
simulWord32 reg = 0;
|
||||
|
||||
cbs->x.bus.clocks = 1;
|
||||
|
||||
USGFAULTENA = IntCtrl->IrqEnable[IRQNUM_USAGEFAULT];
|
||||
BUSFAULTENA = IntCtrl->IrqEnable[IRQNUM_BUSFAULT];
|
||||
MEMFAULTENA = IntCtrl->IrqEnable[IRQNUM_MEMFAULT];
|
||||
|
||||
SVCALLPENDED = IntCtrl->IrqPending[IRQNUM_SVCALL];
|
||||
BUSFAULTPENDED = IntCtrl->IrqPending[IRQNUM_BUSFAULT];
|
||||
MEMFAULTPENDED = IntCtrl->IrqPending[IRQNUM_MEMFAULT];
|
||||
USGFAULTPENDED = IntCtrl->IrqPending[IRQNUM_USAGEFAULT];
|
||||
|
||||
SYSTICKACT = IntCtrl->IrqActive[IRQNUM_SYSTICK];
|
||||
PENDSVACT = IntCtrl->IrqActive[IRQNUM_PENDSV];
|
||||
MONITORACT = IntCtrl->IrqActive[IRQNUM_DEBUG];
|
||||
SVCALLACT = IntCtrl->IrqActive[IRQNUM_SVCALL];
|
||||
USGFAULTACT = IntCtrl->IrqActive[IRQNUM_USAGEFAULT];
|
||||
BUSFAULTACT = IntCtrl->IrqActive[IRQNUM_BUSFAULT];
|
||||
MEMFAULTACT = IntCtrl->IrqActive[IRQNUM_MEMFAULT];
|
||||
|
||||
reg =
|
||||
((USGFAULTENA)?(REG_SHCSR_USGFAULTENA):(0)) |
|
||||
((BUSFAULTENA)?(REG_SHCSR_BUSFAULTENA):(0)) |
|
||||
((MEMFAULTENA)?(REG_SHCSR_MEMFAULTENA):(0)) |
|
||||
|
||||
((SVCALLPENDED)?(REG_SHCSR_SVCALLPENDED):(0)) |
|
||||
((BUSFAULTPENDED)?(REG_SHCSR_BUSFAULTPENDED):(0)) |
|
||||
((MEMFAULTPENDED)?(REG_SHCSR_MEMFAULTPENDED):(0)) |
|
||||
((USGFAULTPENDED)?(REG_SHCSR_USGFAULTPENDED):(0)) |
|
||||
|
||||
((SYSTICKACT)?(REG_SHCSR_SYSTICKACT):(0)) |
|
||||
((PENDSVACT)?(REG_SHCSR_PENDSVACT):(0)) |
|
||||
((MONITORACT)?(REG_SHCSR_MONITORACT):(0)) |
|
||||
((SVCALLACT)?(REG_SHCSR_SVCALLACT):(0)) |
|
||||
((USGFAULTACT)?(REG_SHCSR_USGFAULTACT):(0)) |
|
||||
((BUSFAULTACT)?(REG_SHCSR_BUSFAULTACT):(0)) |
|
||||
((MEMFAULTACT)?(REG_SHCSR_MEMFAULTACT):(0));
|
||||
;
|
||||
|
||||
return BusWrite(&cbs->x.bus, ®);
|
||||
}
|
||||
|
||||
int SHCSR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
int wakeUpEvent = 0;
|
||||
|
||||
simulWord32 USGFAULTENA, BUSFAULTENA, MEMFAULTENA;
|
||||
simulWord32 SVCALLPENDED, BUSFAULTPENDED, MEMFAULTPENDED, USGFAULTPENDED;
|
||||
simulWord32 SYSTICKACT, PENDSVACT, MONITORACT, SVCALLACT, USGFAULTACT, BUSFAULTACT, MEMFAULTACT;
|
||||
|
||||
simulWord32 reg = 0;
|
||||
|
||||
cbs->x.bus.clocks = 1;
|
||||
|
||||
USGFAULTENA = IntCtrl->IrqEnable[IRQNUM_USAGEFAULT];
|
||||
BUSFAULTENA = IntCtrl->IrqEnable[IRQNUM_BUSFAULT];
|
||||
MEMFAULTENA = IntCtrl->IrqEnable[IRQNUM_MEMFAULT];
|
||||
|
||||
SVCALLPENDED = IntCtrl->IrqPending[IRQNUM_SVCALL];
|
||||
BUSFAULTPENDED = IntCtrl->IrqPending[IRQNUM_BUSFAULT];
|
||||
MEMFAULTPENDED = IntCtrl->IrqPending[IRQNUM_MEMFAULT];
|
||||
USGFAULTPENDED = IntCtrl->IrqPending[IRQNUM_USAGEFAULT];
|
||||
|
||||
SYSTICKACT = IntCtrl->IrqActive[IRQNUM_SYSTICK];
|
||||
PENDSVACT = IntCtrl->IrqActive[IRQNUM_PENDSV];
|
||||
MONITORACT = IntCtrl->IrqActive[IRQNUM_DEBUG];
|
||||
SVCALLACT = IntCtrl->IrqActive[IRQNUM_SVCALL];
|
||||
USGFAULTACT = IntCtrl->IrqActive[IRQNUM_USAGEFAULT];
|
||||
BUSFAULTACT = IntCtrl->IrqActive[IRQNUM_BUSFAULT];
|
||||
MEMFAULTACT = IntCtrl->IrqActive[IRQNUM_MEMFAULT];
|
||||
|
||||
reg =
|
||||
((USGFAULTENA)?(REG_SHCSR_USGFAULTENA):(0)) |
|
||||
((BUSFAULTENA)?(REG_SHCSR_BUSFAULTENA):(0)) |
|
||||
((MEMFAULTENA)?(REG_SHCSR_MEMFAULTENA):(0)) |
|
||||
|
||||
((SVCALLPENDED)?(REG_SHCSR_SVCALLPENDED):(0)) |
|
||||
((BUSFAULTPENDED)?(REG_SHCSR_BUSFAULTPENDED):(0)) |
|
||||
((MEMFAULTPENDED)?(REG_SHCSR_MEMFAULTPENDED):(0)) |
|
||||
((USGFAULTPENDED)?(REG_SHCSR_USGFAULTPENDED):(0)) |
|
||||
|
||||
((SYSTICKACT)?(REG_SHCSR_SYSTICKACT):(0)) |
|
||||
((PENDSVACT)?(REG_SHCSR_PENDSVACT):(0)) |
|
||||
((MONITORACT)?(REG_SHCSR_MONITORACT):(0)) |
|
||||
((SVCALLACT)?(REG_SHCSR_SVCALLACT):(0)) |
|
||||
((USGFAULTACT)?(REG_SHCSR_USGFAULTACT):(0)) |
|
||||
((BUSFAULTACT)?(REG_SHCSR_BUSFAULTACT):(0)) |
|
||||
((MEMFAULTACT)?(REG_SHCSR_MEMFAULTACT):(0));
|
||||
;
|
||||
|
||||
BusRead(&cbs->x.bus, ®);
|
||||
|
||||
ChangeEnable(IRQNUM_USAGEFAULT,reg & REG_SHCSR_USGFAULTENA);
|
||||
ChangeEnable(IRQNUM_BUSFAULT,reg & REG_SHCSR_BUSFAULTENA);
|
||||
ChangeEnable(IRQNUM_MEMFAULT,reg & REG_SHCSR_MEMFAULTENA);
|
||||
|
||||
ChangePending(IRQNUM_SVCALL, reg & REG_SHCSR_SVCALLPENDED);
|
||||
ChangePending(IRQNUM_BUSFAULT, reg & REG_SHCSR_BUSFAULTPENDED);
|
||||
ChangePending(IRQNUM_MEMFAULT, reg & REG_SHCSR_MEMFAULTPENDED);
|
||||
ChangePending(IRQNUM_USAGEFAULT,reg & REG_SHCSR_USGFAULTPENDED);
|
||||
|
||||
ChangeActive(IRQNUM_SYSTICK,reg & REG_SHCSR_SYSTICKACT);
|
||||
ChangeActive(IRQNUM_PENDSV,reg & REG_SHCSR_PENDSVACT);
|
||||
ChangeActive(IRQNUM_DEBUG,reg & REG_SHCSR_MONITORACT);
|
||||
ChangeActive(IRQNUM_SVCALL,reg & REG_SHCSR_SVCALLACT);
|
||||
ChangeActive(IRQNUM_USAGEFAULT,reg & REG_SHCSR_USGFAULTACT);
|
||||
ChangeActive(IRQNUM_BUSFAULT,reg & REG_SHCSR_BUSFAULTACT);
|
||||
ChangeActive(IRQNUM_MEMFAULT,reg & REG_SHCSR_MEMFAULTACT);
|
||||
|
||||
Interrupt(processor,IntCtrl,wakeUpEvent);
|
||||
|
||||
return SIMUL_MEMORY_OK;
|
||||
}
|
||||
|
||||
/*************** Configurable Fault Status Register ***************/
|
||||
|
||||
int CFSR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
simulWord32 reg = 0;
|
||||
|
||||
cbs->x.bus.clocks = 1;
|
||||
|
||||
reg = IntCtrl->regs.cfsr & REG_CFSR_MASK;
|
||||
|
||||
return BusWrite(&cbs->x.bus, ®);
|
||||
}
|
||||
|
||||
int CFSR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
simulWord32 reg = 0;
|
||||
|
||||
cbs->x.bus.clocks = 1;
|
||||
|
||||
BusRead(&cbs->x.bus, ®);
|
||||
|
||||
IntCtrl->regs.cfsr &= ~(reg & REG_CFSR_MASK);
|
||||
|
||||
return SIMUL_MEMORY_OK;
|
||||
}
|
||||
|
||||
/*************** Hard Fault Status Register ***************/
|
||||
|
||||
int HFSR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
simulWord32 reg = 0;
|
||||
|
||||
cbs->x.bus.clocks = 1;
|
||||
|
||||
reg = IntCtrl->regs.hfsr & REG_HFSR_MASK;
|
||||
|
||||
return BusWrite(&cbs->x.bus, ®);
|
||||
}
|
||||
|
||||
int HFSR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
simulWord32 reg = 0;
|
||||
|
||||
cbs->x.bus.clocks = 1;
|
||||
|
||||
BusRead(&cbs->x.bus, ®);
|
||||
|
||||
IntCtrl->regs.hfsr &= ~(reg & REG_HFSR_MASK);
|
||||
|
||||
return SIMUL_MEMORY_OK;
|
||||
}
|
||||
|
||||
/*************** Debug Fault Status Register ***************/
|
||||
|
||||
int DFSR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
simulWord32 reg = 0;
|
||||
|
||||
cbs->x.bus.clocks = 1;
|
||||
|
||||
reg = IntCtrl->regs.dfsr & REG_DFSR_MASK;
|
||||
|
||||
return BusWrite(&cbs->x.bus, ®);
|
||||
}
|
||||
|
||||
int DFSR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
simulWord32 reg = 0;
|
||||
|
||||
cbs->x.bus.clocks = 1;
|
||||
|
||||
BusRead(&cbs->x.bus, ®);
|
||||
|
||||
IntCtrl->regs.dfsr &= ~(reg & REG_DFSR_MASK);
|
||||
|
||||
return SIMUL_MEMORY_OK;
|
||||
}
|
||||
|
||||
/*************** Memory Manage Address Register ***************/
|
||||
|
||||
int MMAR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
cbs->x.bus.clocks = 1;
|
||||
return BusWrite(&cbs->x.bus, &IntCtrl->regs.mmar);
|
||||
}
|
||||
|
||||
int MMAR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
simulWord32 reg = IntCtrl->regs.mmar;
|
||||
|
||||
cbs->x.bus.clocks = 1;
|
||||
|
||||
BusRead(&cbs->x.bus, ®);
|
||||
|
||||
IntCtrl->regs.mmar = reg;
|
||||
|
||||
return SIMUL_MEMORY_OK;
|
||||
}
|
||||
|
||||
/*************** Bus Fault Address Register ***************/
|
||||
|
||||
int BFAR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
cbs->x.bus.clocks = 1;
|
||||
return BusWrite(&cbs->x.bus, &IntCtrl->regs.bfar);
|
||||
}
|
||||
|
||||
int BFAR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
simulWord32 reg = IntCtrl->regs.bfar;
|
||||
|
||||
cbs->x.bus.clocks = 1;
|
||||
|
||||
BusRead(&cbs->x.bus, ®);
|
||||
|
||||
IntCtrl->regs.bfar = reg;
|
||||
|
||||
return SIMUL_MEMORY_OK;
|
||||
}
|
||||
|
||||
/*************** Auxiliary Fault Status Register ***************/
|
||||
|
||||
int AFSR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
simulWord32 reg = IntCtrl->regs.afsr;
|
||||
|
||||
cbs->x.bus.clocks = 1;
|
||||
|
||||
return BusWrite(&cbs->x.bus, ®);
|
||||
}
|
||||
|
||||
int AFSR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
simulWord32 reg = 0;
|
||||
|
||||
cbs->x.bus.clocks = 1;
|
||||
|
||||
BusRead(&cbs->x.bus, ®);
|
||||
|
||||
IntCtrl->regs.afsr &= ~(reg & REG_AFSR_MASK);
|
||||
|
||||
return SIMUL_MEMORY_OK;
|
||||
}
|
||||
|
||||
/*************** Debug Halting Control and Status Register ***************/
|
||||
|
||||
int DHCSR_Read(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
simulWord32 reg = IntCtrl->regs.dhcsr;
|
||||
|
||||
cbs->x.bus.clocks = 1;
|
||||
|
||||
return BusWrite(&cbs->x.bus, ®);
|
||||
}
|
||||
|
||||
int DHCSR_Write(simulProcessor processor, simulCallbackStruct * cbs, simulPtr _private)
|
||||
{
|
||||
IntController *IntCtrl = (IntController*) _private;
|
||||
simulWord32 reg = 0;
|
||||
|
||||
cbs->x.bus.clocks = 1;
|
||||
|
||||
BusRead(&cbs->x.bus, ®);
|
||||
|
||||
IntCtrl->regs.dhcsr = reg;
|
||||
|
||||
return SIMUL_MEMORY_OK;
|
||||
}
|
||||
Reference in New Issue
Block a user