void main(void) { INT32 nRet; OEMWriteDebugLED(0, 0x0); // Set up the copy section data. if (!SetupCopySection(pTOC)) { while(1); } // Clear LEDs. OEMWriteDebugLED(0, 0x0); OEMInitDebugSerial(); OEMWriteDebugString(L" [NBL2] main() Starts !\r\n"); OEMWriteDebugString(L" [NBL2] Serial Initialized...\r\n"); nRet = FIL_Init(); if (nRet != FIL_SUCCESS) { OEMWriteDebugString(L" [NBL2:ERR] FIL_Init() : Failed\r\n"); while(1); } OEMWriteDebugString(L" [NBL2] FIL_Init() : Passed\r\n"); ShadowEboot(); OEMWriteDebugString(L" [NBL2] Launch Eboot...\r\n"); OEMLaunchImage(EBOOT_VIRTUAL_BASEADDR); }
uint8_t mmc_read_sector(uint32_t sector, uint16_t count, uint8_t* buffer) { static int nCount=0, nLED=0; if (0 == (nCount%128)) { OEMWriteDebugLED(0, (nLED%4)); nLED++; } nCount++; return (uint8_t)SDHC_READ(sector, (UINT32)count, (UINT32)buffer); }
//------------------------------------------------------------------------------ // // Function: RechargeTimer // // // Assumes: a timer interrupt cannot occur inside this function (caller must ensure this condition) // __inline void RechargeTimer(DWORD reschedMSec) { UINT32 baseMSec; UINT32 deltaMSec = 0; UINT32 deltaCounts; UINT32 TimerCount; UINT32 newTimerMatch; baseMSec = CurMSec; deltaMSec = reschedMSec - baseMSec; // reschedule time already passed? if ((INT32)deltaMSec < 0) { deltaMSec = 0; } else if (deltaMSec > g_oalTimer.maxPeriodMSec) { // If next tick is longer than maximal tick period, // then schedule next tick for max allowed MSec by the timer counter deltaMSec = g_oalTimer.maxPeriodMSec; } // at this point we know the deltaMSec from CurMSec when next systick has to be scheduled // since timers work off of counts calculate deltaCounts deltaCounts = deltaMSec * g_oalTimer.countsPerMSec; // Recharge timer to start new period // ideal case: increment matchreg (osmr0) by deltaCounts // but can't do simply this because while this routine is being executed oscr0 is incrementing. // Hence, for these two conditions need to increment deltaCounts so that new osmr0 will be ahead of oscr0. // 1) if deltaCounts is too small and incrementing osmr0 by deltaCounts puts it before oscr0 // 2) if incremeting osmr0 by deltaCounts puts it ahead of oscr0 but so close that by the time osmr0 is set oscr0 // will be ahead of it // For both these conditions it is suffice to use this condition if (osmr0 + deltaCounts) < (oscr0 + margin) then increment deltaCounts newTimerMatch = LastTimerMatch + deltaCounts; /*** TIMER SPECIFIC CODE ***/ TimerCount = g_XllpOSTHandle.pOSTRegs->oscr0; /*** TIMER SPECIFIC CODE END***/ // setting osmr0 to newTimerMatch puts it before oscr0? if (((INT32)(TimerCount + g_oalTimer.countsMargin - LastTimerMatch - deltaCounts) > 0)) { // set the new match value to the earliest we can set it to newTimerMatch = TimerCount + g_oalTimer.countsMargin; //since timermatch value changed we need to recalculate deltaCounts and deltaMSec. //These values are used to set actualMSecPerSysTick and actualCountsPerSysTick. deltaCounts = (INT32)(newTimerMatch - LastTimerMatch); // deltaMSec denotes the time that CurMSec should be incremented by next time when timer ISR runs. // This is calculated by dividing deltaCounts by countsPerMsec. The following code avoids this expensive // division for the most common cases of delta being between 0 and 1ms and between 1 and 2ms if (deltaCounts < g_oalTimer.countsPerMSec) { // deltaCounts < 1MSec deltaMSec = 0; g_LastPartialCounts = deltaCounts; } else if (deltaCounts < (g_oalTimer.countsPerMSec << 1)) { // deltaCounts < 2MSec deltaMSec = 1; g_LastPartialCounts = deltaCounts - g_oalTimer.countsPerMSec; } else { deltaMSec = deltaCounts / g_oalTimer.countsPerMSec; g_LastPartialCounts = deltaCounts - deltaMSec * g_oalTimer.countsPerMSec; } } /*** TIMER SPECIFIC CODE ***/ XllpOstConfigureTimer(&g_XllpOSTHandle, MatchReg0, newTimerMatch); /*** TIMER SPECIFIC CODE END***/ g_oalTimer.actualMSecPerSysTick = deltaMSec; g_oalTimer.actualCountsPerSysTick = deltaCounts; #ifdef DEBUG //code to check assumption that timer interrupt should not occur during this routine // if (baseMSec != CurMSec) { OEMWriteDebugLED(0, (0xEbbb | 0x1)); //code for error while(1) {}; } #endif }
//------------------------------------------------------------------------------ // // Function: OEMInit // // This is Windows CE OAL initialization function. It is called from kernel // after basic initialization is made. // void OEMInit() { UINT32 logMask_Backup; extern DWORD CEProcessorType; // From nkarm.h in the private tree. //volatile S3C6410_VIC_REG *pIntr = (S3C6410_VIC_REG*)OALPAtoVA(S3C6410_BASE_REG_PA_VIC0, FALSE); //NKForceCleanBoot(); OALMSG(OAL_FUNC, (L"[OAL] ++OEMInit()\r\n")); OALMSG(TRUE, (L"[OAL] ++OEMInit()\r\n")); OALMSG(OAL_FUNC, ((L"[OAL] APLLCLK : %d\n\r"), System_GetAPLLCLK())); OALMSG(OAL_FUNC, ((L"[OAL] ARMCLK : %d\n\r"), System_GetARMCLK())); OALMSG(OAL_FUNC, ((L"[OAL] HCLK : %d\n\r"), System_GetHCLK())); OALMSG(OAL_FUNC, ((L"[OAL] PCLK : %d\n\r"), System_GetPCLK())); g_oalIoCtlClockSpeed = System_GetARMCLK(); // Lie about the Processor Type (we do this so that the visual C tools work) CEProcessorType = PROCESSOR_STRONGARM; logMask_Backup = g_oalLogMask; OALLogSetZones( (1<<OAL_LOG_ERROR) | (1<<OAL_LOG_WARN) | (1<<OAL_LOG_FUNC) ); RETAILMSG(TRUE, (TEXT("CEProcessorType = 0x%x\r\n"),CEProcessorType)); RETAILMSG(TRUE, (TEXT("APLLCLK: %d, FCLK: %d, HCLK: %d, PCLK: %d\r\n"), System_GetAPLLCLK(), System_GetARMCLK(), System_GetHCLK(), System_GetPCLK())); // Set memory size for DrWatson kernel support if (dwOEMDrWatsonSize != NOT_FIXEDUP) { dwNKDrWatsonSize = dwOEMDrWatsonSize; // set size of reserved memory for Watson dump } // Intialize optional kernel functions. (Processor Extended Feature) // pOEMIsProcessorFeaturePresent = OALIsProcessorFeaturePresent; // Set OEMSetMemoryAttributes function pfnOEMSetMemoryAttributes = OEMSetMemoryAttributes; // Turn Off all Debug LED // OEMWriteDebugLED(0, 0x0); // Initialize INFORM SFR // This function should be called for CPU Identification. InitializeINFORMSFR(); // Initialize Clock Source // InitializeCLKSource(); // Initialize Clock Gating // InitializeCLKGating(); // Initialize Block Power // InitializeBlockPower(); // Initialize OTG PHY Clock // InitializeOTGCLK(); // 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 ); // 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); // Initialize GPIO // InitializeGPIO(); // Initialize the KITL connection if required RETAILMSG(1, (TEXT("OALKitlStart() \n\r"))); OALKitlStart(); Init_BspArgs(); OALMSG(OAL_FUNC, (L"-OEMInit\r\n")); OALLogSetZones(logMask_Backup); }