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

📄 main.c

📁 老外的一个开源项目
💻 C
📖 第 1 页 / 共 5 页
字号:
// 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 + -