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

📄 flash.c

📁 windows wm5 下的bootloader代码
💻 C
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//

#include <windows.h>
#include <bsp.h>
#include <am29lv800.h>
#include "loader.h"

extern IMAGE_TYPE    g_ImageType;

/*
    @func   BOOL | OEMIsFlashAddr | Tests whether the address provided resides in the Samsung's flash.
    @rdesc  TRUE = Specified address resides in flash, FALSE = Specified address doesn't reside in flash.
    @comm    
    @xref   
*/
BOOL OEMIsFlashAddr(DWORD dwAddr)
{
    // Does the specified address fall in the AMD flash address range?
    //
    
    if ((dwAddr >= AMD_FLASH_START_UA) && (dwAddr < (AMD_FLASH_START_UA + AMD_FLASH_SIZE)))
    {
        return(TRUE);
    }

    return(FALSE);
}


/*
    @func   LPBYTE | OEMMapMemAddr | Remaps a specified address to a file cache location.  The file cache is used as a temporary store for flash images before they're written to flash.
    @rdesc  Corresponding address within a file cache area.
    @comm    
    @xref   
*/
LPBYTE OEMMapMemAddr(DWORD dwImageStart, DWORD dwAddr)
{
    UINT32 MappedAddr = dwAddr;

    OALMSG(OAL_FUNC, (TEXT("+OEMMapMemAddr (Address=0x%x).\r\n"), dwAddr));

    // If it's a flash address, translate it by "rebasing" the address into the file cache area.
    //
    if (OEMIsFlashAddr(dwAddr) && (dwImageStart <= dwAddr))
    {
        MappedAddr = (FILE_CACHE_START + (dwAddr - dwImageStart));
    }

    OALMSG(OAL_FUNC, (TEXT("-OEMMapMemAddr (Address=0x%x.\r\n"), MappedAddr));

    return((LPBYTE)MappedAddr);
}


/*
    @func   BOOL | OEMStartEraseFlash | Called at the start of image download, this routine begins the flash erase process.
    @rdesc  TRUE = Success, FALSE = Failure.
    @comm    
    @xref   
*/
BOOL OEMStartEraseFlash(DWORD dwStartAddr, DWORD dwLength)
{
    // Nothing to do (erase done in OEMWriteFlash)...
    //
    return(TRUE);
}


/*
    @func   void | OEMContinueEraseFlash | Called frequenty during image download, this routine continues the flash erase process.
    @rdesc  N/A.
    @comm    
    @xref   
*/
void OEMContinueEraseFlash(void)
{
    // Nothing to do (erase done in OEMWriteFlash)...
    //
}


/*
    @func   BOOL | OEMFinishEraseFlash | Called following the image download, this routine completes the flash erase process.
    @rdesc  TRUE = Success, FALSE = Failure.
    @comm    
    @xref   
*/
BOOL OEMFinishEraseFlash(void)
{
    // Nothing to do (erase done in OEMWriteFlash)...
    //
    return(TRUE);
}


// Display a range to debug output
// The bootloader's printf cannot zero-fill high nibbles, so we do it manually.
#define BYTE_NIBBLES(b)   ( ((b) >> 4) & 0xF ), ((b) & 0xF)
#define WORD_NIBBLES(w)   BYTE_NIBBLES( ((w) >> 8) & 0xFF ), BYTE_NIBBLES((w) & 0xFF)
#define DWORD_NIBBLES(dw) WORD_NIBBLES( ((dw) >> 16) & 0xFFFF ), WORD_NIBBLES((dw) & 0xFFFF)

static VOID DisplayBuffer(LPCTSTR pTitle, const VOID *pBuf, DWORD cbBuf)
{
    const BYTE *pbBuf = (PBYTE) pBuf;
    DWORD dw;
    const DWORD cPerLine = 16;
    
    RETAILMSG(1, (TEXT("\r\n*** %s ***"), pTitle));

    for (dw = 0; dw < cbBuf; ++dw) {
        if ((dw % cPerLine) == 0) {
            RETAILMSG(1, (TEXT("\r\n%x%x%x%x%x%x%x%x: "), DWORD_NIBBLES(((DWORD)(pBuf)) + dw)));
        }
        
        RETAILMSG(1, (TEXT("%x%x "), BYTE_NIBBLES(pbBuf[dw])));
    }

    RETAILMSG(1, (TEXT("\r\n")));
}


/*
    @func   BOOL | OEMWriteFlash | Writes data to flash (the source location is determined using OEMMapMemAddr).
    @rdesc  TRUE = Success, FALSE = Failure.
    @comm    
    @xref   
*/
BOOL OEMWriteFlash(DWORD dwStartAddr, DWORD dwLength)
{

    // Are we updating an image in flash?
    //
    if (g_ImageType == IMAGE_OS_FLASH)
    {
        PBYTE pCachedData = OEMMapMemAddr(dwStartAddr, dwStartAddr);
        DWORD dwBaseAddr = 0;

        RETAILMSG(1, (TEXT("Writing image to flash.\r\n")));

        // Erase AMD flash.
        //
        if (!AM29LV800_EraseFlash(dwBaseAddr, dwLength))
        {
            RETAILMSG(1, (TEXT("ERROR: OEMWriteFlash: Flash erase failed.\r\n")));
            return(FALSE);
        }

        // Write flash image.
        //
        if (!AM29LV800_WriteFlash(dwBaseAddr, pCachedData, dwLength))
        {
            RETAILMSG(1, (TEXT("ERROR: OEMWriteFlash: Flash write failed.\r\n")));
            return(FALSE);
        }

        RETAILMSG(1, (TEXT("OEMWriteFlash: Comparing %x to %x, %x bytes\r\n"), AMD_FLASH_START_UA+ dwBaseAddr, pCachedData, dwLength));
        if (memcmp((const void *)(AMD_FLASH_START_UA + dwBaseAddr), (const void *)pCachedData, dwLength) == 0)
        {
            RETAILMSG(1, (TEXT("\r\n*** Flash updated. ***\r\n")));

            // Update LEDs to indicate that flash write is done.
            //
            OEMWriteDebugLED(0, 0);

            return TRUE;
        }
        else
        {
            const DWORD dwCheckSize = 0x100;
            DWORD dwFlashAddr;
            
            RETAILMSG(1, (TEXT("ERROR: OEMWriteFlash: Flash verification failed.\r\n")));

            for (dwFlashAddr = dwBaseAddr + 0; dwFlashAddr < dwLength; dwFlashAddr += dwCheckSize) {
                const void* pFlash = (void*)(dwFlashAddr + AMD_FLASH_START_UA);
                const void* pCached = pCachedData + dwFlashAddr;
                if (memcmp(pFlash, pCached, dwCheckSize) != 0) {
                    RETAILMSG(1, (TEXT("Error: OEMWriteFlash: verification failed at %x - %x\r\n"), pFlash, pCached));
                    DisplayBuffer(TEXT("Cache"), pCached, dwCheckSize);
                    DisplayBuffer(TEXT("Flash"), pFlash, dwCheckSize);                    
                    break;
                }
            }
            
            return(FALSE);
        }

    }

    RETAILMSG(1, (TEXT("ERROR: OEMWriteFlash: Unknown image type.\r\n")));

    return(FALSE);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -