📄 oemioctl.c
字号:
//**********************************************************************
//
// Filename: oemilctl.c
//
// Description: NK Kernel Generic I/O Control Interface
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Use of this source code is subject to the terms of the Cirrus end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to
// use this source code. For a copy of the EULA, please see the
// EULA.RTF on your install media.
//
// Copyright(c) Cirrus Logic Corporation 2005, All Rights Reserved
//
//**********************************************************************
/*++
Module Name:
Abstract:
NK Kernel Generic I/O Control Interface
Functions:
Notes:
This file does not form part of the ARM template. It is included to
show how iocontrol can be implemented in WindowsCE.
--*/
#define WINCEMACRO 1
#include <windows.h>
#include <ceddk.h>
#include <oalintr.h>
#include <halether.h>
#include <pkfuncs.h>
#include <iltiming.h>
#include <ethdbg.h>
#include <kitl.h>
//#include <platform.h>
#include <drv_glob.h>
#include <dbt.h>
#include <memorymap.h>
#include <nkintr.h>
#include <hwdefs.h>
#include <haluser.h>
#include <eeinfo.h>
#include <audiopio.h>
#include <oal.h>
#include <options.h>
#include <clocks.h>
extern void itoa10(int n,char s[]);
#ifdef INTERNAL_HAL_TESTING
#include "intioctl.h"
#include "intioctl.c"
#endif
#ifdef EP93XX_SIMULAT_PS2_KBD
extern BOOL SendDataToPS2( UINT32 code, VOID *pInpBuffer, UINT32 inpSize, VOID *pOutBuffer,
UINT32 outSize, UINT32 *pOutSize);
extern BOOL ReadPS2Data( UINT32 code, VOID *pInpBuffer, UINT32 inpSize, VOID *pOutBuffer,
UINT32 outSize, UINT32 *pOutSize);
#endif
#ifdef EDB9315A_CIR
extern PTCHAR gstrKeyName;
BOOL GetKeyName( UINT32 code, VOID *pInpBuffer, UINT32 inpSize, VOID *pOutBuffer,
UINT32 outSize, UINT32 *pOutSize)
//BOOL GetKeyName( PUCHAR lpOutBuf, int nOutBufSize, LPDWORD lpBytesReturned )
{
int num=min( outSize, 16 );
memcpy( pOutBuffer, gstrKeyName, num );
//for(i=0; i<num; i++)
// lpOutBuf[i] = gstrKeyName[i];
*pOutSize = num;
return TRUE;
}
#endif
BOOL HALRedirectionDebugPort(
UINT32 code, VOID *pInpBuffer, UINT32 inpSize, VOID *pOutBuffer,
UINT32 outSize, UINT32 *pOutSize)
{
extern BOOL DebugPortRedirection( DWORD dwPort );
RETAILMSG(1,(L" HALRedirectionDebugPort entered\r\n"));
if( pInpBuffer && inpSize ==4 ){
DWORD dwPort=*(DWORD*)pInpBuffer;
return DebugPortRedirection( dwPort );
}
return FALSE;
}
//extern PCI_REG_INFO g_KitlInfo;
// ILTIMING Globals
BOOL fIntrTime;
WORD wNumInterrupts;
DWORD dwIsrTime1, dwIsrTime2;
DWORD dwSPC;
DWORD dwIntrTimeCountdown;
DWORD dwIntrTimeCountdownRef;
// Wake from suspend interrupt mask
CRITICAL_SECTION csWakeIntMask;
extern DWORD g_dwWakeIntMask;
//Use the first word of CS8950_VIRTUAL_MEMORY to store if KITL is enabled.
ULONG *gpulCS8950KitlUsed = (ULONG *)CS8950_VIRTUAL_MEMORY;
DWORD OEMGetWakeupSource(void);
void OEMClearIntSources(void );
DWORD OEMResetWakeupSource( DWORD dwSources);
DWORD OEMSetWakeupSource( DWORD dwSources);
extern volatile BOOL gfResumeFlag;
LPCWSTR g_oalIoCtlPlatformType = PROCESSOR_NAME_STRING;
LPCWSTR g_oalIoCtlPlatformOEM = L"Cirrus EP93XX";
//------------------------------------------------------------------------------
//
// Global: g_oalIoctlProcessorVendor/Name/Core
//
// Processor information
//
LPCWSTR g_oalIoCtlProcessorVendor = L"Cirrus Logic";
LPCWSTR g_oalIoCtlProcessorName = PROCESSOR_NAME_STRING;
LPCWSTR g_oalIoCtlProcessorCore = L"ARM920T";
//------------------------------------------------------------------------------
//
// Global: g_oalIoctlInstructionSet
//
// Processor instruction set identifier
//
UINT32 g_oalIoCtlInstructionSet = PROCESSOR_16BITINSTRUCTION;
UINT32 g_oalIoCtlClockSpeed = FCLOCK;
//----------------------------------------------------------------------------
BOOL IsKitlEnabled(
UINT32 code, VOID *pInpBuffer, UINT32 nInBufSize, VOID *lpOutBuf,
UINT32 nOutBufSize, UINT32 *pOutSize)
{
if (nOutBufSize == 4 && lpOutBuf)
{
//KITL will write the pattern 0x5a5a5a5a to gulpCS8950KitlUsed.
if ( (*gpulCS8950KitlUsed) == 0x5a5a5a5a)
{
*(ULONG *)lpOutBuf = 1;
}
//If is not the pattern, just return 0;
else
{
*(ULONG *)lpOutBuf = 0;
}
*pOutSize = 4;
return TRUE;
}
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
//----------------------------------------------------------------------------
BOOL OALIoCtlHalReboot(
UINT32 code, VOID *pInpBuffer, UINT32 inpSize, VOID *pOutBuffer,
UINT32 outSize, UINT32 *pOutSize)
{
RETAILMSG(1, (TEXT("Performing warm reset.\r\n")));
//
// Trun on the red LED
//
*GPIO_PEDR |= 0x02;
//
// Trun on the watchdog.
//
*WATCHDOG_WDCONTROL = 0xAAAA;
return(TRUE);
}
BOOL OALIoCtlHalInitRTC(
UINT32 code, VOID *pInpBuffer, UINT32 inpSize, VOID *pOutBuffer,
UINT32 outSize, UINT32 *pOutSize)
{
return(TRUE);
}
//--------------------------------Wake Source----------------------------------------------
BOOL OALIoCtlHalGetWakeSource(
UINT32 code, VOID *pInpBuffer, UINT32 inpSize, VOID *lpOutBuf,
UINT32 nOutBufSize, UINT32 *lpBytesReturned)
{
if (!gfResumeFlag)
{
//Sometimes, we get a false wakeup interrupt.
//If not wake up by a real wakeup source, just return FALSE.
return FALSE;
}
if (lpOutBuf && nOutBufSize>=sizeof(DWORD))
{
*(PDWORD)lpOutBuf= OEMGetWakeupSource();
if (lpBytesReturned)
*lpBytesReturned=sizeof(DWORD);
return TRUE;
}
SetLastError (ERROR_INVALID_PARAMETER);
return FALSE;
return(TRUE);
}
BOOL OALIoCtlHalEnableWake(
UINT32 code, VOID *pInpBuffer, UINT32 inpSize, VOID *pOutBuffer,
UINT32 outSize, UINT32 *pOutSize)
{
if (pInpBuffer && inpSize == sizeof(DWORD))
{
DWORD dwReturn;
dwReturn = OEMSetWakeupSource( *(PDWORD)pInpBuffer);
if (dwReturn)
{
return TRUE;
}
}
SetLastError (ERROR_INVALID_PARAMETER);
return FALSE;
}
BOOL OALIoCtlHalDisableWake(
UINT32 code, VOID *lpInBuf, UINT32 nInBufSize, VOID *pOutBuffer,
UINT32 outSize, UINT32 *pOutSize)
{
if (lpInBuf && nInBufSize == sizeof(DWORD))
{
DWORD dwReturn;
dwReturn = OEMResetWakeupSource( *(PDWORD)lpInBuf);
if (dwReturn)
{
return TRUE;
}
}
SetLastError (ERROR_INVALID_PARAMETER);
return FALSE;
}
//-------------------------IRQ & SYSINTR-----------------------------------------------------
// case IOCTL_HAL_TRANSLATE_IRQ:
// case IOCTL_HAL_REQUEST_SYSINTR:
UINT32
OALIntrRequestSysIntr(
UINT32 count,
const UINT32 *pIrqs,
UINT32 flags
)
{
return pIrqs[0];
}
BOOL OALIntrReleaseSysIntr( UINT32 sysIntr )
{
return TRUE;
}
// Provide interrupt number based on device location
BOOL OALIntrRequestIrqs(DEVICE_LOCATION *pDevLoc, UINT32 *pCount, UINT32 *pIrqs)
{//we have no PCI, so just return FALSE
return FALSE;
}
void * GetDeviceId( void )
{
#define OAL_MAX_PLAT_ID 10
#define ROUNDUP(len) ((len+3)&0xFFFFFFFC)
#define REQ_SIZE (ROUNDUP(sizeof(DEVICE_ID)) + ROUNDUP(sizeof(g_oalIoCtlPlatformOEM)) + ROUNDUP(OAL_MAX_PLAT_ID))
static UCHAR device_id[REQ_SIZE+10];
static BOOL bInitialized=FALSE;
PDEVICE_ID pDeviceID = (PDEVICE_ID)device_id;
if (!bInitialized ){
bInitialized=TRUE;
pDeviceID->dwSize = REQ_SIZE;
// Tell them how much we actually used.
pDeviceID->dwPresetIDOffset = ROUNDUP(sizeof(DEVICE_ID));
pDeviceID->dwPresetIDBytes = sizeof(g_oalIoCtlPlatformOEM);
memcpy ((PBYTE)device_id + pDeviceID->dwPresetIDOffset, (PBYTE)g_oalIoCtlPlatformOEM, sizeof(g_oalIoCtlPlatformOEM));
pDeviceID->dwPlatformIDOffset = pDeviceID->dwPresetIDOffset + ROUNDUP(pDeviceID->dwPresetIDBytes);
pDeviceID->dwPlatformIDBytes = OAL_MAX_PLAT_ID;
memset( (PBYTE)device_id + pDeviceID->dwPlatformIDOffset, 0, OAL_MAX_PLAT_ID );
itoa10( ((pDriverGlobals->eth.EdbgAddr.wMAC[2]>>8)
| ((pDriverGlobals->eth.EdbgAddr.wMAC[2]& 0x00ff) << 8))
, (PBYTE)device_id + pDeviceID->dwPlatformIDOffset );
}
return pDeviceID;
}
//------------------------------------------------------------------------------
VOID* OALArgsQuery(UINT32 type)
{
VOID *pData = NULL;
OALMSG(OAL_ARGS&&OAL_FUNC, (L"+OALArgsQuery(%d)\r\n", type));
// Depending on required args
switch (type) {
case OAL_ARGS_QUERY_DEVID:
pData = GetDeviceId( );
break;
case OAL_ARGS_QUERY_UUID:
pData= &pDriverGlobals->eth.EdbgAddr.wMAC;
break;
case OAL_ARGS_QUERY_KITL:
pData = gpulCS8950KitlUsed;
break;
/* case OAL_ARGS_QUERY_UPDATEMODE:
pData = &pArgs->fUpdateMode;
break;*/
}
OALMSG(OAL_ARGS&&OAL_FUNC, (L"-OALArgsQuery(pData = 0x%08x)\r\n", pData));
return pData;
}
//----------------------------------------------------------------------------------
BOOL WriteCommonReg( UINT32 code, VOID *lpInBuf, UINT32 nInBufSize, VOID *pOutBuffer,
UINT32 outSize, UINT32 *pOutSize)
{
if (nInBufSize == sizeof(CommonRegStruct) && lpInBuf)
{
CommonRegStruct *psCommon = (CommonRegStruct *)lpInBuf;
BOOL fEnable;
ULONG ulCurValue;
if(psCommon->ulCheckSum == (ULONG)psCommon->pulRegister + psCommon->ulMask + psCommon->ulValue +
(ULONG)psCommon->pulLockRegister)
{
//
// Disable interrupts so that we can perform a lock/read/modify/write.
//
fEnable = INTERRUPTS_ENABLE(FALSE);
//
// Read the current value of the register.
//
ulCurValue = *psCommon->pulRegister;
//
// Set the lock register if necessary.
//
if(psCommon->pulLockRegister)
{
*psCommon->pulLockRegister = 0xAA;
}
//
// Write the value to the register.
//
*psCommon->pulRegister = (ulCurValue & ~psCommon->ulMask) |
(psCommon->ulValue & psCommon->ulMask);
//
// Clear the register lock.
//
if(psCommon->pulLockRegister)
{
*psCommon->pulLockRegister = 0x00;
}
INTERRUPTS_ENABLE(fEnable);
return TRUE;
}
}
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
BOOL OALGetMacAddress(
UINT32 code, VOID *lpInBuf, UINT32 nInBufSize, VOID *lpOutBuf,
UINT32 nOutBufSize , UINT32 *lpBytesReturned)
{
extern BOOL gBoardInformationValid;
if (nInBufSize == 0 && nOutBufSize == 6 && lpOutBuf && !lpInBuf)
{
if(gBoardInformationValid)
{
memcpy(lpOutBuf, &gBoardInformation.MACAddress, 6);
*lpBytesReturned = 6;
return TRUE;
}
// return FALSE;
}
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
//------------------------------------------------------------------------------
//
// Global: g_oalIoCtlTable[]
//
// IOCTL handler table. This table includes the IOCTL code/handler pairs
// defined in the IOCTL configuration file. This global array is exported
// via oal_ioctl.h and is used by the OAL IOCTL component.
//
const OAL_IOCTL_HANDLER g_oalIoCtlTable[] = {
#include "oal_ioctl_tab.h"
#ifdef EDB9315A_CIR
{ IOCTL_HAL_PIO_CIR, 0, GetKeyName },
#endif
#ifdef EP93XX_SIMULAT_PS2_KBD
{ IOCTL_HAL_PS2_SEND, 0, SendDataToPS2 },
{ IOCTL_HAL_PS2_GET, 0, ReadPS2Data },
#endif
{ IOCTL_HAL_WRITE_COMMON_REG, 0, WriteCommonReg },
{ IOCTL_HAL_IS_CS8950_USED_FOR_KITL, 0, IsKitlEnabled },
{ IOCTL_HAL_REDIRECTION_DEBUG_PORT, 0, HALRedirectionDebugPort },
{IOCTL_HAL_GET_MAC_ADDRESS, 0, OALGetMacAddress},
{ 0, 0, NULL}
};
/* EOF oemioctl.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -