📄 xllp_pm_sleepcontext.c
字号:
// Finish off the data storage that didn't need assembler
// and place the checksum.
XllpPmSleepCLevelSaveCksm (pSleepDataArea);
// Call OS-specific late suspend function
if (pSleepParam->pOsSuspendOptionalFn)
{
(*pSleepParam->pOsSuspendOptionalFn)();
}
#if 0
// Not needed for Bulverde.
// Mask off the interrupts (must do as well as setting I+F bits in CPSR)
pIntcRegs->icmr = XLLP_ICMRx_DISABLE_ALL;
#endif
#if 0
// For Bvd B0, don't need to explicitly disable CKENs.
// Set CKEN as specified (all disabled is lowest power, but can't kill memory clocks or OST? (not prob. for B0?)
pClkRegs->cken = ((pSleepParam->CKEN_vals & pSleepParam->CKEN_msk) |
(pClkRegs->cken & ~pSleepParam->CKEN_msk))
& XLLP_CLKEN_MASK;
#endif
//
// Set other sleep state and wake configuration in PCFR and PSLR
pPwrMgrRegs->PCFR = (pSleepParam->PCFR_vals & pSleepParam->PCFR_msk) |
(pPwrMgrRegs->PCFR & ~pSleepParam->PCFR_msk);
dummyRegReadTarget = pPwrMgrRegs->PCFR ;
pPwrMgrRegs->PSLR = (pSleepParam->PSLR_vals & pSleepParam->PSLR_msk) |
(pPwrMgrRegs->PSLR & ~pSleepParam->PSLR_msk);
dummyRegReadTarget = pPwrMgrRegs->PSLR ;
// Make sure that the startup code can find the context.
pPwrMgrRegs->PSPR = pSleepParam->SleepDataAreaPA;
dummyRegReadTarget = pPwrMgrRegs->PSPR ;
#ifdef RECORD_TIME
// Record sleep end time
*(pSleepParam->Addr_EndSleepTime) = *(pSleepParam->OSCR_Addr);
#endif
// Drain all buffers, flush all caches, etc. Must use OS-defined functions.
// Surveys indicate that each OS has unique flushing approaches.
// Must wait until after last time record. Necessary although
// it slightly underreports execution time for context save.
(*pSleepParam->pOsSpecificFlushFn)();
} // XllpPmSleepCLevelProcessing()
// Call after all other data are saved. Will perform checksum at the end.
void XllpPmSleepCLevelSaveCksm (P_XLLP_PM_SLEEP_SAVE_DATA_T pSleepSaveArea)
{
// (total number of 32-bit words stored, excluding only checksum))
pSleepSaveArea->SleepAreaWordCount =
(sizeof(XLLP_PM_SLEEP_SAVE_DATA_T)/4) // Checksum is done on 4-byte words
- 1 // Don't include the checksum itself.
// Add in optional extended checksummed word count.
+ pSleepSaveArea->extendedChecksumWordCount;
pSleepSaveArea->AwakeAddr = XllpPmRestoreAfterSleep;
XllpPmSaveAllRegLists (pSleepSaveArea);
//
// Internal memory banks are copied to SDRAM.
//
if (pSleepSaveArea->StoreAddrForIntlMem_0)
{
memcpy (pSleepSaveArea->StoreAddrForIntlMem_0, pSleepSaveArea->IntlMemVA_0, XLLP_IM_BANK_SIZE);
}
if (pSleepSaveArea->StoreAddrForIntlMem_1)
{
memcpy (pSleepSaveArea->StoreAddrForIntlMem_1, pSleepSaveArea->IntlMemVA_1, XLLP_IM_BANK_SIZE);
}
if (pSleepSaveArea->StoreAddrForIntlMem_2)
{
memcpy (pSleepSaveArea->StoreAddrForIntlMem_2, pSleepSaveArea->IntlMemVA_2, XLLP_IM_BANK_SIZE);
}
if (pSleepSaveArea->StoreAddrForIntlMem_3)
{
memcpy (pSleepSaveArea->StoreAddrForIntlMem_3, pSleepSaveArea->IntlMemVA_3, XLLP_IM_BANK_SIZE);
}
// Now, set the checksum to validate data at wakeup
// Must be done after all data saved.
pSleepSaveArea->checksum = XllpPmChecksumSleepDataVi
(&pSleepSaveArea->SleepAreaWordCount,
pSleepSaveArea->SleepAreaWordCount);
} // XllpPmSleepCLevelSave()
//
// Saves the values from all addresses in the list to the pointed-to storage area,
// after applying the associated masks.
//
// Inputs:
//
void XllpPmSaveRegsInList ( P_XLLP_PM_ADDR_WITH_MASK_T pRegList,
int count,
P_XLLP_VUINT32_T pulStorage)
{
while ( count--)
{
*pulStorage++ = *(pRegList->regAddr) & pRegList->mask;
pRegList++;
}
} // XllpPmSaveRegsInList()
//
// Restores the values to all addresses in the list, from the the
// pointed-to storage area. It is assumed that the bit-validity
// masks were applied before initial storage.
//
// Inputs:
//
void XllpPmRestoreRegsInList ( P_XLLP_PM_ADDR_WITH_MASK_T pRegList,
int count,
P_XLLP_VUINT32_T pulStorage)
{
while ( count--)
{
*(pRegList->regAddr) = *pulStorage++ ;
pRegList++;
}
} // XllpPmSaveRegsInList()
void XllpPmSaveAllRegLists (P_XLLP_PM_SLEEP_SAVE_DATA_T pDataSaveArea)
{
//#if 0
// Exclude for test
// First, store registers from standard list
XllpPmSaveRegsInList ( &XllpPmSleepStdRegList[0],
XLLP_PM_SLEEP_STD_REGLIST_CNT,
&pDataSaveArea->StandardRegListStore[0]);
//#endif
// Then, if any, store registers from deep sleep list
#if XLLP_PM_SLEEP_DEEP_REGLIST_CNT
XllpPmSaveRegsInList ( &XllpPmSleepDeepRegList[0],
sizeof (XllpPmSleepDeepRegList) /XLLP_PM_ADDR_WITH_MASK_T,
/*XLLP_PM_SLEEP_DEEP_REGLIST_CNT,*/
&pDataSaveArea->DeepSleepRegListStore[0]);
#endif // XLLP_PM_SLEEP_DEEP_REGLIST_CNT
// Then, if any, store registers from optional list
XllpPmSaveRegsInList ( pDataSaveArea->pOptionalRegList,
pDataSaveArea->privateRegListCount,
pDataSaveArea->pPrivateRegListStorage);
// Also call special coprocessor save function here.
#ifdef USING_COPROCSUPPORT
// XllpStoreWmxRegs()
// Current name in WinCE space:
BVDStoreAllCoProcRegs(&pDataSaveArea->IWMMXTRegs[0]);
#endif // def USING_COPROCSUPPORT
} // XllpPmSaveAllRegLists()
void XllpPmRestoreAllRegLists (P_XLLP_PM_SLEEP_SAVE_DATA_T pDataSaveArea)
{
// First, restore registers from standard list
XllpPmRestoreRegsInList ( &XllpPmSleepStdRegList[0],
sizeof (XllpPmSleepStdRegList) /sizeof (XllpPmSleepStdRegList[0]),
/*XLLP_PM_SLEEP_STD_REGLIST_CNT,*/
&pDataSaveArea->StandardRegListStore[0]);
// Then, if any, restore registers from deep sleep list
#if XLLP_PM_SLEEP_DEEP_REGLIST_CNT
XllpPmRestoreRegsInList ( &XllpPmSleepDeepRegList[0],
sizeof (XllpPmSleepDeepRegList) /XLLP_PM_ADDR_WITH_MASK_T,
/*XLLP_PM_SLEEP_DEEP_REGLIST_CNT,*/
&pDataSaveArea->DeepSleepRegListStore[0]);
#endif // XLLP_PM_SLEEP_DEEP_REGLIST_CNT
// Then, if any, restore registers from optional list
XllpPmRestoreRegsInList ( pDataSaveArea->pOptionalRegList,
pDataSaveArea->privateRegListCount,
pDataSaveArea->pPrivateRegListStorage);
// Also call special coprocessor restore function here.
#ifdef USING_COPROCSUPPORT
// XllpRestoreWmxRegs()
// Current name in WinCE space:
BVDRestoreAllCoProcRegs(&pDataSaveArea->IWMMXTRegs[0]);
#endif //def USING_COPROCSUPPORT
} // XllpPmRestoreAllRegLists()
void XllpPmRestoreIM(P_XLLP_PM_SLEEP_SAVE_DATA_T pSleepSaveArea)
{
// Restore IM control
*pSleepSaveArea->impmcr_va = pSleepSaveArea->impmcr;
//
// Internal memory banks are copied from SDRAM.
//
if (pSleepSaveArea->StoreAddrForIntlMem_0)
{
memcpy (pSleepSaveArea->IntlMemVA_0, pSleepSaveArea->StoreAddrForIntlMem_0, XLLP_IM_BANK_SIZE);
}
if (pSleepSaveArea->StoreAddrForIntlMem_1)
{
memcpy (pSleepSaveArea->IntlMemVA_1, pSleepSaveArea->StoreAddrForIntlMem_1, XLLP_IM_BANK_SIZE);
}
if (pSleepSaveArea->StoreAddrForIntlMem_2)
{
memcpy (pSleepSaveArea->IntlMemVA_2, pSleepSaveArea->StoreAddrForIntlMem_2, XLLP_IM_BANK_SIZE);
}
if (pSleepSaveArea->StoreAddrForIntlMem_3)
{
memcpy (pSleepSaveArea->IntlMemVA_3, pSleepSaveArea->StoreAddrForIntlMem_3, XLLP_IM_BANK_SIZE);
}
} // XllpPmRestoreIM ()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -