📄 oemioctl.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: oemioctl.c,v
* Revision: 1.0
* ----------------------------------------------------------------
* $
*/
/*++
Module Name:
Abstract:
NK Kernel Generic I/O Control Interface
Functions:
Notes:
This file does not form part of the JADE template. It is included to
show how iocontrol can be implemented in WindowsCE.
--*/
#define WINCEMACRO 1
#include <windows.h>
#include <ceddk.h>
#include <arm_ddk.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 <oemwake.h>
#include <oalfuncs.h>
#include <sp810.h>
#include <dma.h>
#include "dmakern.h"
#ifdef IMGSHAREETH
BOOL OEMEthCurrentPacketFilter(PDWORD pdwRequestedFilter);
BOOL OEMEthMulticastList(PUCHAR pucMulticastAddressList, DWORD dwNoOfAddresses);
#endif
#ifdef INTERNAL_HAL_TESTING
#include "intioctl.h"
#include "intioctl.c"
#endif
#define pDriverGlobals ((PDRIVER_GLOBALS)DRIVER_GLOBALS_PHYSICAL_MEMORY_START)
unsigned int strlenW(LPCWSTR str);
const WCHAR HALPlatformStr[] = L"JADE Z228 Development Board";
const WCHAR HALOEMStr[] = L"JADE";
void CreateDeviceName(EDBG_ADDR *pMyAddr, char *szBuf, LPSTR szPlatformString);
// ILTIMING Globals
BOOL fIntrTime;
WORD wNumInterrupts;
DWORD dwIsrTime1, dwIsrTime2;
DWORD dwSPC;
DWORD dwIntrTimeCountdown;
DWORD dwIntrTimeCountdownRef;
// Wake from suspend interrupt mask
CRITICAL_SECTION csWakeIntMask;
extern CRITICAL_SECTION csRequestSysIntr;
// DMA channel allocation/free critical section
// This is used to protect the channel allocation and the DMA peripheral
// clock enable/disable
CRITICAL_SECTION csDMAChannelAllocation;
#define DebugMsg_Normal 0x01
#define DebugMsg_Important 0x02
#define DebugMsg_Trace 0x04
#define DebugMsgMask (DebugMsg_Important)
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
ULONG OEMGetBusDataByOffset(IN BUS_DATA_TYPE BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN PVOID Buffer,
IN ULONG Offset,
IN ULONG Length)
{
// Not currently supported
ULONG RetVal = 0;
switch (BusDataType)
{
default:
break;
}
return RetVal;
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
ULONG OEMSetBusDataByOffset(
IN BUS_DATA_TYPE BusDataType,
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN PVOID Buffer,
IN ULONG Offset,
IN ULONG Length)
{
// Not currently supported
ULONG RetVal = 0;
switch (BusDataType)
{
default:
break;
}
return RetVal;
}
/*
* @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 Overview.Windows CE Kernel OEM Interface KernelIoControl
*/
BOOL OEMIoControl(DWORD dwIoControlCode, LPVOID lpInBuf, DWORD nInBufSize,
LPVOID lpOutBuf, DWORD nOutBufSize, LPDWORD lpBytesReturned)
{
DWORD len;
PIP_INFO pIPInfo;
EDBG_ADDR *pEdbgAddr;
DEBUGMSG(0, (TEXT("+OEMIoControl %X\r\n"), dwIoControlCode));
switch (dwIoControlCode) {
case IOCTL_HAL_GET_DEVICE_INFO:
// No input buffer of size 4 or output buffer, then this call has failed
if (!lpInBuf || nInBufSize != 4 || !lpOutBuf )
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
switch (*(LPDWORD)lpInBuf)
{
case SPI_GETPLATFORMTYPE:
len = (strlenW(HALPlatformStr)+1)*sizeof(WCHAR);
if (nOutBufSize >= len)
{
memcpy(lpOutBuf,HALPlatformStr,len);
if(lpBytesReturned) *lpBytesReturned = len;
}
else
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
if(lpBytesReturned) *lpBytesReturned = 0;
return FALSE;
}
break;
case SPI_GETOEMINFO:
len = (strlenW(HALOEMStr)+1)*sizeof(WCHAR);
if (nOutBufSize >= len)
{
memcpy(lpOutBuf,HALOEMStr,len);
if(lpBytesReturned) *lpBytesReturned = len;
}
else
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
if(lpBytesReturned) *lpBytesReturned = 0;
return FALSE;
}
break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
break;
case IOCTL_PROCESSOR_INFORMATION:
if (!lpOutBuf) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (sizeof(PROCESSOR_INFO) > nOutBufSize) {
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
} else {
const WCHAR OEMProcCore[] = L"ARM926EJ-S";
const WCHAR OEMProcName[] = L"Z228";
const WCHAR OEMProcVendor[] = L"JADE Ltd.";
PPROCESSOR_INFO pProcInfo = (PPROCESSOR_INFO)lpOutBuf;
if (lpBytesReturned) *lpBytesReturned = sizeof(PROCESSOR_INFO);
memset(pProcInfo, 0, sizeof(PROCESSOR_INFO));
pProcInfo->wVersion = 1;
memcpy(pProcInfo->szProcessCore, OEMProcCore,
(strlenW(OEMProcCore) + 1) * sizeof(WCHAR));
memcpy(pProcInfo->szProcessorName, OEMProcName,
(strlenW(OEMProcName) + 1) * sizeof(WCHAR));
memcpy(pProcInfo->szVendor, OEMProcVendor,
(strlenW(OEMProcVendor) + 1 ) * sizeof(WCHAR));
pProcInfo->dwInstructionSet = PROCESSOR_16BITINSTRUCTION;
return TRUE;
}
case IOCTL_HAL_DDK_CALL:
if (!lpInBuf || (nInBufSize != sizeof(BUSDATA_PARMS)) || !lpBytesReturned)
{
SetLastError(ERROR_INVALID_PARAMETER);
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);
*lpBytesReturned = sizeof(BUSDATA_PARMS);
return TRUE;
} else {
// Oops, parameter list isn't what we expected.
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
break;
case IOCTL_HAL_GET_IP_ADDR:
if ((lpOutBuf == NULL) || (NULL == lpBytesReturned) ||
(nOutBufSize < sizeof(IP_INFO)))
{
SetLastError(ERROR_INVALID_PARAMETER);
return(FALSE);
}
// Default address to download is IPINFO_DOWNLOAD
len = IPINFO_DOWNLOAD;
if ((NULL != lpInBuf) && (nInBufSize == sizeof(len)))
len = *((DWORD *)lpInBuf);
switch (len) {
case IPINFO_ODO:
pEdbgAddr = &(pDriverGlobals->eth.EdbgAddr);
break;
case IPINFO_DEBUGMSG:
pEdbgAddr = &(pDriverGlobals->eth.DbgHostAddr);
break;
case IPINFO_KDEBUG:
pEdbgAddr = &(pDriverGlobals->eth.KdbgHostAddr);
break;
case IPINFO_ESHELL:
pEdbgAddr = &(pDriverGlobals->eth.CeshHostAddr);
break;
case IPINFO_DOWNLOAD:
default:
pEdbgAddr = &(pDriverGlobals->eth.EshellHostAddr);
}
pIPInfo = (PIP_INFO)lpOutBuf;
pIPInfo->dwIP = pEdbgAddr->dwIP;
memcpy(pIPInfo->MAC, (char *)pEdbgAddr->wMAC, sizeof(pIPInfo->MAC));
*lpBytesReturned = sizeof(IP_INFO);
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:
if (!lpInBuf || !lpBytesReturned || (nInBufSize < sizeof(SYSTEMTIME)))
{
SetLastError( ERROR_INVALID_PARAMETER );
return(FALSE);
}
if (OEMSetRealTime((LPSYSTEMTIME)lpInBuf))
*lpBytesReturned = sizeof(SYSTEMTIME);
break;
case IOCTL_HAL_ENABLE_WAKE:
case IOCTL_HAL_DISABLE_WAKE:
if (lpInBuf && nInBufSize == sizeof(DWORD))
{
DWORD dwReturn = (dwIoControlCode == IOCTL_HAL_ENABLE_WAKE ?
OEMSetWakeupSource( *(PDWORD)lpInBuf) :
OEMResetWakeupSource( *(PDWORD)lpInBuf));
if (dwReturn)
return TRUE;
}
SetLastError (ERROR_INVALID_PARAMETER);
return FALSE;
case IOCTL_HAL_GET_WAKE_SOURCE:
if (lpOutBuf && nOutBufSize>=sizeof(DWORD))
{
*(PDWORD)lpOutBuf=OEMGetWakeupSource();
if (lpBytesReturned)
*lpBytesReturned=sizeof(DWORD);
return TRUE;
}
SetLastError (ERROR_INVALID_PARAMETER);
return FALSE;
case IOCTL_HAL_PRESUSPEND:
OEMClearIntSources();
return TRUE;
case IOCTL_HAL_REBOOT:
//
// Perform a warm reset of the device.
//
// Tell system controller to perform reset
((pvstSP810Regs)VA_SC_BASE)->SCSYSSTAT = 1;
break;
case IOCTL_QUERY_PHYSICALMEM:
if (!lpOutBuf || nOutBufSize < sizeof(PHYSICAL_BASIC_INFORMATION))
{
SetLastError(ERROR_INVALID_PARAMETER);
return(FALSE);
}
// Return information about physical memory
((PPHYSICAL_BASIC_INFORMATION)lpOutBuf)->lpBaseAddress = (LPVOID)0;
((PPHYSICAL_BASIC_INFORMATION)lpOutBuf)->dwRegionSize = 0x00000000;
((PPHYSICAL_BASIC_INFORMATION)lpOutBuf)->dwType = PHYSICAL_UNKNOWN;
break;
case IOCTL_HAL_GET_DEVICEID :
if (!lpOutBuf || !lpBytesReturned || (nOutBufSize < sizeof(DEVICE_ID)))
{
SetLastError (ERROR_INVALID_PARAMETER);
return(FALSE);
}
{
PDEVICE_ID pDeviceID = (PDEVICE_ID)lpOutBuf;
#define ROUNDUP(len) ((len+3)&0xFFFFFFFC)
#define REQ_SIZE (ROUNDUP(sizeof(DEVICE_ID)) + ROUNDUP(sizeof(HALOEMStr)) + ROUNDUP(KITL_MAX_DEV_NAMELEN))
if (pDeviceID->dwSize >= REQ_SIZE)
{
// Tell them how much we actually used.
pDeviceID->dwSize = REQ_SIZE;
pDeviceID->dwPresetIDOffset = ROUNDUP(sizeof(DEVICE_ID));
pDeviceID->dwPresetIDBytes = sizeof(HALOEMStr);
memcpy ((PBYTE)lpOutBuf + pDeviceID->dwPresetIDOffset,
(PBYTE)HALOEMStr, sizeof(HALOEMStr));
pDeviceID->dwPlatformIDOffset = pDeviceID->dwPresetIDOffset +
ROUNDUP(pDeviceID->dwPresetIDBytes);
pDeviceID->dwPlatformIDBytes = KITL_MAX_DEV_NAMELEN;
CreateDeviceName(&pDriverGlobals->eth.EdbgAddr,
(PBYTE)lpOutBuf + pDeviceID->dwPlatformIDOffset,
PLATFORM_STRING);
if (lpBytesReturned)
{
*lpBytesReturned = REQ_SIZE;
}
}
else
{
// Tell them how much we actually need.
pDeviceID->dwSize = REQ_SIZE;
SetLastError (ERROR_INSUFFICIENT_BUFFER);
return(FALSE);
}
}
break;
case IOCTL_HAL_ILTIMING:
{
PILTIMING_MESSAGE pITM = (PILTIMING_MESSAGE) lpInBuf;
if ((nInBufSize != sizeof(ILTIMING_MESSAGE)) || !lpInBuf)
{
SetLastError(ERROR_INVALID_PARAMETER);
return(FALSE);
}
switch (pITM->wMsg)
{
case ILTIMING_MSG_ENABLE:
dwIntrTimeCountdownRef = pITM->dwFrequency;
RETAILMSG(1,
(TEXT("ILTiming Enable (@ every %d ticks)\r\n"),
dwIntrTimeCountdownRef));
dwIntrTimeCountdown = dwIntrTimeCountdownRef;
wNumInterrupts = 0;
dwIsrTime1 = 0xFFFFFFFF;
fIntrTime = TRUE;
break;
case ILTIMING_MSG_DISABLE:
RETAILMSG(1, (TEXT("ILTiming Disable\r\n")));
fIntrTime = FALSE;
break;
case ILTIMING_MSG_GET_TIMES:
pITM->dwIsrTime1 = dwIsrTime1;
pITM->dwIsrTime2 = dwIsrTime2;
pITM->wNumInterrupts = wNumInterrupts;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -