main.c
来自「SAMSUNG S3C6410 CPU BSP for winmobile6」· C语言 代码 · 共 348 行
C
348 行
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
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.
Module Name: main.c
Abstract: OEM IPL routines for the Samsung SMDK6410 hardware platform.
Functions:
Notes:
--*/
#include <windows.h>
#include <bsp.h>
#include <pehdr.h>
#include <romldr.h>
#include <XsrTypes.h>
#include <XsrConfig.h>
#include <BML.h>
#include <OAM.h>
#include <STL.h>
ROMHDR * volatile const pTOC = (ROMHDR *)-1;
// Base address of the image flash part.
//
// NOTE: This is the base address of the NAND flash controller...
//
#define EBOOT_VIRTUAL_BASEADDR 0x80038000
#define IPL_VIRTUAL_BASEADDR 0x80138000
void Launch(UINT32 ulLaunchAddr);
void OEMInitDebugSerial(void);
void OEMWriteDebugString(unsigned short *str);
void OEMLaunchImage(UINT32 ulLaunchAddr)
{
UINT32 ulPhysicalJump = 0;
// The IPL is running with the MMU on - before we jump to the loaded image, we need to convert
// the launch address to a physical address and turn off the MMU.
//
// Convert jump address to a physical address.
ulPhysicalJump = OALVAtoPA((void *)ulLaunchAddr);
RETAILMSG(1, (L"LaunchAddr=0x%x PhysicalJump=0x%x\r\n", ulLaunchAddr, ulPhysicalJump));
// Jump...
Launch(ulPhysicalJump);
}
// --- These are used by iplcommon (end) ---
static BOOL
_ReadImage(UINT32 nVol, UINT32 nStartVsn, UINT32 nNumOfScts, UINT32 nSrcAddr, BMLVolSpec *pstVolSpec)
{
UINT32 nVsnAlign;
UINT32 nSctToRead;
UINT8 *pSrcAddr = (UINT8*)nSrcAddr;
INT32 nRet;
while(nNumOfScts)
{
nVsnAlign = nStartVsn % pstVolSpec->nSctsPerPg;
if (nVsnAlign != 0)
{
if (nNumOfScts >= (pstVolSpec->nSctsPerPg - nVsnAlign))
{
nSctToRead = pstVolSpec->nSctsPerPg - nVsnAlign;
}
else
{
nSctToRead = nNumOfScts;
}
}
else
{
if (nNumOfScts >= pstVolSpec->nSctsPerPg)
{
nSctToRead = pstVolSpec->nSctsPerPg;
}
else
{
nSctToRead = nNumOfScts;
}
}
nRet = BML_Read(nVol, /* Volume Number */
nStartVsn, /* Vsn */
nSctToRead, /* Number of Scts */
pSrcAddr, /* pMBuf */
NULL, /* pSBuf */
BML_FLAG_ECC_ON | BML_FLAG_BBM_ON); /* Operation Flag */
if (nRet != BML_SUCCESS)
{
OEMWriteDebugString(L"[NBL2:ERR] BML_Read Erro\r\n");
return FALSE;
}
nNumOfScts -= nSctToRead;
nStartVsn += nSctToRead;
pSrcAddr += nSctToRead * XSR_SECTOR_SIZE;
}
return TRUE;
}
void ShadowEboot()
{
UINT32 nVol = 0;
UINT32 nStartVsn;
UINT32 nNumOfScts;
UINT32 nSctsPerPg;
XSRPartEntry stPEntry;
BMLVolSpec stVolSpec;
UINT32 ulLaunchAddr = EBOOT_VIRTUAL_BASEADDR;
OEMWriteDebugString(L"++ Shadow Eboot ++\r\n");
if (BML_GetVolInfo(nVol, &stVolSpec) != BML_SUCCESS)
{
OEMWriteDebugString(L"BML_GetVolInfo Error\r\n");
while(1);
}
if (BML_LoadPIEntry(nVol, PARTITION_ID_EBOOT, &stPEntry) != BML_SUCCESS)
{
OEMWriteDebugString(L"BML_LoadPIEntry Error!\r\n");
while(1);
}
nSctsPerPg = stVolSpec.nSctsPerPg;
nStartVsn = stPEntry.n1stVbn * stVolSpec.nPgsPerBlk * nSctsPerPg;
nNumOfScts = stPEntry.nNumOfBlks * stVolSpec.nPgsPerBlk * nSctsPerPg;
if(!_ReadImage(nVol, nStartVsn, nNumOfScts, ulLaunchAddr, &stVolSpec)) {
OEMWriteDebugString(L"In ShadowEboot,can't read image.\r\n");
while(1);
}
BML_Close(0);
OEMWriteDebugString(L"-- Shadow Eboot --\r\n");
OEMLaunchImage(ulLaunchAddr);
}
void ShadowIPL()
{
UINT32 nVol = 0;
UINT32 nStartVsn;
UINT32 nNumOfScts;
UINT32 nSctsPerPg;
XSRPartEntry stPEntry;
BMLVolSpec stVolSpec;
UINT32 ulLaunchAddr = IPL_VIRTUAL_BASEADDR;
OEMWriteDebugString(L"++ Shadow IPL ++\r\n");
if (BML_GetVolInfo(nVol, &stVolSpec) != BML_SUCCESS)
{
OEMWriteDebugString(L"BML_GetVolInfo Error\r\n");
while(1);
}
if (BML_LoadPIEntry(nVol, PARTITION_ID_IPL, &stPEntry) != BML_SUCCESS)
{
OEMWriteDebugString(L"BML_LoadPIEntry Error!\r\n");
while(1);
}
nSctsPerPg = stVolSpec.nSctsPerPg;
nStartVsn = stPEntry.n1stVbn * stVolSpec.nPgsPerBlk * nSctsPerPg;
nNumOfScts = stPEntry.nNumOfBlks * stVolSpec.nPgsPerBlk * nSctsPerPg;
if(!_ReadImage(nVol, nStartVsn, nNumOfScts, ulLaunchAddr, &stVolSpec)) {
OEMWriteDebugString(L"In ShadowIPL,can't read image.\r\n");
while(1);
}
BML_Close(0);
OEMWriteDebugString(L"-- Shadow IPL --\r\n");
OEMLaunchImage(ulLaunchAddr);
}
static BOOLEAN SetupCopySection(ROMHDR *const pTOC)
{
UINT32 ulLoop;
COPYentry *pCopyEntry;
if (pTOC == (ROMHDR *const) -1)
{
return(FALSE);
}
// This is where the data sections become valid... don't read globals until after this
//
for (ulLoop = 0; ulLoop < pTOC->ulCopyEntries; ulLoop++)
{
pCopyEntry = (COPYentry *)(pTOC->ulCopyOffset + ulLoop*sizeof(COPYentry));
if (pCopyEntry->ulCopyLen)
{
memcpy((LPVOID)pCopyEntry->ulDest, (LPVOID)pCopyEntry->ulSource, pCopyEntry->ulCopyLen);
}
if (pCopyEntry->ulCopyLen != pCopyEntry->ulDestLen)
{
memset((LPVOID)(pCopyEntry->ulDest+pCopyEntry->ulCopyLen), 0, pCopyEntry->ulDestLen-pCopyEntry->ulCopyLen);
}
}
return(TRUE);
}
#define FROM_BCD(n) ((((n) >> 4) * 10) + ((n) & 0xf))
static BOOL OEMGetRealTime(LPSYSTEMTIME lpst)
{
volatile S3C6410_RTC_REG *s6410RTC = (S3C6410_RTC_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_RTC, FALSE);
do
{
lpst->wYear = FROM_BCD(s6410RTC->BCDYEAR) + 2000 ;
lpst->wMonth = FROM_BCD(s6410RTC->BCDMON & 0x1f);
lpst->wDay = FROM_BCD(s6410RTC->BCDDATE & 0x3f);
lpst->wDayOfWeek = (s6410RTC->BCDDAY - 1);
lpst->wHour = FROM_BCD(s6410RTC->BCDHOUR & 0x3f);
lpst->wMinute = FROM_BCD(s6410RTC->BCDMIN & 0x7f);
lpst->wSecond = FROM_BCD(s6410RTC->BCDSEC & 0x7f);
lpst->wMilliseconds = 0;
}
while (!(lpst->wSecond));
return(TRUE);
}
DWORD OEMEthGetSecs(void)
{
SYSTEMTIME sTime;
OEMGetRealTime(&sTime);
return((60UL * (60UL * (24UL * (31UL * sTime.wMonth + sTime.wDay) + sTime.wHour) + sTime.wMinute)) + sTime.wSecond);
}
void main(void)
{
UINT32 nVol = 0;
BOOL bLoadIPL = TRUE;
// Set up the copy section data.
//
if (!SetupCopySection(pTOC))
{
while(1);
}
OEMInitDebugSerial();
OEMWriteDebugString(L"++ ONBL2 : main ++\r\n");
//BML_Init
if (BML_Init() != BML_SUCCESS)
{
OEMWriteDebugString(L"++ ONBL2 : main : BML_Init failed++\r\n");
while(1);
}
OEMWriteDebugString(L"++ ONBL2 : main : BML_Init ok++\r\n");
//BML_Open
if (BML_Open(nVol) != BML_SUCCESS)
{
OEMWriteDebugString(L"++ ONBL2 : main : BML_Open failed++\r\n");
while(1);
}
OEMWriteDebugString(L"++ ONBL2 : main : BML_Open ok++\r\n");
#if 0 // use button
{
volatile S3C6410_GPIO_REG *pGPIOReg = (S3C6410_GPIO_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_GPIO, FALSE);
UINT32 backup_GPNCON;
UINT32 nGPNDAT;
UINT32 backup_GPNPUD;
backup_GPNCON = pGPIOReg->GPNCON;
backup_GPNPUD = pGPIOReg->GPNPUD;
pGPIOReg->GPNCON = (backup_GPNCON & ~(0x3<<20)) | (0x0<<20); // EINT10(GPN20) is input
pGPIOReg->GPNPUD = (backup_GPNPUD & ~(0x3<<20)) | (0x0<<20); // EINT10(GPN20) is input
nGPNDAT = pGPIOReg->GPNDAT;
pGPIOReg->GPNCON = backup_GPNCON;
pGPIOReg->GPNPUD = backup_GPNPUD;
OEMWriteDebugString(L"++ ONBL2 : main : Check boot mode++\r\n");
if ((nGPNDAT & (0x1<<10)) == 0) bLoadIPL = FALSE;
}
#elif 1 // use rtc timer. if 0, onbl2 load ipl directly.
{
UINT32 nDelay;
UINT8 KeySelect;
UINT32 dwStartTime, dwCurrTime;
RETAILMSG(1, (L"Press [SPACE] to enter EBOOT within 2 sec.\r\n"));
nDelay = 3;
dwStartTime = OEMEthGetSecs();
dwCurrTime = dwStartTime;
KeySelect = 0;
while((dwCurrTime - dwStartTime) < nDelay)
{
KeySelect = OEMReadDebugByte();
if ((KeySelect == 0x20) || (KeySelect == 0x0d))
{
bLoadIPL = FALSE;
break;
}
dwCurrTime = OEMEthGetSecs();
}
}
#endif
if (bLoadIPL) ShadowIPL();
else ShadowEboot();
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?