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

📄 main.c

📁 WINDOWS CE BSP用于SBC2440开发板
💻 C
📖 第 1 页 / 共 4 页
字号:
//
// 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:
    Ethernet boot loader main module. This file contains the C main
    for the boot loader.    NOTE: The firmware "entry" point (the real
    entry point is _EntryPoint in init assembler file.

    The Windows CE boot loader is the code that is executed on a Windows CE
    development system at power-on reset and loads the Windows CE
    operating system. The boot loader also provides code that monitors
    the behavior of a Windows CE platform between the time the boot loader
    starts running and the time the full operating system debugger is
    available. Windows CE OEMs are supplied with sample boot loader code
    that runs on a particular development platform and CPU.

Functions:


Notes:

--*/

#include <windows.h>
#include <pcireg.h>
#include <ethdbg.h>
#include <drv_glob.h>
#include <nkintr.h>
#include <pehdr.h>
#include <romldr.h>
#include <blcommon.h>
#include <bootpart.h>
#include <kitlprot.h>

#include "s2440.h"
#include "loader.h"
#include "fmd.h"
#include "cfnand.h"
#include "warning.h"


/* Start: add by thisway.diy, 2006.06.23 */

#ifndef _RAM_STARTADDRESS
#define _RAM_STARTADDRESS 	0x30000000
#endif

#ifndef VA_BASE
#define VA_BASE             0x8C000000
#endif

#ifndef VIRTUAL_TO_PHYSICAL
#define VIRTUAL_TO_PHYSICAL(va) ((va) - VA_BASE + _RAM_STARTADDRESS)
#endif

#ifndef PHYSICAL_TO_VIRTUAL
#define PHYSICAL_TO_VIRTUAL(pa) ((pa) + VA_BASE - _RAM_STARTADDRESS)
#endif


enum {
    RD_MAGIC,       /* 7 byte "magic number" */
    RD_BIN_RG_CHK,  /* 4 byte BIN region checksum*/
                    /* BIN region descriptions (start address and length) */
    RD_NUM_RG,      /* 4 byte, dwNumRegions */
                    /* dwNumRegions * sizeof(RegionInfo) */
    RD_RG_INFO,
    RD_IMG_ADDR,    /* 4 byte dwImageStart */
    RD_IMG_LEN,     /* 4 byte dwImageLength */
    RD_SEC_ADDR,    /* 4 byte dwRecAddr */
    RD_SEC_LEN,     /* 4 byte dwRecLen */
    RD_SEC_CHK,     /* 4 byte dwRecChk */
    RD_SEC_DAT,     /* dwRecLen byte data */
};

typedef struct SEC_INF {
    DWORD dwRecAddr;
    DWORD dwRecLen;
    DWORD dwRecChk;
}SEC_INF, *PSEC_INF;

typedef struct VIVI_WINCE_IMAGE_INFO {
    
    /* 从vivi跳到eboot时,设置的一些参数,比如是否使用USB下载文件 
     */
    DWORD dwViviToEbootFlg;     
    
    /* magic = "X000FF\x0A", 表示映象文件multi-bin information packet,
     * 此时需要读取dwNumRegions个RegionInfo结构, (sizeof(RegionInfo) = 00000008H)
     *
     * 若magic = "B000FF\x0A", it is a standard BIN file,
     * 映象文件中无RegionInfo成分
     */
    char puMagic[8];   

    DWORD dwBinRegChk;      /* BIN region checksum */
    
    DWORD dwNumRegions;         
    /* 如果dwNumRegions != 0, 
     * 则WINCE_IMAGE_INFO末尾紧跟着存放dwNumRegions个RegionInfo结构
     */
    RegionInfo * pRegionInfo;
    
    DWORD dwImageStart;
    DWORD dwImageLen;
    
    /* SecInfo结构存放在WINCE_IMAGE_INFO后面,
     * 或紧接着最后一个WINCE_IMAGE_INFO存放(dwNumRegions != 0), 
     * 最后一个SecInfo结构结构为全0
     */
    PSEC_INF pSecInfo;          

    struct VIVI_WINCE_IMAGE_INFO *pNextImageInfo;
}VIVI_WINCE_IMAGE_INFO, *PVIVI_WINCE_IMAGE_INFO;

#define WINCE_USB_BUF_BASE    0x30058000 // RAM_BASE, changed by thisway.diy, for wince, 2006.06.18
#define WINCE_USB_BUF_SIZE    ((0x30200000 - 0x30058000)&(~(0x80000-1)))

#define VIVI_WINCE_IMAGE_INFO_BASE      ((PVIVI_WINCE_IMAGE_INFO)(PHYSICAL_TO_VIRTUAL(WINCE_USB_BUF_BASE + WINCE_USB_BUF_SIZE)))

/* End: add by thisway.diy, 2006.06.23 */

/* add by thisway.diy, 2006.07.01 */
typedef struct VIVI_WINCE_Info{
    DWORD               dwViviWinceMagic;   // 0x12345678表示vivi已经通过USB下载了wince
    MultiBINInfo        tMultiBINInfo;  // g_MultiBINInfo
    MultiBINInfo        tBINRegionInfo; // g_BINRegionInfo
    DWORD               dwMinImageStart;// g_dwMinImageStart
    DWORD               dwImageType;    // g_ImageType
    DWORD               dwROMOffset;    // g_dwROMOffset
    DWORD               dwImageStart;
    DWORD               dwImageLength;
    DWORD               dwLaunchAddr;
}VIVI_WINCE_Info, *PVIVI_WINCE_Info;

PVIVI_WINCE_Info g_pViviWinceInfo = ((PVIVI_WINCE_Info)(WINCE_USB_BUF_BASE + WINCE_USB_BUF_SIZE));
#define     VIVI_DWONLOAD_WINCE_WITH_USB    0x12345678



PDRIVER_GLOBALS pDriverGlobals = ((PDRIVER_GLOBALS) DRIVER_GLOBALS_PHYSICAL_MEMORY_START);
extern BOOL UbootReadData (DWORD cbData, LPBYTE pbData);
extern BOOL InitUSB ();
extern void Isr_Init();

//  Some global definitions

#ifdef SIMULATOR
void CleanExit(DWORD dwExitCode);
#define SPIN_FOREVER    CleanExit(41);
#else
#define SPIN_FOREVER    {while(TRUE);}
#endif

//
//  Global variables
//
static BOOLEAN  g_bDownloadImage  = TRUE;
BOOLEAN          g_bHasLoadWithUSB = FALSE; /* add by thisway.diy, 2006.06.29 */
BOOLEAN         g_bWaitForConnect;
DWORD           g_dwImageStartBlock;
DWORD           g_ImageType;
DWORD           g_dwMinImageStart;
MultiBINInfo    g_BINRegionInfo;
BOOL            g_bBootMediaExist = FALSE;
BOOLEAN			g_bUSBDownload = FALSE;

#pragma pack(1)
// N.B: only uses 1 sector for now.
UCHAR g_TOC[SECTOR_SIZE];
#pragma pack()

const PTOC g_pTOC = (PTOC)&g_TOC;
PBOOT_CFG  g_pBootCfg;
DWORD      g_dwTocEntry;

#ifdef DEBUG
DWORD   EdbgDebugZone = 0;//ZONE_WARNING|ZONE_INIT; //ZONE_DHCP;
#endif

//  External functions
extern void  InitClock();
extern DWORD OEMAddressTable[];
void Launch();
void BootloaderMain (void);
BOOL InitEthDevice(PBOOT_CFG  pBootCfg);
static void SetDelay();
static void SetCS8900MACAddress();

//  Function prototypes
static BOOL GetUserIPAddr (EDBG_ADDR *pMyAddr, LPDWORD pdwSubnetMask);

#define LAST_LAUNCH_ADDR_VALID 0xBADBEEF6

//  Local util function
//
DWORD
ToPhysicalAddr(DWORD add)
{
    DWORD   padd = add;
    DWORD * pt = OEMAddressTable;
    DWORD   vir_start;
    DWORD   vir_end;
    DWORD   phy_start;
    DWORD   sz;

EdbgOutputDebugString("+ToPhysicalAddr:0x%x\r\n", add);

    do
    {
        vir_start = *pt++;
        phy_start = *pt++;
        sz        = *pt++;

        if (vir_start == 0 && phy_start == 0 && sz == 0) break;

        vir_end = vir_start + sz * (1024 * 1024);

        if (add >= vir_start && add < vir_end)
        {
            padd = add - vir_start + phy_start;
            break;
        }
    } while (1);

EdbgOutputDebugString("-ToPhysicalAddr:0x%x\r\n", padd);

    return padd;
}


//  util function that should really be in blcommon
//
static void
itoa10(
    int n,
    char s[]
    )
{
    int i = 0;

    // Get absolute value of number
    unsigned int val = (unsigned int)((n < 0) ? -n : n);

    // Extract digits in reverse order
    do {
        s[i++] = (val % 10) + '0';
    } while (val /= 10);

    // Add sign if number negative
    if (n < 0) s[i++] = '-';

    s[i--] = '\0';

    // Reverse string
    for (n = 0; n < i; n++, i--) {
        char swap = s[n];
        s[n] = s[i];
        s[i] = swap;
    }
}


static void
CreateDeviceName(
    EDBG_ADDR *pMyAddr,
    char *szBuf
    )
{
    strcpy(szBuf,PLATFORM_STRING);
    szBuf += strlen(szBuf);
    itoa10(((pMyAddr->wMAC[2]>>8) | ((pMyAddr->wMAC[2] & 0x00ff) << 8)), szBuf);
}



#ifdef TODO
//  This routine programs the serial EEPROM and sets the
//  Ethernet Address to 00 50 F2 08 NN NN (N=Debug board number).
static void SetSerialNumber(USHORT dbgBoardSerialNumber) {
    USHORT i;

    EdbgOutputDebugString("SetSerialNumber: %u \r\n", dbgBoardSerialNumber);

    if ((dbgBoardSerialNumber <0) || (dbgBoardSerialNumber > 32000)) {
        EdbgOutputDebugString("Error Serial Number between 0 and 32000\n");
    }

    for (i=0;i<16;i+=2) {
        // Set all switch Areas to the same
        SMCWriteEEPROM((UINT16)(0x0+i), 0xB0);
        SMCWriteEEPROM((UINT16)(0x1+i), 0x1866);
    }
    for (i=16;i<0x20;i++) {
        SMCWriteEEPROM(i,0x0);
        }

                                    // Avenger is 00-50-F2-03-XX-XX
                                    // Trango  is 00-50-F2-08-XX-XX
                                    // Catfish is 00-50-F2-08-XX-XX ??
    SMCWriteEEPROM(0x20, 0x5000);   // Is 00-50-??-??-??-??
    SMCWriteEEPROM(0x21, 0x08F2);   // Is ??-??-F2-08-??-??
    SMCWriteEEPROM(0x22, htons((UINT16)(dbgBoardSerialNumber)));
    SMCWriteEEPROM(0x23, 0x389D);
    SMCWriteEEPROM(0x24, 0x4595);
    SMCWriteEEPROM(0x25, 0xFFFF);
    SMCWriteEEPROM(0x26, 0x00FC);
    SMCWriteEEPROM(0x27, 0x0000);
    SMCWriteEEPROM(0x28, 0x5765);
    SMCWriteEEPROM(0x29, 0x2776);
    SMCWriteEEPROM(0x2A, 0x6520);
    SMCWriteEEPROM(0x2B, 0x7374);
    SMCWriteEEPROM(0x2C, 0x696C);
    SMCWriteEEPROM(0x2D, 0x6C20);
    SMCWriteEEPROM(0x2E, 0x676F);
    SMCWriteEEPROM(0x2F, 0x7420);
}
#endif

//
//  Functions called from blcommon
//

/*
    @func   BOOL | OEMVerifyMemory | Verify that the memory to be used by the downloaded BIN file is valid.  This function also decides whether the image is the
                                     bootloader or not based on its address (this information is used later when deciding how to store the image in flash).
    @rdesc  TRUE = Address specified is valid memory, FALSE = Address specified is *not* valid memory.
    @comm
    @xref
*/
BOOL OEMVerifyMemory(DWORD dwStartAddr, DWORD dwLength)
{
    RETAILMSG(1, (TEXT("OEMVerifyMemory: StartAddr: 0x%x, Length:0x%x \r\n"), dwStartAddr, dwLength));

    // Is the image being downloaded the bootloader?
    if ((dwStartAddr >= EBOOT_STORE_ADDRESS) &&
        ((dwStartAddr + dwLength - 1) < (EBOOT_STORE_ADDRESS + EBOOT_STORE_MAX_LENGTH)))
    {
        RETAILMSG(1, (TEXT("Downloading Bootloader image\r\n")));
        g_ImageType = IMAGE_TYPE_LOADER;     // Bootloader image.
        return TRUE;
    }

    // if it's MXIP don't test address to allow PPC images using funky addresses in their .BIN regions
    else if ( g_BINRegionInfo.dwNumRegions > 1 )
    {
        RETAILMSG(1, (TEXT("Downloading %d regions of MXIP image\r\n"), g_BINRegionInfo.dwNumRegions));
        // 1st region is RAMIMAGE, remaining are MXIP
        g_ImageType = IMAGE_TYPE_RAMIMAGE | IMAGE_TYPE_BINFS | IMAGE_TYPE_MXIP;
        return TRUE;
    }

    // Is it a ram image?
    else if ((dwStartAddr >= ROM_RAMIMAGE_START) &&
        ((dwStartAddr + dwLength - 1) < (ROM_RAMIMAGE_START + ROM_RAMIMAGE_SIZE)))
    {
        RETAILMSG(1, (TEXT("Downloading RAM image\r\n")));

⌨️ 快捷键说明

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