BOOL OEMKitlStartup(void) { OAL_KITL_ARGS KITLArgs; OAL_KITL_ARGS *pKITLArgs; BOOL bRet = FALSE; UCHAR *szDeviceId,buffer[OAL_KITL_ID_SIZE]="\0"; OALMSG(OAL_KITL&&OAL_FUNC, (L"[KITL] ++OEMKitlStartup()\r\n")); // Look for bootargs left by the bootloader or left over from an earlier boot. // pKITLArgs = (OAL_KITL_ARGS *)OALArgsQuery(OAL_ARGS_QUERY_KITL); szDeviceId = (UCHAR*)OALArgsQuery(OAL_ARGS_QUERY_DEVID); // If no KITL arguments were found (typically provided by the bootloader), then select // some default settings. // if (pKITLArgs == NULL) { memset(&KITLArgs, 0, sizeof(OAL_KITL_ARGS)); // By default, enable KITL and use USB Serial KITLArgs.flags |= OAL_KITL_FLAGS_ENABLED; KITLArgs.devLoc.IfcType = Internal; KITLArgs.devLoc.BusNumber = 0; KITLArgs.devLoc.PhysicalLoc = (PVOID)S3C6410_BASE_REG_PA_USBOTG_LINK; KITLArgs.devLoc.LogicalLoc = (DWORD)KITLArgs.devLoc.PhysicalLoc; pKITLArgs = &KITLArgs; } if (pKITLArgs->devLoc.LogicalLoc == BSP_BASE_REG_PA_DM9000A_IOBASE) { // Ethernet specific initialization //configure chipselect for DM9000A InitSROMC_DM9000A(); //setting EINT7 as IRQ_LAN if (!(pKITLArgs->flags & OAL_KITL_FLAGS_POLL)) { g_pGPIOReg = (S3C6410_GPIO_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_GPIO, FALSE); } // Setup pointers to the power on and power off functions to enable KITL // functionality across suspend/resume // Modify the g_kitlEthCS8900A structure defined in kitl_cfg.h g_kitlEthDM9000A.pfnPowerOff = (OAL_KITLETH_POWER_OFF)BSPKitlEthPowerOff; g_kitlEthDM9000A.pfnPowerOn = (OAL_KITLETH_POWER_ON)BSPKitlEthPowerOn; } bRet = OALKitlInit ((LPCSTR)szDeviceId, pKITLArgs, g_kitlDevices); OALMSG(OAL_KITL&&OAL_FUNC, (L"[KITL] --OEMKitlStartup() = %d\r\n", bRet)); return bRet; }
//------------------------------------------------------------------------------ // // Function: OALIoCtlHalQueryDisplaySettings // // This function is called by GDI to query the kernel for information // about a preferred resolution for the system to use. // static BOOL OALIoCtlHalQueryDisplaySettings( UINT32 dwIoControlCode, VOID *lpInBuf, UINT32 nInBufSize, VOID *lpOutBuf, UINT32 nOutBufSize, UINT32* lpBytesReturned) { DWORD dwErr = 0; DWORD *displayType; DWORD *framebufferDepth; OALMSG(TRUE, (TEXT("++OALIoCtlHalQueryDisplaySettings()\r\n"))); displayType=(DWORD*) OALArgsQuery(BSP_ARGS_QUERY_DISPLAYTYPE); OALMSG(TRUE, (TEXT("++BSP_ARGS_QUERY_DISPLAYTYPE: %d\r\n"), *displayType)); framebufferDepth=(DWORD*) OALArgsQuery(BSP_ARGS_QUERY_FRAMEBUFFERDEPTH); OALMSG(TRUE, (TEXT("++BSP_ARGS_QUERY_FRAMEBUFFERDEPTH: %d\r\n"), *framebufferDepth)); if (lpBytesReturned) { *lpBytesReturned = 0; } if (lpOutBuf == NULL) { dwErr = 1; } else if ((sizeof(DWORD)*2) > nOutBufSize) { dwErr = 2; } else { // Check the boot arg structure for the default display settings. __try { ((PDWORD)lpOutBuf)[0] = (DWORD)(*displayType); ((PDWORD)lpOutBuf)[1] = (DWORD)(*framebufferDepth); if (lpBytesReturned) { *lpBytesReturned = sizeof (DWORD)*2; } } __except (EXCEPTION_EXECUTE_HANDLER) { dwErr = 3; } } if (dwErr) { OALMSG(OAL_ERROR, (TEXT("[OAL:ERR] OALIoCtlHalQueryDisplaySettings() Failed dwErr = %s\r\n"), (dwErr==1)?"outbuf is NULL":"size of outbuf is too small")); NKSetLastError(dwErr); } OALMSG(TRUE, (TEXT("++OALIoCtlHalQueryDisplaySettings()\r\n"))); return !dwErr; }
static BOOL OALIoCtlEBootMAC( UINT32 dwIoControlCode, VOID *lpInBuf, UINT32 nInBufSize, VOID *lpOutBuf, UINT32 nOutBufSize, UINT32* lpBytesReturned) { OAL_KITL_ARGS *pKITLArgs; BOOL rc = FALSE; pKITLArgs = (OAL_KITL_ARGS *)OALArgsQuery(OAL_ARGS_QUERY_KITL); // Check buffer size if (lpBytesReturned != NULL) { *lpBytesReturned = sizeof(UINT8[6]); } if (lpOutBuf == NULL || nOutBufSize < sizeof(UINT8[6])) { NKSetLastError(ERROR_INSUFFICIENT_BUFFER); RETAILMSG(TRUE, (L"WARN: OALIoCtlEBootMAC: Buffer too small\r\n")); } else { // Copy pattern to output buffer memcpy(lpOutBuf, pKITLArgs->mac, sizeof(UINT8[6])); // We are done rc = TRUE; } // Indicate status //OALMSG(OAL_IOCTL&&OAL_FUNC, (L"-OALIoCtlEBootMAC(rc = %d)\r\n", rc)); RETAILMSG(TRUE, (L"-OALIoCtlEBootMAC(rc = %d)\r\n", rc)); return rc; }
void BSPKitlEthPowerOn(void) { OAL_KITL_ARGS *pKITLArgs; PBYTE pBaseIOAddress = NULL; UINT32 MemoryBase = 0; KITL_RETAILMSG(ZONE_INIT, ("BSPKitlEthPowerOn: Powering On Ethernet KITL.\r\n")); pKITLArgs = (OAL_KITL_ARGS *)OALArgsQuery(OAL_ARGS_QUERY_KITL); if (pKITLArgs == NULL) { // This should do not happen, since this function is part of the Eth KITL driver structure // But still, just in case... KITL_RETAILMSG(ZONE_ERROR, ("BSPKitlEthPowerOn: No KITL args, returning.\r\n")); return; } //configure chipselect for DM9000A InitSROMC_DM9000A(); pBaseIOAddress = (PBYTE)OALPAtoVA(pKITLArgs->devLoc.LogicalLoc, FALSE); MemoryBase = (UINT32)OALPAtoVA(BSP_BASE_REG_PA_DM9000A_MEMBASE, FALSE); // Initialize the controller. if (!DM9000AInit((PBYTE)pBaseIOAddress, MemoryBase, pKITLArgs->mac)) { KITL_RETAILMSG(ZONE_INIT, ("BSPKitlEthPowerOn: ERROR: Failed to re-initialize Ethernet controller.\r\n")); } }
//------------------------------------------------------------------------------ // // Function: OALIoCtlHalQueryFormatPartition // // This function is called by Filesys.exe to allow an OEM to specify whether a specific // partition is to be formatted on mount. Before Filesys.exe calls this IOCTL, it checks // the CheckForFormat registry value in the storage profile for your block driver. // static BOOL OALIoCtlHalQueryFormatPartition( UINT32 code, VOID *lpInBuf, UINT32 nInBufSize, VOID *lpOutBuf, UINT32 nOutBufSize, UINT32 *pOutSize) { OALMSG(OAL_IOCTL&&OAL_FUNC, (TEXT("++OALIoCtlHalFormatPartition()\r\n"))); if ( (lpInBuf == NULL) ||(nInBufSize != sizeof(STORAGECONTEXT)) || (lpOutBuf == NULL) || (nOutBufSize < sizeof(BOOL))) { OALMSG(OAL_ERROR, (TEXT("[OAL:ERR] OALIoCtlHalFormatPartition() Invalid Input Parameter\r\n"))); return FALSE; } else { STORAGECONTEXT *pStore = (STORAGECONTEXT *)lpInBuf; BOOL *pbClean = (BOOL *)lpOutBuf; // This is the global shared Args flag BOOL *bFormatPartFlag = (BOOL *) OALArgsQuery(BSP_ARGS_QUERY_FORMATPART); OALMSG(OAL_VERBOSE, (TEXT("[OAL] Store partition info:\r\n"))); OALMSG(OAL_VERBOSE, (TEXT("[OAL] \tszPartitionName=%s\r\n"), pStore->PartInfo.szPartitionName)); OALMSG(OAL_VERBOSE, (TEXT("[OAL] \tsnNumSectors=%d\r\n"), pStore->PartInfo.snNumSectors)); OALMSG(OAL_VERBOSE, (TEXT("[OAL] \tdwAttributes=0x%x\r\n"), pStore->PartInfo.dwAttributes)); OALMSG(OAL_VERBOSE, (TEXT("[OAL] \tbPartType=0x%x\r\n"), pStore->PartInfo.bPartType)); // Set return value *pbClean = *bFormatPartFlag; // Clear the flag so that we don't do it again in next boot unless it is set again. *bFormatPartFlag = FALSE; if(*pbClean) { if(pStore->dwFlags & AFS_FLAG_BOOTABLE) { OALMSG(TRUE, (TEXT("[OAL] Clear Storage (System Registry Hive)\r\n"))); } else { OALMSG(TRUE, (TEXT("[OAL] Clear Storage\r\n"))); } } else { OALMSG(TRUE, (TEXT("[OAL] Not Clear Storage\r\n"))); } } if(pOutSize) { *pOutSize = sizeof(UINT32); } OALMSG(OAL_IOCTL&&OAL_FUNC, (TEXT("--OALIoCtlHalFormatPartition()\r\n"))); return TRUE; }
void InitPowerCTL() { DWORD *powerCTL; volatile S3C6410_GPIO_REG *pGPIOReg = (S3C6410_GPIO_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_GPIO, FALSE); powerCTL = (DWORD *)OALArgsQuery(BSP_ARGS_QUERY_POWERCTL); PWRCTL_InitializePowerCTL(powerCTL,pGPIOReg); }
//------------------------------------------------------------------------------ // // Function: OALIoCtlHalPowerCTL // // This function is called by GDI to query the kernel for information // about a preferred resolution for the system to use. // static BOOL OALIoCtlHalPowerCTL( UINT32 dwIoControlCode, VOID *lpInBuf, UINT32 nInBufSize, VOID *lpOutBuf, UINT32 nOutBufSize, UINT32* lpBytesReturned) { DWORD dwErr = 0; DWORD *powerCTL; OALMSG(OAL_IOCTL&&OAL_FUNC, (TEXT("++OALIoCtlHalPowerCTL()\r\n"))); powerCTL=(DWORD*) OALArgsQuery(BSP_ARGS_QUERY_POWERCTL); if (lpBytesReturned) { *lpBytesReturned = 0; } if (lpOutBuf == NULL) { dwErr = ERROR_INVALID_PARAMETER; } else if (sizeof(DWORD)*1 > nOutBufSize) { dwErr = ERROR_INSUFFICIENT_BUFFER; } else { // Check the boot arg structure for the default display settings. __try { ((PDWORD)lpOutBuf)[0] = (DWORD)(*powerCTL); if (lpBytesReturned) { *lpBytesReturned = sizeof (DWORD)*1; } } __except (EXCEPTION_EXECUTE_HANDLER) { dwErr = ERROR_INVALID_PARAMETER; } } if (dwErr) { OALMSG(OAL_ERROR, (TEXT("[OAL:ERR] OALIoCtlHalPowerCTL() Failed dwErr = 0x%08x\r\n"), dwErr)); NKSetLastError(dwErr); } OALMSG(OAL_IOCTL&&OAL_FUNC, (TEXT("++OALIoCtlHalPowerCTL()\r\n"))); return !dwErr; }
//------------------------------------------------------------------------------ // // Function: OALIoCtlHalGetHWEntropy // // Implements the IOCTL_HAL_GET_HWENTROPY handler. This function creates a // 64-bit value which is unique to the hardware. This value never changes. // static BOOL OALIoCtlHalGetHWEntropy( UINT32 dwIoControlCode, VOID *lpInBuf, UINT32 nInBufSize, VOID *lpOutBuf, UINT32 nOutBufSize, UINT32* lpBytesReturned) { // TODO by Device Maker : This code is only sample. // S3C6410 has IDs only for chip type not for each chip. // If Device Maker wants unique ID for each device // Device maker must modify this function. // If Device has Ethernet Device, Use MAC address // Recommended method is to use NAND's ID or UUIC's ID // Device maker can make Unique ID with CHIP ID UINT8 *UniqueID; BOOL rc = FALSE; OALMSG(OAL_IOCTL&&OAL_FUNC, (L"+OALIoCtlHalGetHWEntropy\r\n")); UniqueID = (UINT8 *)OALArgsQuery(OAL_ARGS_QUERY_UUID); // Check buffer size if (lpBytesReturned != NULL) { *lpBytesReturned = sizeof(UINT8[16]); } if (lpOutBuf == NULL || nOutBufSize < sizeof(UINT8[16])) { NKSetLastError(ERROR_INSUFFICIENT_BUFFER); OALMSG(OAL_WARN, (L"WARN: OALIoCtlHalGetHWEntropy: Buffer too small\r\n")); } else { // Copy pattern to output buffer memcpy(lpOutBuf, UniqueID, sizeof(UINT8[16])); // We are done rc = TRUE; } // Indicate status OALMSG(OAL_IOCTL&&OAL_FUNC, (L"-OALIoCtlHalGetHWEntropy(rc = %d)\r\n", rc)); return rc; }
//------------------------------------------------------------------------------ // // Function: OEMInit // // This is Windows CE OAL initialization function. It is called from kernel // after basic initialization is made. // void OEMInit() { BOOL *bCleanBootFlag; OALMSG(OAL_FUNC, (L"[OAL] ++OEMInit()\r\n")); OALMSG(OAL_FUNC, (TEXT("[OAL] S3C6410_APLL_CLK : %d\n\r"), System_GetAPLLCLK())); OALMSG(OAL_FUNC, (TEXT("[OAL] ARMCLK : %d\n\r"), System_GetARMCLK())); OALMSG(OAL_FUNC, (TEXT("[OAL] HCLK : %d\n\r"), System_GetHCLK())); OALMSG(OAL_FUNC, (TEXT("[OAL] PCLK : %d\n\r"), System_GetPCLK())); OALMSG(1, (TEXT("[OAL] S3C6410_APLL_CLK : %d\n\r"), System_GetAPLLCLK())); OALMSG(1, (TEXT("[OAL] ARMCLK : %d\n\r"), System_GetARMCLK())); OALMSG(1, (TEXT("[OAL] HCLK : %d\n\r"), System_GetHCLK())); OALMSG(1, (TEXT("[OAL] PCLK : %d\n\r"), System_GetPCLK())); g_oalIoCtlClockSpeed = System_GetARMCLK(); //CEProcessorType = PROCESSOR_STRONGARM; // Set memory size for DrWatson kernel support // dwNKDrWatsonSize = 128 * 1024; // Intialize optional kernel functions. (Processor Extended Feature) // g_pOemGlobal->pfnIsProcessorFeaturePresent = (PFN_IsProcessorFeaturePresent)OALIsProcessorFeaturePresent; // Set OEMSetMemoryAttributes function g_pOemGlobal->pfnSetMemoryAttributes = (PFN_SetMemoryAttributes)OEMSetMemoryAttributes; // Turn Off all Debug LED // // Initialize Clock Source // InitializeCLKSource(); // Initialize Clock Gating // InitializeCLKGating(); // Initialize Block Power // InitializeBlockPower(); // Initialize ExtPowerCTL // InitPowerCTL(); // Initialize OTG PHY Clock // InitializeOTGCLK(); // Initialize BCD registers in RTC to known values // Initilize cache globals // OALCacheGlobalsInit(); OALLogSerial(L"DCache: %d sets, %d ways, %d line size, %d size\r\n", g_oalCacheInfo.L1DSetsPerWay, g_oalCacheInfo.L1DNumWays, g_oalCacheInfo.L1DLineSize, g_oalCacheInfo.L1DSize); OALLogSerial(L"ICache: %d sets, %d ways, %d line size, %d size\r\n", g_oalCacheInfo.L1ISetsPerWay, g_oalCacheInfo.L1INumWays, g_oalCacheInfo.L1ILineSize, g_oalCacheInfo.L1ISize); // Check and Initialize the BSP Args area // OALArgsInit((BSP_ARGS *)IMAGE_SHARE_ARGS_UA_START); // Check clean boot flag in BSP Args area // OALMSG(OAL_FUNC, (TEXT("[OAL] OEMInit() : BSP Args forces Clean Boot\r\n"))); bCleanBootFlag = (BOOL *)OALArgsQuery(BSP_ARGS_QUERY_CLEANBOOT); if (*bCleanBootFlag) { // Notify to filesys.exe that we want a clean boot. NKForceCleanBoot(); } // Initialize Interrupts // if (!OALIntrInit()) { OALMSG(OAL_ERROR, (L"[OAL:ERR] OEMInit() : failed to initialize interrupts\r\n")); } // Initialize System Clock // OALTimerInit(RESCHED_PERIOD, (OEM_COUNT_1MS ), 0); // Make high-res Monte Carlo profiling available to the kernel // g_pOemGlobal->pfnProfileTimerEnable = OEMProfileTimerEnable; g_pOemGlobal->pfnProfileTimerDisable = OEMProfileTimerDisable; // Initialize the KITL connection if required // KITLIoctl(IOCTL_KITL_STARTUP, NULL, 0, NULL, 0, NULL); InitializeBank(); OALMSG(OAL_FUNC, (L"[OAL] --OEMInit()\r\n")); }
//------------------------------------------------------------------------------ // // Function: OEMPowerOff // // Description: Called when the system is to transition to it's lowest power mode (off) // // void OEMPowerOff() { volatile S3C6400_SYSCON_REG *pSysConReg; volatile S3C6400_GPIO_REG *pGPIOReg; volatile S3C6400_VIC_REG *pVIC0Reg; volatile S3C6400_VIC_REG *pVIC1Reg; volatile S3C6400_DMAC_REG *pDMAC0Reg; volatile S3C6400_DMAC_REG *pDMAC1Reg; int nIndex = 0; OALMSG(TRUE, (L"[OEM] ++OEMPowerOff()")); #if 0 // KITL can not support Sleep // Make sure that KITL is powered off pArgs = (OAL_KITL_ARGS*)OALArgsQuery(OAL_ARGS_QUERY_KITL); if ((pArgs->flags & OAL_KITL_FLAGS_ENABLED) != 0) { OALKitlPowerOff(); OALMSG(1, (L"OEMPowerOff: KITL Disabled\r\n")); } #endif //----------------------------- // Disable DVS and Set to Full Speed //----------------------------- #ifdef DVS_EN ChangeDVSLevel(SYS_L0); #endif //----------------------------- // Prepare Specific Actions for Sleep //----------------------------- BSPPowerOff(); //------------------------------ // Prepare CPU Entering Sleep Mode //------------------------------ //---------------- // Map SFR Address //---------------- pSysConReg = (S3C6400_SYSCON_REG *)OALPAtoVA(S3C6400_BASE_REG_PA_SYSCON, FALSE); pGPIOReg = (S3C6400_GPIO_REG *)OALPAtoVA(S3C6400_BASE_REG_PA_GPIO, FALSE); pVIC0Reg = (S3C6400_VIC_REG *)OALPAtoVA(S3C6400_BASE_REG_PA_VIC0, FALSE); pVIC1Reg = (S3C6400_VIC_REG *)OALPAtoVA(S3C6400_BASE_REG_PA_VIC1, FALSE); pDMAC0Reg = (S3C6400_DMAC_REG *)OALPAtoVA(S3C6400_BASE_REG_PA_DMA0, FALSE); pDMAC1Reg = (S3C6400_DMAC_REG *)OALPAtoVA(S3C6400_BASE_REG_PA_DMA1, FALSE); //------------------ // Save VIC Registers //------------------ S3C6400_SaveState_VIC((void *)pVIC0Reg, (void *)pVIC1Reg, g_aSleepSave_VIC); // Disable All Interrupt pVIC0Reg->VICINTENCLEAR = 0xFFFFFFFF; pVIC1Reg->VICINTENCLEAR = 0xFFFFFFFF; pVIC0Reg->VICSOFTINTCLEAR = 0xFFFFFFFF; pVIC1Reg->VICSOFTINTCLEAR = 0xFFFFFFFF; //-------------------- // Save DMAC Registers //-------------------- S3C6400_SaveState_DMACon((void *)pDMAC0Reg, g_aSleepSave_DMACon0); S3C6400_SaveState_DMACon((void *)pDMAC1Reg, g_aSleepSave_DMACon1); //------------------ // Save GPIO Register //------------------ S3C6400_SaveState_GPIO((void *)pGPIOReg, g_aSleepSave_GPIO); //-------------------- // Save SysCon Register //-------------------- S3C6400_SaveState_SysCon((void *)pSysConReg, g_aSleepSave_SysCon); //------------------------------------------------------- // Unmask Clock Gating and Block Power turn On (SW workaround) //------------------------------------------------------- // HCLK_IROM, HCLK_MEM1, HCLK_MEM0, HCLK_MFC Should be Always On for power Mode (Something coupled with BUS operation) //pSysConReg->HCLK_GATE |= ((1<<25)|(1<<22)|(1<<21)|(1<<0)); pSysConReg->HCLK_GATE = 0xFFFFFFFF; pSysConReg->PCLK_GATE = 0xFFFFFFFF; pSysConReg->SCLK_GATE = 0xFFFFFFFF; // Turn On All Block Block Power pSysConReg->NORMAL_CFG = 0xFFFFFF00; // Wait for Block Power Stable while((pSysConReg->BLK_PWR_STAT & 0x7E) != 0x7E); //---------------------------- // Wake Up Source Configuration //---------------------------- S3C6400_WakeUpSource_Configure(); //------------------------------- // Extra work for Entering Sleep Mode //------------------------------- // USB Power Control pSysConReg->OTHERS &= ~(1<<16); // USB Signal Mask Clear pGPIOReg->SPCON |= (1<<3); // USB Tranceiver PAD to Suspend // TODO: SPCONSLP ??? //pGPIOReg->SPCONSLP; // Use Default Valie //------------------------------- // GPIO Configuration for Sleep State //------------------------------- // TODO: Configure GPIO at Sleep //BSPConfigGPIOforPowerOff(); // Sleep Mode Pad Configuration pGPIOReg->SLPEN = 0x2; // Controlled by SLPEN Bit (You Should Clear SLPEN Bit in Wake Up Process...) //----------------------- // CPU Entering Sleep Mode //----------------------- OALCPUPowerOff(); // Now in Sleep //---------------------------- // CPU Wake Up from Sleep Mode //---------------------------- //---------------------------- // Wake Up Source Determine //---------------------------- S3C6400_WakeUpSource_Detect(); // USB Power Control pSysConReg->OTHERS |= (1<<16); // TODO: USB Signal Mask Set (Device must handle it...) pGPIOReg->SPCON &= ~(1<<3); // USB Tranceiver PAD to Normal // Restore SysCon Register S3C6400_RestoreState_SysCon((void *)pSysConReg, g_aSleepSave_SysCon); // Restore GPIO Register S3C6400_RestoreState_GPIO((void *)pGPIOReg, g_aSleepSave_GPIO); // Sleep Mode Pad Configuration pGPIOReg->SLPEN = 0x2; // Clear SLPEN Bit for Pad back to Normal Mode //----------------------- // Restore DMAC Registers //----------------------- S3C6400_RestoreState_DMACon((void *)pDMAC0Reg, g_aSleepSave_DMACon0); S3C6400_RestoreState_DMACon((void *)pDMAC1Reg, g_aSleepSave_DMACon1); // Restore VIC Registers S3C6400_RestoreState_VIC((void *)pVIC0Reg, (void *)pVIC1Reg, g_aSleepSave_VIC); //pVIC0Reg->VICADDRESS = 0x0; //pVIC1Reg->VICADDRESS = 0x0; // UART Debug Port Initialize OEMInitDebugSerial(); // Disable Vectored Interrupt Mode on CP15 System_DisableVIC(); // Enable Branch Prediction on CP15 System_EnableBP(); // Enable IRQ Interrupt on CP15 System_EnableIRQ(); // Enable FIQ Interrupt on CP15 System_EnableFIQ(); if (g_oalWakeSource == SYSWAKE_UNKNOWN) { OALMSG(TRUE, (L"[OEM:ERR] OEMPowerOff() : SYSWAKE_UNKNOWN , WAKEUP_STAT = 0x%08x", g_LastWakeupStatus)); } // Initialize System Timer OEMInitializeSystemTimer(RESCHED_PERIOD, OEM_COUNT_1MS, 0); #if 0 // KITL can not support Sleep // Reinitialize KITL if ((pArgs->flags & OAL_KITL_FLAGS_ENABLED) != 0) { OALKitlPowerOn(); } #endif //-------------------------------------- // Post Processing Specific Actions for Wake Up //-------------------------------------- BSPPowerOn(); OALMSG(TRUE, (L"[OEM] --OEMPowerOff()")); }
//------------------------------------------------------------------------------ // // Function: OALIoCtlHalGetHiveCleanFlag // // This function is used by Filesys.exe to query the OEM to determine if the registry hives // and user profiles should be deleted and recreated. // // Notes: During a OS start up, Filesys.exe calls HIVECLEANFLAG_SYSTEM twice and followed by // HIVECLEANFLAG_USER. We'll clear the shared Args flag after that. // static BOOL OALIoCtlHalGetHiveCleanFlag( UINT32 code, VOID *lpInBuf, UINT32 nInBufSize, VOID *lpOutBuf, UINT32 nOutBufSize, UINT32 *pOutSize) { BOOL bRet = FALSE; OALMSG(OAL_IOCTL&&OAL_FUNC, (TEXT("++OALIoCtlHalGetHiveCleanFlag()\r\n"))); if ( (lpInBuf == NULL) || (nInBufSize != sizeof(DWORD)) || (lpOutBuf == NULL) || (nOutBufSize != sizeof(BOOL))) { OALMSG(OAL_ERROR, (TEXT("[OAL:ERR] OALIoCtlHalGetHiveCleanFlag() Invalid Input Parameter\r\n"))); return FALSE; } else { DWORD *pdwFlags = (DWORD*)lpInBuf; BOOL *pbClean = (BOOL*)lpOutBuf; // This is the global shared Args flag BOOL *bHiveCleanFlag = (BOOL*) OALArgsQuery(BSP_ARGS_QUERY_HIVECLEAN); *pbClean = *bHiveCleanFlag; bRet = *bHiveCleanFlag; if (*pdwFlags == HIVECLEANFLAG_SYSTEM) { if(bRet) { OALMSG(TRUE, (TEXT("[OAL] Clear System Hive\r\n"))); } else { OALMSG(TRUE, (TEXT("[OAL] Not Clear System Hive\r\n"))); } } else if (*pdwFlags == HIVECLEANFLAG_USERS) { if(bRet) { OALMSG(TRUE, (TEXT("[OAL] Clear User Hive\r\n"))); } else { OALMSG(TRUE, (TEXT("[OAL] Not Clear User Hive\r\n"))); } // We are done checking HiveCleanFlag by now (system hive is checked before user hive). // Now is the time to clear the global shared Args flag if it is set by switch or software. *bHiveCleanFlag = FALSE; } else { OALMSG(OAL_ERROR, (TEXT("[OAL] Unknown Flag 0x%x\r\n"), *pdwFlags)); } } OALMSG(OAL_IOCTL&&OAL_FUNC, (TEXT("--OALIoCtlHalGetHiveCleanFlag()\r\n"))); return(bRet); }
//------------------------------------------------------------------------------ // // Function: OEMPowerOff // // Description: Called when the system is to transition to it's lowest power mode (off) // // void OEMPowerOff() { volatile S3C6410_SYSCON_REG *pSysConReg; volatile S3C6410_GPIO_REG *pGPIOReg; volatile S3C6410_VIC_REG *pVIC0Reg; volatile S3C6410_VIC_REG *pVIC1Reg; volatile S3C6410_DMAC_REG *pDMAC0Reg; volatile S3C6410_DMAC_REG *pDMAC1Reg; volatile OTG_PHY_REG *pOtgPhyReg; OAL_KITL_ARGS *pArgs; BOOL PowerStateOn; int nIndex = 0; OALMSG(TRUE, (L"[OEM] ++OEMPowerOff()")); // Make sure that KITL is powered off pArgs = (OAL_KITL_ARGS*)OALArgsQuery(OAL_ARGS_QUERY_KITL); if (pArgs && ((pArgs->flags & OAL_KITL_FLAGS_ENABLED) != 0)) { PowerStateOn = FALSE; KITLIoctl (IOCTL_KITL_POWER_CALL, &PowerStateOn, sizeof(PowerStateOn), NULL, 0, NULL); OALMSG(OAL_VERBOSE, (L"OEMPowerOff: KITL Disabled\r\n")); } //----------------------------- // Prepare Specific Actions for Sleep //----------------------------- BSPPowerOff(); //------------------------------ // Prepare CPU Entering Sleep Mode //------------------------------ //---------------- // Map SFR Address //---------------- pSysConReg = (S3C6410_SYSCON_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_SYSCON, FALSE); pGPIOReg = (S3C6410_GPIO_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_GPIO, FALSE); pVIC0Reg = (S3C6410_VIC_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_VIC0, FALSE); pVIC1Reg = (S3C6410_VIC_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_VIC1, FALSE); pDMAC0Reg = (S3C6410_DMAC_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_DMA0, FALSE); pDMAC1Reg = (S3C6410_DMAC_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_DMA1, FALSE); pOtgPhyReg = (OTG_PHY_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_USBOTG_PHY, FALSE); //------------------ // Save VIC Registers //------------------ S3C6410_SaveState_VIC((void *)pVIC0Reg, (void *)pVIC1Reg, g_aSleepSave_VIC); // Disable All Interrupt pVIC0Reg->VICINTENCLEAR = 0xFFFFFFFF; pVIC1Reg->VICINTENCLEAR = 0xFFFFFFFF; pVIC0Reg->VICSOFTINTCLEAR = 0xFFFFFFFF; pVIC1Reg->VICSOFTINTCLEAR = 0xFFFFFFFF; //-------------------- // Save DMAC Registers //-------------------- S3C6410_SaveState_DMACon((void *)pDMAC0Reg, g_aSleepSave_DMACon0); S3C6410_SaveState_DMACon((void *)pDMAC1Reg, g_aSleepSave_DMACon1); //------------------ // Save GPIO Register //------------------ S3C6410_SaveState_GPIO((void *)pGPIOReg, g_aSleepSave_GPIO); //-------------------- // Save SysCon Register //-------------------- S3C6410_SaveState_SysCon((void *)pSysConReg, g_aSleepSave_SysCon); //--------------------------------------------------------------------------- // Unmask Clock Gating for All IPsand Block Power turn On for the IPs not going to sleep //--------------------------------------------------------------------------- // HCLK_IROM, HCLK_MEM1, HCLK_MEM0, HCLK_MFC Should be Always On for power Mode (Something coupled with BUS operation) //pSysConReg->HCLK_GATE |= ((1<<25)|(1<<22)|(1<<21)|(1<<0)); pSysConReg->HCLK_GATE = 0xFFFFFFFF; pSysConReg->PCLK_GATE = 0xFFFFFFFF; pSysConReg->SCLK_GATE = 0xFFFFFFFF; // Turn On All Block Block Power pSysConReg->NORMAL_CFG = 0xFFFFFF00; // Wait for Block Power Stable while((pSysConReg->BLK_PWR_STAT & 0x7E) != 0x7E); //---------------------------- // Wake Up Source Configuration //---------------------------- // S3C6410_WakeUpSource_Configure(); //------------------------------- // Extra work for Entering Sleep Mode //------------------------------- // USB Power Control pSysConReg->OTHERS &= ~(1<<16); // USB Signal Mask Clear pGPIOReg->SPCON |= (1<<3); // USB Tranceiver PAD to Suspend #ifdef _IROM_SDMMC_ // Sleep Mode Pad Configuration. HSJANG 070926. SLPEN must be 0 to change cpcon value for reading OM. #else // Sleep Mode Pad Configuration pGPIOReg->SLPEN = 0x2; // Controlled by SLPEN Bit (You Should Clear SLPEN Bit in Wake Up Process...) #endif //----------------------- // CPU Entering Sleep Mode //----------------------- OALCPUPowerOff(); // Now in Sleep //---------------------------- // CPU Wake Up from Sleep Mode //---------------------------- // Restore SysCon Register S3C6410_RestoreState_SysCon((void *)pSysConReg, g_aSleepSave_SysCon); // Restore GPIO Register S3C6410_RestoreState_GPIO((void *)pGPIOReg, g_aSleepSave_GPIO); #ifdef _IROM_SDMMC_ // Sleep Mode Pad Configuration. HSJANG 070926. SLPEN must be 0 to change cpcon value for reading OM. #else // Sleep Mode Pad Configuration pGPIOReg->SLPEN = 0x2; // Clear SLPEN Bit for Pad back to Normal Mode #endif //----------------------- // Restore DMAC Registers //----------------------- S3C6410_RestoreState_DMACon((void *)pDMAC0Reg, g_aSleepSave_DMACon0); S3C6410_RestoreState_DMACon((void *)pDMAC1Reg, g_aSleepSave_DMACon1); // Restore VIC Registers S3C6410_RestoreState_VIC((void *)pVIC0Reg, (void *)pVIC1Reg, g_aSleepSave_VIC); // UART Debug Port Initialize OEMInitDebugSerial(); // Disable Vectored Interrupt Mode on CP15 System_DisableVIC(); // Enable Branch Prediction on CP15 System_EnableBP(); // Enable IRQ Interrupt on CP15 System_EnableIRQ(); // Enable FIQ Interrupt on CP15 System_EnableFIQ(); // Initialize System Timer OEMInitializeSystemTimer(RESCHED_PERIOD, OEM_COUNT_1MS, 0); // USB Power Control InitializeOTGCLK(); // pll_powerdown, suspend mode pGPIOReg->SPCON &= ~(1<<3); // USB Tranceiver PAD to Normal //-------------------------------------- // Post Processing Specific Actions for Wake Up //-------------------------------------- BSPPowerOn(); // Reinitialize KITL if (pArgs && ((pArgs->flags & OAL_KITL_FLAGS_ENABLED) != 0)) { PowerStateOn = TRUE; KITLIoctl (IOCTL_KITL_POWER_CALL, &PowerStateOn, sizeof(PowerStateOn), NULL, 0, NULL); } OALMSG(TRUE, (L"[OEM] --OEMPowerOff()")); }
BOOL OEMKitlStartup(void) { OAL_KITL_ARGS kitlArgs; OAL_KITL_ARGS *pArgs; BOOL bRet = FALSE; UCHAR *szDeviceId,buffer[OAL_KITL_ID_SIZE]="\0"; OALMSG(OAL_KITL&&OAL_FUNC, (L"[KITL] ++OEMKitlStartup()\r\n")); OALMSG(TRUE, (L"[KITL] ++OEMKitlStartup()\r\n")); memset(&kitlArgs, 0, sizeof (kitlArgs)); pArgs = (OAL_KITL_ARGS *)OALArgsQuery(OAL_ARGS_QUERY_KITL); szDeviceId = (UCHAR*)OALArgsQuery(OAL_ARGS_QUERY_DEVID); // Common parts kitlArgs.devLoc.IfcType = InterfaceTypeUndefined; g_kitlDevice.ifcType = InterfaceTypeUndefined; if((pArgs->flags & OAL_KITL_FLAGS_ENABLED) == 0) { RETAILMSG(1,(TEXT("KITL was Disabled from EBOOT !!\r\nPlease set KITL Configuration in EBoot !!\r\n"))); return FALSE; } #ifdef KITL_SERIAL KITLOutputDebugString ("[KITL] KITL: Serial\n"); bRet = InitKitlSerialArgs (&kitlArgs); strcpy(buffer,"6400SerialKITL"); szDeviceId = buffer; g_kitlDevice.id = kitlArgs.devLoc.LogicalLoc; #endif #ifdef KITL_USBSERIAL KITLOutputDebugString ("[KITL] KITL: USB Serial\n"); bRet = InitKitlUSBSerialArgs (&kitlArgs); strcpy(buffer,"6400USBSerialKITL"); szDeviceId = buffer; g_kitlDevice.id = kitlArgs.devLoc.LogicalLoc; #endif #ifdef KITL_USBRNDIS // TODO: TO be implemented #endif #ifdef KITL_ETHERNET KITLOutputDebugString("[KITL]: Ethernet\r\n"); if (pArgs->devLoc.LogicalLoc == 0) { KITLOutputDebugString ("[KITL] pArgs = NULL\n"); bRet = InitKitlEtherArgs(&kitlArgs); OALKitlCreateName(BSP_DEVICE_PREFIX, kitlArgs.mac, buffer); szDeviceId = buffer; g_kitlDevice.id = kitlArgs.devLoc.LogicalLoc; } else { KITLOutputDebugString ("[KITL] Kitl args bring from argument setting of RAM\n"); pArgs->flags |= OAL_KITL_FLAGS_VMINI; memcpy(&kitlArgs, pArgs, sizeof(kitlArgs)); g_kitlDevice.name = L"6400Ethernet"; g_kitlDevice.ifcType = kitlArgs.devLoc.IfcType; g_kitlDevice.id = kitlArgs.devLoc.LogicalLoc; g_kitlDevice.type = OAL_KITL_TYPE_ETH; g_kitlDevice.pDriver = (void *)&g_kitlEthCS8900A; bRet = TRUE; } #endif // KITL_ETHERNET RETAILMSG(KITL_DBON, (L"DeviceId................. %hs\r\n", szDeviceId)); RETAILMSG(KITL_DBON, (L"kitlArgs.flags............. 0x%x\r\n", kitlArgs.flags)); RETAILMSG(KITL_DBON, (L"kitlArgs.devLoc.IfcType.... %d\r\n", kitlArgs.devLoc.IfcType)); RETAILMSG(KITL_DBON, (L"kitlArgs.devLoc.LogicalLoc. 0x%x\r\n", kitlArgs.devLoc.LogicalLoc)); RETAILMSG(KITL_DBON, (L"kitlArgs.devLoc.PhysicalLoc 0x%x\r\n", kitlArgs.devLoc.PhysicalLoc)); RETAILMSG(KITL_DBON, (L"kitlArgs.devLoc.Pin........ %d\r\n", kitlArgs.devLoc.Pin)); RETAILMSG(KITL_DBON, (L"kitlArgs.ip4address........ %s\r\n", OALKitlIPtoString(kitlArgs.ipAddress))); if (bRet == FALSE) { KITLOutputDebugString ("[KITL] KITL: None\n"); RETAILMSG(TRUE, (TEXT("[KITL] KITL Argument Initialize Fail !!\n"))); return FALSE; } KITLOutputDebugString ("[KITL] Call OALKitlInit()\r\n"); bRet = OALKitlInit ((LPCSTR)szDeviceId, &kitlArgs, &g_kitlDevice); OALMSG(OAL_KITL&&OAL_FUNC, (L"[KITL] --OEMKitlStartup() = %d\r\n", bRet)); OALMSG(TRUE, (L"[KITL] --OEMKitlStartup() = %d\r\n", bRet)); return bRet; }
BOOL OEMKitlStartup( ) { BOOL rc = FALSE; OAL_KITL_ARGS *pArgs, args; CHAR *szDeviceId; KITLSetDebug( ZONE_ERROR | ZONE_WARNING | // ZONE_INIT | // ZONE_KITL_OAL | // ZONE_KITL_ETHER | 0); KITL_RETAILMSG(ZONE_KITL_OAL, ("+OALKitlStart\r\n")); // First get boot args and device id pArgs = (OAL_KITL_ARGS*)OALArgsQuery(OAL_ARGS_QUERY_KITL); // If we don't get kitl arguments use default if (pArgs == NULL) { const UINT16 defaultMac[] = DEFAULT_MAC_ADDRESS; KITL_RETAILMSG(ZONE_WARNING, ( "WARN: Boot arguments not found, use defaults\r\n" )); memset(&args, 0, sizeof(args)); args.flags = OAL_KITL_FLAGS_ENABLED|OAL_KITL_FLAGS_DHCP; args.devLoc.IfcType = Internal; args.devLoc.BusNumber = 0; args.devLoc.LogicalLoc = BSP_LAN9115_REGS_PA; memcpy(args.mac,defaultMac,sizeof(args.mac)); pArgs = &args; } // We always create device name // Try to generate from device id... szDeviceId = OALArgsQuery(OAL_ARGS_QUERY_DEVICE_PREFIX); if (szDeviceId == NULL) { szDeviceId = BSP_DEVICE_35xx_PREFIX; } pArgs->flags |= OAL_KITL_FLAGS_EXTNAME; // Initialize debug device switch (pArgs->devLoc.IfcType) { case Internal: switch (pArgs->devLoc.LogicalLoc) { case BSP_LAN9115_REGS_PA: #if 0 // enable clocks to GPIO banks that have KITL dependencies so we can do initialization OEMKitlEnableClocks(TRUE); // Reset LAN chip pGPIORegs = OALPAtoUA(BSP_RESET_ETHER_KITL_GPIO_PA); CLRREG32(&pGPIORegs->DATAOUT, 1 << (BSP_RESET_ETHER_KITL_GPIO % 32)); OALStall(1000); SETREG32(&pGPIORegs->DATAOUT, 1 << (BSP_RESET_ETHER_KITL_GPIO % 32)); OALStall(1000); // Prepare interrupt pGPIORegs = OALPAtoUA(BSP_ETHER_GPIO_PA); SETREG32(&pGPIORegs->OE, 1 << (BSP_IRQ_ETHER_KITL % 32)); // Interrupt on falling edge SETREG32(&pGPIORegs->FALLINGDETECT, 1 << (BSP_IRQ_ETHER_KITL % 32)); OEMKitlEnableClocks(FALSE); #endif break; } break; } // Finally call KITL library rc = OALKitlInit(szDeviceId, pArgs, g_kitlDevices); // If it failed or KITL is disabled if (!rc || (pArgs->flags & OAL_KITL_FLAGS_ENABLED) == 0) goto cleanUp; // enable kitl interrupts s_bKitlActive = TRUE; OEMKitlEnable(TRUE); cleanUp: KITL_RETAILMSG(ZONE_KITL_OAL, ("-OALKitlStart(rc = %d)\r\n", rc)); return rc; }
BOOLEAN OEMGetUpdateMode(void) { BOOL *pfUpdateMode = NULL; BSP_ARGS *iplpBSPArgs = ((BSP_ARGS *) IMAGE_SHARE_ARGS_UA_START); BOOL fUpdateMode = iplpBSPArgs->fUpdateMode; OALLog(L"OEMGetUpdateMode\r\n"); if(!fUpdateMode){ pfUpdateMode = (BOOL *) OALArgsQuery(OAL_ARGS_QUERY_UPDATEMODE); if (pfUpdateMode == NULL) { OEMWriteDebugString(L"Invalid BSP Args - initializing to good values\r\n"); InitBSPArgs(); } else { fUpdateMode = *pfUpdateMode; } } else { // create the header iplpBSPArgs->header.signature = OAL_ARGS_SIGNATURE; iplpBSPArgs->header.oalVersion = OAL_ARGS_VERSION; iplpBSPArgs->header.bspVersion = BSP_ARGS_VERSION; RETAILMSG(1,(TEXT("updateTRUE but set ARG\r\n"))); } if (fUpdateMode) { OEMWriteDebugString(L"Update Mode RAM flag is set\r\n"); } else { // RAM flag is not set - are we recovering from power failure? if (!BP_GetUpdateModeFlag(&fUpdateMode)) { OEMWriteDebugString(L"Error in BP_GetUpdateModeFlag\r\n"); } if (fUpdateMode) { OEMWriteDebugString(L"Update Mode Persistent flag is set\r\n"); } } if (fUpdateMode) { OEMWriteDebugString(L"----------------------------------------\r\n"); OEMWriteDebugString(L"--------------- LOAD ULDR --------------\r\n"); OEMWriteDebugString(L"----------------------------------------\r\n"); } else { OEMWriteDebugString(L"----------------------------------------\r\n"); OEMWriteDebugString(L"--------------- LOAD OS --------------\r\n"); OEMWriteDebugString(L"----------------------------------------\r\n"); } return(fUpdateMode); }
//------------------------------------------------------------------------------ // // Function: OALIoCtlHalGetDeviceId/OALIoCtlHalGetUUID // // Implements the IOCTL_HAL_GET_DEVICEID and IOCTL_HAL_GET_UUID handlers. // // A "universally unique" 128 bit identifier is required on all Windows // Mobile devices. At a minimum, the 64 bit Device Identifier described // below must be permanent (i.e., cannot be modified) and the UUID in // total cannot duplicate any other existing UUID. // // The UUID is composed of 128 bits in the following order: // * 48 bit Manufacturer Code stored in the OAL. The 48 bit Manufacturer // Code is specific to the manufacturer and will be provided to each // manufacturer by Microsoft. // * 16 bit Version/Variant Code stored in the Kernel. The 16 bit // Version/Variant Code describes the version and variant of the UUID. // The version is "1" and the variant is "8". // * 64 bit Device Identifier Code stored in the hardware (see // Realization in OEM documentation). The Device Identifier Code // must be stored in hardware and be un-alterable without destroying // the device. // // There are two ways how to call this IOCTL. First will pass buffer with // size 16 bytes (size of UUID structure). In such case // BOOL OALIoCtlHalGetDeviceId( UINT32 code, VOID *pInpBuffer, UINT32 inpSize, VOID *pOutBuffer, UINT32 outSize, UINT32 *pOutSize ) { DEVICE_ID *pId = (DEVICE_ID *)pOutBuffer; UINT32 size; BOOL rc = FALSE; int i; #if defined SMARTFON || defined WPC // Smartphone or PocketPC build // First, handle the special case where we care called with a buffer size of 16 bytes if ( outSize == sizeof(UUID) ) { rc = OALIoCtlHalGetUUID(IOCTL_HAL_GET_UUID, pInpBuffer, inpSize, pOutBuffer, outSize, pOutSize); //for(i=0;i<outSize;i++) // RETAILMSG(1,(TEXT(" %x \r\n"),*((BYTE *)pOutBuffer+i))); } else // If buffer size is not 16 bytes, return a DEVICE_ID structure { UCHAR uuid[sizeof(UUID)]; //RETAILMSG(1,(TEXT(" Large than 16 \r\n"))); // Compute required structure size size = sizeof(DEVICE_ID) + sizeof(uuid); // update size if pOutSize is specified if (pOutSize != NULL) { *pOutSize = size; } // Check for invalid parameters if (pOutBuffer == NULL || outSize < sizeof(DEVICE_ID)) { NKSetLastError(ERROR_INVALID_PARAMETER); OALMSG(OAL_WARN, ( L"WARN: OALIoCtlHalGetDeviceID: Invalid parameter\r\n" )); goto cleanUp; } // Set size to DEVICE_ID structure pId->dwSize = size; // If the size is too small, indicate the correct size if (outSize < size) { NKSetLastError(ERROR_INSUFFICIENT_BUFFER); goto cleanUp; } // Get UUID if (OALIoCtlHalGetUUID(IOCTL_HAL_GET_UUID, NULL, 0, uuid, sizeof(uuid), NULL) == FALSE) { // IOCTL_HAL_GET_UUID handler will set last error, but this really should never happen. goto cleanUp; } // Populate DEVICE_ID structure members with fields from the UUID // The manufacturer ID portion of the UUID maps to the "PresetIDBytes" field // The HW-unique portion of the UUID maps to the "PlatformIDBytes" field // PresetIDBytes pId->dwPresetIDOffset = size - sizeof(g_oalIoCtlVendorId); pId->dwPresetIDBytes = sizeof(g_oalIoCtlVendorId); // PlatformIDBytes pId->dwPlatformIDOffset = sizeof(DEVICE_ID); pId->dwPlatformIDBytes = sizeof(uuid) - sizeof(g_oalIoCtlVendorId); memcpy((UINT8*)pId + sizeof(DEVICE_ID), uuid, sizeof(uuid)); // We are done rc = TRUE; } #else // Not Smartphone or PocketPC build UINT32 length1, length2, offset; LPSTR pDeviceId = NULL; // Get device unique id from arguments pDeviceId = OALArgsQuery(OAL_ARGS_QUERY_DEVID); if (pDeviceId == NULL) pDeviceId = ""; // Compute required size (first is unicode, second multibyte!) length1 = (NKwcslen(g_oalIoCtlPlatformType) + 1) * sizeof(WCHAR); length2 = strlen(pDeviceId) + 1; size = sizeof(DEVICE_ID) + length1 + length2; // update size if pOutSize is specified if (pOutSize) *pOutSize = size; // Validate inputs (do it after we can return required size) if (pOutBuffer == NULL || outSize < sizeof(DEVICE_ID)) { NKSetLastError(ERROR_INVALID_PARAMETER); OALMSG(OAL_WARN, ( L"WARN: OALIoCtlHalGetDeviceID: Invalid parameter\r\n" )); goto cleanUp; } // Set size to DEVICE_ID structure pId->dwSize = size; // If the size is too small, indicate the correct size if (outSize < size) { NKSetLastError(ERROR_INSUFFICIENT_BUFFER); goto cleanUp; } // Fill in the Device ID type offset = sizeof(DEVICE_ID); // Copy in PlatformType data pId->dwPresetIDOffset = offset; pId->dwPresetIDBytes = length1; memcpy((UINT8*)pId + offset, g_oalIoCtlPlatformType, length1); offset += length1; // Copy device id data pId->dwPlatformIDOffset = offset; pId->dwPlatformIDBytes = length2; memcpy((UINT8*)pId + offset, pDeviceId, length2); // We are done rc = TRUE; #endif // SP/PPC build check cleanUp: return rc; }