www.pudn.com > iMx31_WCE600.rar > 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. 
// 
//------------------------------------------------------------------------------ 
// 
//  Copyright (C) 2004-2007, Freescale Semiconductor, Inc. All Rights Reserved. 
//  THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS 
//  AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT 
// 
//------------------------------------------------------------------------------ 
// 
//  File:  main.c 
// 
//  Common routines for the bootloader. 
// 
//----------------------------------------------------------------------------- 
#include "bsp.h" 
#include  
#pragma warning(push) 
#pragma warning(disable: 4115) 
#include  
#pragma warning(pop) 
#include "loader.h" 
 
 
//----------------------------------------------------------------------------- 
// External Functions 
extern BOOL NANDLoadIPL(VOID); 
extern BOOL NANDLoadNK(VOID); 
extern BOOL SDHCLoadNK(VOID); 
extern BOOL FlashLoadBootCFG(BYTE *pBootCfg, DWORD cbBootCfgSize); 
extern BOOL FlashStoreBootCFG(BYTE *pBootCfg, DWORD cbBootCfgSize); 
extern void Launch(unsigned int uAddr); 
extern BOOL BLMenu(); 
extern UINT32 OEMGetMagicNumber(); 
 
//----------------------------------------------------------------------------- 
// External Variables 
extern PCSP_PBC_REGS g_pPBC; 
 
 
//----------------------------------------------------------------------------- 
// Defines 
 
 
//----------------------------------------------------------------------------- 
// Types 
 
 
//----------------------------------------------------------------------------- 
// Global Variables 
BSP_ARGS *g_pBSPArgs; 
IMAGE_TYPE g_ImageType; 
IMAGE_MEMORY g_ImageMemory; 
 
BOOT_CFG   g_BootCFG; 
BOOL g_DownloadImage = TRUE; 
UCHAR *g_DefaultRamAddress; 
BOOL g_bNandBootloader; 
BOOL g_bNandExist; 
BOOL g_bSDHCBootloader; 
BOOL g_bSDHCExist; 
 
