📄 bl_main.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//------------------------------------------------------------------------------
//
// main.c
//
// Main bootloader functions
//
#include <windows.h>
#include <blcommon.h>
#include <oal.h>
//BSP Includes
#include <image_cfg.h>
#include <eboot.h>
#include <kitl_cfg.h>
#include <boot_cfg.h>
#include "boot_utilities.h"
#include "bsp_serial.h"
#include "boot_led.h"
#include "boot_flash.h"
#include "lpc32xx_rtc.h"
#include "lpc32xx_mstimer.h"
#include "lpc32xx_timer.h"
#include "phy3250_board.h"
#include "clkpwr_support.h"
//From BLCOMMON.C
void BootloaderMain (void);
// Define to use timer 0 for the MS timer
#define USETMR0
//------------------------------------------------------------------------------
//
// g_bootCfg
//
// This global variable is used to save boot configuration. It is readed from
// flash memory or initialized to default values if flash memory doesn't
// contain valid structure. It can be modified by user in bootloader
// configuration menu invoked by BLMenu.
//
BOOT_CFG g_bootCfg;
//------------------------------------------------------------------------------
//
// phyhwdesc
//
// This structure contains the board configuration data including the MAC
// address and SDRAM configuration.
//
PHY_HW_T phyhwdesc;
//------------------------------------------------------------------------------
//
// g_eboot
//
// This global variable is used to save information about downloaded regions.
//
EBOOT_CONTEXT g_eboot;
//------------------------------------------------------------------------------
//
// cleanboot
//
// Flag used to indicate if a clean boot should occur.
//
BOOL cleanboot;
//------------------------------------------------------------------------------
//
// NAND FLASH flags
//
// Flag used to indicate if image should be placed in FLASH.
//
BOOL flashburnflag;
BOOL flashgood;
extern NAND_GEOM_T savedgeom;
//------------------------------------------------------------------------------
//
// Time_Setup
//
// Sets up the RTC and Millisecond timer for a 1 second count.
//
void Time_Setup (void)
{
#ifndef USETMR0
UNS_32 rtcsecs;
RTC_REGS_T *pRTCRegs;
MSTIMER_REGS_T *pMSTRegs;
pRTCRegs = (RTC_REGS_T *) OALPAtoVA((UINT32) RTC, FALSE);
pMSTRegs = (MSTIMER_REGS_T *) OALPAtoVA((UINT32) MSTIMER, FALSE);
// Enable MSTimer and set it to match every second
pMSTRegs->mstim_match0 = RTCCLKRATE;
pMSTRegs->mstim_mctrl = MSTIM_MCTRL_RST_COUNT0;
pMSTRegs->mstim_ctrl = MSTIM_CTRL_RESET_COUNT;
// Wait for RTC to 'tick' before setting MS Timer
pRTCRegs->ctrl &= ~RTC_SW_RESET;
rtcsecs = pRTCRegs->ucount;
while (rtcsecs == pRTCRegs->ucount);
pMSTRegs->mstim_ctrl = MSTIM_CTRL_COUNT_ENAB;
#else
TIMER_CNTR_REGS_T *pTMR0Regs;
UINT32 baseclk;
pTMR0Regs = (TIMER_CNTR_REGS_T *) OALPAtoVA((UINT32) TIMER_CNTR0, FALSE);
// Enable clock for timer 0
clkpwr_clk_en_dis(CLKPWR_TIMER0_CLK, 1);
// Enable counter to update count every 1mS with no match
pTMR0Regs->tcr = 0;
pTMR0Regs->ir = TIMER_CNTR_MTCH_BIT(0);
pTMR0Regs->mcr = 0;
pTMR0Regs->pc = 0;
pTMR0Regs->tc = 0;
// Get base clock for the timer
baseclk = clkpwr_get_base_clock_rate(CLKPWR_PERIPH_CLK);
// Compute prescale divider to get the desired tick rate
baseclk = baseclk / 1000;
pTMR0Regs->pr = baseclk;
// Enable timer
pTMR0Regs->tcr = TIMER_CNTR_TCR_EN;
#endif
}
//------------------------------------------------------------------------------
//
// SpinForever
//
// Spins forever and flashes the LEDs.
//
void SpinForever()
{
KITLOutputDebugString("Spin Forever\r\n");
while(TRUE)
{
SetLEDValue(0xff);
OALWaitMS(500);
SetLEDValue(0x00);
OALWaitMS(500);
}
}
//------------------------------------------------------------------------------
//
// getbldata
//
// Gets the persistent bootloader configuration data
//
BOOL getbldata(VOID)
{
BOOL usecfg;
// Read saved configration and check for validity
usecfg = BLReadBootCfg(&g_bootCfg);
if ((usecfg == FALSE) ||
(g_bootCfg.signature != BOOT_CFG_SIGNATURE) ||
(g_bootCfg.version != BOOT_CFG_VERSION))
{
memset(&g_bootCfg, 0, sizeof(g_bootCfg));
g_bootCfg.signature = BOOT_CFG_SIGNATURE;
g_bootCfg.version = BOOT_CFG_VERSION;
g_bootCfg.bootDevLoc.IfcType = Internal;
g_bootCfg.bootDevLoc.BusNumber = 0;
g_bootCfg.bootDevLoc.LogicalLoc = SD_BASE;
g_bootCfg.kitlDevLoc.IfcType = Internal;
g_bootCfg.kitlDevLoc.BusNumber = 0;
g_bootCfg.kitlDevLoc.LogicalLoc = ETHERNET_BASE;
g_bootCfg.kitlFlags |= OAL_KITL_FLAGS_DHCP|OAL_KITL_FLAGS_ENABLED;
g_bootCfg.kitlFlags |= OAL_KITL_FLAGS_VMINI|OAL_KITL_FLAGS_EXTNAME;
g_bootCfg.ipAddress = 0;
g_bootCfg.ipMask = 0;
g_bootCfg.ipRoute = 0;
g_bootCfg.boot_to = 5;
g_bootCfg.baudRate = BSP_UART_RATE;
strcpy(g_bootCfg.binName, "nk.bin");
}
return usecfg;
}
//------------------------------------------------------------------------------
//
// lpc32xxMain
//
// This function is called from StartUp.s.
//
void lpc32xxMain(void)
{
// Initialize LED port
SetupLEDSGPIO();
SetLEDValue(0x00);
// Setup RTC and MSTimer for seconds counter
Time_Setup();
// Go to BLCOMMON
BootloaderMain ();
// Should never get here
SpinForever();
}
//------------------------------------------------------------------------------
//
// OALGetTickCount
//
// Returns the number of milliSecond ticks since boot
//
UINT32 OALGetTickCount()
{
#ifndef USETMR0
UINT64 tmp;
UINT32 trtc, tmst;
RTC_REGS_T *pRTCRegs;
MSTIMER_REGS_T *pMSTRegs;
pRTCRegs = (RTC_REGS_T *) OALPAtoVA((UINT32) RTC, FALSE);
pMSTRegs = (MSTIMER_REGS_T *) OALPAtoVA((UINT32) MSTIMER, FALSE);
trtc = pRTCRegs->ucount;
tmst = pMSTRegs->mstim_counter;
tmp = (UINT64) (tmst + (trtc * RTCCLKRATE));
// Convert to milliseconds
tmp = (tmp * 1000) / RTCCLKRATE;
return (UINT32) tmp;
#else
TIMER_CNTR_REGS_T *pTMR0Regs;
pTMR0Regs = (TIMER_CNTR_REGS_T *) OALPAtoVA((UINT32) TIMER_CNTR0, FALSE);
return (UINT32) pTMR0Regs->tc;
#endif
}
//------------------------------------------------------------------------------
//
// OEMKitlGetSecs
//
// This function returns relative time in seconds.
//
DWORD OEMKitlGetSecs()
{
return (DWORD) (OALGetTickCount() / 1000);
}
//------------------------------------------------------------------------------
//
// OALStall
//
// Stall for a period of microSeconds.
//
VOID OALStall(UINT32 uSecs) {
// MilliSecond granularity
uSecs = uSecs / 1000;
uSecs = uSecs + 1 + OALGetTickCount();
while (uSecs > OALGetTickCount());
}
//------------------------------------------------------------------------------
//
// OEMMultiBinNotify
//
// This function check download type
//
VOID OEMMultiBinNotify( MultiBINInfo *pInfo )
{
BOOL rc = FALSE;
UINT32 base = IMAGE_EBOOT_RAM_PA;
UINT32 start, length;
UINT32 ix;
OALMSGS(OAL_FUNC, (
L"+OEMMultiBinNotify(0x%08x -> %d)\r\n", pInfo, pInfo->dwNumRegions
));
OALMSG(OAL_INFO, (
L"Download file information:\r\n"
));
OALMSG(OAL_INFO, (
L"-----------------------------------------------------------\r\n"
));
// Copy information to EBOOT structure and set also save address
g_eboot.numRegions = pInfo->dwNumRegions;
for (ix = 0; ix < pInfo->dwNumRegions; ix++)
{
g_eboot.region[ix].start = pInfo->Region[ix].dwRegionStart;
g_eboot.region[ix].length = pInfo->Region[ix].dwRegionLength;
g_eboot.region[ix].base = base;
base += g_eboot.region[ix].length;
OALMSG(OAL_INFO, (
L"[%d]: Address=0x%08x Length=0x%08x Save=0x%08x\r\n",
ix, g_eboot.region[ix].start, g_eboot.region[ix].length,
g_eboot.region[ix].base
));
}
OALMSG(OAL_INFO, (
L"-----------------------------------------------------------\r\n"
));
// Determine type of image downloaded
if (g_eboot.numRegions > 1)
{
OALMSG(OAL_ERROR, (L"ERROR: MultiXIP image is not supported\r\n"));
goto cleanUp;
}
base = g_eboot.region[0].base;
start = g_eboot.region[0].start;
length = g_eboot.region[0].length;
if (start == IMAGE_EBOOT_CODE_PA)
{
g_eboot.type = DOWNLOAD_TYPE_EBOOT;
memset((VOID*)base, 0x00, length);
}
else if (flashburnflag == TRUE)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -