⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xllp_suspendresume.c

📁 Intel PXA270底层设备驱动代码
💻 C
📖 第 1 页 / 共 3 页
字号:
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 + -