// Used to save information about downloaded DIO mage 
BOOT_BINDIO_CONTEXT g_BinDIO; 
 
 
//----------------------------------------------------------------------------- 
// Local Variables 
 
 
//------------------------------------------------------------------------------ 
// Local Functions 
// 
BOOL LoadBootCFG(BOOT_CFG *BootCFG); 
BOOL StoreBootCFG(BOOT_CFG *BootCFG); 
void ResetDefaultBootCFG(BOOT_CFG *pBootCFG); 
BOOL OEMVerifyMemory(DWORD dwStartAddr, DWORD dwLength); 
BOOL OEMReportError (DWORD dwReason, DWORD dwReserved); 
void OEMMultiBINNotify(const PMultiBINInfo pInfo); 
 
 
//------------------------------------------------------------------------------ 
// 
//  Function:  main 
// 
//  Bootloader main routine. 
// 
//  Parameters: 
//      None. 
// 
//  Returns: 
//      None. 
// 
//------------------------------------------------------------------------------ 
void main(void) 
{ 
 
    // Common boot loader (blcommon) main routine. 
    // 
    BootloaderMain(); 
 
    // Should never get here. 
    // 
    SpinForever(); 
 
} 
 
 
//------------------------------------------------------------------------------ 
// 
//  Function:  OEMDebugInit 
// 
//  This function is the first called by the BLCOMMON framework when a boot  
//  loader starts. This function initializes the debug transport, usually just  
//  initializing the debug serial universal asynchronous receiver-transmitter  
//  (UART). 
// 
//  Parameters: 
//      None. 
// 
//  Returns: 
//      TRUE indicates success. FALSE indicates failure. 
// 
//------------------------------------------------------------------------------ 
BOOL OEMDebugInit (void) 
{ 
    OEMInitDebugSerial(); 
    return TRUE; 
} 
 
 
//------------------------------------------------------------------------------ 
// 
//  Function:  OEMPlatformInit 
// 
//  This function initializes the platform and is called by the BLCOMMON  
//  framework. 
// 
//  Parameters: 
//      None. 
// 
//  Returns: 
//      TRUE indicates success. FALSE indicates failure. 
//------------------------------------------------------------------------------ 
BOOL OEMPlatformInit (void) 
{ 
    PCSP_CCM_REGS pCCM; 
    UINT32 rcsr; 
 
    OEMBootInit (); 
 
    // Get reset status from CCM 
    pCCM = (PCSP_CCM_REGS) OALPAtoUA(CSP_BASE_REG_PA_CCM); 
    rcsr = INREG32(&pCCM->RCSR); 
 
    // Determine boot mode 
    switch(CSP_BITFEXT(rcsr, CCM_RCSR_BTP)) 
    { 
        // BOOT[4:0] configured for NAND boot 
        case 0x01: 
        case 0x02: 
        case 0x03: 
        case 0x04: 
        case 0x10: 
        case 0x11: 
        case 0x12: 
        case 0x13: 
            g_bNandBootloader = TRUE; 
            KITLOutputDebugString("INFO:  Bootloader launched from NAND\r\n"); 
            break; 
 
        // Otherwise assume NOR bootloader 
        default: 
            KITLOutputDebugString("INFO:  Bootloader launched from NOR\r\n"); 
            g_bNandBootloader = FALSE; 
            break; 
    } 
 
    // Check for image reflash flag from RVD 
    if (CSP_BITFEXT(rcsr, CCM_RCSR_GPF) == 0xF) 
    {         
        KITLOutputDebugString("Reflash request detected!\r\n"); 
 
        // Write out the image previously downloaded into SDRAM 
        // by RVD 
        OEMWriteFlash((DWORD) OALPAtoCA(IMAGE_BOOT_NORDEV_NOR_PA_START), IMAGE_BOOT_NORDEV_NOR_SIZE); 
 
        // EBOOT download is unnecessary since RVD downloaded image via JTAG 
        g_DownloadImage = FALSE; 
             
        // Jump to OS image 
        OEMLaunch(0, 0, (DWORD) OALPAtoCA(IMAGE_BOOT_NKIMAGE_NOR_PA_START), NULL); 
    } 
 
    // Initialize the BSP args structure. 
    // 
    g_pBSPArgs = (BSP_ARGS *) IMAGE_SHARE_ARGS_UA_START; 
    if ((g_pBSPArgs->header.signature != OAL_ARGS_SIGNATURE) ||  
        (g_pBSPArgs->header.oalVersion != OAL_ARGS_VERSION) ||  
        (g_pBSPArgs->header.bspVersion != BSP_ARGS_VERSION)) 
    { 
        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; 
        g_pBSPArgs->kitl.flags             = (OAL_KITL_FLAGS_ENABLED | OAL_KITL_FLAGS_VMINI); 
        g_pBSPArgs->kitl.devLoc.IfcType    = Internal; 
        g_pBSPArgs->kitl.devLoc.BusNumber  = 0; 
        g_pBSPArgs->kitl.devLoc.LogicalLoc = BSP_BASE_REG_PA_CS8900A_IOBASE; 
		g_pBSPArgs->kitl.devLoc.PhysicalLoc = (PVOID)(BSP_BASE_REG_PA_CS8900A_IOBASE); 
        g_pBSPArgs->updateMode = FALSE; 
    } 
     
    // Update global BSP args struct with user switches on ADS board 
    OALBspArgsInit(g_pBSPArgs); 
 
    // Attempt to initialize the NAND flash driver 
    if (!FMD_Init(NULL, NULL, NULL)) 
    { 
        KITLOutputDebugString("WARNING: OEMPlatformInit: Failed to initialize NAND flash device.\r\n"); 
        g_bNandExist = FALSE; 
    } 
    else 
    { 
        KITLOutputDebugString("INFO: OEMPlatformInit: Initialized NAND flash device.\r\n"); 
        g_bNandExist = TRUE; 
    } 
 
    // Load eboot configuration 
    // 
    if (!LoadBootCFG(&g_BootCFG))  
    { 
 
        // Load default bootloader configuration settings. 
        KITLOutputDebugString("ERROR: flash initialization failed - loading bootloader defaults...\r\n"); 
        ResetDefaultBootCFG(&g_BootCFG); 
    } 
 
    // Set up optional bootloader function pointers. 
    // 
    g_pOEMMultiBINNotify = OEMMultiBINNotify; 
    g_pOEMVerifyMemory = OEMVerifyMemory; 
    g_pOEMReportError = OEMReportError; 
         
    return TRUE; 
} 
 
 
//------------------------------------------------------------------------------ 
// 
//  Function:  OEMPreDownload 
// 
//  This function is called by the BLCOMMON framework prior to download and can 
//  be customized to prompt for user feedback, such as obtaining a static IP  
//  address or skipping the download and jumping to a flash-resident run-time  
//  image. 
// 
//  Parameters:         
//      None. 
// 
//  Returns: 
//      Possible return values for OEMPreDownload: 
//       
//      Value               Description  
//      -----               ----------- 
//      BL_DOWNLOAD = 0     Download the OS image from the host machine.  
//      BL_JUMP = 1         Skip the download and jump to a resident OS image.  
//      BL_ERROR = -1       Image download is unsuccessful.  
//------------------------------------------------------------------------------ 
DWORD OEMPreDownload(void) 
{ 
    UINT32 rc = (DWORD)BL_ERROR; 
    BOOL  fGotJumpImg = FALSE; 
 
    // User menu code... 
    // 
    if (!BLMenu()) 
    { 
        return rc; 
    } 
 
    // Create device name based on Ethernet address (this is how Platform Builder identifies this device). 
    // 
    OALKitlCreateName(BSP_DEVICE_PREFIX, g_pBSPArgs->kitl.mac, (CHAR *)g_pBSPArgs->deviceId); 
    KITLOutputDebugString("INFO: Using device name: '%s'\n", g_pBSPArgs->deviceId); 
 
    fGotJumpImg = GetPreDownloadInfo (&g_BootCFG); 
      
    if (!g_DownloadImage || // this gets set in the BLMenu() function 
        fGotJumpImg)        // this gets set in EbootInitEtherTransport 
    { 
        switch(g_BootCFG.autoDownloadImage) 
        { 
        case BOOT_CFG_AUTODOWNLOAD_NK_NOR: 
            rc = BL_JUMP; 
            break; 
 
        case BOOT_CFG_AUTODOWNLOAD_NK_NAND: 
            if (NANDLoadNK()) 
            { 
                rc = BL_JUMP; 
            } 
            else 
            { 
                KITLOutputDebugString("ERROR: Failed to load OS image from NAND.\r\n"); 
            } 
            break; 
             
        case BOOT_CFG_AUTODOWNLOAD_IPL_NAND: 
            if (NANDLoadIPL()) 
            { 
                rc = BL_JUMP; 
            } 
            else 
            { 
                KITLOutputDebugString("ERROR: Failed to load IPL image from NAND.\r\n"); 
            } 
            break; 
        } 
 
        // Set the clean boot flag so that OAL will let the kernel know that 
        // it needs a clean boot 
        // 
        // g_pBSPArgs->bCleanBootFlag = TRUE; 
    } 
    else if (g_DownloadImage) 
    { 
        rc = BL_DOWNLOAD; 
    } 
 
    return(rc); 
} 
 
 
//------------------------------------------------------------------------------ 
// 
//  Function:  OEMLaunch 
// 
//  This function launches the run-time image. It is the last one called by  
//  the BLCOMMON framework. 
// 
//  Parameters:         
//      dwImageStart  
//          [in] Starting address of OS image.  
// 
//      dwImageLength  
//          [in] Length, in bytes, of the OS image.  
// 
//      dwLaunchAddr  
//          [in] First instruction of the OS image. 
// 
//      pRomHdr  
//          [out] Pointer to the ROM header structure. 
// 
//  Returns: 
//      None. 
//------------------------------------------------------------------------------ 
void OEMLaunch (DWORD dwImageStart, DWORD dwImageLength, DWORD dwLaunchAddr, const ROMHDR *pRomHdr) 
{ 
    UINT32 PhysAddress; 
 
    // Remove-W4: Warning C4100 workaround 
    UNREFERENCED_PARAMETER(pRomHdr); 
 
    switch(g_BootCFG.autoDownloadImage) 
    { 
    case BOOT_CFG_AUTODOWNLOAD_NK_NOR: 
        // Set launch address for NOR OS image.  OS executes-in-place from NOR. 
        PhysAddress = IMAGE_BOOT_NKIMAGE_NOR_PA_START; 
        break; 
 
    case BOOT_CFG_AUTODOWNLOAD_NK_NAND: 
        // Set launch address for NAND/SDHC OS image.  OS is copied into RAM for execution. 
        PhysAddress = IMAGE_BOOT_NKIMAGE_RAM_PA_START; 
        break; 
 
    case BOOT_CFG_AUTODOWNLOAD_IPL_NAND: 
        // Set launch address for NAND IPL image.  IPL is copied into RAM for execution. 
        PhysAddress = IMAGE_BOOT_IPLIMAGE_RAM_START; 
        break; 
 
    default: 
        // If a launch address wasn't specified - use the last known good address. 
        // 
        if (!dwLaunchAddr) 
        { 
            dwLaunchAddr = g_BootCFG.dwLaunchAddr; 
        } 
        else 
        { 
            if (g_BootCFG.dwLaunchAddr != dwLaunchAddr || 
                g_BootCFG.dwPhysStart  != dwImageStart || 
                g_BootCFG.dwPhysLen    != dwImageLength) 
            { 
                g_BootCFG.dwLaunchAddr = dwLaunchAddr; 
                g_BootCFG.dwPhysStart  = dwImageStart; 
                g_BootCFG.dwPhysLen    = dwImageLength; 
 
                StoreBootCFG(&g_BootCFG); 
            } 
        } 
 
        // Translate the image start address (virtual address) to a physical address. 
        // 
        PhysAddress = (UINT32) OALVAtoPA((VOID *)dwLaunchAddr); 
        break; 
    } 
     
    KITLOutputDebugString("Download successful!  Jumping to image at 0x%x (physical 0x%x)...\r\n", dwLaunchAddr, PhysAddress); 
 
    // Wait for PB connection... 
    // 
    if (g_DownloadImage) 
    { 
	GetLaunchInfo (); 
    } 
 
    // Jump to the image we just downloaded. 
    // 
    KITLOutputDebugString("\r\n\r\n\r\n"); 
    OEMWriteDebugLED(0, 0x00FF); 
    Launch(PhysAddress); 
 
    // Should never get here... 
    // 
    SpinForever(); 
 
} 
 
 
//------------------------------------------------------------------------------ 
// 
//  Function:  OEMMultiBINNotify 
// 
//  Receives/processes download file manifest. 
// 
//  Parameters: 
//      pInfo  
//          [in] Download manifiest provided by BLCOMMON framework. 
// 
//  Returns: 
//             void 
//------------------------------------------------------------------------------ 
void OEMMultiBINNotify(const PMultiBINInfo pInfo) 
{ 
    CHAR szFileName[MAX_PATH]; 
    int i, key, fileExtPos; 
 
    if (!pInfo) return; 
 
    KITLOutputDebugString("INFO: OEMMultiBINNotify (dwNumRegions = %d, dwRegionStart = 0x%x).\r\n",  
        pInfo->dwNumRegions, pInfo->Region[0].dwRegionStart); 
     
    // Only inspect manifest if this is a monolithic .nb0 or diskimage file 
    if (pInfo->dwNumRegions != 1)  
        return; 
 
    //  NBO and DIO files will have start address of zero 
    if (pInfo->Region[0].dwRegionStart == 0) 
    { 
 
        // Convert the file name to lower case 
        i = 0; 
        fileExtPos = 0; 
        while ((pInfo->Region[0].szFileName[i] != '\0') && (i < MAX_PATH)) 
        { 
            szFileName[i] = (CHAR)tolower(pInfo->Region[0].szFileName[i]); 
            // Keep track of file extension position 
            if (szFileName[i] == '.') 
            { 
                fileExtPos = i; 
            } 
            i++; 
        } 
         
        // Check for NAND XLDR update 
        if (strncmp(szFileName, XLDR_NB0_FILE, XLDR_NB0_FILE_LEN) == 0) 
        { 
			// Remap the start address to the NAND XLDR region 
            pInfo->Region[0].dwRegionStart = (DWORD) OALPAtoCA(IMAGE_BOOT_XLDRIMAGE_NAND_PA_START); 
            KITLOutputDebugString("INFO: XLDR NB0 remapped to 0x%x.\r\n", pInfo->Region[0].dwRegionStart); 
        } 
 
        // Check for EBOOT/SBOOT update 
        else if  ( (strncmp(szFileName, EBOOT_NB0_FILE, EBOOT_NB0_FILE_LEN) == 0) || 
		   (strncmp(szFileName, SBOOT_NB0_FILE, SBOOT_NB0_FILE_LEN) == 0) ) 
        { 
            // Remap the start address to the region specified by the user 
            KITLOutputDebugString("Specify destination for EBOOT/SBOOT NB0 [1 = NOR, 2 = NAND]: "); 
            do { 
                key = OEMReadDebugByte(); 
            } while ((key != '1') && (key != '2')); 
            KITLOutputDebugString("\r\n"); 
            switch (key) 
            { 
            case '1': 
                pInfo->Region[0].dwRegionStart = (DWORD) OALPAtoCA(IMAGE_BOOT_BOOTIMAGE_NOR_PA_START); 
                break; 
                 
            case '2': 
                pInfo->Region[0].dwRegionStart = (DWORD) OALPAtoCA(IMAGE_BOOT_BOOTIMAGE_NAND_PA_START); 
                break; 
 
			default: 
                return; 
            } 
 
            KITLOutputDebugString("\r\nINFO: EBOOT/SBOOT NB0 remapped to 0x%x.\r\n", pInfo->Region[0].dwRegionStart); 
        } 
         
        // If  file to be downloaded has an NB0 extension, assume it is an NK NB0 image 
        else if (fileExtPos && (strncmp(&szFileName[fileExtPos], ".nb0", 4) == 0)) 
        { 
            // Remap the start address to the region specified by the user 
            KITLOutputDebugString("Specify destination for NK NB0 [0 = RAM, 1 = NOR, 2 = NAND,]: "); 
            do { 
                key = OEMReadDebugByte(); 
            } while ((key != '0') && (key != '1') && (key != '2')); 
            KITLOutputDebugString("\r\n"); 
            switch (key) 
            { 
            case '0': 
                pInfo->Region[0].dwRegionStart = (DWORD) OALPAtoCA(IMAGE_BOOT_NKIMAGE_RAM_PA_START); 
                break; 
 
            case '1': 
                pInfo->Region[0].dwRegionStart = (DWORD) OALPAtoCA(IMAGE_BOOT_NKIMAGE_NOR_PA_START); 
                break; 
                 
            case '2': 
                pInfo->Region[0].dwRegionStart = (DWORD) OALPAtoCA(IMAGE_BOOT_NKIMAGE_NAND_PA_START); 
                break; 
 
			default: 
                return; 
            } 
 
            KITLOutputDebugString("\r\nINFO: NK NB0 remapped to 0x%x.\r\n", pInfo->Region[0].dwRegionStart); 
        } 
 
        // Notify user of unsupported format 
        else  
        { 
            KITLOutputDebugString("\r\nWARNING: Unsupported binary format.  Image not remapped.\r\n"); 
        } 
    } 
 
    // If this is a Windows Mobile disk image BIN, then dwRegionStart will 
    // be offset into NAND. 
    else if (pInfo->Region[0].dwRegionStart < IMAGE_BOOT_RAMDEV_RAM_PA_START) 
    { 
        g_ImageType = IMAGE_TYPE_BINDIO; 
        g_ImageMemory = IMAGE_MEMORY_NAND; 
        KITLOutputDebugString("\r\nINFO: DIO image with starting address 0x%x.\r\n", pInfo->Region[0].dwRegionStart); 
    } 
     
    return; 
} 
 
//------------------------------------------------------------------------------ 
// 
//  Function:  OEMReportError 
// 
//  Error reporting function provided by BLCOMMON framework. 
// 
//  Parameters: 
//      dwReason  
//          [in] Reason for error 
// 
//      dwReserved  
//          [in] Reserved parameter 
// 
//  Returns: 
//             void 
//------------------------------------------------------------------------------ 
BOOL OEMReportError (DWORD dwReason, DWORD dwReserved) 
{ 
    // Remove-W4: Warning C4100 workaround 
    UNREFERENCED_PARAMETER(dwReserved); 
 
    KITLOutputDebugString("INFO: OEMReportError Reason 0x%x\r\n", dwReason); 
 
	return TRUE;	 
} 
 
//----------------------------------------------------------------------------- 
// 
//  Function:  OEMVerifyMemory 
// 
//  This function verifies that the address provided is in valid memory, 
//  and sets globals to describe the image region being updated. 
// 
//  Parameters: 
//      dwStartAddr  
//          [in] Address to be verified.  
// 
//      dwLength  
//          [in] Length of the address, in bytes. 
// 
//  Returns: 
//      TRUE indicates success. FALSE indicates failure. 
// 
//----------------------------------------------------------------------------- 
BOOL OEMVerifyMemory(DWORD dwStartAddr, DWORD dwLength) 
{ 
    BOOL  rc = TRUE; 
    DWORD dwPhysVerifyStart;  
    DWORD dwPhysVerifyEnd; 
 
    // First check for DIO image flagged by OEMMultiBINNotify 
    if (g_ImageType == IMAGE_TYPE_BINDIO) 
    { 
        KITLOutputDebugString("INFO: Downloading DIO NAND image.\r\n"); 
        return (TRUE); 
    } 
 
    dwPhysVerifyStart = (DWORD) OALVAtoPA((void *)dwStartAddr);  
    dwPhysVerifyEnd   = dwPhysVerifyStart + dwLength - 1; 
 
    KITLOutputDebugString("INFO: OEMVerifyMemory (CA = 0x%x, PA = 0x%x, length = 0x%x)\r\n",  
        dwStartAddr, dwPhysVerifyStart, dwLength); 
 
    if ((dwPhysVerifyStart >= IMAGE_BOOT_XLDRIMAGE_NAND_PA_START) && (dwPhysVerifyEnd <= IMAGE_BOOT_XLDRIMAGE_NAND_PA_END)) 
    { 
        KITLOutputDebugString("INFO: Downloading XLDR NAND image.\r\n"); 
        g_ImageType = IMAGE_TYPE_XLDR; 
        g_ImageMemory = IMAGE_MEMORY_NAND; 
    } 
    else if ((dwPhysVerifyStart >= IMAGE_BOOT_BOOTIMAGE_NAND_PA_START) && (dwPhysVerifyEnd <= IMAGE_BOOT_BOOTIMAGE_NAND_PA_END)) 
    { 
        KITLOutputDebugString("INFO: Downloading EBOOT/SBOOT NAND image.\r\n"); 
        g_ImageType = IMAGE_TYPE_BOOT; 
        g_ImageMemory = IMAGE_MEMORY_NAND; 
    } 
    else if ((dwPhysVerifyStart >= IMAGE_BOOT_IPLIMAGE_NAND_PA_START) && (dwPhysVerifyEnd <= IMAGE_BOOT_IPLIMAGE_NAND_PA_END)) 
    { 
        KITLOutputDebugString("INFO: Downloading IPL NAND image.\r\n"); 
        g_ImageType = IMAGE_TYPE_IPL; 
        g_ImageMemory = IMAGE_MEMORY_NAND; 
    } 
    // DIO and NK share this start address 
    else if ((dwPhysVerifyStart >= IMAGE_BOOT_NKIMAGE_NAND_PA_START) && (dwPhysVerifyEnd <= IMAGE_BOOT_NKIMAGE_NAND_PA_END)) 
    { 
        KITLOutputDebugString("INFO: Downloading NK NAND image.\r\n"); 
        g_ImageType = IMAGE_TYPE_NK; 
        g_ImageMemory = IMAGE_MEMORY_NAND; 
    } 
    else if ((dwPhysVerifyStart >= IMAGE_BOOT_BOOTIMAGE_NOR_PA_START) && (dwPhysVerifyEnd <= IMAGE_BOOT_BOOTIMAGE_NOR_PA_END)) 
    { 
        KITLOutputDebugString("INFO: Downloading EBOOT/SBOOT NOR image.\r\n"); 
        g_ImageType = IMAGE_TYPE_BOOT; 
        g_ImageMemory = IMAGE_MEMORY_NOR; 
    } 
    else if ((dwPhysVerifyStart >= IMAGE_BOOT_NKIMAGE_NOR_PA_START) && (dwPhysVerifyEnd <= IMAGE_BOOT_NKIMAGE_NOR_PA_END)) 
    { 
        KITLOutputDebugString("INFO: Downloading NK NOR image.\r\n"); 
        g_ImageType = IMAGE_TYPE_NK; 
        g_ImageMemory = IMAGE_MEMORY_NOR; 
    } 
    else if ((dwPhysVerifyStart >= IMAGE_BOOT_NORDEV_NOR_PA_START) && (dwPhysVerifyEnd <= IMAGE_BOOT_NORDEV_NOR_PA_END)) 
    { 
        KITLOutputDebugString("INFO: Downloading NK NOR image.\r\n"); 
        KITLOutputDebugString("WARNING:  NK image will overwrite EBOOT reserved space \r\n"); 
        g_ImageType = IMAGE_TYPE_NK; 
        g_ImageMemory = IMAGE_MEMORY_NOR; 
    } 
    else if ((dwPhysVerifyStart >= IMAGE_BOOT_RAMDEV_RAM_PA_START) && (dwPhysVerifyEnd <= IMAGE_BOOT_RAMDEV_RAM_PA_END)) 
    { 
        KITLOutputDebugString("INFO: Downloading NK RAM image.\r\n"); 
        g_ImageType = IMAGE_TYPE_NK; 
        g_ImageMemory = IMAGE_MEMORY_RAM; 
    } 
    else 
    { 
        KITLOutputDebugString("ERROR: Invalid address range.\r\n"); 
        rc = FALSE; 
    } 
 
    return(rc); 
 
} 
 
 
//------------------------------------------------------------------------------ 
// 
//  Function:  StoreBootCFG 
// 
//  Stores bootloader configuration information (menu settings, etc.) in flash. 
// 
//  Parameters: 
//      BootCfg  
//          [in] Points to bootloader configuration to be stored.  
// 
//  Returns: 
//      TRUE indicates success. FALSE indicates failure. 
// 
//----------------------------------------------------------------------------- 
BOOL StoreBootCFG(BOOT_CFG *BootCfg) 
{ 
 
    if (!FlashStoreBootCFG((BYTE*) BootCfg, sizeof(BOOT_CFG))) 
    { 
        KITLOutputDebugString("ERROR: StoreBootCFG: failed to write configuration.\r\n"); 
        return(FALSE); 
    } 
 
    return(TRUE); 
} 
 
 
//------------------------------------------------------------------------------ 
// 
//  Function:  LoadBootCFG 
// 
//  Retrieves bootloader configuration information (menu settings, etc.) from  
//  flash. 
// 
//  Parameters: 
//      BootCfg  
//          [out] Points to bootloader configuration that will be filled with 
//          loaded data.  
// 
//  Returns: 
//      TRUE indicates success. FALSE indicates failure. 
// 
//----------------------------------------------------------------------------- 
BOOL LoadBootCFG(BOOT_CFG *BootCfg) 
{ 
 
    if (!FlashLoadBootCFG((BYTE*) BootCfg, sizeof(BOOT_CFG))) { 
        KITLOutputDebugString("ERROR: LoadBootCFG: failed to load configuration.\r\n"); 
        return(FALSE); 
    } 
 
    // Is the CFG data valid?  Check for the magic number that was written the last time 
    // the CFG block was updated.  If Eboot has never been run, there will be no configuration 
    // information, so the magic number will likely not be found.  In this case, setup the  
    // factory defaults and store them into Flash. 
    // 
    if (BootCfg->ConfigMagicNumber != OEMGetMagicNumber()) 
    { 
        KITLOutputDebugString("ERROR: LoadBootCFG: ConfigMagicNumber not correct. Expected = 0x%x ; Actual = 0x%x.\r\n",  
            OEMGetMagicNumber(), BootCfg->ConfigMagicNumber); 
        ResetDefaultBootCFG(BootCfg); 
    } 
 
    g_DefaultRamAddress = (PUCHAR)g_BootCFG.dwLaunchAddr; 
 
    return(TRUE); 
}