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

📄 main.c

📁 Sirf/Centrality公司GPS平台AtlasIII芯片AT640的Nboot源码
💻 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.
//
/*++
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.
--*/

#include "def.h"
#include "at4x0f.h"
#include "debug.h"
#include "oem.h"
#include "cspregs.h"
#include "nand.h"
#include "vendormsg.h"
#include "menu.h"
#include "loader.h"
#include <string.h>

#ifdef RS232_UPDATER
#include "rs232.h"
#endif

#define SIGN_ON "\r\nCentrality NBOOT v5.0\r\n" __DATE__ " " __TIME__ "\r\n"
#define pDriverGlobals ((PDRIVER_GLOBALS) 0xC0002000)


//#define   MEASURE_BOOTING_TIME

#if defined (MEASURE_BOOTING_TIME)
	#define	TIMER_CLOCK						(g_SysClock.dwSystemClock / 2000)
    #define DECLARE_MEASURE_BOOTING_TIME    DWORD   t0, t1, dt
    #define MEASURE_BOOTING_TIME_BEGIN      do {	\
    	TIMER_LATCH = 1;							\
    	t0 = TIMER_LATCHED_LO;						\
    } while (0)
    #define MEASURE_BOOTING_TIME_END        do {    \
    	TIMER_LATCH = 1;							\
    	t1 = TIMER_LATCHED_LO;						\
    	TIMER_LATCH = 1;							\
    	dt = TIMER_LATCHED_LO - t1;					\
        DbgPutString ("\r\nTime Start (tick): ");   \
        DbgPutHex (t0);                             \
        DbgPutString ("\r\nTime Stop (tick): ");    \
        DbgPutHex (t1 - dt);                        \
        DbgPutString ("\r\nTime lapse (ms): ");     \
        DbgPutHex ((t1 - t0 - dt) / TIMER_CLOCK);	\
    } while (0)
#else
    #define DECLARE_MEASURE_BOOTING_TIME
    #define MEASURE_BOOTING_TIME_BEGIN
    #define MEASURE_BOOTING_TIME_END
#endif

//
// Globals
//
DWORD	g_dwJumpAddr;
DWORD	g_dwEntry;
SYSTEMCLOCKINFO g_SysClock;
int		g_bMenuNeedInput;
int		g_bTransportChange = 0;
int		g_iDevStatus = ATLAS_DEV_STATUS_UNINITED_NBOOT;

extern TOC* g_pTOC; // made global because it's too big for our tiny stack
extern DWORD dwCacheInfo;
extern DWORD			g_dwCpuFreq;
extern SYSFREQRATIO	g_sysFreqRatio;
extern FlashInfoEx g_FlashExtInfo;

extern DWORD	ARMReadCacheInfo(void);
extern DWORD	NandReadImage(void);
extern void		CheckAndCfgClock(void);
extern DWORD    FMD_GetBlockStatus(DWORD blockID);

#define BLOCK_STATUS_UNKNOWN	0x01
#define BLOCK_STATUS_BAD		0x02
#define BLOCK_STATUS_READONLY	0x04
#define BLOCK_STATUS_RESERVED	0x08

void HardwareInit()
{
    int i;

	//This function clear the driver global structure. Do it here and we don't need (want) to do it in OEMInit again.
	memset((void *)pDriverGlobals,0,sizeof(DRIVER_GLOBALS));

	ENABLE_CAMSM_PADH();
	ENABLE_CAMSM_PADL();
	PWR_CLK_EN |= PWRCLK_DMA_EN | PWRCLK_SM_EN | PWRCLK_IO_EN;

	INT_RISC_MASK = 0;

	OEMHardwareEarlyInit();

	dwCacheInfo = ARMReadCacheInfo();

	GetCurrentSysClk(&g_SysClock);
	DbgInit(DBG_BAUDRATE);

	if(!OEMNBootCheck())
	{
		OEMNBootSleep();
	}

	FMD_Init();

	if (OEMRestoreDefaultTOC())
	{
		TOC_Reset(0);
	}

    for (i = 5; i > 0; --i)
    {
        if (NandLocateBlocks ())
            break;
    }

    if (!(i > 0))
    {
        TOC_Reset(0);
        if(!NandLocateBlocks())
        {
            DbgPutString("\r\nUncovered Nand Err!");
            while(1);
        }
    }

	DbgPutString("\r\nClockInfo ");
	DbgPutHex(g_pTOC->dwClockInfo);
	

	g_sysFreqRatio = (g_pTOC->dwClockInfo >> 16) & 0xffff;
	g_dwCpuFreq = g_pTOC->dwClockInfo  & 0xffff;

	CheckAndCfgClock();

	DbgPutString(SIGN_ON);

    USB_Init();

	//Init the RTC to 1Hz
	RTC_DIV = 16383;  // 1 Hz

	OEMHardwareInit();
}

