📄 pwrbuttonpdd.c
字号:
/*
** INTEL CONFIDENTIAL
** Copyright 2000-2003 Intel Corporation All Rights Reserved.
**
** The source code contained or described herein and all documents
** related to the source code (Material) are owned by Intel Corporation
** or its suppliers or licensors. Title to the Material remains with
** Intel Corporation or its suppliers and licensors. The Material contains
** trade secrets and proprietary and confidential information of Intel
** or its suppliers and licensors. The Material is protected by worldwide
** copyright and trade secret laws and treaty provisions. No part of the
** Material may be used, copied, reproduced, modified, published, uploaded,
** posted, transmitted, distributed, or disclosed in any way without Intel抯
** prior express written permission.
**
** No license under any patent, copyright, trade secret or other intellectual
** property right is granted to or conferred upon you by disclosure or
** delivery of the Materials, either expressly, by implication, inducement,
** estoppel or otherwise. Any license under such intellectual property rights
** must be express and approved by Intel in writing.
Module Name:
PwrButton.cpp
Abstract:
Implementation of the WinCE off button IST device driver.
Functions:
PwrButton_InitializeDriver
PwrButtonIntrThread
PwrButton_PowerHandler
Notes:
*/
#include <windows.h>
#include <memory.h>
#include <nkintr.h>
#include "bvd1.h"
#include "bvd1bd.h"
#include "drv_glob.h"
#include "oalintr.h"
#include "PwrButtonpdd.h"
#include "bcr.h"
#include "wait.h"
#include "pmgr.h"
#include "dbgTrace.h"
#ifndef TEST_SR_AUTO_REPEAT
// #define TEST_SR_AUTO_REPEAT
#endif
// Support IOCTL_HAL_REBOOT here for now. HW support is unavailable
// and OEMIoctl.c doesn't link with (Gwes)PowerOffSystem()
//#define SUPPORTING_IOCTL_HAL_REBOOT
#ifdef SUPPORTING_IOCTL_HAL_REBOOT
#define PWR_WAIT_DELAY 250 // Check 4 times per second
#else
#define PWR_WAIT_DELAY INFINITE
#endif
extern PVOID VirtualAllocCopy(unsigned size,char *str,PVOID pVirtualAddress);
const DWORD gIntrPwrButton = SYSINTR_POWER;
#define USE_REGISTRY 0
#define PAGE_SIZE 0x1000
#define ALIGNMENT_MASK (PAGE_SIZE-1)
#if (WINCEOSVER >= 400)
extern void GwesPowerOffSystem(void);
#else
extern void PowerOffSystem(void);
#endif
VOID *gPwrButtonIntrEvent;
VOID *gPwrButtonIntrThread;
//#ifdef BVDMAIN
volatile BLR_REGS *v_pBLRegs = NULL;
// Mainstone SW11 is bit 14 of the General-Purpose Switch Register GPSWR
#define BLR_GPSWR_SW11_MSK 0x4000 // Note: Bit set if no-dot position
//#endif
// Pointer to driver globals area
PDRIVER_GLOBALS pDriverGlobals;
// Pointer to System Registers
volatile XLLP_GPIO_T *v_pGPIORegs = NULL;
// Pointer to Sleep Data Area, untyped to avoid need for private structure defs.
static PVOID pvu_SleepAreaBase = NULL;
#ifdef DEBUG
DBGPARAM dpCurSettings = {
TEXT("PwrButton"), {
TEXT("Data"),TEXT("IntrThread"),TEXT("2"),TEXT("3"),
TEXT("4"),TEXT("5"),TEXT("6"),TEXT("7"),
TEXT("8"),TEXT("9"),TEXT("10"),TEXT("Values"),
TEXT("Init"),TEXT("Function"),TEXT("Warning"),TEXT("Error")},
0xB518 // Errors & Init only, by default
};
#define ZONE_DATA DEBUGZONE(0)
#define ZONE_INTRTHREAD DEBUGZONE(1)
#define ZONE_VALUE DEBUGZONE(11)
#define ZONE_FUNCTION DEBUGZONE(13)
#define ZONE_WARN DEBUGZONE(14)
#define ZONE_ERROR DEBUGZONE(15)
#endif
BOOL
PwrButtonInitializeAddresses(
void
)
{
if ( NULL == (pDriverGlobals=VirtualAllocCopy(DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,"mapping of BCR in BCRWrite failed", (LPVOID)DRIVER_GLOBALS_U_VIRTUAL)) ) {
ERRORMSG(1,
(TEXT("Pwrbutton InitializeAddresses: pDriverGlobals VirtualAllocCopy failed!\r\n")));
goto error_return;
}
v_pGPIORegs = (volatile XLLP_GPIO_T *)VirtualAllocCopy(sizeof(XLLP_GPIO_T),
"PwrButtonInitializeAddresses : v_pGPIORegs",(PVOID)(GPIO_BASE_U_VIRTUAL));
if ( v_pGPIORegs == NULL )
{
ERRORMSG(1,
(TEXT("Pwrbutton InitializeAddresses: GPIO VirtualAllocCopy failed!\r\n")));
goto error_return;
}
pvu_SleepAreaBase = (PVOID) VirtualAllocCopy(SLEEP_SAVE_BYTES,
"PwrButtonInitializeAddresses: pvu_SleepAreaBase",(PVOID)(SLEEP_SAVE_U_VIRTUAL));
if ( pvu_SleepAreaBase == NULL )
{
ERRORMSG(1,
(TEXT("Pwrbutton InitializeAddresses: pvu_SleepAreaBase VirtualAllocCopy failed!\r\n")));
goto error_return;
}
//#ifdef BVDMAIN
if ( NULL == (v_pBLRegs=(BLR_REGS *)VirtualAllocCopy(sizeof(BLR_REGS),"mapping of BLR failed", (LPVOID)FPGA_REGS_BASE_U_VIRTUAL)) ) {
ERRORMSG(1,
(TEXT("Pwrbutton InitializeAddresses: v_pBLRegs VirtualAllocCopy failed!\r\n")));
goto error_return;
}
//#endif // def BVDMAIN
DelayInit();
return TRUE;
error_return:
if ( pDriverGlobals ) {
if (!VirtualFree((PVOID)((unsigned int)pDriverGlobals & ALIGNMENT_MASK), 0, MEM_RELEASE) )
ERRORMSG(1,(TEXT("Virtualfree failed! at PwrButtonInitializeAddresses\r\n")) );
}
pDriverGlobals = 0;
if ( v_pGPIORegs )
VirtualFree((PVOID)v_pGPIORegs, 0, MEM_RELEASE);
v_pGPIORegs = 0;
DEBUGMSG(ZONE_INIT, (TEXT("PwrBUTTON INTR Thread ERR: 0x%x\r\r"), GetLastError()));
return FALSE;
}
void WINAPI PWR_PowerHandler(
BOOL bOff // @parm TRUE, the system is powering off; FALSE, the system is powering up.
)
{
if (bOff) {}
else {}
} // PWR_PowerHandler()
INT WINAPI PwrButtonIntrThread(
void
)
{
(void) PmgrSetValue(pvu_SleepAreaBase,
PMDS_SLEEP_TYPE,
SLEEP_TYPE_STANDARD);
//NKDbgPrintfW(TEXT("+PwrButtonIntrThread\r\n"));
while (1) {
//NKDbgPrintfW(TEXT("++PwrButtonIntrThread\r\n"));
#ifndef TEST_SR_AUTO_REPEAT
WaitForSingleObject(gPwrButtonIntrEvent, PWR_WAIT_DELAY);
#else // ifndef TEST_SR_AUTO_REPEAT
// For testing purposes, add a short delay and activate suspend logic
Sleep (3000); // unit = milliseconds
pDriverGlobals->uninit_misc.offButton = DRVG_OFFBTN_SUSPEND;
#endif // else of ifndef TEST_SR_AUTO_REPEAT
//NKDbgPrintfW(TEXT("DRVG_OFFBTN_SOFT_RESET\r\n"));
//KernelIoControl(IOCTL_HAL_REBOOT,NULL,0,NULL,0,NULL);
// Check for a power switch event
//DEBUGMSG(ZONE_INIT, (TEXT("PwrBUTTON INTR Thread Got Power Off Event\r\n")));
if (pDriverGlobals->uninit_misc.offButton != DRVG_OFFBTN_INACTIVE)
{
#if 0 //hzh
GEDR_GPIO1_EDGE_CLR (v_pGPIORegs->GEDR1); // Clear edge detect on release
#else
Sleep (300);
GEDR_GPIO0_EDGE_CLR (v_pGPIORegs->GEDR0); // Clear edge detect on release
#endif
// At this point, if not supporting autotest, S11 in Mainstone
// indicates soft reset for Power Button activation.
if (pDriverGlobals->uninit_misc.offButton == DRVG_OFFBTN_PWRBUTTON)
{
// User switches exist only in the Lubbock platform. If not Lubbock,
// power button can only request a suspend.
// For Lubbock, use this as the default, also.
pDriverGlobals->uninit_misc.offButton = DRVG_OFFBTN_SUSPEND;
// #ifdef PLAT_MAINSTONE
// On Mainstone I, use S11 to determine whether the off button was a request
// for suspend or soft reset. Use equivalent switch (S20) for M-II
// S11 in normal dot position: off button means suspend
if (v_pBLRegs->gpsw & BLR_GPSWR_SW11_MSK)
{
//NKDbgPrintfW(TEXT("v_pBLRegs->gpsw & BLR_GPSWR_SW11_MSK\r\n"));
// S18 in no-dot position: off button means soft reset
pDriverGlobals->uninit_misc.offButton = DRVG_OFFBTN_SOFT_RESET;
}
// #endif // #ifdef PLAT_LUBBOCK
} // if (pDriverGlobals->uninit_misc.offButton == DRVG_OFFBTN_PWRBUTTON)
if (pDriverGlobals->uninit_misc.offButton == DRVG_OFFBTN_SOFT_RESET)
{
NKDbgPrintfW(TEXT("DRVG_OFFBTN_SOFT_RESET\r\n"));
//KernelIoControl(IOCTL_HAL_REBOOT,NULL,0,NULL,0,NULL);
// For soft reset, set flag used by startup code to simulate
// GPIO reset and bypass resume.
(void) PmgrSetValue(pvu_SleepAreaBase,
PMDS_SLEEP_TYPE,
SLEEP_TYPE_SOFT_RESET);
}
// Finished with global. Clear out for next use.
pDriverGlobals->uninit_misc.offButton = DRVG_OFFBTN_INACTIVE;
//DEBUGMSG(ZONE_INIT, (TEXT("PwrBUTTON INTR Thread calling PowerOffSystem\r\n")));
NKDbgPrintfW(TEXT("----------------\r\n"));
NKDbgPrintfW(TEXT("PowerOff\r\n"));
#if (WINCEOSVER >= 400)
// NKDbgPrintfW(TEXT("G\r\n"));
GwesPowerOffSystem();
#else
// NKDbgPrintfW(TEXT("P\r\n"));
PowerOffSystem();
#endif
// Give control back to system if it wants it for anything. Not in
// power handling mode any more. All suspend and resume operations
// were performed in the PowerOffSystem() function.
// NKDbgPrintfW(TEXT("+D\r\n"));
DriverSleep(0, FALSE);
// NKDbgPrintfW(TEXT("-D\r\n"));
//NKDbgPrintfW(TEXT("-(almost)PwrButtonIntrThread\r\n"));
InterruptDone(SYSINTR_POWER);
NKDbgPrintfW(TEXT("Wakeup ins over.\r\n"));
} // end if (pDriverGlobals->uninit_misc.offButton != DRVG_OFFBTN_INACTIVE)
} // end while
} // PwrButtonIntrThread()
BOOL WINAPI PWR_Init(
)
{
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
gPwrButtonIntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
DEBUGMSG(ZONE_INIT, (TEXT("+PwrButton PWR Init\r\n")));
if ( !PwrButtonInitializeAddresses() ) {
return FALSE;
}
if (!(InterruptInitialize(SYSINTR_POWER, gPwrButtonIntrEvent, NULL, 0))) {
DEBUGMSG(ZONE_INIT, (TEXT("PwrBUTTON INTR INIT Failed\r\n")));
DEBUGMSG(ZONE_INIT, (TEXT("PwrBUTTON INTR INIT ERR: 0x%x\r\r"), GetLastError()));
return FALSE;
}
gPwrButtonIntrThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) PwrButtonIntrThread, NULL, 0, NULL);
if ( gPwrButtonIntrThread == NULL ) {
DEBUGMSG(1, (TEXT("Fatal Error! Failed to create PwrButton Intterupt thread.\r\n")));
return (FALSE);
} else {
DEBUGMSG(ZONE_INIT, (TEXT("-PwrButton PWR Init\r\n")));
return TRUE;
}
}
BOOL WINAPI
PWR_DllEntry(
HANDLE hInstDll,
DWORD dwReason,
LPVOID lpvReserved
)
{
switch ( dwReason ) {
case DLL_PROCESS_ATTACH:
DEBUGREGISTER((HINSTANCE) hInstDll);
DEBUGMSG(ZONE_INIT, (TEXT("PwrButton : DLL_PROCESS_ATTACH\r\n")));
break;
case DLL_PROCESS_DETACH:
// should be signaling thread here
DEBUGMSG(ZONE_INIT, (TEXT("PwrButton : DLL_PROCESS_DETACH\r\n")));
break;
}
return (TRUE);
}
DWORD PWR_Open (DWORD dwData, DWORD dwAccess, DWORD dwShareMode)
{return (4);}
BOOL PWR_Close(DWORD dwData)
{return (TRUE);}
DWORD PWR_Read (DWORD dwData, LPVOID pBuf, DWORD Len)
{return (0);}
DWORD PWR_Write(DWORD dwData, LPCVOID pBuf, DWORD Len)
{return (0);}
DWORD PWR_Seek (DWORD dwData, long pos, DWORD type)
{return (DWORD)-1;}
VOID PWR_PowerUp (VOID)
{
SHOW_DBGTRACE_SR(SDSI_PWR_BUTTON_UP_START);
(void) PmgrSetValue(pvu_SleepAreaBase,
PMDS_SLEEP_TYPE,
SLEEP_TYPE_STANDARD);
SHOW_DBGTRACE_SR(SDSI_PWR_BUTTON_UP_END );
} // PWR_PowerUp()
BOOL PWR_PowerDown(VOID)
{
SHOW_DBGTRACE_SR(SDSI_PWR_BUTTON_DOWN_START);
SHOW_DBGTRACE_SR(SDSI_PWR_BUTTON_DOWN_END );
SHOW_DBGTRACE_SR_WAIT();
return (TRUE);
} // PWR_PowerDown(()
BOOL PWR_Deinit(DWORD dwData)
{return (TRUE);}
BOOL PWR_IOControl(DWORD p1, DWORD p2, PBYTE p3, DWORD p4, PBYTE p5,
DWORD p6, PDWORD p7) {return (TRUE);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -