📄 main.c
字号:
LPDWORD lpdwToc; // toc pointer
DWORD dwPhysStart; // image physical starting address
DWORD dwPhysLen; // image physical length
DWORD dwOffset=0;
// EdbgOutputDebugString( "OEMLaunch: Image=%x length=%x launch=%x\r\n", dwImageStart, dwImageLength, dwLaunchAddr);
// init RomHdr
memset((LPVOID)&RomHdr,-1,sizeof(ROMHDR));
// Execute the transport callout function
if(gbStoreSDRAMImageToFlash){
// Otherwise we should copy image to memory
if (!BLFlashDownload(&dwImageStart, &dwImageLength, &dwLaunchAddr)) {
EdbgOutputDebugString( "ERROR: Failed copy image from flash, spin forever...\r\n" );
SpinForever();
}
pDriverGlobals->eth.etherFlags |= EDBG_FL_CLEANBOOT; // force clean boot
}
dwPhysStart = dwImageStart;
dwPhysLen = dwImageLength;
// if we are downloading, find pTOC
if (dwPhysLen > 0)
{
// Check for pTOC signature ("CECE") here, after image in place
if (*(DWORD*)(dwPhysStart - dwOffset + 64) == 0x43454345)
{
EdbgOutputDebugString("Found pTOC signature.\n");
lpdwToc= (LPDWORD)(*(DWORD*)(dwPhysStart - dwOffset + 68));
}
else if (*(DWORD*)((dwPhysStart+0x1000) - dwOffset + 64) == 0x43454345)
{
EdbgOutputDebugString("Found pTOC signature in XIP.BIN.\n");
lpdwToc= (LPDWORD)(*(DWORD*)((dwPhysStart+0x1000) - dwOffset + 68));
}
else
{
EdbgOutputDebugString("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
EdbgOutputDebugString("! ERROR: Did not find pTOC signature. ABORTING. !\n");
EdbgOutputDebugString("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
// If no signature, we're going to fail anyway, so loop forever
while (1);
}
// Copy RomHdr from image
memcpy((LPVOID)&RomHdr, (LPVOID)lpdwToc, sizeof(ROMHDR));
EdbgOutputDebugString("ROMHDR at Address %Xh\r\n",lpdwToc);
EdbgOutputDebugString("RomHdr.ulRAMStart=%Xh RomHdr.physfirst=%Xh.\r\n",RomHdr.ulRAMStart,RomHdr.physfirst);
}
if (RomHdr.physfirst != -1) {
if (pDriverGlobals->eth.etherFlags & EDBG_FL_CLEANBOOT) {
//
// Check to see if the bootloader's image overlaps the real image's
// ram section. If so there might be a problem doing the cleanboot.
// Of course that means warm boots are never valid for this image/processor.
//
// RomHdr contains the real image's parameters
// pTOC contains the bootloader's parameters
//
if ((RomHdr.ulRAMStart < pTOC->physlast) && (RomHdr.ulRAMEnd > pTOC->physfirst)) {
//
// We have an overlap
//
EdbgOutputDebugString("WARNING! : Bootloader detected a possible overlap between the bootloader code\r\n");
EdbgOutputDebugString("and the image's RAM section. Ignoring the CLEANBOOT request.\r\n");
EdbgOutputDebugString(" Bootloader image => 0x%X - 0x%X\r\n",pTOC->physfirst,pTOC->physlast);
EdbgOutputDebugString(" NK RAM => 0x%X - 0x%X\r\n",RomHdr.ulRAMStart,RomHdr.ulRAMEnd);
} else {
EdbgOutputDebugString( "CLEANBOOT Clearing RAM from %Xh-%Xh.\r\n",RomHdr.ulRAMStart,RomHdr.ulRAMEnd);
memset((LPVOID)RomHdr.ulRAMStart,0,RomHdr.ulRAMEnd-RomHdr.ulRAMStart);
}
}
}
if(pfnLaunch){
pfnLaunch( dwImageStart, dwImageLength, dwLaunchAddr, pRomHdr );
}
if(gbJumpToFlash) pDriverGlobals->eth.KitlTransport = KTS_PASSIVE_MODE;
if( dwLaunchAddr == 0 ){
dwLaunchAddr = FLASH_IMAGE_START_CACHED; // Default launch address
}
// Launch the OS - never returns
JumpToOS( dwLaunchAddr );
SpinForever();
}
//------------------------------------------------------------------------------
// Function: JumpToOS
//
// Jumps to OS - does not return
//
void JumpToOS( DWORD dwLaunchAddr )
{
EdbgOutputDebugString( "+JumpToOS( 0x%x )\r\n", dwLaunchAddr );
if( dwLaunchAddr==0x80000004 )
{
// Reset Vector
EdbgOutputDebugString("Bootloader or Nk.bin has been downloaded. Press Reset button to restart...\n");
SpinForever();
};
dwLaunchAddr |= 0xA0000000;
EdbgOutputDebugString(
"INFO: JumpToOS: Jumping to image at %Xh\r\n",dwLaunchAddr);
EdbgOutputDebugString(
"INFO: JumpToOS: First instructions=(%Xh,%Xh,%Xh)...\r\n",
*(LPDWORD)dwLaunchAddr,*(LPDWORD)(dwLaunchAddr+4),*(LPDWORD)(dwLaunchAddr+8) );
Launch( dwLaunchAddr );
// why is this in here twice - is this a mistake?
EdbgOutputDebugString(
"INFO:JumpToOS: First instructions=(%Xh,%Xh,%Xh)...\r\n",
*(LPDWORD)dwLaunchAddr,*(LPDWORD)(dwLaunchAddr+4),*(LPDWORD)(dwLaunchAddr+8) );
Launch( dwLaunchAddr );
// Some catastrophic error occurred
EdbgOutputDebugString("ERROR: JumpToOS: Fatal error in Ethernet Bootloader, halting...\n");
DisplayLED( "DEADDEAD" );
SpinForever();
}
//------------------------------------------------------------------------------
// Function: SpinForever
//
// Busy wait forever. Used to stall execution until reset.
//
void SpinForever( void )
{
EdbgOutputDebugString( "\r\n\r\nERROR: <<<<< SPINFOREVER >>>>>\r\n\r\n" );
while( TRUE ) { ; }
}
//------------------------------------------------------------------------------
// Function: ReadEEPROMData
//
// Read IP address and netmask from serial EEPROM on the SMC board
// (stored from the last time we got this info from user or DHCP).
//
BOOL ReadEEPROMData (DWORD *pdwIP, DWORD *pdwSubnetMask)
{
UINT16 wIPH, wIPL, wSMH, wSML;
// Compare
if( !SMCReadEEPROM(0x23,&wIPL) ||
!SMCReadEEPROM(0x24,&wIPH) ||
!SMCReadEEPROM(0x25,&wSML) ||
!SMCReadEEPROM(0x26,&wSMH) )
{
return( FALSE );
}
// Update passed in values
*pdwIP = ((ULONG)wIPH << 16) | wIPL;
*pdwSubnetMask = ((ULONG)wSMH << 16) | wSML;
return( TRUE );
}
//------------------------------------------------------------------------------
// Function: WriteEEPROMData
//
// Write new address info to the serial EEPROM on the SMC board, if
// necessary. Only update data if it is different.
//
BOOL UpdateEEPROMData(DWORD dwIP, DWORD dwSubnetMask)
{
DWORD dwPrevIP, dwPrevSubnetMask;
if( !ReadEEPROMData(&dwPrevIP, &dwPrevSubnetMask) )
{
return FALSE;
}
if( dwPrevIP != dwIP )
{
EdbgOutputDebugString( "Writing EEPROM 0x23 with new IP\r\n" );
if( !SMCWriteEEPROM( 0x23, (WORD)(dwIP) ) )
{
return FALSE;
}
EdbgOutputDebugString( "Writing EEPROM 0x24 with new IP\r\n" );
if( !SMCWriteEEPROM( 0x24, (WORD)(dwIP >> 16) ) )
{
return FALSE;
}
}
if( dwPrevSubnetMask != dwSubnetMask )
{
EdbgOutputDebugString( "Writing EEPROM 0x25 with new netmask\r\n" );
if( !SMCWriteEEPROM( 0x25, (WORD)(dwSubnetMask) ) )
{
return FALSE;
}
EdbgOutputDebugString( "Writing EEPROM 0x26 with new netmask\r\n" );
if( !SMCWriteEEPROM( 0x26, (WORD)(dwSubnetMask >> 16) ) )
{
return FALSE;
}
}
return( TRUE );
}
//------------------------------------------------------------------------------
//
// Function: OEMVerifyMemory
//
// Verifies passed in address is within defined ranges.
//
static BOOL OEMVerifyMemory( DWORD dwStartAddr, DWORD dwLength )
{
BOOL rc; // return code
DWORD Addr1; // starting address
DWORD Addr2; // ending address
// Select cached address
dwStartAddr &= ~CACHED_TO_UNCACHED_OFFSET;
// Setup address range for comparison
Addr1 = dwStartAddr;
Addr2 = Addr1 + (dwLength - 1);
EdbgOutputDebugString( "****** OEMVerifyMemory Checking Range [ 0x%x ==> 0x%x ]\r\n", Addr1, Addr2 );
// Validate each range
if( (Addr1 >= RAM_START_CACHED) && (Addr2 <= RAM_END_CACHED) )
{
EdbgOutputDebugString("****** RAM address ****** \r\n");
rc = TRUE;
}
else if( (Addr1 >= FLASH_START_CACHED) && (Addr2 <= FLASH_END_CACHED) )
{
EdbgOutputDebugString("****** FLASH address ****** \r\n");
rc = TRUE;
}
else
{
EdbgOutputDebugString("****** OEMVerifyMemory FAILED - Invalid Memory Area ****** \r\n");
rc = FALSE;
}
IsFlash(dwStartAddr, dwLength);
if(gbStoreSDRAMImageToFlash){
if ((dwStartAddr & 0x1C000000) == AREA_0
|| (dwStartAddr & 0x1C000000) == AREA_1) {
EdbgOutputDebugString("This isn't a SDRAM image.\r\n" );
PrintLED("BadImage");
rc = FALSE;
}
Addr1 = FLASH_IMAGE_START_UNCACHED; // top of image stored blocks
Addr2 = Addr1 + (dwLength - 1);
EdbgOutputDebugString( "****** OEMVerifyMemory Checking Range [ 0x%x ==> 0x%x ]\r\n", Addr1, Addr2 );
// Validate each range
if( (Addr1 >= FLASH_START_UNCACHED) && (Addr2 <= FLASH_END_UNCACHED) )
{
EdbgOutputDebugString("****** FLASH address ****** \r\n");
rc = TRUE;
}
else
{
EdbgOutputDebugString("****** OEMVerifyMemory FAILED - Invalid Memory Area ****** \r\n");
rc = FALSE;
}
IsFlash(Addr1, dwLength);
}
// Indicate status
return( rc );
}
void OEMMultiBINNotify(const PMultiBINInfo pInfo)
{
BYTE nCount;
if (!pInfo || !pInfo->dwNumRegions)
{
EdbgOutputDebugString("WARNING: OEMMultiBINNotify: Invalid BIN region descriptor(s).\r\n");
return;
}
g_dwMinImageStart = pInfo->Region[0].dwRegionStart;
EdbgOutputDebugString("\r\nDownload BIN file information:\r\n");
EdbgOutputDebugString("-----------------------------------------------------\r\n");
for (nCount = 0 ; nCount < pInfo->dwNumRegions ; nCount++)
{
EdbgOutputDebugString("[%d]: Base Address=0x%x Length=0x%x\r\n" , nCount, pInfo->Region[nCount].dwRegionStart, pInfo->Region[nCount].dwRegionLength);
if (pInfo->Region[nCount].dwRegionStart < g_dwMinImageStart)
{
g_dwMinImageStart = pInfo->Region[nCount].dwRegionStart;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -