⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 oemioctl.c

📁 ARM9基于WINDOWSCE的BSP源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
*   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 + -