📄 main.c
字号:
// Function: OEMVerifyMemory
//
// This function verifies the passed address range lies
// within a valid region of memory. Additionally this function
// sets the g_ImageType if the image is a boot loader.
//
BOOL OEMVerifyMemory(DWORD dwStartAddr, DWORD dwLength)
{
BOOL rc = TRUE;
g_dwBytesRead = 0;
if (rc == TRUE)
g_dwTotalBytes = dwLength;
return(rc);
}
//------------------------------------------------------------------------------
//
// Function: OEMMultiBinNotify
//
VOID OEMMultiBinNotify(MultiBINInfo *pInfo)
{
UINT32 base = IMAGE_WINCE_CODE_PA, ix;
OALMSGS(1, (
L"+OEMMultiBinNotify(0x%08x -> %d)\r\n", pInfo, pInfo->dwNumRegions
));
OALMSG(1, (
L"OEMMultiBINNotify: Download BIN file information:\r\n"
));
OALMSG(1, (
L"-----------------------------------------------------------\r\n"
));
// Copy information to EBOOT structure and set also save address
g_eboot.numRegions = pInfo->dwNumRegions;
for (ix = 0; ix < pInfo->dwNumRegions; ix++) {
g_eboot.region[ix].start = pInfo->Region[ix].dwRegionStart;
g_eboot.region[ix].length = pInfo->Region[ix].dwRegionLength;
g_eboot.region[ix].base = base;
base += g_eboot.region[ix].length;
OALMSG(OAL_INFO, (
L"[%d]: Address=0x%08x Length=0x%08x Base=0x%08x\r\n",
ix, g_eboot.region[ix].start, g_eboot.region[ix].length,
g_eboot.region[ix].base
));
}
OALMSG(1, (
L"-----------------------------------------------------------\r\n"
));
// Determine type of image downloaded
if (g_eboot.numRegions == 1) {
if (g_eboot.region[0].start == 0) {
OALMSG(1, (L"DOWNLOAD_TYPE_NB0\r\n"));
if (g_eboot.region[0].length == IMAGE_XLDR_CODE_SIZE+0xff8) {
OALMSG(1, (L"DOWNLOAD_TYPE_XLDR\r\n"));
g_eboot.type = DOWNLOAD_TYPE_XLDR;
} else
if (g_eboot.region[0].length == IMAGE_EBOOT_CODE_SIZE) {
OALMSG(1, (L"DOWNLOAD_TYPE_EBOOT\r\n"));
g_eboot.type = DOWNLOAD_TYPE_EBOOT;
} else if (g_eboot.region[0].length == IMAGE_IPL_CODE_SIZE) {
OALMSG(1, (L"DOWNLOAD_TYPE_IPL\r\n"));
g_eboot.type = DOWNLOAD_TYPE_IPL;
}
} else if (g_eboot.region[0].start == IMAGE_XLDR_CODE_PA) {
OALMSG(1, (L"DOWNLOAD_TYPE_XLDR\r\n"));
g_eboot.type = DOWNLOAD_TYPE_XLDR;
} else if (g_eboot.region[0].start < IMAGE_WINCE_CODE_PA) {
OALMSG(1, (L"DOWNLOAD_TYPE_BINDIO\r\n"));
g_eboot.type = DOWNLOAD_TYPE_BINDIO;
} else if (g_eboot.region[0].start == IMAGE_EBOOT_CODE_PA) {
OALMSG(1, (L"DOWNLOAD_TYPE_EBOOT\r\n"));
g_eboot.type = DOWNLOAD_TYPE_EBOOT;
} else if (g_eboot.region[0].start == IMAGE_IPL_CODE_PA) {
OALMSG(1, (L"DOWNLOAD_TYPE_IPL\r\n"));
g_eboot.type = DOWNLOAD_TYPE_IPL;
} else if (g_eboot.region[0].start == IMAGE_WINCE_CODE_PA) {
OALMSG(1, (L"DOWNLOAD_TYPE_FLASHRAM\r\n"));
g_eboot.type = DOWNLOAD_TYPE_FLASHRAM;
} else {
OALMSG(1, (L"DOWNLOAD_TYPE_RAM\r\n"));
g_eboot.type = DOWNLOAD_TYPE_RAM;
}
memset((VOID*)g_eboot.region[0].base, 0xFF, g_eboot.region[0].length);
} else {
OALMSG(1, (L"DOWNLOAD_TYPE_RAM\r\n"));
g_eboot.type = DOWNLOAD_TYPE_RAM;
}
OALMSGS(OAL_FUNC, (L"-OEMMultiBinNotify\r\n"));
}
//------------------------------------------------------------------------------
//
// Function: OEMReadData
//
// This function is called to read data from the transport during
// the download process.
//
BOOL OEMReadData(ULONG size, UCHAR *pData)
{
BOOL rc = FALSE;
g_dwBytesRead += size;
// Save read data size and location. It is used in workaround
// for download BIN DIO images larger than RAM.
g_eboot.readSize = size;
g_eboot.pReadBuffer = pData;
switch (g_eboot.bootDeviceType) {
case OAL_KITL_TYPE_ETH:
rc = EbootEtherReadData(size, pData);
break;
case OAL_KITL_TYPE_SERIAL:
rc = SerialReadData(size, pData);
break;
}
return rc;
}
//------------------------------------------------------------------------------
//
// Function: OEMMapMemAddr
//
// This function maps image relative address to memory address. It is used
// by boot loader to verify some parts of downloaded image.
//
// For OMAP2420 EBOOT mapping depends on download type. Download type is
// set in OMEMultiBinNotify.
//
UINT8* OEMMapMemAddr(DWORD image, DWORD address)
{
UINT8 *pAddress = NULL;
OALMSG(OAL_FUNC, (L"+OEMMapMemAddr(0x%08x, 0x%08x)\r\n", image, address));
switch (g_eboot.type) {
case DOWNLOAD_TYPE_BINDIO:
g_eboot.recordOffset = address - image;
pAddress = (UINT8*)g_eboot.region[0].base;
break;
case DOWNLOAD_TYPE_XLDR:
case DOWNLOAD_TYPE_EBOOT:
case DOWNLOAD_TYPE_IPL:
pAddress = (UINT8*)(g_eboot.region[0].base + address - image);
break;
case DOWNLOAD_TYPE_RAM:
pAddress = BLVAtoPA(address);
break;
case DOWNLOAD_TYPE_FLASHRAM:
pAddress = (UINT8*)address;
break;
default:
OALMSG(OAL_ERROR, (L"ERROR: OEMMapMemAddr: "
L"Invalid download type %d\r\n", g_eboot.type
));
}
OALMSGS(OAL_FUNC, (L"-OEMMapMemAddr(pAddress = 0x%08x)\r\n", pAddress));
return pAddress;
}
//------------------------------------------------------------------------------
//
// Function: OEMIsFlashAddr
//
// This function determines whether the address provided lies in a platform's
// flash or RAM address range.
//
// For EBOOT decision depends on download type. Download type is
// set in OMEMultiBinNotify.
//
BOOL OEMIsFlashAddr(ULONG address)
{
BOOL rc;
OALMSG(OAL_FUNC, (L"+OEMIsFlashAddr(0x%08x)\r\n", address));
// Depending on download type
switch (g_eboot.type) {
case DOWNLOAD_TYPE_BINDIO:
case DOWNLOAD_TYPE_XLDR:
case DOWNLOAD_TYPE_EBOOT:
case DOWNLOAD_TYPE_IPL:
case DOWNLOAD_TYPE_FLASHRAM:
rc = TRUE;
break;
case DOWNLOAD_TYPE_RAM:
rc = FALSE;
break;
default:
rc = FALSE;
}
OALMSG(OAL_FUNC, (L"-OEMIsFlashAddr(rc = %d)\r\n", rc));
return rc;
}
//------------------------------------------------------------------------------
//
// Function: OEMShowProgress
//
// This function is called during the download process to visualise
// download progress.
//
VOID OEMShowProgress(ULONG packetNumber)
{
static DWORD PrevPercentComplete = -1;
DWORD PercentComplete;
// g_dwBytesRead is updated during a data packet read.
// g_dwTotalBytes is determined from the size of the download image
// (which is obtained from the .bin file header for example).
PercentComplete = (g_dwBytesRead * 100) / g_dwTotalBytes;
// Update the display only when the percent complete changes.
if (PercentComplete != PrevPercentComplete)
{
OALMSG(1, (L"%d%%",PercentComplete));
if ( PercentComplete >= 10 )
{
OALMSG(1, (L"\b",PercentComplete));
}
OALMSG(1, (L"\b\b",PercentComplete));
PrevPercentComplete = PercentComplete;
}
}
//------------------------------------------------------------------------------
//
// Function: OALGetTickCount
//
UINT32 OALGetTickCount()
{
static UINT32 tcr0 = 0x00000000, base = 0;
UINT32 tcr1;
INT32 delta;
tcr1 = INREG32(&g_pTimerRegs->ulTCRR);
delta = tcr1 - tcr0;
//if (delta < 0) delta += 0xFFFFFF;
base += delta;
tcr0 = tcr1;
return base/OMAP3_GPTIMER_COUNTS_PER_1MS;
}
//------------------------------------------------------------------------------
//
// Function: OEMEthGetSecs
//
// This function returns relative time in seconds.
//
DWORD OEMEthGetSecs()
{
return OALGetTickCount()/1000;
}
//------------------------------------------------------------------------------
//
// Function: OALStall
//
// Stall system for time specified in microseconds.
//
VOID OALStall(UINT32 microSec)
{
INT32 base, ticks, delay;
ticks = (microSec * OMAP3_GPTIMER_COUNTS_PER_1MS + 999)/1000 + 1;
base = INREG32(&g_pTimerRegs->ulTCRR);
do {
delay = INREG32(&g_pTimerRegs->ulTCRR)-base;
if (delay < 0) delay += 0xFFFFFFFF;
} while (delay < ticks);
}
//------------------------------------------------------------------------------
VOID *BLVAtoPA(UINT32 address)
{
VOID *pAddress = INVALID_HANDLE_VALUE;
OAL_ADDRESS_TABLE *pTable = g_oalAddressTable;
if (address < 0x80000000 || address >= 0xC0000000) goto cleanUp;
// Address must be cached, as entries in OEMAddressTable are cached
address = address & ~OAL_MEMORY_CACHE_BIT;
// Search the table for address range
while (pTable->size != 0) {
if (
address >= pTable->CA &&
address <= pTable->CA + (pTable->size << 20) - 1
) break;
pTable++;
}
// If address table entry is valid compute the PA
if (pTable->size == 0) goto cleanUp;
// Get final address
pAddress = (UINT8*)(pTable->PA + address - pTable->CA);
cleanUp:
return pAddress;
}
//------------------------------------------------------------------------------
//
// This function creates a unique kitl ID name
// Note: UUID from OMAP3 chip used, not mac address.
//
VOID OALKitlCreateName(CHAR *pPrefix, UINT16 mac[3], CHAR *pBuffer)
{
UINT32 code=0, count, d;
INT32 j;
OMAP3_DEVICE_DIEID_REGS *pDevIdRegs = OALPAtoUA(OMAP3_DEVICE_DIEID_REGS_PA);
OALMSG(OAL_KITL&&OAL_FUNC, (
L"+OALKitlCreateName('%hs', 0x%04x:0x%04x:0x%04x, 0x%08x)\r\n", pPrefix, mac[0],mac[1],mac[2], pBuffer
));
// Copy prefix
count = 0;
while (count < OAL_KITL_ID_SIZE - 1 && pPrefix[count] != '\0') {
pBuffer[count] = pPrefix[count];
count++;
}
// Create unique part of name from SoC ID
code = INREG32(&pDevIdRegs->ulDIE_ID_0);
code ^= INREG32(&pDevIdRegs->ulDIE_ID_1);
code ^= INREG32(&pDevIdRegs->ulDIE_ID_2);
code ^= INREG32(&pDevIdRegs->ulDIE_ID_3);
// Convert it to hexa number
for (j = 28; j >= 0 && count < OAL_KITL_ID_SIZE - 1; j -= 4) {
d = (code >> j) & 0xF;
pBuffer[count++] = d < 10 ? '0' + d : 'A' + d - 10;
}
pBuffer[count] = '\0';
OALMSG(OAL_KITL&&OAL_FUNC, (
L"-OALKitlCreateName(pBuffer = '%hs')\r\n", pBuffer
));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -