📄 main.c
字号:
//
// 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 SMDK2410 hardware platform.
Functions:
Notes:
--*/
#include <windows.h>
#include <iplcommon.h>
#include <bootpart.h> // Needed for partition types...
#include <bsp.h>
#include <fmd.h>
//#include "..\eboot\loader.h"
// Virtual address of bootpart work buffer.
//
#define BPART_BUFFER_U_VIRTUAL 0xA1121000
#define BPART_BUFFER_LENGTH_BYTES 0x00021000
// Global variables.
//
// --- These are used by iplcommon (start) ---
UINT32 g_ulFlashBase = 0; // Flash start and length.
UINT32 g_ulFlashLengthBytes = NAND_FLASH_SIZE - IMAGE_IPL_SIZE;
UINT32 g_ulBPartBase = BPART_BUFFER_U_VIRTUAL; // BootPart work buffer start and length.
UINT32 g_ulBPartLengthBytes = BPART_BUFFER_LENGTH_BYTES;
// --- These are used by iplcommon (end) ---
// External variables.
//
extern PFN_MessageHandler g_pfnMessageHandler;
// Function prototypes.
//
void OEMInitDebugSerial(void);
void OEMWriteDebugString(unsigned short *str);
static void OEMMessageHandler(IPL_MESSAGE_CODE MessageCode, LPWSTR pMessageString);
void Launch(UINT32 ulLaunchAddr);
void InitBSPArgs();
void main(void)
{
// Call into the IPLcommon main routine.
//
S3C2440X_IOPORT_REG *pOalPortRegs;
ULONG value;
// Then get virtual address for IO port
pOalPortRegs = OALPAtoVA(S3C2440X_BASE_REG_PA_IOPORT, FALSE);
// Set GPG11 as output and pull-up disabling for forcing UpdateLoader
value = INREG32(&pOalPortRegs->GPGCON);
OUTREG32(&pOalPortRegs->GPGCON, (value & ~(3 << 22))|(1 << 22));
value = INREG32(&pOalPortRegs->GPGUP);
OUTREG32(&pOalPortRegs->GPGUP, value | (1 << 11));
//value = INREG32(&pOalPortRegs->GSTATUS4);
//RETAILMSG(1,(TEXT("GSTATUS4= %x \r\n"),value));
//value = INREG32(&pOalPortRegs->GSTATUS2);
//RETAILMSG(1,(TEXT("GSTATUS2= %x \r\n"),value));
OALMSG(OAL_ERROR, (TEXT("Start: IPLmain start \r\n")));
IPLmain();
}
static void OEMMessageHandler(IPL_MESSAGE_CODE MessageCode, LPWSTR pMessageString)
{
// Write a hex LED code.
//
OEMWriteDebugString((UINT16 *)pMessageString);
}
/*
@func BOOL | ReadBootConfig | Read bootloader settings from flash.
@rdesc TRUE = Success, FALSE = Failure.
@comm This routine came from eboot\main.c
@xref
*/
/*
static BOOL ReadBootConfig(PBOOT_CFG pBootCfg)
{
BOOLEAN bResult = FALSE;
OALMSG(OAL_FUNC, (TEXT("+ReadBootConfig.\r\n")));
// Valid caller buffer?
if (!pBootCfg)
{
OALMSG(OAL_ERROR, (TEXT("ERROR: Bad caller buffer.\r\n")));
goto CleanUp;
}
// Read settings from flash...
//
if (!AM29LV800_ReadFlash(EBOOT_CONFIG_OFFSET, (PBYTE)pBootCfg, sizeof(BOOT_CFG)))
{
OALMSG(OAL_ERROR, (TEXT("ERROR: Flash read failed.\r\n")));
goto CleanUp;
}
// Check configuration signature...
//
if (pBootCfg->Signature != CONFIG_SIGNATURE)
{
OALMSG(OAL_WARN, (TEXT("WARNING: Boot configuration signature invalid - choosing defaults...\r\n")));
memset(pBootCfg, 0, sizeof(*pBootCfg));
// We'll just treat all the settings as uninitialized.
}
bResult = TRUE;
CleanUp:
OALMSG(OAL_FUNC, (TEXT("-ReadBootConfig.\r\n")));
return(bResult);
}
*/
#define COMPILE_TIME_ASSERT(condition) { int compile_time_assert[(condition)]; compile_time_assert; }
void InitBSPArgs()
{
UINT8 maccount = 0;
BSP_ARGS *pBSPArgs = ((BSP_ARGS *) IMAGE_SHARE_ARGS_UA_START);
// create the header
pBSPArgs->header.signature = OAL_ARGS_SIGNATURE;
pBSPArgs->header.oalVersion = OAL_ARGS_VERSION;
pBSPArgs->header.bspVersion = BSP_ARGS_VERSION;
// Clear BSP Reserved Parameter.
pBSPArgs->fUpdateMode = FALSE ;
pBSPArgs->fUldrReboot = FALSE ;
pBSPArgs->dwExtensionRAMFMDSize = 0;
pBSPArgs->pvExtensionRAMFMDBaseAddr = NULL;
// if (ReadBootConfig(&BootCfg))
// {
// COMPILE_TIME_ASSERT(sizeof(BootCfg.CS8900MAC) == sizeof(pBSPArgs->kitl.mac));
// memcpy(pBSPArgs->kitl.mac, BootCfg.CS8900MAC, sizeof(BootCfg.CS8900MAC));
// }
// store a base name for the device and signal to KITL to extend it later
//strncpy(pBSPArgs->deviceId, BSP_DEVICE_PREFIX, OAL_KITL_ID_SIZE);
//pBSPArgs->kitl.flags |= OAL_KITL_FLAGS_EXTNAME;
}
///////////////////////////////////////////////////////////////////////////////
// Required OEM IPL routines.
///////////////////////////////////////////////////////////////////////////////
// --- These are used by iplcommon (start) ---
BOOLEAN OEMIPLInit(void)
{
// Initialize the UART.
//
OEMInitDebugSerial();
OALLog(L"\r\nMicrosoft Windows CE IPL for SMDK2440 Ref board\r\n");
// Set the flash address
g_ulFlashBase = NAND_FLASH_START_UA;
// Messaging handler callback.
//
g_pfnMessageHandler = OEMMessageHandler;
return(TRUE);
}
BOOLEAN OEMGetUpdateMode(void)
{
S3C2440X_IOPORT_REG *pOalPortRegs;
BOOL fUpdateMode=FALSE;
BOOL *pfUpdateMode = NULL;
BSP_ARGS *pBSPArgs = ((BSP_ARGS *) IMAGE_SHARE_ARGS_UA_START);
OALLog(L"OEMGetUpdateMode\r\n");
//Check forcing updateloader with GPIO button
pOalPortRegs = OALPAtoVA(S3C2440X_BASE_REG_PA_IOPORT, FALSE);
RETAILMSG(1,(TEXT("GPGCON= 0x%x, GPGDAT= 0x%x, GPGUP= 0x%x\r\n"),INREG32(&pOalPortRegs->GPGCON),INREG32(&pOalPortRegs->GPGDAT),INREG32(&pOalPortRegs->GPGUP)));
RETAILMSG(1,(TEXT("GSTATUS2= 0x%x, GSTATUS4= 0x%x \r\n"),INREG32(&pOalPortRegs->GSTATUS2),INREG32(&pOalPortRegs->GSTATUS4)));
RETAILMSG(1,(TEXT("UpdateMode Adderss 0x%x Value= 0x%x\r\n"),&(pBSPArgs->fUpdateMode),*((UINT32 *)0xA0020044)));
RETAILMSG(1,(TEXT("ULDRReboot Adderss 0x%x Value= 0x%x\r\n"),&(pBSPArgs->fUldrReboot),*((UINT32 *)0xA0020048)));
if(!(INREG32(&pOalPortRegs->GPGDAT)&~(0xf7ff)))
fUpdateMode=TRUE;
// check the RAM flag
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
pBSPArgs->header.signature = OAL_ARGS_SIGNATURE;
pBSPArgs->header.oalVersion = OAL_ARGS_VERSION;
pBSPArgs->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"Launching the Update Loader\r\n");
}
return(fUpdateMode);
}
BOOLEAN OEMTranslateBaseAddress(UINT32 ulPartType, UINT32 ulAddr, UINT32 *pulTransAddr)
{
if (pulTransAddr == NULL)
{
return(FALSE);
}
switch(ulPartType)
{
case PART_BOOTSECTION:
// No translation.
*pulTransAddr = ulAddr;
break;
case PART_XIP:
*pulTransAddr = ulAddr | 0xa0000000;
break;
default:
// No translation.
*pulTransAddr = ulAddr;
break;
}
return(TRUE);
}
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, (TEXT("Jumping to VA 0x%x PA 0x%x...\r\n"), ulLaunchAddr, ulPhysicalJump));
// Jump...
Launch(ulPhysicalJump);
}
// --- These are used by iplcommon (end) ---
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -