⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 Windows CE 6.0 针对PXA270的开发板的BSP参考代码
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// 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.
//
//------------------------------------------------------------------------------
//
//  File:  main.c
//
//  Core routines for the Intel Mainstone bootloader.
//
#include <windows.h>
#include <nkintr.h>
#include <bulverde.h>
#include <mainstoneii.h>
#include <oal_memory.h>
#include <pcireg.h>
#include <fmd.h>
#include <xllp_pccardsocket.h>
#include <bsp.h>
#include "loader.h"

#define NUM_BOOT_DEVICES  5
#define NUM_BOOT_ORDERS   6
#define SDBG_USB_SERIAL   101

//------------------------------------------------------------------------------
// Local variables.
//
static PCI_REG_INFO g_FlashAddress;
EBOOT_CFG           g_EbootCFG;
static BOOLEAN      g_DownloadImage = TRUE;
BOOLEAN             g_SerialUSBDownload = FALSE;

// This table describes the boot order for a given configuration.
//
static BOOT_DEVICE_TYPE BootOrder[NUM_BOOT_ORDERS][NUM_BOOT_DEVICES] = {
    { ETH_DEVICE_SMSC,    ETH_DEVICE_USB,     ETH_DEVICE_PCMCIA0, ETH_DEVICE_PCMCIA1, SER_DEVICE_USB },  // pEbootCFG->bootDeviceOrder = 0.
    { ETH_DEVICE_PCMCIA0, ETH_DEVICE_PCMCIA1, ETH_DEVICE_SMSC,    ETH_DEVICE_USB, SER_DEVICE_USB  },       // pEbootCFG->bootDeviceOrder = 1.
    { ETH_DEVICE_PCMCIA1, ETH_DEVICE_PCMCIA0, ETH_DEVICE_SMSC,    ETH_DEVICE_USB, SER_DEVICE_USB },       // pEbootCFG->bootDeviceOrder = 2.
    { ETH_DEVICE_USB,     ETH_DEVICE_SMSC,    ETH_DEVICE_PCMCIA0, ETH_DEVICE_PCMCIA1, SER_DEVICE_USB },  // pEbootCFG->bootDeviceOrder = 3.
    { SER_DEVICE_USB,     ETH_DEVICE_SMSC,    ETH_DEVICE_USB,     ETH_DEVICE_PCMCIA0, ETH_DEVICE_PCMCIA1 },  // pEbootCFG->bootDeviceOrder = 4.
    { SER_DEVICE_USB,     ETH_DEVICE_USB,     ETH_DEVICE_SMSC,    ETH_DEVICE_PCMCIA0, ETH_DEVICE_PCMCIA1 },  // pEbootCFG->bootDeviceOrder = 5.
};

static char* BootOrderString[NUM_BOOT_ORDERS] =
{
    "SMSC, USB RNDIS, PCMCIA0, PCMCIA1, USB SERIAL (DL Only)",
    "PCMCIA0, PCMCIA1, SMSC, USB RNDIS, USB SERIAL (DL Only)",
    "PCMCIA1, PCMCIA0, SMSC, USB RNDIS, USB SERIAL (DL Only)",
    "USB RNDIS, SMSC, PCMCIA0, PCMCIA1, USB SERIAL (DL Only)",
    "USB SERIAL (DL Only), SMSC, USB RNDIS, PCMCIA0, PCMCIA1",
    "USB SERIAL (DL Only), USB RNDIS, SMSC, PCMCIA0, PCMCIA1",
};

//------------------------------------------------------------------------------
// Global variables.
//
FlashInfo g_FlashInfo;
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.
XLLP_PCCARDSOCKET_T strEbtPCCardSocketHandle;
IMAGE_TYPE g_ImageType;

extern BSP_ARGS *g_pBSPArgs;

//------------------------------------------------------------------------------
// Local function prototypes.
//
static BOOL LoadEBootCFG(EBOOT_CFG *EBootCFG);
static BOOL StoreEBootCFG(EBOOT_CFG *EBootCFG);
static void ResetDefaultEBootCFG(EBOOT_CFG *pEbootCFG);

static void SetMAC(unsigned char *mac);
static void SetIP(EBOOT_CFG *pEbootCFG);
static void SetMask(EBOOT_CFG *pEbootCFG);
static void SetBootMe(EBOOT_CFG *pEbootCFG);
static void SetDelay(EBOOT_CFG *pEbootCFG);

BOOL OEMVerifyMemory(DWORD dwStartAddr, DWORD dwLength);

//------------------------------------------------------------------------------
// External function prorotypes.
//
extern void  Launch(unsigned int uAddr);
extern BOOL  SerialSendBlockAck(DWORD uBlockNumber);
extern BOOL  SerialSendBootRequest(const char * platformString);
extern BOOL  SerialWaitForBootAck(BOOL *pfJump);
extern DWORD SerialWaitForJump(VOID);

extern BOOL USBSerialInit();


//------------------------------------------------------------------------------
//
//  Function:  main
//
//  Bootloader main routine.
//
void main(void)
{

    // Common boot loader (blcommon) main routine.
    //
    BootloaderMain();

    // Should never get here.
    //
    SpinForever();

}


//------------------------------------------------------------------------------
//
//  Function:  OEMDownloadFileNotify
//
//  This routine receives a download manifest from blcommon describing the .bin
//  and/or .nb0 file(s) being downloaded from the host.  It's purpose is to
//  assign an address (typically flash address) where the .nb0 file(s) should be
//  placed (since .nb0 files aren't self-describing like .bin files are) and to
//  display the manifest information to the user (over serial).
//
void OEMDownloadFileNotify(PDownloadManifest pInfo)
{
    DWORD dwCount;
    DWORD dwNumNB0Files = 0;

    if (!pInfo) return;

    KITLOutputDebugString("\r\nDownload file information:\r\n");
    KITLOutputDebugString("-------------------------------------------------------------------------------\r\n");

    for (dwCount = 0 ; dwCount < pInfo->dwNumRegions ; dwCount++)
    {

        KITLOutputDebugString("[%d]: Address=0x%x  Length=0x%x  Name=%s\r\n", dwCount, 
                              pInfo->Region[dwCount].dwRegionStart, 
                              pInfo->Region[dwCount].dwRegionLength, 
                              pInfo->Region[dwCount].szFileName);

        // .nb0 files will have a start address of 0 because Platform Builder
        // won't know where to place them.  We'll support only one .nb0 file
        // download (this is an Image Update disk image).  If we need to
        // support more than one .nb0 file download in the future, we'll need
        // to differentiate them by filename.
        //
        if (pInfo->Region[dwCount].dwRegionStart == 0)
        {
            // We only support one raw binary file (disk image).
            if (dwNumNB0Files++)
            {
                KITLOutputDebugString("ERROR: This bootloader doesn't support downloading a second .nb0 binary image.\r\n");
                SpinForever();
            }

            // The disk image .nb0 file should be placed immediately after the
            // bootloader image in flash (we'll assume that the disk image has the IPL prepended to it).
            pInfo->Region[dwCount].dwRegionStart = (DWORD)OALPAtoVA(IMAGE_BOOT_IPL_FLASH_PA_START, FALSE);

            KITLOutputDebugString("INFO: This bootloader assumes any .nb0 file is an Image Update disk image.\r\n");
            KITLOutputDebugString("INFO: Storing file \"%s\" in flash after boot loader.\r\n", pInfo->Region[dwCount].szFileName);
            KITLOutputDebugString("INFO: Changed start address for %s to 0x%x.\r\n", pInfo->Region[dwCount].szFileName, 
                                                                                     pInfo->Region[dwCount].dwRegionStart);

        }
    }

    KITLOutputDebugString("\r\n");

    return;
}


//------------------------------------------------------------------------------
//
//  Function:  OEMDebugInit
//
//  Initialize debug serial UART.
//
BOOL OEMDebugInit(void)
{
    // Initialize the flash interface (needed so we can determine which serial
    // port to use for bootloader and OS debug message output).
    //
    if (!FlashInit((UINT32) OALPAtoVA(MAINSTONEII_BASE_PA_BOOT_FLASH, FALSE), MAINSTONEII_SIZE_BOOT_FLASH))
    {
        // Load default bootloader configuration settings.
        //
        KITLOutputDebugString("ERROR: flash initialization failed - loading bootloader defaults...\r\n");
        ResetDefaultEBootCFG(&g_EbootCFG);
    }
    else
    {
        // Load the bootloader configuration from flash (menu settings).
        //
        LoadEBootCFG(&g_EbootCFG);
    }

    // Check and initialize the BSP Args area
    // Note: OALArgsInit should be called AFTER FlashInit so that 
    // the g_UniqueDeviceID structure can be populated. This is to ensure
    // we have unique device data for UUID's, etc.
    OALArgsInit((BSP_ARGS *) IMAGE_SHARE_ARGS_UA_START);

    // Initialize the debug UART.
    //
    InitDebugSerial(g_EbootCFG.dwDbgSerPhysAddr, FALSE);

    // Clear the hex LEDs.
    //
    OEMWriteDebugLED(0, 0);

    // Set up optional bootloader function pointers.
    //
    g_pOEMVerifyMemory   = OEMVerifyMemory;
    g_pOEMMultiBINNotify = OEMDownloadFileNotify;

    return(TRUE);
}


//------------------------------------------------------------------------------
//
//  Function:  OEMPlatformInit
//
//  Initialize the Mainstone platform.
//
BOOL OEMPlatformInit(void)
{
    UINT32 AutoBootDelay = 0;
    BOOLEAN bXIPMode     = TRUE;
    BOOLEAN bCFGChanged  = FALSE;
    SYSTEMTIME SysTime;
    UINT32 StartTime, CurrTime, PrevTime;
    UINT32 Selection;
    UINT32 BootDevice;
    int i;
    UCHAR  rndis_mac[6] = {0,0,0,0,0,0};

    KITLOutputDebugString("Microsoft Windows CE Ethernet Bootloader %d.%d for the Intel MainstoneIII Development Platform Built %s\r\n", \
                          EBOOT_VERSION_MAJOR, EBOOT_VERSION_MINOR, __DATE__);

    // Initialize the global XLLP device handle for the PC Card interface.
    //
    memset((void *) &strEbtPCCardSocketHandle, 0, sizeof(XLLP_PCCARDSOCKET_T));
    strEbtPCCardSocketHandle.pstrGpioRegsHandle = (XLLP_GPIO_T *) OALPAtoVA(BULVERDE_BASE_REG_PA_GPIO, FALSE);
    XllpPCCardConfigureGPIOs(&strEbtPCCardSocketHandle);

    // Get the Ehternet MAC address to use as RNDIS MAC address
    // Note: This only applies to Mainstone platform because it has Ehternet controller on it.
    //
    if (!g_EbootCFG.RNDISMac[0] && !g_EbootCFG.RNDISMac[1] && !g_EbootCFG.RNDISMac[2])
    {
        if (LAN91CInit((UINT8 *) (((UINT32) OALPAtoVA(MAINSTONEII_BASE_REG_PA_SMSC_ETHERNET, FALSE)) + 0x300), 0, g_EbootCFG.RNDISMac))
        {
            bCFGChanged = TRUE;
        }
    }

    // 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.autoDownloadImage)
    {
        g_DownloadImage = TRUE;
        KITLOutputDebugString ( "\r\nPress [ENTER] to download now or [SPACE] to cancel.\r\n");
        KITLOutputDebugString ( "\r\nInitiating image download in %d seconds. ", AutoBootDelay--);
    }
    else
    {
        g_DownloadImage = FALSE;
        KITLOutputDebugString ( "\r\nPress [ENTER] to launch image stored in flash or [SPACE] to cancel.\r\n");
        KITLOutputDebugString ( "\r\nInitiating image launch in %d seconds. ", AutoBootDelay--);
    }

    // Get a snapshot of the RTC seconds count.
    //
    StartTime     = OEMKitlGetSecs();
    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 k=0;
        UINT8 j;
        UINT8 x,y,z;

        Selection = OEMReadDebugByte(); 
        if ((Selection == 0x20) || (Selection == 0x0d))
        {
            break;
        }
        CurrTime = OEMKitlGetSecs();   
        if (CurrTime > PrevTime)
        {
            PrevTime = CurrTime;
            if (AutoBootDelay < 9)
                k = 11;
            else if (AutoBootDelay < 99)
                k = 12;
            else if (AutoBootDelay < 999)
                k = 13;

            for (j = 0; j < k; j++)
            {
                OEMWriteDebugByte((BYTE)0x08); // print back space
            }
            x = AutoBootDelay / 100;
            y = (AutoBootDelay % 100) / 10;
            z = ((AutoBootDelay % 100) % 10);
            OEMWriteDebugLED(0, ((x << 8) | (y << 4) | (z)));
            KITLOutputDebugString ( "%d seconds. ", AutoBootDelay--);
        }

    }

    switch (Selection)
    {
    case 0x00: // fall through if nothing typed
    case 0x0d: // user canceled wait
        {
            if (g_EbootCFG.autoDownloadImage)
            {
                KITLOutputDebugString ( "\r\nStarting auto download ... \r\n");
            }
            else
            {
                KITLOutputDebugString ( "\r\nLaunching flash image  ... \r\n");
            }
            break;
        }
    case 0x20:
        {
            Selection = 0;
            while (1)
            {
                // Get the Ehternet MAC address to use as RNDIS MAC address
                // Note: This only applies to Mainstone platform because it has Ehternet controller on it.
                //
                if (!g_EbootCFG.RNDISMac[0] && !g_EbootCFG.RNDISMac[1] && !g_EbootCFG.RNDISMac[2])
                {
                    if (LAN91CInit((UINT8 *) (((UINT32) OALPAtoVA(MAINSTONEII_BASE_REG_PA_SMSC_ETHERNET, FALSE)) + 0x300), 0, g_EbootCFG.RNDISMac))
                    {
                        bCFGChanged = TRUE;
                    }
                }

                // Show menu
                KITLOutputDebugString ( "\r\n\r\nEBoot Loader Configuration:\r\n\r\n");

                KITLOutputDebugString ( "0) IP address: %s\r\n",inet_ntoa(g_EbootCFG.IP));
                KITLOutputDebugString ( "1) Subnet mask: %s\r\n", inet_ntoa(g_EbootCFG.subnetMask));
                KITLOutputDebugString ( "2) Boot delay: %d seconds\r\n", g_EbootCFG.delay);
                KITLOutputDebugString ( "3) DHCP: %s\r\n", (g_EbootCFG.DHCPEnable == TRUE?"(Enabled)":"(Disabled)"));
                KITLOutputDebugString ( "4) Reset to factory default configuration\r\n");
                KITLOutputDebugString ( "5) RNDIS MAC address: %x-%x-%x-%x-%x-%x\r\n",(UCHAR) g_EbootCFG.RNDISMac[0], (UCHAR) (g_EbootCFG.RNDISMac[0]>>8), (UCHAR)g_EbootCFG.RNDISMac[1],
                                             (UCHAR)(g_EbootCFG.RNDISMac[1]>>8), (UCHAR)g_EbootCFG.RNDISMac[2], (UCHAR)(g_EbootCFG.RNDISMac[2]>>8));
                KITLOutputDebugString ( "6) %s image at startup\r\n", g_EbootCFG.autoDownloadImage?"Download new":"Launch existing flash resident");
                KITLOutputDebugString ( "7) Boot device order: ");
                {
                    if(g_EbootCFG.bootDeviceOrder >= NUM_BOOT_ORDERS)
                    g_EbootCFG.bootDeviceOrder = 0;
     
                    KITLOutputDebugString ( "%s\r\n", BootOrderString[g_EbootCFG.bootDeviceOrder]);
                }
                KITLOutputDebugString ( "8) Debug serial port: ");
                {
                    switch (g_EbootCFG.dwDbgSerPhysAddr)
                    {
                        case BULVERDE_BASE_REG_PA_FFUART:
                        KITLOutputDebugString ( "FFUART\r\n");
                        break;

                        case BULVERDE_BASE_REG_PA_BTUART:
                        default:
                        KITLOutputDebugString ( "BTUART\r\n");
                        break;
                    }
                }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -