📄 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.
//
/*++
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 + -