int ToggleNbootMenu(unsigned int wParam)
{
	g_pTOC->BootCfg.ConfigFlags ^= CONFIG_FLAGS_NBOOT_MENU;
	NandWriteToc();
}

int LaunchImage(DWORD dwEntry)
{
	typedef void (*FUNC_VOID) (void);
	DWORD err;
	DECLARE_MEASURE_BOOTING_TIME;

	MEASURE_BOOTING_TIME_BEGIN;

    if(g_dwEntry != dwEntry - '1')
    {
        g_dwEntry = dwEntry - '1';
        g_pTOC->BootCfg.ConfigFlags &= ~( BOOT_TYPE_EBOOT | BOOT_TYPE_DMCODE );
        if(g_dwEntry == TOC_EBOOT_ENTRY)
        {
            g_pTOC->BootCfg.ConfigFlags |= BOOT_TYPE_EBOOT;
        }
        else if(g_dwEntry == TOC_DM_ENTRY)
        {
            g_pTOC->BootCfg.ConfigFlags |= BOOT_TYPE_DMCODE;
        }
		NandWriteToc();
	}

	// Save the TOC into driver global data structure
	memcpy((void *)(&(pDriverGlobals->g_TOC)),(void *)g_pTOC,sizeof(TOC));
	// If we have got ether net address from dhcp before, just pass to wince kernel
	memcpy((void*)&(pDriverGlobals->eth.TargetAddr), (void*)&(g_pTOC->BootCfg.EdbgAddr), sizeof(EDBG_ADDR)+sizeof(DWORD));
	pDriverGlobals->misc.iDevStatus = g_iDevStatus;
	// Hardcoded to fetch TOC descriptor g_dwEntry
	err = NandReadImage();

	MEASURE_BOOTING_TIME_END;

	if (ERR_SUCCESS == err)
	{
//		DbgPutString("\r\nJump to: ");
//		DbgPutHex(g_dwJumpAddr);
		DbgFlush();
		((FUNC_VOID) g_dwJumpAddr) ();
	}
	return err;
}

void C_Entry(void)
{
	DWORD dwStartTime;
	char * pInstruction;

#define NBOOT_DELAY		5
#define ResetTimeOut()	dwStartTime = RTC_COUNTER;

	OEMWriteLed1(0x0b);
	OEMWriteLed2(0);

    	//By default, we launch image CE image. If you want to launch
    	//Eboot, you need to hold down APP4 button (sw803) when it boots.
    
	HardwareInit();

	OEMMenuInit();

	//	DisplayLogo();
      
	if(g_pTOC->BootCfg.ConfigFlags & BOOT_TYPE_DMCODE)
		g_dwEntry = TOC_DM_ENTRY;
	else if(g_pTOC->BootCfg.ConfigFlags & BOOT_TYPE_EBOOT)
		g_dwEntry = TOC_EBOOT_ENTRY;
	else
		g_dwEntry = TOC_NK_ENTRY;

	g_bMenuNeedInput = FALSE;

    	/************************************************************************/
    	/* These codes are for supporting Gang Programmer                       */
    	/************************************************************************/
    	if ( ((PBYTE)g_pTOC)[511] == 0xA5 )
    	{
        	DWORD i;

        	for (i = 1; i < g_FlashExtInfo.fi.dwNumBlocks; i++)
        	{
            		if (NandIsOEMReservedBlock(i) || !(FMD_GetBlockStatus (i) & BLOCK_STATUS_BAD))
            		{
                		continue;
            		}

            		// This is a true bad block
            		if (i * g_FlashExtInfo.fi.wSectorsPerBlock <= g_pTOC->id[TOC_EBOOT_ENTRY].sgList[0].dwSector)
            		{
               		 g_pTOC->id[TOC_EBOOT_ENTRY].dwStartBlock += 1;
                		g_pTOC->id[TOC_EBOOT_ENTRY].sgList[0].dwSector += g_FlashExtInfo.fi.wSectorsPerBlock;
            		}
					
            		if (i * g_FlashExtInfo.fi.wSectorsPerBlock <= g_pTOC->id[TOC_NK_ENTRY].sgList[0].dwSector)
            		{
                		g_pTOC->id[TOC_NK_ENTRY].dwStartBlock += 1;
                		g_pTOC->id[TOC_NK_ENTRY].sgList[0].dwSector += g_FlashExtInfo.fi.wSectorsPerBlock;
            		}
					
            		if ((i <= g_pTOC->nandxipInfo.dwBlockNo) && (g_pTOC->nandxipInfo.dwCodePages > 0))
            		{
                		g_pTOC->nandxipInfo.dwBlockNo += 1;
            		}
					
            		if(g_pTOC->bNewNFDrvEnabled != 0 && i <= g_pTOC->dwImageBlocks)
            		{
                		g_pTOC->dwImageBlocks += 1;
            		}
					
            		if (i * g_FlashExtInfo.fi.wSectorsPerBlock <= g_pTOC->chainInfo.dwFlashAddress)
            		{
                		g_pTOC->chainInfo.dwFlashAddress += g_FlashExtInfo.fi.wSectorsPerBlock;
            		}
					
            		if(i <= g_pTOC->dwReadOnlyPartBlk)
            		{
                		g_pTOC->dwReadOnlyPartBlk += 1;
            		}               
        	}       
			
        	((PBYTE)g_pTOC)[511] = 0x00;
        	NandWriteToc();     
    	}
		
    	/************************************************************************/
    	/* These codes are for supporting Gang Programmer: code end             */
    	/************************************************************************/	
		
  if((g_pTOC->BootCfg.ConfigFlags & CONFIG_FLAGS_NBOOT_MENU) || OEMDisplayNbootMenu())
	{
		ResetTimeOut();
		while(1)
		{
			USB_Process();

			if(g_bTransportChange)
			{
				g_bMenuNeedInput = 0;
				g_bTransportChange = 0;
			}

			if(g_iDevStatus < ATLAS_DEV_STATUS_IN_USB_SESSION_NBOOT && Menu_IsCurTop())
			{
				//If we don't start the usb session the NBOOT_DELAY time, we will fall through
				if(RTC_COUNTER - dwStartTime > NBOOT_DELAY)
				{
					break;
				}
			}
			else
			{
				ResetTimeOut();
			}

			if(!g_bMenuNeedInput)
			{
				//We simply display the current menu again
				Menu_Display();
				g_bMenuNeedInput = 1;
			}
			else
			{
				pInstruction = DbgGetString();
				if(pInstruction)
				{
					ResetTimeOut();
					g_bMenuNeedInput = 0;
					Menu_Process(pInstruction);
				}
			}
		}
	}

	//we can only come here if timeout or no menu display. The OEM can design a specific method to 
	//launch a specific image, for example, to press a specific hot key to enter DM, etc.
	//Please note that when the user select from the NBOOT menu to launch an image, the code doesn't
	//fall through here to launch. Instead, it calls the menu item's pMenuFunc to directly launch it.
	OEMSpecifyTargetImage(&g_dwEntry);
// for SD update start		
#define PUSH_TIME 4
	ResetTimeOut();
	while( !(GPIO0_CTRL0 & GPIO_DATA_IN_FLAG )&& !(GPIO0_CTRL3 & GPIO_DATA_IN_FLAG ))//sun Using Joystick in and SD in to launch Eboot
	{
			if(RTC_COUNTER - dwStartTime > PUSH_TIME)
			{
					LaunchImage(TOC_EBOOT_ENTRY+ '1');
					break;
			}
	}
// for SD update end
	LaunchImage(g_dwEntry + '1');

	while(1);
}

⌨️ 快捷键说明

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