📄 xllp_suspendresume.c
字号:
void XllpOSTRestore(XLLP_OST_T *regs, XLLP_OST_T *save)
{
OSTCopy(regs, save);
}
void XllpGPIOSave(XLLP_GPIO_T *regs, XLLP_GPIO_T *save)
{
GPIOCopy(save, regs);
save->GPLR0 = regs->GPLR0;
save->GPLR1 = regs->GPLR1;
save->GPLR2 = regs->GPLR2;
save->GPLR3 = regs->GPLR3;
}
void XllpGPIORestore(XLLP_GPIO_T *regs, XLLP_GPIO_T *save)
{
GPIOCopy(regs, save);
regs->GPSR0 = save->GPLR0 & save->GPDR0;
regs->GPCR0 = ~(save->GPLR0) & save->GPDR0;
regs->GPSR1 = save->GPLR1 & save->GPDR1;
regs->GPCR1 = ~(save->GPLR1) & save->GPDR1;
regs->GPSR2 = save->GPLR2 & save->GPDR2;
regs->GPCR2 = ~(save->GPLR2) & save->GPDR2;
regs->GPSR3 = save->GPLR3 & save->GPDR3;
regs->GPCR3 = ~(save->GPLR3) & save->GPDR3;
}
#ifdef BSP_MAINSTONE
void BCRCopy(XLLP_BCR_T *dst, XLLP_BCR_T *src)
{
REG_COPY(dst, src, HLDR1, XLLP_BCR_HEXLED1_MASK);
REG_COPY(dst, src, HLDR2, XLLP_BCR_HEXLED2_MASK);
REG_COPY(dst, src, LCR, XLLP_BCR_LEDCTRL_MASK);
REG_COPY(dst, src, MISCWR1, XLLP_BCR_MISCWR1_MASK);
REG_COPY(dst, src, MISCWR2, XLLP_BCR_MISCWR2_MASK);
REG_COPY(dst, src, MISCWR3, XLLP_BCR_MISCWR3_MASK);
REG_COPY(dst, src, PIMER1, XLLP_BCR_INTMASK_ENABLE_MASK);
// Interrupt set/clear register needs to be handled specially
// REG_COPY(dst, src, PSCR1, XLLP_BCR_INTSET_CLEAR_MASK);
REG_COPY(dst, src, PCMCIAS0SCR, XLLP_BCR_PCMCIA_SCR_S0_MASK);
REG_COPY(dst, src, PCMCIAS1SCR, XLLP_BCR_PCMCIA_SCR_S1_MASK);
}
#endif
void XllpINTCSave(XLLP_INTC_T *regs, XLLP_INTC_T *save)
{
INTCCopy(save, regs);
}
void XllpINTCRestore(XLLP_INTC_T *regs, XLLP_INTC_T *save)
{
INTCCopy(regs, save);
}
void XllpIMSave(char *im, char *save, unsigned int size)
{
memcpy(save, im, size);
}
void XllpIMRestore(char *im, char *save, unsigned int size)
{
memcpy(im, save, size);
}
#ifdef BSP_MAINSTONE
void XllpBCRSave(XLLP_BCR_T *regs, XLLP_BCR_T *save)
{
BCRCopy(save, regs);
save->PSCR1 = regs->PSCR1;
}
void XllpBCRRestore(XLLP_BCR_T *regs, XLLP_BCR_T *save)
{
BCRCopy(regs, save);
}
static XLLP_BCR_T *pBCRegS = (void *)0;
static void SetHexLeds(XLLP_VUINT32_T val)
{
if (pBCRegS != (void *)0)
pBCRegS->HLDR1 = val;
}
static XLLP_UINT32_T GetHexLeds(void)
{
if (pBCRegS != (void *)0)
return(pBCRegS->HLDR1);
else
return(0);
}
static void DisableHexLeds(void)
{
if (pBCRegS != (void *)0)
pBCRegS->LCR = 0xffffffff;
}
#else
static void SetHexLeds(XLLP_VUINT32_T val) {}
static XLLP_UINT32_T GetHexLeds(void) {return(0);}
static void DisableHexLeds(void) {}
#endif
// Variables for saving pre-suspend state.
// These are static to minimize stack usage.
// Since it's hard to imagine suspending the system being a re-entrant operation, this shouldn't be a problem.
//XLLP_OST_T OSTSave;
XLLP_INTC_T INTCSave;
XLLP_GPIO_T GPIOSave;
XLLP_PWRMGR_T PWRSave;
XLLP_CLKMGR_T CLKSave;
#ifdef BSP_MAINSTONE
XLLP_BCR_T BCRSave;
#endif // BSP_MAINSTONE
XLLP_UINT32_T *pFIQ_regs;
XLLP_UINT32_T FIQ_words;
XLLP_UINT32_T *pIRQ_regs;
XLLP_UINT32_T IRQ_words;
XLLP_UINT32_T *pUND_regs;
XLLP_UINT32_T UND_words;
XLLP_UINT32_T *pABT_regs;
XLLP_UINT32_T ABT_words;
XLLP_UINT32_T *pSVC_regs;
XLLP_UINT32_T SVC_words;
XLLP_UINT32_T *pSYS_regs;
XLLP_UINT32_T SYS_words;
// area where core reg values are actually stored
unsigned long crsa[64]; // don't really need this much but allow for growth
XLLP_UINT32_T *crsa_sp;
XLLP_MEMORY_CONTROL_REGISTER_T *pMEMCRegs;
XLLP_RTC_T *pRTCRegs;
XLLP_OST_T *pOSTRegs;
XLLP_GPIO_T *pGPIORegs;
XLLP_INTC_T *pINTCRegs;
XLLP_PWRMGR_T *pPWRRegs;
XLLP_CLKMGR_T *pCLKRegs;
XLLP_I2C_T *pI2CRegs;
#ifdef BSP_MAINSTONE
XLLP_BCR_T *pBCRegs;
#endif // BSP_MAINSTONE
RESTART_DATA_T *pRestartData;
RESUMEPHASE2_DATA_T *pResumePhase2Data;
XLLP_UINT32_T ResumePhase2DataPA;
XLLP_UINT32_T entry_CPSR;
XLLP_UINT32_T entry_SPSR;
XLLP_UINT32_T entry_SP; // used only for debugging
XLLP_UINT32_T entry_OSCR0;
XLLP_UINT32_T entry_OSMR0;
XLLP_UINT32_T entry_OIER;
XLLP_UINT32_T entry_hexleds;
XLLP_UINT32_T resume_PWR_PEDR;
XLLP_UINT32_T resume_PWR_PKSR;
XLLP_UINT32_T resume_FPGA_ISCR; // INT SET/CLEAR
XLLP_UINT32_T resume_FPGA_IER; // INT ENABLE
unsigned long Xllp_SuspendAndResume(XLLP_SR_OSD_ADDRESSES_T *pOSDAddr)
{
// This routine is called from a priveledged mode (eg. SVC, SYS).
// Stack space is therefore limited.
// Since this routine does/should not need to be re-entrant most variables are static.
entry_CPSR = Xllp_Get_ARM_CPSR();
// Make sure all interrupts are disabled
Xllp_Set_ARM_CPSR(entry_CPSR | (XLLP_CPSR_I_bit | XLLP_CPSR_F_bit));
entry_SPSR = Xllp_Get_ARM_SPSR();
entry_SP = Xllp_Get_ARM_SP(); // This is only for debugging
// Get OS dependent addresses passed in
pMEMCRegs = (XLLP_MEMORY_CONTROL_REGISTER_T *)pOSDAddr->pMEMCRegs;
pRTCRegs = (XLLP_RTC_T *)pOSDAddr->pRTCRegs;
pOSTRegs = (XLLP_OST_T *)pOSDAddr->pOSTRegs;
pGPIORegs = (XLLP_GPIO_T *)pOSDAddr->pGPIORegs;
pINTCRegs = (XLLP_INTC_T *)pOSDAddr->pINTCRegs;
pPWRRegs = (XLLP_PWRMGR_T *)pOSDAddr->pPWRRegs;
pCLKRegs = (XLLP_CLKMGR_T *)pOSDAddr->pCLKRegs;
pI2CRegs = (XLLP_I2C_T *)pOSDAddr->pI2CRegs;
#ifdef BSP_MAINSTONE
pBCRegs = (XLLP_BCR_T *)pOSDAddr->pBCRegs;
#endif // BSP_MAINSTONE
pRestartData = (RESTART_DATA_T *)pOSDAddr->pRestartData;
pResumePhase2Data = (RESUMEPHASE2_DATA_T *)&(pRestartData->RESUME_DATA[0]);
ResumePhase2DataPA = (XLLP_UINT32_T)&(((RESTART_DATA_T *)(pOSDAddr->RestartDataPA))->RESUME_DATA[0]);
#ifdef BSP_MAINSTONE
pBCRegS = pBCRegs; // local static copy for HexLed functions
#endif // BSP_MAINSTONE
entry_hexleds = GetHexLeds();
SetHexLeds(0xce050000);
// How OST registers should be handled across suspend/resume is in doubt.
// In general, it seems pointless to restore them to their pre-suspend state.
// This will probably be OS dependent.
// Currently...
// WinCE seems to only use OSCR0 and seems to require an interrupt be generated on wakeup.
entry_OSCR0 = pOSTRegs->oscr0;
entry_OSMR0 = pOSTRegs->osmr0;
entry_OIER = pOSTRegs->oier;
#ifdef BSP_MAINSTONE
DBGMSG(("Xllp_SuspendResume: BSP_MAINSTONE defined\r\n"));
#else
DBGMSG(("Xllp_SuspendResume: BSP_MAINSTONE not defined\r\n"));
#endif
DBGMSG(("Xllp_SuspendResume: Entry: CPSR==x%08x, SPSR=x%08x, SP=x%08x, pBCRegS=x%08x\r\n",
entry_CPSR, entry_SPSR, entry_SP, pBCRegS));
DBGMSG(("Xllp_SuspendResume: Entry: RCNR=x%08x, RTAR=x%08x, RTSR=x%08x, PICR=x%08x\r\n",
pRTCRegs->rcnr, pRTCRegs->rtar, pRTCRegs->rtsr, pRTCRegs->picr));
DBGMSG(("Xllp_SuspendResume: Entry: RYAR1=x%08x, RDAR1=x%08x\r\n",
pRTCRegs->ryar1, pRTCRegs->rdar1));
DBGMSG(("Xllp_SuspendResume: Entry: OSCR0=x%08x, OSMR0=x%08x, OIER=x%08x\r\n",
pOSTRegs->oscr0, pOSTRegs->osmr0, pOSTRegs->oier));
DBGMSG(("Xllp_SuspendResume: Entry: OSMR0=x%08x, OSMR1=x%08x, OSMR2=x%08x, OSMR3=x%08x\r\n",
pOSTRegs->osmr0, pOSTRegs->osmr1, pOSTRegs->osmr2, pOSTRegs->osmr3));
DBGMSG(("Xllp_SuspendResume: Entry: OSMR4=x%08x, OSMR5=x%08x, OSMR6=x%08x, OSMR7=x%08x\r\n",
pOSTRegs->osmr4, pOSTRegs->osmr5, pOSTRegs->osmr6, pOSTRegs->osmr7));
DBGMSG(("Xllp_SuspendResume: Entry: OSMR8=x%08x, OSMR9=x%08x, OSMR10=x%08x, OSMR11=x%08x\r\n",
pOSTRegs->osmr8, pOSTRegs->osmr9, pOSTRegs->osmr10, pOSTRegs->osmr11));
DBGMSG(("Xllp_SuspendResume: Entry: ResumePhase2Data @ x%08x->x%08x\r\n",
pResumePhase2Data, ResumePhase2DataPA));
DBGMSG(("Xllp_SuspendResume: Entry: ICPR=x%08x, ICMR=x%08x\r\n",
pINTCRegs->icpr, pINTCRegs->icmr));
#ifdef BSP_MAINSTONE
DBGMSG(("Xllp_SuspendResume: Entry: IMER=x%08x, ISCR=x%08x\r\n",
pBCRegs->PIMER1, pBCRegs->PSCR1));
#endif // BSP_MAINSTONE
XllpPWRSave(pOSDAddr->pPWRRegs, &PWRSave);
XllpGPIOSave(pOSDAddr->pGPIORegs, &GPIOSave);
XllpINTCSave(pOSDAddr->pINTCRegs, &INTCSave);
XllpCLKSave(pOSDAddr->pCLKRegs, &CLKSave);
#ifdef BSP_MAINSTONE
XllpBCRSave(pOSDAddr->pBCRegs, &BCRSave);
#endif // BSP_MAINSTONE
// Save CPU core registers
//DBGMSG(("Xllp_SuspendResume: Saving mode specific core registers\r\n"));
crsa_sp = &(crsa[DIMENSION(crsa)-1]);
pFIQ_regs = Xllp_SaveMSARMRegs(crsa_sp, XLLP_CPSR_Mode_FIQ);
FIQ_words = (crsa_sp - pFIQ_regs);
//DBGMSG(("Xllp_SuspendResume: FIQ(x%x) saved: x%08x-x%08x, (%d)\r\n",
// XLLP_CPSR_Mode_FIQ, crsa_sp, pFIQ_regs, FIQ_words));
crsa_sp = pFIQ_regs;
pIRQ_regs = Xllp_SaveMSARMRegs(crsa_sp, XLLP_CPSR_Mode_IRQ);
IRQ_words = (crsa_sp - pIRQ_regs);
//DBGMSG(("Xllp_SuspendResume: IRQ(x%x) saved: x%08x-x%08x, (%d)\r\n",
// XLLP_CPSR_Mode_IRQ, crsa_sp, pIRQ_regs, IRQ_words));
crsa_sp = pIRQ_regs;
pUND_regs = Xllp_SaveMSARMRegs(crsa_sp, XLLP_CPSR_Mode_UND);
UND_words = (crsa_sp - pUND_regs);
//DBGMSG(("Xllp_SuspendResume: UND(x%x) saved: x%08x-x%08x, (%d)\r\n",
// XLLP_CPSR_Mode_UND, crsa_sp, pUND_regs, UND_words));
crsa_sp = pUND_regs;
pABT_regs = Xllp_SaveMSARMRegs(crsa_sp, XLLP_CPSR_Mode_ABT);
ABT_words = (crsa_sp - pABT_regs);
//DBGMSG(("Xllp_SuspendResume: ABT(x%x) saved: x%08x-x%08x, (%d)\r\n",
// XLLP_CPSR_Mode_ABT, crsa_sp, pABT_regs, ABT_words));
crsa_sp = pABT_regs;
pSVC_regs = Xllp_SaveMSARMRegs(crsa_sp, XLLP_CPSR_Mode_SVC);
SVC_words = (crsa_sp - pSVC_regs);
//DBGMSG(("Xllp_SuspendResume: SVC(x%x) saved: x%08x-x%08x, (%d)\r\n",
// XLLP_CPSR_Mode_SVC, crsa_sp, pSVC_regs, SVC_words));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -