📄 oemioctl.c
字号:
/*++
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, 1996, 1997 Microsoft Corporation
Module Name:
Abstract:
NK Kernel Generic I/O Control Interface
Functions:
Notes:
--*/
#include "windows.h"
#include "p2.h"
#include "drv_glob.h"
#include "ethdbg.h"
#include "halether.h"
#include "nkintr.h"
#include <pkfuncs.h>
#include <iltiming.h>
#include <sa11x0.h>
#include <sa11x0bd.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);
#define pDriverGlobals ((PDRIVER_GLOBALS) DRIVER_GLOBALS_PHYSICAL_MEMORY_START)
/*
@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 preemtible 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>
*/
const WCHAR HALPlatformStr[] = L"ASSABET multi-platform";
const WCHAR HALOEMStr[] = L"ASSABET";
// ILTIMING Globals
BOOL fIntrTime;
BOOL fIntrTimeToggle;
WORD wNumInterrupts;
DWORD dwIsrTime1, dwIsrTime2;
DWORD dwSPC;
DWORD dwIntrTimeCountdown;
DWORD dwIntrTimeCountdownRef;
//void SynchClocks(void);
//void FixupIntrTimeISR(void);
BOOL OEMIoControl(DWORD dwIoControlCode, LPVOID lpInBuf, DWORD nInBufSize,
LPVOID lpOutBuf, DWORD nOutBufSize, LPDWORD lpBytesReturned) {
BOOL retval = FALSE;
DWORD len;
PIP_INFO pIPInfo;
PUDP_PACKET pUDPPacket;
EDBG_ADDR *pEdbgAddr;
EDBG_ADDR DestAddr;
switch (dwIoControlCode) {
case IOCTL_HAL_GET_DEVICE_INFO :
if (nInBufSize == 4) {
switch (*(LPDWORD)lpInBuf) {
case SPI_GETPLATFORMTYPE:
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_SEND_UDP :
if ((lpInBuf == NULL) || (nInBufSize < sizeof(EDBG_ADDR))) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
}
pUDPPacket = (PUDP_PACKET)lpInBuf;
// Send the packet
DestAddr.dwIP = pUDPPacket->dwDestIP;
memcpy ((char *)DestAddr.wMAC, pUDPPacket->DestMAC,
sizeof(pUDPPacket->DestMAC));
DestAddr.wPort = pUDPPacket->wDestPort;
len = EdbgSendUDP(lpInBuf, &DestAddr, pUDPPacket->wSrcPort, pUDPPacket->Packet,
pUDPPacket->wPacketLen);
// This returns 0 for success
if (0 == len) {
retval = TRUE;
}
break;
case IOCTL_HAL_GET_IP_ADDR :
if ((lpOutBuf == NULL) || (NULL == lpBytesReturned) ||
(nOutBufSize < sizeof(IP_INFO))) {
SetLastError(ERROR_INVALID_PARAMETER);
break;
}
// 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.TargetAddr);
break;
case IPINFO_DEBUGMSG :
pEdbgAddr = &(pDriverGlobals->eth.DbgHostAddr);
break;
case IPINFO_KDEBUG :
pEdbgAddr = &(pDriverGlobals->eth.KdbgHostAddr);
break;
case IPINFO_ESHELL :
pEdbgAddr = &(pDriverGlobals->eth.PpshHostAddr);
break;
default :
case IPINFO_DOWNLOAD :
pEdbgAddr = &(pDriverGlobals->eth.DownloadHostAddr);
break;
}
pIPInfo = (PIP_INFO)lpOutBuf;
pIPInfo->dwIP = pEdbgAddr->dwIP;
memcpy (pIPInfo->MAC, (char *)pEdbgAddr->wMAC, sizeof(pIPInfo->MAC));
*lpBytesReturned = sizeof(IP_INFO);
retval = TRUE;
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:
// The kernel has detected a cold-boot. We probably need to reset our Real Time Clock
if( nInBufSize >= sizeof(SYSTEMTIME) )
return OEMSetRealTime( (LPSYSTEMTIME)lpInBuf );
else
return FALSE;
break;
case IOCTL_HAL_REBOOT:
// Perform a warm reset of the device. Note that this requires HW modifications to the standard
// power board.
{
volatile struct rstreg * pRstReg= (volatile struct rstreg *)RST_BASE_VIRTUAL;
pRstReg->rsrr.swr=1;
}
return TRUE;
break;
case IOCTL_QUERY_PHYSICALMEM: {
// Return information about physical memory
#ifdef SH3
if (((DWORD)lpInBuf >= 0)&&((DWORD)lpInBuf < 0x01000000)) {
((PPHYSICAL_BASIC_INFORMATION)lpOutBuf)->lpBaseAddress = (LPVOID)0x00000000;
((PPHYSICAL_BASIC_INFORMATION)lpOutBuf)->dwRegionSize = 0x01000000;
((PPHYSICAL_BASIC_INFORMATION)lpOutBuf)->dwType = PHYSICAL_ROM;
}
else if (((DWORD)lpInBuf >= 0x0C000000)&&((DWORD)lpInBuf < 0x0E000000)) {
((PPHYSICAL_BASIC_INFORMATION)lpOutBuf)->lpBaseAddress = (LPVOID)0x0C000000;
((PPHYSICAL_BASIC_INFORMATION)lpOutBuf)->dwRegionSize = 0x02000000;
((PPHYSICAL_BASIC_INFORMATION)lpOutBuf)->dwType = PHYSICAL_RAM;
}
else {
((PPHYSICAL_BASIC_INFORMATION)lpOutBuf)->lpBaseAddress = (LPVOID)0x00000000;
((PPHYSICAL_BASIC_INFORMATION)lpOutBuf)->dwRegionSize = 0x00000000;
((PPHYSICAL_BASIC_INFORMATION)lpOutBuf)->dwType = PHYSICAL_UNKNOWN;
}
return TRUE;
#endif
((PPHYSICAL_BASIC_INFORMATION)lpOutBuf)->lpBaseAddress = (LPVOID)0x00000000;
((PPHYSICAL_BASIC_INFORMATION)lpOutBuf)->dwRegionSize = 0x00000000;
((PPHYSICAL_BASIC_INFORMATION)lpOutBuf)->dwType = PHYSICAL_UNKNOWN;
return TRUE;
break;
}
#ifdef HALPROFILE
case IOCTL_HAL_PROFILE:
return HalProfileControl(lpInBuf, lpOutBuf,
nOutBufSize, lpBytesReturned);
break;
#endif
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;
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;
pITM->dwSPC = dwSPC;
pITM->dwFrequency = PerfCountFreq();
wNumInterrupts = 0;
// RETAILMSG (1, (TEXT("ILTiming GetTime @ 0x%08X:%08X\r\n"), pITM->dwParam1, pITM->dwParam2));
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);
}
}
} else {
RETAILMSG (1, (TEXT("IOCTL_HAL_ILTIMING : BAD PARAMETERS!!!\r\n")));
SetLastError(ERROR_INVALID_PARAMETER);
return (FALSE);
}
return (TRUE);
}
#ifdef HAL_DVCM
case IOCTL_COLLECTOR_REGISTER:
if( FAILED(Ioctl_Register_DataCollector(lpInBuf,nInBufSize,lpOutBuf,nOutBufSize)))
return FALSE;
else
retval = TRUE;
break;
case IOCTL_COLLECTOR_SEND:
if( FAILED(Ioctl_Send_DataCollector(lpInBuf,nInBufSize,lpOutBuf,nOutBufSize)))
return FALSE;
else
retval = TRUE;
break;
case IOCTL_COLLECTOR_UNREGISTER:
if( FAILED(Ioctl_Unregister_DataCollector(lpInBuf,nInBufSize,lpOutBuf,nOutBufSize)))
return FALSE;
else
retval = TRUE;
break;
#endif // HAL_DVCM
default :
#ifdef INTERNAL_HAL_TESTING
if (retval = InternalHalTesting (dwIoControlCode, lpInBuf, nInBufSize, lpOutBuf, nOutBufSize, lpBytesReturned)) {
break;
}
#endif
SetLastError(ERROR_NOT_SUPPORTED);
break;
}
return retval;
}
#if defined(SHx)
#define RWE_DISABLE 0x0 // Disables BP
#define RWE_READ 0x1
#define RWE_WRITE 0x2
#define RWE_READWRITE 0x3
#define CON_DISABLE 0x0 // Disables BP
#define CON_INST 0x1
#define CON_DATA 0x2
#define CON_BOTH 0x3
#define FULL_ADDR_ENABLE 0x0
#define ASID_DISABLE 0x4
typedef struct _BREAK_BUS_CYCLE *PBREAK_BUS_CYCLE;
typedef struct _BREAK_BUS_CYCLE {
USHORT Size : 2;
USHORT R_WSel : 2;
USHORT I_DSel : 2;
USHORT Pad : 10;
} BREAK_BUS_CYCLE;
#if defined(SHx)
//
// User Break Controller memory-mapped addresses
//
#if SH4
#define UBCBarA 0xFF200000 // 32 bit Break Address A
#define UBCBamrA 0xFF200004 // 8 bit Break Address Mask A
#define UBCBbrA 0xFF200008 // 16 bit Break Bus Cycle A
#define UBCBasrA 0xFF000014 // 8 bit Break ASID A
#define UBCBarB 0xFF20000C // 32 bit Break Address B
#define UBCBamrB 0xFF200010 // 8 bit Break Address Mask B
#define UBCBbrB 0xFF200014 // 16 bit Break Bus Cycle A
#define UBCBasrB 0xFF000018 // 8 bit Break ASID B
#define UBCBdrB 0xFF200018 // 32 bit Break Data B
#define UBCBdmrB 0xFF20001C // 32 bit Break Data Mask B
#define UBCBrcr 0xFF200020 // 16 bit Break Control Register
#else
#define UBCBarA 0xffffffb0
#define UBCBamrA 0xffffffb4
#define UBCBbrA 0xffffffb8
#define UBCBasrA 0xffffffe4
#define UBCBarB 0xffffffa0
#define UBCBamrB 0xffffffa4
#define UBCBbrB 0xffffffa8
#define UBCBasrB 0xffffffe8
#define UBCBdrB 0xffffff90
#define UBCBdmrB 0xffffff94
#define UBCBrcr 0xffffff98
#endif
#endif
#define CLEARUBCA \
WRITE_REGISTER_ULONG(UBCBarA, 0); \
WRITE_REGISTER_USHORT(UBCBrcr, 0); \
WRITE_REGISTER_UCHAR(UBCBamrA, 0); \
WRITE_REGISTER_USHORT(UBCBbrA, 0); \
WRITE_REGISTER_UCHAR(UBCBasrA, 0);
#define CLEARUBCB \
WRITE_REGISTER_ULONG(UBCBarB, 0); \
WRITE_REGISTER_USHORT(UBCBrcr, 0); \
WRITE_REGISTER_UCHAR(UBCBamrB, 0); \
WRITE_REGISTER_USHORT(UBCBbrB, 0); \
WRITE_REGISTER_UCHAR(UBCBasrB, 0);
USHORT BreakBusCycle = 0;
BOOL OEMKDIoControl( DWORD dwIoControlCode, LPVOID lpBuf, DWORD nBufSize)
{
switch(dwIoControlCode) {
case KD_IOCTL_INIT:
CLEARUBCA;
CLEARUBCB;
return TRUE;
case KD_IOCTL_SET_CBP:
case KD_IOCTL_CLEAR_CBP:
case KD_IOCTL_ENUM_CBP:
break;
case KD_IOCTL_QUERY_CBP:
((PKD_BPINFO)lpBuf)->ulCount = 0;
return TRUE;
case KD_IOCTL_SET_DBP:
{
PBREAK_BUS_CYCLE pbbc = (PBREAK_BUS_CYCLE)&BreakBusCycle;
if (!READ_REGISTER_ULONG(UBCBarA)) {
BreakBusCycle = 0;
pbbc->R_WSel = RWE_WRITE;
pbbc->I_DSel = CON_DATA;
WRITE_REGISTER_ULONG(UBCBarA, ((PKD_BPINFO)lpBuf)->ulAddress);
WRITE_REGISTER_USHORT(UBCBrcr, 0);
WRITE_REGISTER_UCHAR(UBCBamrA, FULL_ADDR_ENABLE | ASID_DISABLE);
WRITE_REGISTER_USHORT(UBCBbrA, BreakBusCycle);
WRITE_REGISTER_UCHAR(UBCBasrA, 0);
((PKD_BPINFO)lpBuf)->ulHandle = 1;
return TRUE;
}
if (!READ_REGISTER_ULONG(UBCBarB)) {
BreakBusCycle = 0;
pbbc->R_WSel = RWE_WRITE;
pbbc->I_DSel = CON_DATA;
WRITE_REGISTER_ULONG(UBCBarB, ((PKD_BPINFO)lpBuf)->ulAddress);
WRITE_REGISTER_USHORT(UBCBrcr, 0);
WRITE_REGISTER_UCHAR(UBCBamrB, FULL_ADDR_ENABLE | ASID_DISABLE);
WRITE_REGISTER_USHORT(UBCBbrB, BreakBusCycle);
WRITE_REGISTER_UCHAR(UBCBasrB, 0);
((PKD_BPINFO)lpBuf)->ulHandle = 2;
return TRUE;
}
}
break;
case KD_IOCTL_CLEAR_DBP:
if (((PKD_BPINFO)lpBuf)->ulHandle == 1) {
CLEARUBCA
return TRUE;
}
if (((PKD_BPINFO)lpBuf)->ulHandle == 2) {
CLEARUBCB
return TRUE;
}
break;
case KD_IOCTL_QUERY_DBP:
((PKD_BPINFO)lpBuf)->ulCount = 2;
return TRUE;
case KD_IOCTL_ENUM_DBP:
break;
case KD_IOCTL_MAP_EXCEPTION:
if (((PKD_EXCEPTION_INFO)lpBuf)->ulExceptionCode == 0x80000113) {
((PKD_EXCEPTION_INFO)lpBuf)->ulExceptionCode = STATUS_BREAKPOINT;
return TRUE;
}
break;
case KD_IOCTL_RESET:
*((volatile DWORD *) (CPU_BASE + CPU_RR)) |= 1;
return TRUE;
default:
break;
}
return FALSE;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -