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 + -
显示快捷键?