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

📄 oemioctl.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 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 + -