📄 idle.c
字号:
// because dwPartialCurMSec will be modified in the next function call.
//
CPUGetSysTimerCountElapsed(RESCHED_PERIOD, pCurMSec, &dwPartialCurMSec, pCurTicks);
if ((int) (dwIdleMSec -= *pCurMSec - dwPrevMSec) > 0) {
dwPrevMSec = *pCurMSec;
//
// The system timer may not be capable of arbitrary timeouts. Get the
// CPU-specific highest possible timeout available.
//
dwIdleMSec = CPUGetSysTimerCountMax(dwIdleMSec);
//
// Set the timer to wake up much later than usual, if needed.
//
CPUSetSysTimerCount(dwIdleMSec);
CPUClearSysTimerIRQ( );
//
// Enable wakeup on any interrupt, then go to sleep.
//
CPUEnterIdle(dwIdleParam);
INTERRUPTS_OFF( );
//
// We're awake! The wake-up ISR (or any other ISR) has already run.
//
if (dwPrevMSec != *pCurMSec) {
//
// We completed the full period we asked to sleep. Update the counters.
//
*pCurMSec += (dwIdleMSec - RESCHED_PERIOD); // Subtract resched period, because ISR also incremented.
CurTicks.QuadPart += (dwIdleMSec - RESCHED_PERIOD) * dwReschedIncrement;
currIdle.QuadPart += dwIdleMSec;
} else {
//
// Some other interrupt woke us up before the full idle period was
// complete. Determine how much time has elapsed.
//
currIdle.QuadPart += CPUGetSysTimerCountElapsed(dwIdleMSec, pCurMSec, &dwPartialCurMSec, pCurTicks);
}
}
// Re-arm counters
CPUSetSysTimerCount(RESCHED_PERIOD);
CPUClearSysTimerIRQ( );
// Update global idle time
curridlelow = currIdle.LowPart;
curridlehigh = currIdle.HighPart;
return;
}
#endif // CE_MAJOR_VER == 0x0003
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//
// SC_GetTickCount must take into account the partials to reflect where we really
// are in time AND IT SHOULD NOT MODIFY ANY OF THE GLOBALS.
//
DWORD SC_GetTickCount(void)
{
#if (CE_MAJOR_VER == 0x0003)
return *pCurMSec;
#else
DWORD dwInc = 0, dwPartial = dwPartialCurMSec, dwPrev = *pCurMSec;
ULARGE_INTEGER cdummy = {0, 0};
CPUGetSysTimerCountElapsed(RESCHED_PERIOD, &dwInc, &dwPartial, &cdummy);
return (dwPrev == *pCurMSec)? dwPrev + dwInc : *pCurMSec;
#endif
}
//****************************************************************************
// OEMPowerOff
//****************************************************************************
// Power management stuff.
//
//
VOID OEMPowerOff(void)
{
volatile ULONG ulTemp;
ULONG ulCscPwrCnt, ulCscDevCfg;
//
// Print out the current clock rates to the debug port.
//
NKDbgPrintfW( L"OEMPowerOff\r\n" );
INTERRUPTS_OFF();
//
// Replace the interrupt mask with the wake event interrupt mask. These
// will be the only interrupts that can wake us from suspend.
//
*VIC1_INTCLEAR = 0xFFFFFFFF;
*VIC2_INTCLEAR = 0xFFFFFFFF;
*VIC1_INTENABLE = gdwInterruptWakeMask1 | INT1_TIMER1;
*VIC2_INTENABLE = gdwInterruptWakeMask2;
//
// Check to see if there is a kitl connection. If so then
// keep the clocks on.
//
if(!gulCS8950KitlUsed)
{
//
// Power down the system clocks here.
//
ulCscPwrCnt = *CSC_PWRCNT;
ulCscDevCfg = *CSC_DEVCFG;
//
// Power down the clocks as much as possible.
//
*CSC_SYSLOCK = 0xAA;
*CSC_PWRCNT = 0;
*CSC_SYSLOCK = 0xAA;
*CSC_DEVCFG = (ulCscDevCfg &
~(DEVCFG_KEYS | DEVCFG_ADCPD | DEVCFG_RAS |
DEVCFG_TIN | DEVCFG_U1EN | DEVCFG_U2EN |
DEVCFG_U3EN)) | DEVCFG_SHENA;
*CSC_SYSLOCK = 0xAA;
*CSC_CLKSET2 = CLKSET2_VALUE & ~( CLKSET2_PLL2_EN | CLKSET2_PLL2_NBYP);
*SDRAM_REFRESH = SDRAM_14MHZ_REFRESH_VALUE;
*CSC_SYSLOCK = 0xAA;
*CSC_CLKSET1 = CLKSET1_VALUE & ~CLKSET1_PLL1_NBYP;
//
// Flush the pipeline.
//
__emit(0xe1a00000);
__emit(0xe1a00000);
__emit(0xe1a00000);
__emit(0xe1a00000);
__emit(0xe1a00000);
__emit(0xe1a00000);
}
gfResumeFlag = FALSE;
INTERRUPTS_ON();
dwTimeValueWhenSuspend=*TIM_DEBUGVALUELOW;
while(!gfResumeFlag)
{
if(gulCS8950KitlUsed)
{
CPUEnterIdle(0);
}
else
{
ulTemp = *CSC_HALT;
}
}
INTERRUPTS_OFF();
//
// Check to see if there is a kitl connection. If so then
// keep the clocks on.
//
if(!gulCS8950KitlUsed)
{
//
// Power down the system clocks here.
//
*CSC_SYSLOCK = 0xAA;
*CSC_CLKSET1 = CLKSET1_VALUE;
//
// Flush the pipeline.
//
__emit(0xe1a00000);
__emit(0xe1a00000);
__emit(0xe1a00000);
__emit(0xe1a00000);
__emit(0xe1a00000);
__emit(0xe1a00000);
*SDRAM_REFRESH = SDRAM_REFRESH_VALUE;
*CSC_SYSLOCK = 0xAA;
*CSC_CLKSET2 = CLKSET2_VALUE;
*CSC_SYSLOCK = 0xAA;
*CSC_DEVCFG = ulCscDevCfg;
*CSC_SYSLOCK = 0xAA;
*CSC_PWRCNT = ulCscPwrCnt;
}
//
// Restore the original interupt mask.
//
*VIC1_INTCLEAR = 0xFFFFFFFF;
*VIC2_INTCLEAR = 0xFFFFFFFF;
*VIC1_INTENABLE = gdwInterruptMask1 | INT1_TIMER1;
*VIC2_INTENABLE = gdwInterruptMask2;
INTERRUPTS_ON();
}
//****************************************************************************
// OEMPowerManagerInit
//****************************************************************************
// Power Managment Initialization routine.
//
//
DWORD OEMPowerManagerInit(void)
{
int ulInt;
for(ulInt = 0; ulInt < SYSINTR_MAXIMUM ; ulInt++)
{
gfSysIntrWakeupMask[ ulInt ] = 0;
}
//
// Clear the interrupt wake mask
//
gdwInterruptWakeMask1 = 0 ;
gdwInterruptWakeMask2 = 0 ;
return 1;
}
//****************************************************************************
// OEMSetWakeupSource
//****************************************************************************
// This sets the source for the wakeup interrupt.
//
//
DWORD OEMSetWakeupSource( DWORD dwSources)
{
DWORD dwIntMask1, dwIntMask2;
NKDbgPrintfW( L"OEMSetWakeupSource dwSource = 0x%x\r\n",dwSources );
if(dwSources <SYSINTR_MAXIMUM)
{
//
// OEMTranslateSysIntr currently returns the passed value.
//
// DWORD dwPhysInt = OEMTranslateSysIntr(dwSources);
gfSysIntrWakeupMask[dwSources] = 1;
SysIntrNumToInterruptMask(dwSources, &dwIntMask1, &dwIntMask2);
gdwInterruptWakeMask1 |= dwIntMask1;
gdwInterruptWakeMask2 |= dwIntMask2;
return 1;
}
return 0;
}
//****************************************************************************
// OEMResetWakeupSource
//****************************************************************************
// This clears the specified wakeup interrupt.
//
//
DWORD OEMResetWakeupSource( DWORD dwSources)
{
DWORD dwIntMask1, dwIntMask2;
NKDbgPrintfW( L"OEMResetWakeupSource dwSource = 0x%x\r\n",dwSources );
if(dwSources < SYSINTR_MAXIMUM)
{
//
// OEMTranslateSysIntr just returns the passed value.
//
//DWORD physInt = OEMTranslateSysIntr(dwSources);
gfSysIntrWakeupMask[dwSources] = 0;
SysIntrNumToInterruptMask(dwSources, &dwIntMask1, &dwIntMask2);
gdwInterruptWakeMask1 &= ~dwIntMask1;
gdwInterruptWakeMask2 &= ~dwIntMask2;
return 1;
}
return 0;
}
//****************************************************************************
// OEMClearIntSources
//****************************************************************************
// I am going to assume there is only one interrupt in the queue
// when the system wakes up from an interrupt.
//
//
void OEMClearIntSources( )
{
NKDbgPrintfW( L"OEMClearIntSources.\r\n");
gfResumeFlag = FALSE;
}
//****************************************************************************
// OEMGetWakeupSource
//****************************************************************************
// Gets the last interrupt that woke up the system.
//
//
DWORD OEMGetWakeupSource(void)
{
NKDbgPrintfW( L"OEMGetWakeupSource.\r\n");
return gdwLastWakeupSource;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -