📄 main.c
字号:
// Copyright (c) David Vescovi. All rights reserved.
// Part of Project DrumStix
// Windows Embedded Developers Interest Group (WE-DIG) community project.
// http://www.we-dig.org
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
//
// File: main.c
//
// Core routines for the bootloader.
//
//
//------------------------------------------------------------------------------
#include <windows.h>
#include <nkintr.h>
#include <oal_memory.h>
#include <oal_kitl.h>
#include <oal_log.h>
#include <pcireg.h>
#include <fmd.h>
#include "bsp.h"
#include "kitl_cfg.h"
#include "loader.h"
#include "mmcapi.h"
extern BOOL OALKitlSerialInit(
LPSTR deviceId, OAL_KITL_DEVICE *pDevice, OAL_KITL_ARGS *pArgs,
KITLTRANSPORT *pKitl);
//------------------------------------------------------------------------------
// Defines
//
#define FLASH_DEVICE_ID_XM 0x0018
#define TIMEOUT_RECV 3 // seconds serial timeout
//------------------------------------------------------------------------------
// Local variables.
//
static PCI_REG_INFO g_PCIFlashInfo;
static EBOOT_CFG g_EbootCFG;
static BOOLEAN g_DownloadImage = TRUE;
static UINT32 g_EthDevice = -1;
//------------------------------------------------------------------------------
// Global variables.
//
DWORD EdbgDebugZone;
FlashInfo g_FlashInfo;
BSP_ARGS *g_pBSPArgs = (BSP_ARGS *) IMAGE_SHARE_ARGS_UA_START;
EDBG_ADDR g_DeviceAddr; // NOTE: global used so it remains in scope throughout download process
// since eboot library code keeps a global pointer to the variable provided.
IMAGE_TYPE g_ImageType;
BYTE g_SectorBuffer[512];
DWORD g_dwBytesRead = 0;
DWORD g_dwTotalBytes = 0;
//------------------------------------------------------------------------------
// Local function prototypes.
//
static BOOL InitFlash(void);
static BOOL LockBootBlocks(BOOL Lockit);
static void InitSpeed(void);
static BOOL LoadEBootCFG(EBOOT_CFG *EBootCFG);
static BOOL StoreEBootCFG(EBOOT_CFG *EBootCFG);
static void ResetDefaultEBootCFG(EBOOT_CFG *pEbootCFG);
static void SetIP(EBOOT_CFG *pEbootCFG);
static void SetIPConfig(EBOOT_CFG *pEbootCFG);
static void SetMask(EBOOT_CFG *pEbootCFG);
static void SetMACAddress(EBOOT_CFG *pEbootCFG, UINT32 GumEthDevice);
static void SetBootMe(EBOOT_CFG *pEbootCFG);
static void SetDelay(EBOOT_CFG *pEbootCFG);
static void SetHardwareCFG(void);
static void EditMemory(void);
static BOOL DetectXMFlashDevice(UINT32 FlashBaseAddress);
static DWORD hexstrtoul(char *str, UINT32 len);
static void printProgress(void);
static void InitHardware(void);
static BOOL SRecordDownload(void);
static void GPIORegisterDump(void);
BOOL OEMVerifyMemory(DWORD dwStartAddr, DWORD dwLength);
void OEMDownloadFileNotify(PDownloadManifest pInfo);
BOOL OEMReportError(DWORD dwReason, DWORD dwReserved);
DWORD OEMSerialPreDownload (void);
//------------------------------------------------------------------------------
// External function prorotypes.
//
extern void Launch(unsigned int uAddr);
extern void FreqChange(void);
extern OAL_ADDRESS_TABLE g_oalAddressTable[];
extern BOOL SerialReadData(DWORD cbData, LPBYTE pbData);
extern BOOL SerialSendBlockAck(DWORD uBlockNumber);
extern BOOL SerialSendBootRequest(const char * platformString);
extern DWORD SerialWaitForJump(VOID);
extern BOOL SerialWaitForBootAck(BOOL *pfJump);
//------------------------------------------------------------------------------
//
// Function: main
//
// Bootloader main routine.
//
//------------------------------------------------------------------------------
void main(void)
{
// Common boot loader (blcommon) main routine.
//
BootloaderMain();
// Should never get here.
//
OALSpinForever();
}
//------------------------------------------------------------------------------
//
// Function: OEMDebugInit
//
// Initialize debug serial UART.
//
BOOL OEMDebugInit(void)
{
OEMInitDebugLED();
OEMWriteDebugLED(0, 1); // blip LED if we get this far
InitDebugSerial(DEFAULT_DEBUG_PORT);
EdbgOutputDebugString("\r\n");
OEMWriteDebugLED(0, 0);
// Set up optional bootloader function pointers.
//
g_pOEMVerifyMemory = OEMVerifyMemory;
g_pOEMMultiBINNotify = OEMDownloadFileNotify;
g_pOEMReportError = OEMReportError;
return(TRUE);
}
//------------------------------------------------------------------------------
//
// Function: OEMPlatformInit
//
// Initialize the Gumstix platform.
//
BOOL OEMPlatformInit(void)
{
UINT32 AutoBootDelay = 0;
BOOLEAN bXIPMode = TRUE;
SYSTEMTIME SysTime;
UINT32 StartTime, CurrTime, PrevTime;
UINT32 Selection;
BOOL retVal = FALSE;
volatile GPIO_REG_T *pGPIORegs = (volatile GPIO_REG_T *) OALPAtoVA(PXA255_BASE_REG_PA_GPIO, FALSE);
volatile CLK_REG_T *pCLKRegs = (volatile CLK_REG_T *) OALPAtoVA(PXA255_BASE_REG_PA_CLK, FALSE);
volatile PWR_REG_T *pPWRRegs = (volatile PWR_REG_T *) OALPAtoVA(PXA255_BASE_REG_PA_PWR, FALSE);
//TODO: get the reset cause bits
// do sleep wake up/power up/reset loqic
pPWRRegs->PSSR = (PSSR_RDH | PSSR_PH | PSSR_VFS | PSSR_BFS | PSSR_SSS);
pCLKRegs->CCCR = (CCCR_L27 | CCCR_M2 | CCCR_N10); // 200Mhz to start
FreqChange();
// CS2, CS3 outputs and chip selects
pGPIORegs->GPSR2 = ( GPIO_78 | GPIO_79 ); // CS high
pGPIORegs->GPDR2 = 0x0000C000;
pGPIORegs->GAFR2_L = 0xA0000000;
pGPIORegs->GAFR2_U = 0x00000000;
// enable the 32khz RTC oscillator
pCLKRegs->OSCC = OSCC_OON;
do { // loop till stable
OALStall(100);
} while (!(pCLKRegs->OSCC & OSCC_OOK));
// if sleep reset do other stuff ..jump over
//TODO: add power manager general config stuff
OALMSG(1, (L"Microsoft Windows CE Bootloader for the Gumstix Development Platform \r\nWE-BOOT %d.%02d", \
EBOOT_VERSION_MAJOR, EBOOT_VERSION_MINOR));
EdbgOutputDebugString(" Built %s %s\r\n", __DATE__,__TIME__);
// clear image RAM
// for (pDWord = (UINT32 *)IMAGE_NK_CA_START;(UINT32)pDWord < (IMAGE_NK_CA_START + IMAGE_NK_MAX_SIZE);pDWord++)
// {
// *pDWord = 0;
// }
// init Flash
//
if (!InitFlash())
{
EdbgOutputDebugString("ERROR: Invalid Flash initialization.\n");
return(FALSE);
}
// Load the bootloader configuration from flash (menu settings).
//
LoadEBootCFG(&g_EbootCFG);
// we now have the hardware configuration dword
OALMSG(1, (L"System Hardware: 0x%08X\r\n",g_EbootCFG.dwPlatformHardware));
Selection = OEMReadDebugByte();
OALStall(1000000);
Selection = OEMReadDebugByte();
//
memset((LPVOID)g_pBSPArgs, 0, sizeof(BSP_ARGS));
g_pBSPArgs->header.signature = OAL_ARGS_SIGNATURE;
g_pBSPArgs->header.oalVersion = OAL_ARGS_VERSION;
g_pBSPArgs->header.bspVersion = BSP_ARGS_VERSION;
// Provide the bootloader version to the OS image.
//
g_pBSPArgs->bootloaderVersion = EBOOT_VERSION_MAJOR<<16 | EBOOT_VERSION_MINOR;
//
// bootloader flags.
g_pBSPArgs->bootFlags = 0;
if (Selection == 0x1B)
{ // bypass init if ESC pressed
EdbgOutputDebugString("Bypassing hardware initialization.\r\n");
}
else
{
InitHardware();
}
// Read the current wall-clock time.
// NOTE: At reset, the RTC value is set to 1/1/1980 at 0:0:0.
//
OEMGetRealTime(&SysTime);
// User menu code...
//
AutoBootDelay = g_EbootCFG.delay;
if (g_EbootCFG.imageLoadDevice == IMG_LOAD_DOWNLOAD)
{
g_DownloadImage = TRUE;
EdbgOutputDebugString ( "\r\nPress [ENTER] to download now or [SPACE] to cancel.\r\n");
EdbgOutputDebugString ( "\r\nInitiating image download in %d seconds. ", AutoBootDelay--);
}
else
{
g_DownloadImage = FALSE;
EdbgOutputDebugString ( "\r\nPress [ENTER] to launch image stored ");
switch (g_EbootCFG.imageLoadDevice)
{
case IMG_LOAD_MMC:
EdbgOutputDebugString ( "on MMC ");
break;
case IMG_LOAD_CF:
EdbgOutputDebugString ( "on CF ");
break;
default: // flash
EdbgOutputDebugString ( "in flash ");
break;
}
EdbgOutputDebugString ( "or [SPACE] to cancel.\r\n");
EdbgOutputDebugString ( "\r\nInitiating image launch in %d seconds. ", AutoBootDelay--);
}
// Get a snapshot of the RTC seconds count.
//
StartTime = OEMEthGetSecs();
PrevTime = StartTime;
CurrTime = StartTime;
Selection = 0;
// Allow the user an amount of time to halt the auto boot/download process.
// Count down to 0 before proceeding with default operation.
//
while ((CurrTime - StartTime) < g_EbootCFG.delay)
{
UINT8 i=0;
UINT8 j;
UINT8 x,y,z;
Selection = OEMReadDebugByte();
if ((Selection == 0x20) || (Selection == 0x0d) || (Selection == 0x1B))
{
break;
}
CurrTime = OEMEthGetSecs();
if (CurrTime > PrevTime)
{
PrevTime = CurrTime;
if (AutoBootDelay < 9)
i = 11;
else if (AutoBootDelay < 99)
i = 12;
else if (AutoBootDelay < 999)
i = 13;
for (j = 0; j < i; j++)
{
OEMWriteDebugByte((BYTE)0x08); // print back space
}
x = AutoBootDelay / 100;
y = (AutoBootDelay % 100) / 10;
z = ((AutoBootDelay % 100) % 10);
EdbgOutputDebugString ( "%d seconds. ", AutoBootDelay--);
}
}
switch (Selection)
{
case OEM_DEBUG_READ_NODATA: // fall through if nothing typed
case 0x00:
case 0x0d: // user canceled wait
{
if (g_EbootCFG.imageLoadDevice == IMG_LOAD_DOWNLOAD)
{
EdbgOutputDebugString ( "\r\nStarting auto download ... \r\n");
}
else if (g_EbootCFG.imageLoadDevice == IMG_LOAD_FLASH)
{
EdbgOutputDebugString ( "\r\nLaunching flash resident image ... \r\n");
}
else
{
EdbgOutputDebugString ( "\r\nLaunching file resident image ... \r\n");
}
break;
}
case 0x1B:
case 0x20:
{
Selection = 0;
while (1)
{
// Show menu
EdbgOutputDebugString ( "\r\n\r\nEthernet Boot Loader Configuration:\r\n\r\n");
EdbgOutputDebugString ( "0) IP configuration: ");
if (g_EbootCFG.DHCPEnable == TRUE)
{
EdbgOutputDebugString("DHCP\r\n");
}
else
{
EdbgOutputDebugString("STATIC:%s",inet_ntoa(g_EbootCFG.IP));
EdbgOutputDebugString(" MASK:%s\r\n",inet_ntoa(g_EbootCFG.subnetMask));
}
OALMSG(1, (L"1) Eth1 MAC address: %02X-%02X-%02X-%02X-%02X-%02X\r\n",
g_EbootCFG.Eth1mac[0] & 0x00FF, g_EbootCFG.Eth1mac[0] >> 8,
g_EbootCFG.Eth1mac[1] & 0x00FF, g_EbootCFG.Eth1mac[1] >> 8,
g_EbootCFG.Eth1mac[2] & 0x00FF, g_EbootCFG.Eth1mac[2] >> 8));
OALMSG(1, (L"2) Eth2 MAC address: %02X-%02X-%02X-%02X-%02X-%02X\r\n",
g_EbootCFG.Eth2mac[0] & 0x00FF, g_EbootCFG.Eth2mac[0] >> 8,
g_EbootCFG.Eth2mac[1] & 0x00FF, g_EbootCFG.Eth2mac[1] >> 8,
g_EbootCFG.Eth2mac[2] & 0x00FF, g_EbootCFG.Eth2mac[2] >> 8));
EdbgOutputDebugString ( "3) Boot delay: %d seconds\r\n", g_EbootCFG.delay);
OALMSG(1, (L"4) Hardware configuration: 0x%08X\r\n",g_EbootCFG.dwPlatformHardware));
EdbgOutputDebugString ( "5) Startup: ");
switch (g_EbootCFG.imageLoadDevice)
{
case IMG_LOAD_DOWNLOAD:
EdbgOutputDebugString ( "Download image\r\n");
break;
case IMG_LOAD_MMC:
EdbgOutputDebugString ( "Launch MMC resident image\r\n");
break;
case IMG_LOAD_CF:
EdbgOutputDebugString ( "Launch CF resident image\r\n");
break;
case IMG_LOAD_FLASH:
default: // flash
EdbgOutputDebugString ( "Launch flash resident image\r\n");
break;
}
EdbgOutputDebugString ( "6) Primary download device: ");
switch (g_EbootCFG.priBootDevice)
{
case BOOT_DEVICE_CF:
EdbgOutputDebugString ( "CF\r\n");
break;
case BOOT_DEVICE_ETH1:
EdbgOutputDebugString ( "ETH1\r\n");
break;
case BOOT_DEVICE_ETH2:
EdbgOutputDebugString ( "ETH2\r\n");
break;
case BOOT_DEVICE_STUART:
EdbgOutputDebugString ( "STUART\r\n");
break;
case BOOT_DEVICE_FFUART:
EdbgOutputDebugString ( "FFUART (SRecord)\r\n");
break;
case BOOT_DEVICE_HWUART:
EdbgOutputDebugString ( "HWUART\r\n");
break;
case BOOT_DEVICE_BTUART:
EdbgOutputDebugString ( "BTUART\r\n");
break;
default:
EdbgOutputDebugString ( "CF\r\n");
g_EbootCFG.priBootDevice = 0;
break;
}
EdbgOutputDebugString ( "7) Secondary download device: ");
switch (g_EbootCFG.secBootDevice)
{
case BOOT_DEVICE_CF:
EdbgOutputDebugString ( "CF\r\n");
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -