📄 cfg.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//------------------------------------------------------------------------------
//
// File: cfg.c
//
// This file implements functions used to load/save EBOOT configuration info.
// The EBOOT configuration is located on last block reserved for EBOOT image
// on NAND flash memory.
//
//------------------------------------------------------------------------------
#include <eboot.h>
// Types
typedef struct {
union {
struct { // Bank 0
UINT16 TCR; // 0000
UINT16 EPHSR; // 0002
UINT16 RCR; // 0004
UINT16 ECR; // 0006
UINT16 MIR; // 0008
UINT16 MCRPCR; // 000A
};
struct { // Bank 1
UINT16 CR; // 0000
UINT16 BAR; // 0002
UINT16 IAR0; // 0004
UINT16 IAR1; // 0006
UINT16 IAR2; // 0008
UINT16 GPR; // 000A
UINT16 CTR; // 000C
};
struct { // Bank 2
UINT16 MMUCR; // 0000
UINT16 PNRARR; // 0002
UINT16 FIFO; // 0004
UINT16 PTR; // 0006
UINT16 DATA; // 0008
UINT16 DATAEX; // 000A
UINT16 INTR; // 000C
};
struct { // Bank 3
UINT16 MT[4]; // 0000
UINT16 MGMT; // 0008
UINT16 REV; // 000A
UINT16 ERDV; // 000C
};
};
UINT16 BANKSEL; // 000E
} LAN91C_REGS;
BOOL g_LAN=TRUE;
BOOL LANReadEEPROM(UINT8 *pAddress, UINT16 EEPROMAddress , UINT16 *pwVal);
BOOL LANWriteEEPROM(UINT8 *pAddress, UINT16 EEPROMAddress, UINT16 Data );
//------------------------------------------------------------------------------
BOOL BLReadBootCfg(BOOT_CFG *pBootCfg)
{
BOOL rc = FALSE;
HANDLE hFMD;
FlashInfo flashInfo;
SectorInfo sectorInfo;
SECTOR_ADDR sector;
BLOCK_ID block;
UINT32 count, offset;
UINT8 buffer[512], *pConfig;
// EBOOT configuration is placed in a block after IPL
if ((hFMD = FMD_Init(NULL, NULL, NULL)) == NULL) {
OALMSG(OAL_ERROR, (L"ERROR: EBOOT: FMD_Init call failed!\r\n"));
goto cleanUp;
}
// Get flash info
if (!FMD_GetInfo(&flashInfo)) {
OALMSG(OAL_ERROR, (L"ERROR: EBOOT: FMD_GetInfo call failed!\r\n"));
goto cleanUp;
}
// We can support only flash with sector size <= 512 bytes
if (flashInfo.wDataBytesPerSector > sizeof(buffer)) {
OALMSG(OAL_ERROR, (L"ERROR: EBOOT: "
L"Flash sector size %d bytes bigger that supported %d bytes\r\n",
flashInfo.wDataBytesPerSector, sizeof(buffer)
));
goto cleanUp;
}
// Configuration is placed in a block after IPL
offset = IMAGE_XLDR_CODE_SIZE + IMAGE_EBOOT_CODE_SIZE + IMAGE_IPL_CODE_SIZE;
// Start from beginning
block = 0;
sector = 0;
// Skip X-Loader & EBOOT code
count = 0;
while (count < offset && block < flashInfo.dwNumBlocks) {
if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_BAD) == 0) {
count += flashInfo.dwBytesPerBlock;
}
block++;
sector += flashInfo.wSectorsPerBlock;
}
count = sizeof(BOOT_CFG);
pConfig = (UINT8*)pBootCfg;
while (count > 0) {
// Read sector to buffer
if (!FMD_ReadSector(sector, buffer, §orInfo, 1)) {
OALMSG(OAL_ERROR, (L"ERROR: EBOOT!BLReadBootCfg: "
L"Flash sector %d read failed\r\n", sector
));
goto cleanUp;
}
// Copy data to BOOT_CFG structure
if (count < sizeof(buffer)) {
memcpy(pConfig, buffer, count);
count = 0;
pConfig += count;
} else {
memcpy(pConfig, buffer, sizeof(buffer));
count -= sizeof(buffer);
pConfig += sizeof(buffer);
}
// Move to next sector
sector++;
}
// Done
rc = TRUE;
cleanUp:
if (hFMD != NULL) FMD_Deinit(hFMD);
return rc;
}
//------------------------------------------------------------------------------
BOOL BLWriteBootCfg(BOOT_CFG *pBootCfg)
{
BOOL rc = FALSE;
HANDLE hFMD;
FlashInfo flashInfo;
SectorInfo sectorInfo;
SECTOR_ADDR sector;
BLOCK_ID block;
UINT32 count, offset;
UINT8 buffer[512], *pConfig;
// Configuration is placed in a block after IPL
if ((hFMD = FMD_Init(NULL, NULL, NULL)) == NULL) {
OALMSG(OAL_ERROR, (L"ERROR: EBOOT: FMD_Init call failed!\r\n"));
goto cleanUp;
}
// Get flash info
if (!FMD_GetInfo(&flashInfo)) {
OALMSG(OAL_ERROR, (L"ERROR: EBOOT: FMD_GetInfo call failed!\r\n"));
goto cleanUp;
}
// We can support only flash with sector size which fit to our buffer
if (flashInfo.wDataBytesPerSector > sizeof(buffer)) {
OALMSG(OAL_ERROR, (L"ERROR: EBOOT: "
L"Flash sector size %d bytes bigger that supported %d bytes\r\n",
flashInfo.wDataBytesPerSector, sizeof(buffer)
));
goto cleanUp;
}
// Configuration is placed in a block after IPL
offset = IMAGE_XLDR_CODE_SIZE + IMAGE_EBOOT_CODE_SIZE + IMAGE_IPL_CODE_SIZE;
// Start from beginning
block = 0;
sector = 0;
// Skip X-Loader EBOOT and IPL code
count = 0;
while (count < offset && block < flashInfo.dwNumBlocks) {
if ((FMD_GetBlockStatus(block) & BLOCK_STATUS_BAD) == 0) {
count += flashInfo.dwBytesPerBlock;
}
block++;
sector += flashInfo.wSectorsPerBlock;
}
// Erase block
if (!FMD_EraseBlock(block)) {
OALMSG(OAL_ERROR, (L"ERROR: EBOOT!BLWriteBootCfg: "
L"Flash block %d erase failed\r\n", block
));
goto cleanUp;
}
// Write boot configuration
count = sizeof(BOOT_CFG);
pConfig = (UINT8*)pBootCfg;
while (count > 0) {
// Copy data from BOOT_CFG structure
if (count < sizeof(buffer)) {
memcpy(buffer, pConfig, count);
memset(buffer + count, 0xFF, sizeof(buffer) - count);
count = 0;
pConfig += count;
} else {
memcpy(buffer, pConfig, sizeof(buffer));
count -= sizeof(buffer);
pConfig += sizeof(buffer);
}
// Prepare sector info
memset(§orInfo, 0xFF, sizeof(sectorInfo));
sectorInfo.bOEMReserved &= ~(OEM_BLOCK_READONLY|OEM_BLOCK_RESERVED);
sectorInfo.dwReserved1 = 0;
sectorInfo.wReserved2 = 0;
// Write sector
if (!FMD_WriteSector(sector, buffer, §orInfo, 1)) {
OALMSG(OAL_ERROR, (L"ERROR: EBOOT!BLWriteBootCfg: "
L"Flash sector %d write failed\r\n", sector
));
goto cleanUp;
}
// Move to next sector
sector++;
}
// Done
rc = TRUE;
cleanUp:
if (hFMD != NULL) FMD_Deinit(hFMD);
return rc;
}
BOOL LANReadEEPROM(UINT8 *pAddress, UINT16 EEPROMAddress , UINT16 *pwVal)
{
DWORD dwCurTime;
DWORD dwRetry;
LAN91C_REGS *pLAN91C;
// Save address
pLAN91C = (LAN91C_REGS*)pAddress;
// Verify that network chip can be detected
if ((INPORT16(&pLAN91C->BANKSEL) & 0xFF00) != 0x3300) {
g_LAN=FALSE;
OALMSGS(OAL_ERROR, (
L"ERROR: LANRead_EEPROM: Network Chip not found at 0x%08x, read 0x%04x\r\n", pAddress, INPORT16(&pLAN91C->BANKSEL) & 0xFF00
));
goto cleanUp;
}
for (dwRetry=0;dwRetry<4;dwRetry++)
{
OUTPORT16(&pLAN91C->BANKSEL, 2);
OUTPORT16(&pLAN91C->PTR, (EEPROMAddress & 0x003F) | 0x6000);
OUTPORT16(&pLAN91C->BANKSEL, 1);
OUTPORT16(&pLAN91C->CTR, INPORT16(&pLAN91C->CTR) | 0x0006);
// Loop until EEPROM data is retrieved
dwCurTime = OEMEthGetSecs();
do {
if ((INPORT16(&pLAN91C->CTR) & 0x0003 ) ==0) { // Success.
*pwVal = INPORT16(&pLAN91C->GPR);
return TRUE;
};
} while ( (OEMEthGetSecs() - dwCurTime) < 2);
EdbgOutputDebugString("LANReadEEPROM Timeout(%d) INPORT16(&pLAN91C->CTR) = 0x%x\n",dwRetry,INPORT16(&pLAN91C->CTR));
}
cleanUp:
// EdbgOutputDebugString("!!!!LANReadEEPROM read timed out\n");
return FALSE;
}
BOOL LANWriteEEPROM(UINT8 *pAddress, UINT16 EEPROMAddress, UINT16 Data )
{
DWORD dwCurTime;
LAN91C_REGS *pLAN91C;
// Save address
pLAN91C = (LAN91C_REGS*)pAddress;
if (g_LAN==FALSE) return FALSE;
OUTPORT16(&pLAN91C->BANKSEL, 2);
OUTPORT16(&pLAN91C->PTR, (EEPROMAddress & 0x003F) | 0x6000);
OUTPORT16(&pLAN91C->BANKSEL, 1);
OUTPORT16(&pLAN91C->GPR, Data);
OUTPORT16(&pLAN91C->CTR, INPORT16(&pLAN91C->CTR) | 0x0005);
// Loop until EEPROM data is written
dwCurTime = OEMEthGetSecs();
while( INPORT16(&pLAN91C->CTR) & 0x0003 ) {
if ((OEMEthGetSecs() - dwCurTime) > 2) {
EdbgOutputDebugString("!LANWriteEEPROM read timed out\n");
return FALSE;
}
}
return TRUE;
}
//------------------------------------------------------------------------------
BOOL BLReadMAC(BOOT_CFG *pConfig, UINT16 *pMAC)
{
BOOL rc = FALSE;
// Chip settle time.
OALStall(750);
// if ( !LANReadEEPROM((UINT8*)BSP_SMSC91C96_REGS_PA, 0x20, pMAC ) )
// {
//// EdbgOutputDebugString("EEPROM 1 read failure.\r\n" );
// goto cleanUp;
// }
// if ( !LANReadEEPROM((UINT8*)BSP_SMSC91C96_REGS_PA, 0x21, pMAC+1 ) )
// {
// EdbgOutputDebugString("EEPROM 2 read failure.\r\n" );
// goto cleanUp;
// }
// if ( !LANReadEEPROM((UINT8*)BSP_SMSC91C96_REGS_PA, 0x22, pMAC+2 ) )
// {
// EdbgOutputDebugString("EEPROM 3 read failure.\r\n" );
// goto cleanUp;
// }
// Done
rc = TRUE;
//cleanUp:
return rc;
}
//------------------------------------------------------------------------------
BOOL BLWriteMAC(BOOT_CFG *pConfig, UINT16 MAC[3])
{
BOOL rc = FALSE;
// UINT16 PrevData;
if (g_LAN==FALSE) goto cleanUp;
//LANReadEEPROM((UINT8*)BSP_SMSC91C96_REGS_PA, 0x20, &PrevData );
//if ( PrevData != MAC[0] && !LANWriteEEPROM((UINT8*)pConfig->bootDevLoc.LogicalLoc, 0x20, MAC[0] ) )
// {
// EdbgOutputDebugString("EEPROM 1 write failure.\r\n" );
// goto cleanUp;
// }
//LANReadEEPROM((UINT8*)BSP_SMSC91C96_REGS_PA, 0x21, &PrevData );
//if ( PrevData != MAC[1] && !LANWriteEEPROM((UINT8*)pConfig->bootDevLoc.LogicalLoc, 0x21, MAC[1] ) )
// {
// EdbgOutputDebugString("EEPROM 2 write failure.\r\n" );
// goto cleanUp;
// }
//LANReadEEPROM((UINT8*)BSP_SMSC91C96_REGS_PA, 0x22, &PrevData );
//if ( PrevData != MAC[2] && !LANWriteEEPROM((UINT8*)pConfig->bootDevLoc.LogicalLoc, 0x22, MAC[2] ) )
// {
// EdbgOutputDebugString("EEPROM 3 write failure.\r\n" );
// goto cleanUp;
// }
//rc = TRUE;
cleanUp:
return rc;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -