oemioctl.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 481 行 · 第 1/2 页

C
481
字号
/*++
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.

Module Name:  

Abstract:  
   NK Kernel Generic I/O Control Interface
   
Functions:


Notes: 

--*/

#include "windows.h"
#include "drv_glob.h"
#include "ethdbg.h"
#include "halether.h"
#include "nkintr.h"
#include "platform.h"
#include <pkfuncs.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);

#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"S1 HITACHI SH4 PLATFORM";
const WCHAR HALOEMStr[] = L"S1";

// ILTIMING Globals
BOOL  fIntrTime;
BOOL  fIntrTimeToggle;
WORD  wNumInterrupts;
DWORD dwIsrTime1, dwIsrTime2;
DWORD dwSPC;                                                            
DWORD dwIntrTimeCountdown;
DWORD dwIntrTimeCountdownRef;


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.PlatformAddr);
            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 DWORD *)SW_RESET_REG)= SW_RESET_KEY;
        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)) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?