⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cfg.c

📁 Windows CE 6.0 BSP for the Beagle Board.
💻 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, &sectorInfo, 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(&sectorInfo, 0xFF, sizeof(sectorInfo));
        sectorInfo.bOEMReserved &= ~(OEM_BLOCK_READONLY|OEM_BLOCK_RESERVED);
        sectorInfo.dwReserved1 = 0;
        sectorInfo.wReserved2 = 0;
        // Write sector        
        if (!FMD_WriteSector(sector, buffer, &sectorInfo, 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 + -