oemioctl.c
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:13k
源码类别:

Windows CE

开发平台:

Windows_Unix

  1. /*++
  2. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  3. ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  4. THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  5. PARTICULAR PURPOSE.
  6. Copyright (c) 2001. Samsung Electronics, co. ltd  All rights reserved.
  7. Module Name:  
  8. Abstract:
  9.   NK Kernel Generic I/O Control Interface
  10. rev:
  11. 2002.4.3 : First S3C2410 version (SOC)
  12. 2002.1.28 : CE.NET port (kwangyoon LEE, kwangyoon@samsung.com)
  13. Notes: 
  14. --*/
  15. #include <windows.h>
  16. #include <p2.h>
  17. #include <drv_glob.h>
  18. #include <ethdbg.h>
  19. #include <halether.h>
  20. #include <nkintr.h>
  21. #include <pkfuncs.h>
  22. #include <iltiming.h>
  23. #include <kitl.h>
  24. #include <s2440.h>
  25.                      
  26. #ifdef INTERNAL_HAL_TESTING
  27. #include "intioctl.h"
  28. #include "intioctl.c"
  29. #endif
  30. #ifdef IMGSHAREETH
  31. BOOL OEMEthCurrentPacketFilter(PDWORD pdwRequestedFilter);
  32. BOOL OEMEthMulticastList(PUCHAR  pucMulticastAddressList, DWORD  dwNoOfAddresses);
  33. #endif // IMGSHAREETH.
  34. unsigned int strlenW(LPCWSTR str);
  35. #define pDriverGlobals  ((PDRIVER_GLOBALS) DRIVER_GLOBALS_PHYSICAL_MEMORY_START)
  36. /*
  37. @func BOOL | OEMIoControl | generic HAL request
  38. @rdesc none
  39. @comm  OEMIoControl is called by the Kernel when a device driver or application
  40.         program calls <f KernelIoControl>. The system is fully preemtible when this
  41. function is called. The kernel does no processing of this API. It is
  42. provided to allow an OEM device driver to communicate with kernel mode
  43. HAL code.
  44. @xref <l Overview.Windows CE Kernel OEM Interface> <f KernelIoControl>
  45. */
  46. const WCHAR HALPlatformStr[] = L"S3C2440 multi-platform";
  47. const WCHAR HALOEMStr[] = L"S3C2440";
  48. // ILTIMING Globals
  49. BOOL  fIntrTime;
  50. WORD  wNumInterrupts;
  51. DWORD dwIsrTime1, dwIsrTime2;
  52. DWORD dwSPC;                                                            
  53. DWORD dwIntrTimeCountdown;
  54. DWORD dwIntrTimeCountdownRef;
  55. //void SynchClocks(void);
  56. //void FixupIntrTimeISR(void);
  57. extern EDBG_ADDR MyAddr;
  58. void CreateDeviceName(EDBG_ADDR *pMyAddr, char *szBuf);
  59. DWORD OEMTranslateIrq(DWORD dwIrq);
  60. extern VOID OEMCPUPowerReset();
  61. BOOL OEMIoControl(DWORD dwIoControlCode, LPVOID lpInBuf, DWORD nInBufSize,
  62. LPVOID lpOutBuf, DWORD nOutBufSize, LPDWORD lpBytesReturned) {
  63. BOOL retval = FALSE;
  64. DWORD len;
  65. PIP_INFO pIPInfo;
  66. EDBG_ADDR *pEdbgAddr;
  67.     
  68. switch (dwIoControlCode) {
  69.     case IOCTL_PROCESSOR_INFORMATION:
  70.         if (!lpOutBuf) {
  71.             SetLastError(ERROR_INVALID_PARAMETER);
  72.             return FALSE;
  73.         }
  74.     
  75.         if (sizeof(PROCESSOR_INFO) > nOutBufSize) {
  76.             SetLastError(ERROR_INSUFFICIENT_BUFFER);
  77.             return FALSE;
  78.         } else {
  79.             const WCHAR OEMProcCore[] = L"ARM";
  80.             const WCHAR OEMProcName[] = L"ARM920";
  81.             const WCHAR OEMProcVendor[] = L"SAMSUNG";
  82.             PPROCESSOR_INFO pProcInfo = (PPROCESSOR_INFO)lpOutBuf;
  83.     
  84.             if (lpBytesReturned) *lpBytesReturned = sizeof(PROCESSOR_INFO);
  85.             memset(pProcInfo, 0, *lpBytesReturned);
  86.     
  87.             pProcInfo->wVersion = 1;
  88.     
  89.             memcpy(pProcInfo->szProcessCore, OEMProcCore, (strlenW(OEMProcCore) + 1) * sizeof(WCHAR));
  90.             memcpy(pProcInfo->szProcessorName, OEMProcName, (strlenW(OEMProcName) + 1) * sizeof(WCHAR));
  91.             memcpy(pProcInfo->szVendor, OEMProcVendor, (strlenW(OEMProcVendor) + 1 ) * sizeof(WCHAR));
  92.     
  93.             pProcInfo->dwInstructionSet = 0;
  94.     
  95.             return TRUE;
  96.         }
  97. case IOCTL_HAL_GET_DEVICE_INFO :
  98. if (nInBufSize == 4) {
  99. switch (*(LPDWORD)lpInBuf) {
  100. case SPI_GETPLATFORMTYPE:
  101. len = (strlenW(HALPlatformStr)+1)*sizeof(WCHAR);
  102. if (nOutBufSize >= len) {
  103. memcpy(lpOutBuf,HALPlatformStr,len);
  104. retval = TRUE;
  105. } else
  106. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  107. break;
  108. case SPI_GETOEMINFO:
  109. len = (strlenW(HALOEMStr)+1)*sizeof(WCHAR);
  110. if (nOutBufSize >= len) {
  111. memcpy(lpOutBuf,HALOEMStr,len);
  112. retval = TRUE;
  113. } else
  114. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  115. break;
  116. default:
  117. SetLastError(ERROR_INVALID_PARAMETER);
  118. }
  119. } else {
  120. SetLastError(ERROR_INVALID_PARAMETER);
  121. }
  122. break;
  123. case IOCTL_HAL_GET_IP_ADDR :
  124. if ((lpOutBuf == NULL) || (NULL == lpBytesReturned) ||
  125. (nOutBufSize < sizeof(IP_INFO))) {
  126. SetLastError(ERROR_INVALID_PARAMETER);
  127. break;
  128. }
  129. // Default address to download is IPINFO_DOWNLOAD
  130. len = IPINFO_DOWNLOAD;
  131. if ((NULL != lpInBuf) && (nInBufSize ==sizeof(len))) {
  132. len = *((DWORD *)lpInBuf);
  133. }
  134. switch (len) {
  135. case IPINFO_ODO :
  136. pEdbgAddr = &(pDriverGlobals->eth.TargetAddr);
  137. break;
  138. case IPINFO_DEBUGMSG :
  139. pEdbgAddr = &(pDriverGlobals->eth.DbgHostAddr);
  140. break;
  141. case IPINFO_KDEBUG :
  142. pEdbgAddr = &(pDriverGlobals->eth.KdbgHostAddr);
  143. break;
  144. case IPINFO_ESHELL :
  145. pEdbgAddr = &(pDriverGlobals->eth.PpshHostAddr);
  146. break;
  147. default :
  148. case IPINFO_DOWNLOAD :
  149. pEdbgAddr = &(pDriverGlobals->eth.DownloadHostAddr);
  150. break;
  151. }
  152. pIPInfo = (PIP_INFO)lpOutBuf;
  153. pIPInfo->dwIP = pEdbgAddr->dwIP;
  154. memcpy (pIPInfo->MAC, (char *)pEdbgAddr->wMAC, sizeof(pIPInfo->MAC));
  155. *lpBytesReturned = sizeof(IP_INFO);
  156. retval = TRUE;
  157. break;
  158.     case IOCTL_SET_KERNEL_COMM_DEV:
  159.         // Routine to change underlying communications device for kernel services
  160.         return SetKernelCommDev((UCHAR)nInBufSize,(UCHAR)nOutBufSize);
  161.         
  162.     case IOCTL_HAL_INIT_RTC:
  163.         // The kernel has detected a cold-boot.  We probably need to reset our Real Time Clock
  164.         if( nInBufSize >= sizeof(SYSTEMTIME) )
  165.             return OEMSetRealTime( (LPSYSTEMTIME)lpInBuf );
  166.         else
  167.             return FALSE;
  168.         break;
  169. case IOCTL_HAL_REBOOT:
  170. // Warm-reset the device.  Since the SMDK2440 doesn't have any software-accessable board
  171. // logic to assert nRESET to the CPU, we'll use the watchdog timer.  Note that nRSTOUT isn't
  172. // asserted - thus none of the other board-level logic is hardware reset.  Wish there was a 
  173. // better way to do this...
  174. //
  175. OEMCPUPowerReset();
  176. //CPUPowerReset();
  177.         return TRUE;
  178. /*
  179. {
  180. volatile WATCHreg *pWDReg = (volatile WATCHreg *)WATCH_BASE;
  181. // Setup the watchdog.
  182. //
  183. pWDReg->rWTDAT = 0;
  184. pWDReg->rWTCNT = 5; // Load count with low value (value can be used to hold nRSTOUT assertion).
  185. pWDReg->rWTCON = 0x8021; // Enable watchdog timer...
  186. // Wait for watchdog reset...
  187. //
  188. while(TRUE);
  189. }
  190. */
  191.         break;
  192. case IOCTL_QUERY_PHYSICALMEM: {
  193. // Return information about physical memory
  194. if (nOutBufSize>=sizeof(PHYSICAL_BASIC_INFORMATION) && lpOutBuf!=NULL) {
  195. ((PPHYSICAL_BASIC_INFORMATION)lpOutBuf)->lpBaseAddress = (LPVOID)0x00000000;
  196. ((PPHYSICAL_BASIC_INFORMATION)lpOutBuf)->dwRegionSize = 0x00000000;
  197. ((PPHYSICAL_BASIC_INFORMATION)lpOutBuf)->dwType = PHYSICAL_UNKNOWN;
  198. return TRUE;
  199. }
  200. else {
  201. SetLastError(ERROR_INVALID_PARAMETER);
  202. return FALSE;
  203. }
  204. break;
  205. }
  206. case IOCTL_HAL_TRANSLATE_IRQ:
  207. // Translate a logical interrupt number to a SYSINTR value.
  208. //
  209. if (nInBufSize>=sizeof(PULONG) && nOutBufSize>=sizeof(PULONG) &&
  210. lpOutBuf && lpInBuf) {
  211.             *(PULONG)lpOutBuf = OEMTranslateIrq(*(PULONG)lpInBuf);
  212.             if (lpBytesReturned)
  213.                 *lpBytesReturned = sizeof(ULONG);
  214.             retval = TRUE;
  215. }
  216. else {
  217. SetLastError(ERROR_INVALID_PARAMETER);
  218. retval=FALSE;
  219. }
  220. break;
  221.     case IOCTL_HAL_GET_DEVICEID :
  222.         if (!lpOutBuf || (nOutBufSize < sizeof(DEVICE_ID))) {
  223.             SetLastError (ERROR_INVALID_PARAMETER);
  224.             return FALSE;
  225.         } else {
  226.             PDEVICE_ID  pDeviceID = (PDEVICE_ID)lpOutBuf;
  227.             
  228. #define ROUNDUP(len)        ((len+3)&0xFFFFFFFC)
  229. #define REQ_SIZE            (ROUNDUP(sizeof(DEVICE_ID)) + ROUNDUP(sizeof(HALOEMStr)) + ROUNDUP(KITL_MAX_DEV_NAMELEN))
  230.             
  231.             if (pDeviceID->dwSize >= REQ_SIZE) {
  232.                 // Tell them how much we actually used.
  233.                 pDeviceID->dwSize = REQ_SIZE;
  234.                 pDeviceID->dwPresetIDOffset = ROUNDUP(sizeof(DEVICE_ID));
  235.                 pDeviceID->dwPresetIDBytes = sizeof(HALOEMStr);
  236.                 memcpy ((PBYTE)lpOutBuf + pDeviceID->dwPresetIDOffset, (PBYTE)HALOEMStr, sizeof(HALOEMStr));
  237.                 
  238.                 pDeviceID->dwPlatformIDOffset = pDeviceID->dwPresetIDOffset + ROUNDUP(pDeviceID->dwPresetIDBytes);
  239.                 pDeviceID->dwPlatformIDBytes = KITL_MAX_DEV_NAMELEN;
  240.                 CreateDeviceName(&pDriverGlobals->eth.TargetAddr, (PBYTE)lpOutBuf + pDeviceID->dwPlatformIDOffset);
  241.                 if (lpBytesReturned) {
  242.                     *lpBytesReturned = REQ_SIZE;
  243.                 }
  244.                 SetLastError(0);
  245.                 return TRUE;
  246.                 
  247.             } else {
  248.                 // Tell them how much we actually need.
  249.                 pDeviceID->dwSize = REQ_SIZE;
  250.                 SetLastError (ERROR_INSUFFICIENT_BUFFER);
  251.                 return FALSE;
  252.             }
  253.         }
  254.         break;
  255.     case IOCTL_HAL_ILTIMING : {
  256.         
  257.         if ((nInBufSize == sizeof(ILTIMING_MESSAGE)) && (lpInBuf != NULL)) {
  258.             
  259.             extern DWORD PerfCountSinceTick();
  260.             extern DWORD PerfCountFreq();
  261.             
  262.             PILTIMING_MESSAGE pITM = (PILTIMING_MESSAGE) lpInBuf;
  263.             
  264.             switch (pITM->wMsg) {
  265.                 
  266.                 case ILTIMING_MSG_ENABLE : {
  267.                     dwIntrTimeCountdownRef = pITM->dwFrequency;
  268.                     RETAILMSG (1, (TEXT("ILTiming Enable (@ every %d ticks)rn"), dwIntrTimeCountdownRef));
  269.                     dwIntrTimeCountdown = dwIntrTimeCountdownRef;
  270.                     wNumInterrupts = 0;
  271.                     dwIsrTime1 = 0xFFFFFFFF;
  272.                     fIntrTime = TRUE;
  273.                     break;
  274.                 }
  275.                 
  276.                 case ILTIMING_MSG_DISABLE : {
  277.                     RETAILMSG (1, (TEXT("ILTiming Disablern")));
  278.                     fIntrTime = FALSE;
  279.                     break;
  280.                 }
  281.                 
  282.                 case ILTIMING_MSG_GET_TIMES : {
  283.                     pITM->dwIsrTime1 = dwIsrTime1;
  284.                     pITM->dwIsrTime2 = dwIsrTime2;
  285.                     pITM->wNumInterrupts = wNumInterrupts;
  286.                     pITM->dwSPC = dwSPC;
  287.                     pITM->dwFrequency = PerfCountFreq();
  288.                     wNumInterrupts = 0;
  289.                     // RETAILMSG (1, (TEXT("ILTiming GetTime @ 0x%08X:%08Xrn"), pITM->dwParam1, pITM->dwParam2));
  290.                     break;
  291.                 }
  292.                 
  293.                 case ILTIMING_MSG_GET_PFN : {
  294.                     pITM->pfnPerfCountSinceTick = (PVOID) PerfCountSinceTick;
  295.                     RETAILMSG (1, (TEXT("ILTiming GetPFNrn")));
  296.                     break;
  297.                 }
  298.                 
  299.                 default : {
  300.                     RETAILMSG (1, (TEXT("IOCTL_HAL_ILTIMING : BAD MESSAGE!!!rn")));
  301.                     SetLastError(ERROR_INVALID_PARAMETER);
  302.                     return (FALSE);
  303.                 }
  304.             }
  305.     
  306.         } else {
  307.             RETAILMSG (1, (TEXT("IOCTL_HAL_ILTIMING : BAD PARAMETERS!!!rn")));
  308.             SetLastError(ERROR_INVALID_PARAMETER);
  309.             return (FALSE);
  310.         }
  311.         return (TRUE);
  312.     }
  313. #if IMGSHAREETH
  314.     ////////////////////////////////////////////////////////////////////////////
  315.     //  The support for VMini..
  316.     //
  317.     case IOCTL_VBRIDGE_GET_TX_PACKET:
  318.         return VBridgeUGetOneTxPacket((PUCHAR *)lpOutBuf, nInBufSize);
  319.     case IOCTL_VBRIDGE_GET_TX_PACKET_COMPLETE:
  320.         VBridgeUGetOneTxPacketComplete((PUCHAR)lpInBuf, nInBufSize);
  321.         return TRUE;
  322.     case IOCTL_VBRIDGE_GET_RX_PACKET:
  323.         return VBridgeUGetOneRxPacket((PUCHAR *)lpOutBuf, lpBytesReturned);
  324.     case IOCTL_VBRIDGE_GET_RX_PACKET_COMPLETE:
  325.         VBridgeUGetOneRxPacketComplete((PUCHAR)lpInBuf);
  326.         return TRUE;
  327.     case IOCTL_VBRIDGE_GET_ETHERNET_MAC:
  328.         VBridgeUGetEDBGMac((PBYTE)lpOutBuf);
  329.         return TRUE;
  330. case IOCTL_VBRIDGE_CURRENT_PACKET_FILTER:
  331. ////////////////////////////////////////////////////////////////////////
  332. // First, see if filter setting is implemented, then inform vbridge
  333. // on the new filtering.
  334. //
  335. if (OEMEthCurrentPacketFilter((PDWORD)lpInBuf))
  336. {
  337. VBridgeUCurrentPacketFilter((PDWORD)lpInBuf);
  338. return TRUE;
  339. }
  340. return FALSE;
  341. case IOCTL_VBRIDGE_802_3_MULTICAST_LIST:
  342. if (OEMEthMulticastList((PUCHAR)lpInBuf, nInBufSize))
  343. return TRUE;
  344. return FALSE;
  345. case IOCTL_VBRIDGE_WILD_CARD:
  346. return VBridgeUWildCard(
  347. lpInBuf,
  348. nInBufSize,
  349. lpOutBuf,
  350. nOutBufSize,
  351. lpBytesReturned);
  352.         
  353.     case IOCTL_VBRIDGE_SHARED_ETHERNET:
  354.         ////////////////////////////////////////////////////////////////////////
  355.         //  Yes, this kernel supports shared ethernet port.
  356.         //
  357.         return TRUE;
  358. #endif // IMGSHAREETH.
  359. default :
  360. #ifdef INTERNAL_HAL_TESTING
  361. if (retval = InternalHalTesting (dwIoControlCode, lpInBuf, nInBufSize, lpOutBuf, nOutBufSize, lpBytesReturned)) {
  362. break;
  363. }
  364. #endif
  365. SetLastError(ERROR_NOT_SUPPORTED);
  366. break;
  367. }
  368.     return retval;
  369. }