📄 oemwake.c
字号:
/*
* The content of this file or document is CONFIDENTIAL and PROPRIETARY
* to Jade Technologies Co., Ltd. It is subjected to the terms of a
* License Agreement between Licensee and Jade Technologies Co., Ltd.
* restricting among other things, the use, reproduction, distribution
* and transfer. Each of the embodiments, including this information
* and any derivative work shall retain this copyright notice.
*
* Copyright (c) 2004 - 2005 Jade Technologies Co., Ltd.
* All rights reserved.
* ----------------------------------------------------------------
* File: oemwake.c,v
* Revision: 1.
* ----------------------------------------------------------------
* $
*/
//
// Power off/Suspend routines
//
#include <windows.h>
#include <nkintr.h>
#include <oalintr.h>
#include <oemwake.h>
#include <bldver.h>
#include <platform.h>
#include <board.h>
#include <pl190.h>
#include <oalfuncs.h>
//#include <apcharlcd.h>
#include <dma.h>
#include "dmakern.h"
extern CRITICAL_SECTION csWakeIntMask;
// What devices can wake us up - sysintr array and a physical IRQ enable mask
static BYTE fInterruptWakeupMask[SYSINTR_MAXIMUM];
// What device actually woke us up
static BYTE fInterruptWakeup[SYSINTR_MAXIMUM];
static DWORD dwLastWakeupSource = SYSWAKE_UNKNOWN;
DWORD OEMPowerManagerInit(void)
{
memset(fInterruptWakeup,0,SYSINTR_MAXIMUM);
memset(fInterruptWakeupMask,0,SYSINTR_MAXIMUM);
// Setting of any default wakeup devices (e.g. Keyboard and mouse) should be done
// via their relevent drivers using the IOCTL_HAL_ENABLE_WAKE kernel message.
// If this is not possible, then default set-up could be done here, but do not use
// the OEMSetWakeupSource() function as the critical section is not yet
// initialised.
return 0;
}
DWORD OEMSetWakeupSource(DWORD dwSysIntr)
{
DWORD physInt = OEMTranslateSysIntr(dwSysIntr);
if (physInt != LOGINTR_UNDEFINED) {
EnterCriticalSection(&csWakeIntMask);
fInterruptWakeupMask[dwSysIntr] = 1;
LeaveCriticalSection(&csWakeIntMask);
return 1;
}
return 0;
}
DWORD OEMResetWakeupSource(DWORD dwSysIntr)
{
DWORD physInt = OEMTranslateSysIntr(dwSysIntr);
if (physInt != LOGINTR_UNDEFINED) {
EnterCriticalSection(&csWakeIntMask);
fInterruptWakeupMask[dwSysIntr] = 0;
LeaveCriticalSection(&csWakeIntMask);
return 1;
}
return 0;
}
void OEMIndicateIntSource(DWORD dwSysIntr)
{
if (dwSysIntr < SYSINTR_MAXIMUM )
{
fInterruptWakeup[dwSysIntr] = 1;
}
}
DWORD OEMGetWakeupSource(void)
{
return dwLastWakeupSource;
}
DWORD OEMFindFirstWakeSource()
{
DWORD dwCount;
DWORD dwWake = SYSWAKE_UNKNOWN;
for (dwCount = 0; dwCount < SYSINTR_MAXIMUM; dwCount++)
{
if (fInterruptWakeup[dwCount] && fInterruptWakeupMask[dwCount])
{
dwWake = dwCount;
break;
}
}
return dwWake;
}
void OEMClearIntSources()
{
memset(fInterruptWakeup,0,SYSINTR_MAXIMUM);
}
VOID OEMPowerOff(void)
{
#if 0//为防止软关机之前,该函数把所有中断关闭,故屏蔽 qzsu 2006-11-4
volatile DWORD ulOldIntMask = 0;
pvstVICRegs pVic = (pvstVICRegs)VA_VIC_BASE;
DWORD irq, dwWake;
/* Disable interrupts at the core */
INTERRUPTS_OFF();
/* Save current interrupt mask. */
ulOldIntMask = pVic->IntEnable;
/* Clear ALL enabled interrupts */
pVic->IntEnClear = 0xffffffff;
/* Clear any pending interrupts that may be around in the vector address
* register. Actual values are unimportant, the read/write actions clears
* the next pending interrupt
*/
for (irq = 0; irq < VIC_NUM_VECTIRQ_LINES; irq++)
{
pVic->VectAddr = pVic->VectAddr + 1;
}
/* We read/write once more to cover any non-vectored interrupts */
pVic->VectAddr = pVic->VectAddr + 1;
/* Wake on an RTC event and anything in the wake event mask
* NOTE: We use pHALir_EnableIrq() as the IRQ mappings need translating
* but if an invalid Irq is set a debug message will be produced
* possibly hanging this power down code.
*/
pHALir_EnableIrq( LOGINTR_RTC );
for( irq = 0; irq < SYSINTR_MAXIMUM; irq++ )
{
if( fInterruptWakeupMask[irq] )
{
pHALir_EnableIrq( OEMTranslateSysIntr(irq) );
}
}
// apCHARLCD_PrintXY( 0, 0, "-Standby-" );
do
{
/* Enable interrupts at the core */
INTERRUPTS_ON();
#ifdef EXAMPLE_POWERDOWN
/* Branch to assembly-based code in fw_utils.s */
ARM_PowerOff();
#else
/* Currently just enter idle until interrupt */
CPUEnterIdle(0);
#endif
/* Disable interrupts at the core */
INTERRUPTS_OFF();
dwWake = OEMFindFirstWakeSource();
} while( dwWake == SYSWAKE_UNKNOWN );
dwLastWakeupSource = dwWake;
// apCHARLCD_PrintXY( 0, 0, " " );
/* Clear ALL enabled interrupts */
pVic->IntEnClear = 0xffffffff;
/*/ Restore the original interupt mask. */
pVic->IntEnable = ulOldIntMask;
/* Enable interrupts at the core */
INTERRUPTS_ON();
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -