📄 iplmain.c
字号:
}
BOOLEAN OEMTranslateBaseAddress(UINT32 ulPartType, UINT32 ulAddr, UINT32 *pulTransAddr)
{
if (pulTransAddr == NULL)
{
return(FALSE);
}
switch(ulPartType)
{
case PART_BOOTSECTION:
// No translation.
*pulTransAddr = ulAddr;
break;
case PART_XIP:
*pulTransAddr = ulAddr | 0xa0000000;
break;
default:
// No translation.
*pulTransAddr = ulAddr;
break;
}
return(TRUE);
}
/*
@func void | IPLmain | Main IPLcommon entry point.
@rdesc None.
@comm
@xref
*/
void IPLmain(void)
{
BOOLEAN bROMimage = FALSE;
UINT32 ulPartType = PART_ROMIMAGE;
PCI_REG_INFO RegInfo;
FlashInfo StorageInfo;
HANDLE hPartition = INVALID_HANDLE_VALUE;
UINT32 ulImageStartAddr = 0;
DWORD dwPhysLaunchAddr;
memset(&RegInfo, 0, sizeof(PCI_REG_INFO));
RegInfo.MemBase.Num = 1;
RegInfo.MemLen.Num = 1;
RegInfo.MemBase.Reg[0] = g_ulFlashBase;
RegInfo.MemLen.Reg[0] = g_ulFlashLengthBytes;
// Determine whether we should enter update mode or not.
//
// ulPartType = ((OEMGetUpdateMode() == TRUE) ? PART_BOOTSECTION : PART_ROMIMAGE);
ulPartType = PART_ROMIMAGE;
// ulPartType = PART_BOOTSECTION;
// Open a handle to the requested partition.
//
hPartition = BP_OpenPartition(NEXT_FREE_LOC, USE_REMAINING_SPACE, ulPartType, FALSE, PART_OPEN_EXISTING);
// there are two types of XIP partitions - if PART_ROMIMAGE failed, look for PART_RAMIMAGE
if (hPartition == INVALID_HANDLE_VALUE && ulPartType == PART_ROMIMAGE)
{
ulPartType = PART_RAMIMAGE;
hPartition = BP_OpenPartition(NEXT_FREE_LOC, USE_REMAINING_SPACE, ulPartType, FALSE, PART_OPEN_EXISTING);
// if we fail to open any XIP partition, try to find the update loader (as a fail-safe)
if (hPartition == INVALID_HANDLE_VALUE)
{
ulPartType = PART_BOOTSECTION;
hPartition = BP_OpenPartition(NEXT_FREE_LOC, USE_REMAINING_SPACE, ulPartType, FALSE, PART_OPEN_EXISTING);
}
}
// if we still can't find a valid partition, fail
if (hPartition == INVALID_HANDLE_VALUE)
{
MessageDispatch(IPL_ERROR_OPENPARTITION_FAILED);
SpinForever();
}
// Call the FMD to get the flash's sector size.
//
if (!FMD_GetInfo(&StorageInfo))
{
MessageDispatch(IPL_ERROR_GETSTORAGETYPE_FAILED);
SpinForever();
}
g_wSectorSize = StorageInfo.wDataBytesPerSector;
// Lock the flash part if we're not loading the Update Loader (added flash protection).
//
if ((ulPartType == PART_ROMIMAGE) || (ulPartType == PART_RAMIMAGE))
{
FAL_LockFlashRegion(XIP);
FAL_LockFlashRegion(READONLY_FILESYS);
}
else if (ulPartType == PART_BOOTSECTION)
{
FAL_UnlockFlashRegion(XIP);
FAL_UnlockFlashRegion(READONLY_FILESYS);
}
// Get image attributes from the table of contents.
//
if (!GetImageInfo(hPartition, &ulImageStartAddr))
{
MessageDispatch(IPL_ERROR_GETIMAGEINFO_FAILED);
SpinForever();
}
// Convert the returned addressed into IPL-compatible addresses.
//
if (!OEMTranslateBaseAddress(ulPartType, ulImageStartAddr, &ulImageStartAddr))
{
MessageDispatch(IPL_ERROR_TRANSLATEADDR_FAILED);
SpinForever();
}
// If the start address is in RAM, then copy the image to RAM.
//
bROMimage = ((ulImageStartAddr >= g_ulFlashBase) && (ulImageStartAddr < (g_ulFlashBase + g_ulFlashLengthBytes)));
if (!bROMimage)
{
// Let the user know we're about the load the image.
//
MessageDispatch(IPL_INFO_LOADING_IMAGE);
if (!CopyToRAM(hPartition, ulImageStartAddr))
{
MessageDispatch(IPL_ERROR_READDATA_FAILED);
SpinForever();
}
}
// Let the user know we're about to jump to the image.
//
MessageDispatch(IPL_INFO_JUMPING_IMAGE);
// Jump to downloaded image (use the physical address since we'll be turning the MMU off)...
//
dwPhysLaunchAddr = (DWORD)OALVAtoPA((void *)ulImageStartAddr);
RETAILMSG(TRUE, (TEXT("INFO: OEMLaunch: Jumping to Physical Address 0x%Xh (Virtual Address 0x%Xh)...\r\n\r\n\r\n"), dwPhysLaunchAddr, ulImageStartAddr));
// Jump...
//
Launch(dwPhysLaunchAddr);
// We should never get here.
//
MessageDispatch(IPL_ERROR_JUMP_FAILED);
SpinForever();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL InitDecompressor(HANDLE hPartition, DWORD dwHeaderSize)
{
// Allocate space for the compression header
g_CompressionHeader = (PCOMPRESSED_RAMIMAGE_HEADER) MyAlloc(NULL, dwHeaderSize);
if (g_CompressionHeader == NULL)
{
return(FALSE);
}
// read the entire compression header into memory
if (!BP_SetDataPointer(hPartition, 0))
{
return(FALSE);
}
if (!BP_ReadData(hPartition, (LPVOID) g_CompressionHeader, dwHeaderSize))
{
return(FALSE);
}
// now create a decode stream
g_DecodeStream = CeCompressDecodeCreate(NULL, MyAlloc);
if (g_DecodeStream == NULL)
{
return(FALSE);
}
return(TRUE);
}
VOID DeInitDecompressor()
{
CeCompressDecodeClose(g_DecodeStream, NULL, MyDeAlloc);
g_DecodeStream = NULL;
}
LPVOID MyAlloc(LPVOID pIgnored, DWORD dwAllocSize)
{
static DWORD dwCurRAMBase = 0;
LPVOID pAllocBase = NULL;
// initialize the current allocation base if necessary
if (dwCurRAMBase == 0)
{
dwCurRAMBase = pTOC->ulRAMFree;
}
// if there is enough free RAM, perform the allocation
if ((pTOC->ulRAMEnd - dwCurRAMBase) > dwAllocSize)
{
pAllocBase = (LPVOID) dwCurRAMBase;
dwCurRAMBase += dwAllocSize;
}
return pAllocBase;
}
VOID MyDeAlloc(LPVOID pIgnored, LPVOID pAddress)
{
// we're not actually managing memory, so this function is a no-op
}
BOOL CopyToRAM(HANDLE hPartition, DWORD dwPartitionBase)
{
ROMHDR TOC;
PWORD pwCompBlockSize = NULL;
DWORD dwBytesRead = 0, dwCurRAMLoc = 0, i;
if (g_fCompressed)
{
// set the data pointer to the first byte after the compressed header
if (!BP_SetDataPointer(hPartition, g_CompressionHeader->dwHeaderSize))
{
return(FALSE);
}
// point our block size pointer to the first entry in the table
pwCompBlockSize = &g_CompressionHeader->wBlockSizeTable[0];
// start at the beginning of RAM
dwCurRAMLoc = dwPartitionBase;
// iterate through all compressed blocks, decompressing straight into RAM
for (i = 0; i < g_CompressionHeader->dwCompressedBlockCount; i++)
{
// read the compressed data into our temporary buffer
if (!BP_ReadData(hPartition, CompressedData, *pwCompBlockSize))
{
return(FALSE);
}
// RETAILMSG(TRUE, (TEXT("INFO: CopyToRAM: RAMIMAGE_COMPRESSION_BLOCK_SIZE(0x%x)...\r\n"), RAMIMAGE_COMPRESSION_BLOCK_SIZE));
// RETAILMSG(TRUE, (TEXT("INFO: CopyToRAM: *pwCompBlockSize(0x%x)...\r\n"), *pwCompBlockSize));
// determine if decompression is necessary
if (*pwCompBlockSize == RAMIMAGE_COMPRESSION_BLOCK_SIZE)
{
// RETAILMSG(TRUE, (TEXT("INFO: CopyToRAM: just do a memcpy...\r\n")));
// just do a memcpy
memcpy((LPVOID) dwCurRAMLoc, CompressedData, RAMIMAGE_COMPRESSION_BLOCK_SIZE);
}
else
{
// RETAILMSG(TRUE, (TEXT("INFO: CopyToRAM: decode...\r\n")));
// decompress the data to RAM
dwBytesRead = CeCompressDecode(g_DecodeStream, (LPVOID) dwCurRAMLoc, RAMIMAGE_COMPRESSION_BLOCK_SIZE, RAMIMAGE_COMPRESSION_BLOCK_SIZE, CompressedData, *pwCompBlockSize);
if (dwBytesRead != RAMIMAGE_COMPRESSION_BLOCK_SIZE)
{
return(FALSE);
}
}
// increment current RAM location and block number
++pwCompBlockSize;
dwCurRAMLoc += RAMIMAGE_COMPRESSION_BLOCK_SIZE;
}
}
else
{
// if the partition is not compressed, we need to read the TOC
// to figure out how much we need to copy to RAM
if (!ReadTOC(hPartition, &TOC))
{
return(FALSE);
}
// simply copy the data to RAM
if (!BP_ReadData(hPartition, (LPBYTE) dwPartitionBase, (TOC.physlast - TOC.physfirst)))
{
return(FALSE);
}
/*
RETAILMSG(TRUE, (TEXT("TOC.physlast = 0x%x, TOC.physfirst = 0x%x \r\n"), TOC.physlast, TOC.physfirst));
memcpy(CompressedData, (LPVOID) dwPartitionBase, RAMIMAGE_COMPRESSION_BLOCK_SIZE);
for ( j = 0; j < 512; j++ )
{
RETAILMSG(TRUE, (TEXT("[0x%X]"), CompressedData[j]));
if ( j % 16 == 15 ) RETAILMSG(TRUE, (TEXT("\r\n")));
}
*/
}
return(TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -