oemioctl.c
来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 682 行 · 第 1/2 页
C
682 行
// -----------------------------------------------------------------------------
//
// 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.
// Copyright (c) 1995-2000 Microsoft Corporation. All rights reserved.
//
// -----------------------------------------------------------------------------
#include "windows.h"
#include "ceddk.h"
#include "pc_ddk.h"
#include "hal.h"
#include "nkintr.h"
#include "halether.h"
#include "bootarg.h"
#include <iltiming.h>
#ifdef HALPROFILE
BOOL HalProfileControl(LPVOID pProfCtrl, LPVOID lpOutBuf,
DWORD nOutBufSize, LPDWORD lpBytesReturned);
#endif
#ifdef HAL_DVCM
extern HRESULT Ioctl_Register_DataCollector(LPVOID,DWORD,LPVOID,DWORD);
extern HRESULT Ioctl_Send_DataCollector(LPVOID,DWORD,LPVOID,DWORD);
extern HRESULT Ioctl_Unregister_DataCollector(LPVOID,DWORD,LPVOID,DWORD);
#endif
#ifdef INTERNAL_HAL_TESTING
#include "intioctl.h"
#include "intioctl.c"
#endif
unsigned int strlenW(LPCWSTR str);
WCHAR HALPlatformStr[80];
const WCHAR INIT_HALPlatformStr[] = L"CEPC platform";
const WCHAR HALOEMStr[] = L"CEPC";
// ILTIMING Globals
BOOL fIntrTime;
DWORD dwIntrTimeIsr1;
DWORD dwIntrTimeIsr2;
DWORD dwIntrTimeNumInts;
DWORD dwIntrTimeCountdown;
DWORD dwIntrTimeCountdownRef;
DWORD dwIntrTimeSPC;
// Reboot address
extern DWORD dwRebootAddress;
extern USHORT wLocalMAC[3]; // in halether.c
#ifdef IMGSHAREETH
extern BOOL OEMEthCurrentPacketFilter(PDWORD pdwRequestedFilter);
extern BOOL OEMEthMulticastList(PUCHAR pucMulticastAddressList, DWORD dwNoOfAddresses);
#endif
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
ULONG
OEMGetBusDataByOffset(
IN BUS_DATA_TYPE BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN PVOID Buffer,
IN ULONG Offset,
IN ULONG Length
)
{
switch ( BusDataType ) {
case PNPISAConfiguration:
return (ISAGetBusDataByOffset(
BusNumber, SlotNumber, Buffer, Offset, Length));
case PCIConfiguration:
return (PCIGetBusDataByOffset(
BusNumber, SlotNumber, Buffer, Offset, Length));
default:
return (0);
}
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
ULONG
OEMSetBusDataByOffset(
IN BUS_DATA_TYPE BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN PVOID Buffer,
IN ULONG Offset,
IN ULONG Length
)
{
switch ( BusDataType ) {
case PNPISAConfiguration:
return (ISASetBusDataByOffset(
BusNumber, SlotNumber, Buffer, Offset, Length));
case PCIConfiguration:
return (PCISetBusDataByOffset(
BusNumber, SlotNumber, Buffer, Offset, Length));
default:
return (0);
}
}
extern DWORD PerfCountSinceTick();
extern DWORD PerfCountFreq();
extern void StartUp();
// -----------------------------------------------------------------------------
//
// @func BOOL | OEMIoControl | generic HAL request
// @rdesc none
// @comm OEMIoControl is called by the Kernel when a device driver or application
// program calls <f KernelIoControl>. The system is fully preemptible when this
// function is called. The kernel does no processing of this API. It is
// provided to allow an OEM device driver to communicate with kernel mode
// HAL code.
// @xref <l Overview.Windows CE Kernel OEM Interface> <f KernelIoControl>
//
// -----------------------------------------------------------------------------
BOOL OEMIoControl(DWORD dwIoControlCode, LPVOID lpInBuf, DWORD nInBufSize,
LPVOID lpOutBuf, DWORD nOutBufSize, LPDWORD lpBytesReturned)
{
BOOL retval = FALSE;
DWORD len;
DEBUGMSG(0, (TEXT("+OEMIoControl %X\r\n"), dwIoControlCode));
switch ( dwIoControlCode ) {
case IOCTL_HAL_SET_DEVICE_INFO :
// Since the CEPC is a generic test platform this allows some of the DEVICE
// info data of the platorm to be set as required for the specific product.
// Any application that uses this API should query that the current settings
// indicate a generic platform (i.e. check that platformtype == "CEPC platform")
if (nInBufSize >= sizeof(DWORD)) {
len = *(LPDWORD)lpInBuf;
switch (len) {
case SPI_GETPLATFORMTYPE :
nInBufSize -= sizeof(DWORD);
if (nInBufSize <= sizeof(HALPlatformStr)) {
memcpy (HALPlatformStr, ((LPBYTE)lpInBuf)+sizeof(DWORD), nInBufSize);
retval = TRUE;
} else {
SetLastError(ERROR_INVALID_PARAMETER);
}
break;
default :
SetLastError(ERROR_INVALID_PARAMETER);
break;
}
} else {
SetLastError(ERROR_INVALID_PARAMETER);
}
break;
case IOCTL_HAL_GET_DEVICE_INFO :
if (nInBufSize == 4) {
switch (*(LPDWORD)lpInBuf) {
case SPI_GETPLATFORMTYPE:
if (TEXT('\0') == HALPlatformStr[0]) {
memcpy (HALPlatformStr, INIT_HALPlatformStr, sizeof(INIT_HALPlatformStr));
}
len = (strlenW(HALPlatformStr)+1)*sizeof(WCHAR);
if (nOutBufSize >= len) {
memcpy(lpOutBuf,HALPlatformStr,len);
retval = TRUE;
} else
SetLastError(ERROR_INSUFFICIENT_BUFFER);
break;
case SPI_GETOEMINFO:
len = (strlenW(HALOEMStr)+1)*sizeof(WCHAR);
if (nOutBufSize >= len) {
memcpy(lpOutBuf,HALOEMStr,len);
retval = TRUE;
} else
SetLastError(ERROR_INSUFFICIENT_BUFFER);
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
}
} else {
SetLastError(ERROR_INVALID_PARAMETER);
}
break;
case IOCTL_HAL_DDK_CALL:
// For now, the only ddk ioctls in CEPC are SetBusData & GetBusData
if ( (nInBufSize != sizeof(BUSDATA_PARMS)) ||
(!lpInBuf) ) {
// Oops, parameter list isn't what we expected.
return (FALSE);
}
if ( *(DWORD *)lpInBuf == IOCTL_HAL_SETBUSDATA ) {
((PBUSDATA_PARMS)lpInBuf)->ReturnCode = OEMSetBusDataByOffset(
((PBUSDATA_PARMS)lpInBuf)->BusDataType,
((PBUSDATA_PARMS)lpInBuf)->BusNumber,
((PBUSDATA_PARMS)lpInBuf)->SlotNumber,
((PBUSDATA_PARMS)lpInBuf)->Buffer,
((PBUSDATA_PARMS)lpInBuf)->Offset,
((PBUSDATA_PARMS)lpInBuf)->Length
);
return (TRUE);
} else if ( *(DWORD *)lpInBuf == IOCTL_HAL_GETBUSDATA ) {
((PBUSDATA_PARMS)lpInBuf)->ReturnCode = OEMGetBusDataByOffset(
((PBUSDATA_PARMS)lpInBuf)->BusDataType,
((PBUSDATA_PARMS)lpInBuf)->BusNumber,
((PBUSDATA_PARMS)lpInBuf)->SlotNumber,
((PBUSDATA_PARMS)lpInBuf)->Buffer,
((PBUSDATA_PARMS)lpInBuf)->Offset,
((PBUSDATA_PARMS)lpInBuf)->Length
);
return (TRUE);
} else {
// Oops, parameter list isn't what we expected.
return (FALSE);
}
break;
case IOCTL_EDBG_REGISTER_CLIENT:
return (EdbgRegisterClient(lpInBuf, lpOutBuf, (UCHAR)nInBufSize, (UCHAR)nOutBufSize, (UCHAR *)lpBytesReturned));
case IOCTL_EDBG_DEREGISTER_CLIENT:
return (EdbgDeregisterClient((UCHAR)nInBufSize));
case IOCTL_EDBG_REGISTER_DFLT_CLIENT:
return (EdbgRegisterDfltClient((UCHAR)nInBufSize, (UCHAR)nOutBufSize, (UCHAR **)lpInBuf, (UCHAR **)lpOutBuf));
case IOCTL_EDBG_SEND:
return (EdbgSend((UCHAR)nInBufSize, lpInBuf, nOutBufSize));
case IOCTL_EDBG_RECV:
return (EdbgRecv((UCHAR)nInBufSize, lpInBuf, lpOutBuf, nOutBufSize));
case IOCTL_EDBG_SET_DEBUG:
EdbgSetDebug(nInBufSize);
break;
case IOCTL_SET_KERNEL_COMM_DEV:
// Routine to change underlying communications device for kernel services
return (SetKernelCommDev((UCHAR)nInBufSize,(UCHAR)nOutBufSize));
case IOCTL_HAL_INIT_RTC:
// We have a battery backed CMOS based clock. Don't actually do anything
// to the RTC unless it appears to have been corrupted. I guess the best
// way to detect corruption is by checksumming CMOS
break;
case IOCTL_HAL_REBOOT:
if (1) {
BOOT_ARGS *pBootArgs = (BOOT_ARGS *) ((ULONG)(*(PBYTE *)BOOT_ARG_PTR_LOCATION) | 0x80000000);
if ( pBootArgs->dwEBootFlag == BOOTARG_SIG && pBootArgs->dwEBootAddr )
dwRebootAddress = pBootArgs->dwEBootAddr;
else
dwRebootAddress = (DWORD) StartUp;
RETAILMSG(1, (TEXT("Rebooting to startup @ 0x%08X\r\n"), dwRebootAddress));
} else {
// Perform a warm reset of the device.
__asm
{
cli ; Disable Interrupts
mov al, 0FEh ; Reset CPU
out 064h, al
jmp near $ ; Should not get here
}
}
retval = TRUE;
break;
case IOCTL_SET_KERNEL_DEV_PORT:
{
BOOT_ARGS *pBootArgs = (BOOT_ARGS *) ((ULONG)(*(PBYTE *)BOOT_ARG_PTR_LOCATION) | 0x80000000);
// DEBUGMSG(1, (TEXT("IOCTL_SET_KERNEL_DEV_PORT reached!\r\n")));
if ( nInBufSize == sizeof(UCHAR) && KERNEL_PORT_NONE < *((UCHAR*)lpInBuf) && *((UCHAR*)lpInBuf) <= KERNEL_PORT_MAX )
{
pBootArgs->ucComPort = *((UCHAR*)lpInBuf);
RETAILMSG(1, (TEXT("Debug port changed to port %d.\r\n"), *((UCHAR*)lpInBuf)));
}
}
break;
case IOCTL_HAL_ILTIMING : {
if ((nInBufSize == sizeof(ILTIMING_MESSAGE)) && (lpInBuf != NULL)) {
extern DWORD PerfCountSinceTick();
extern DWORD PerfCountFreq();
PILTIMING_MESSAGE pITM = (PILTIMING_MESSAGE) lpInBuf;
switch (pITM->wMsg) {
case ILTIMING_MSG_ENABLE : {
dwIntrTimeCountdownRef = pITM->dwFrequency;
RETAILMSG (1, (TEXT("ILTiming Enable (@ every %d ticks)\r\n"), dwIntrTimeCountdownRef));
dwIntrTimeCountdown = dwIntrTimeCountdownRef;
dwIntrTimeNumInts = 0;
fIntrTime = TRUE;
break;
}
case ILTIMING_MSG_DISABLE : {
RETAILMSG (1, (TEXT("ILTiming Disable\r\n")));
fIntrTime = FALSE;
break;
}
case ILTIMING_MSG_GET_TIMES : {
pITM->dwIsrTime1 = dwIntrTimeIsr1;
pITM->dwIsrTime2 = dwIntrTimeIsr2;
pITM->wNumInterrupts = (WORD) dwIntrTimeNumInts;
pITM->dwSPC = dwIntrTimeSPC;
pITM->dwFrequency = PerfCountFreq();
dwIntrTimeNumInts = 0;
break;
}
case ILTIMING_MSG_GET_PFN : {
pITM->pfnPerfCountSinceTick = (PVOID) PerfCountSinceTick;
RETAILMSG (1, (TEXT("ILTiming GetPFN\r\n")));
break;
}
default : {
RETAILMSG (1, (TEXT("IOCTL_HAL_ILTIMING : BAD MESSAGE!!!\r\n")));
SetLastError(ERROR_INVALID_PARAMETER);
return (FALSE);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?