flashmenu.c

来自「mx27 f14v2 源代码。包括ADS板上诸多驱动的源码。」· C语言 代码 · 共 1,008 行 · 第 1/2 页

C
1,008
字号
//
// 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 OR INDEMNITIES.
//
//------------------------------------------------------------------------------
//
//  File:  menu.c
//
#include <windows.h>
#include <blcommon.h>
#include "loader.h"
#include <fmd.h>
#include "bsp.h"

//------------------------------------------------------------------------------
//
//  Define:  dimof
//
#ifdef dimof
#undef dimof
#endif
#define dimof(x)                (sizeof(x)/sizeof(x[0]))

//------------------------------------------------------------------------------

static VOID ShowFlashGeometry(void);
static VOID EraseFlash(void);
static VOID MenuEraseBlock(void);
static VOID SetBadBlock(void);
static VOID DumpFlash(void);
static UINT32 OALStringToUINT32(LPCWSTR psz);
static VOID ReservedBlocks(void);
static VOID DumpBlocks(void);
static BOOL ReservedSpareArea(BLOCK_ID start, int NoOfBlocks);


WCHAR OALBLMenuReadKey(BOOL wait)
{
    CHAR key;

    while ((key = OEMReadDebugByte()) == OEM_DEBUG_READ_NODATA && wait);
    if (key == OEM_DEBUG_READ_NODATA) key = 0;
    return (WCHAR)key;
}

UINT32 OALBLMenuReadLine(LPWSTR szBuffer, size_t CharCount)
{
    UINT32 count;
    WCHAR key;
    
    count = 0;
    while (count < CharCount) {
        key = OALBLMenuReadKey(TRUE);
       if (key == L'\r' || key == L'\n') {
          OALLog(L"\r\n");
          break;
       } if (key == L'\b' && count > 0) {
          OALLog(L"\b \b");
          count--;
       } else if (key >= L' ' && key < 128 && count < (CharCount - 1)) {
          szBuffer[count++] = key;
          OALLog(L"%c", key);
       } 
    }
    szBuffer[count] = '\0';
    return count;
    
}

//------------------------------------------------------------------------------

VOID NANDTest(void)
{
    UINT16 InChar = 0;
    BOOL fExit = FALSE;

    while (!fExit) {
        KITLOutputDebugString ( "\r\nNAND : \r\n");
        KITLOutputDebugString ( "(0) Show flash geometry \r\n");
        KITLOutputDebugString ( "(1) Dump flash sector \r\n");
        KITLOutputDebugString ( "(2) Erase flash \r\n");
        KITLOutputDebugString ( "(3) Erase block range \r\n");
        KITLOutputDebugString ( "(4) Set bad blocks \r\n");
        KITLOutputDebugString ( "(5) Set reserved blocks \r\n");
        KITLOutputDebugString ( "(6) Dump block ranges \r\n");
        KITLOutputDebugString ( "(Q) Quit \r\n");        
        {
            InChar = OALBLMenuReadKey(TRUE);
            switch (InChar) {
            case L'0':
                ShowFlashGeometry();
                break;
            case L'1':
                DumpFlash();
                break;
            case L'2':
                EraseFlash();
                break;
            case L'3':
                MenuEraseBlock();
                break;
            case L'4':
                SetBadBlock();
                break;
            case L'5':
                ReservedBlocks();
                break;
            case L'6':
                DumpBlocks();
                break;
            case L'Q':
            case L'q':
                fExit = TRUE;
                break;
            default:
                break;
            }
        }
    }

    return;
}
//------------------------------------------------------------------------------

VOID
ShowFlashGeometry(void)
{
    HANDLE hFMD;
    FlashInfo flashInfo;
    LPCWSTR pszType;
    BLOCK_ID block;
    UINT32 status;
    UINT32 listmode=0;
    
    hFMD = FMD_Init(NULL, NULL, NULL);
    if (hFMD == NULL)
    {
        OALLog(L" Oops, can't open FMD driver\r\n");
        goto cleanUp;
    }

    if (!FMD_GetInfo(&flashInfo))
    {
        OALLog(L" Oops, can't get flash geometry info\r\n");
        goto cleanUp;
    }

    switch (flashInfo.flashType)
    {
        case NAND:
            pszType = L"NAND";
            break;
        case NOR:
            pszType = L"NOR";
            break;
        default:
            pszType = L"Unknown";
    }

    OALLog(L"\r\n");
    OALLog(L" Flash Type:    %s\r\n", pszType);
    OALLog(L" Blocks:        %d\r\n", flashInfo.dwNumBlocks);
    OALLog(L" Bytes/block:   %d\r\n", flashInfo.dwBytesPerBlock);
    OALLog(L" Sectors/block: %d\r\n", flashInfo.wSectorsPerBlock);
    OALLog(L" Bytes/sector:  %d\r\n", flashInfo.wDataBytesPerSector);

    // now list bad/reserved sectors
    OALLog(L"\r\nScanning flash ... \r\n");

    // First offset given
    block = 0;
    while (block < flashInfo.dwNumBlocks)
    {
#if 0
        if (!(block & 0x3F))
        {
            OALLog(L".");
        }
#endif

        // If block is bad, we have to offset it
        status = FMD_GetBlockStatus(block);

        // bad block
        if ((status & BLOCK_STATUS_BAD) != 0)
        {
            if (listmode!=1)
            {
                OALLog(L"\r\n[bad]     ");
                listmode=1;
            }

            OALLog(L" %d", block);

            block++;
            continue;
        }

        // reserved block
        if ((status & BLOCK_STATUS_RESERVED) != 0)
        {
            if (listmode!=2)
            {
                OALLog(L"\r\n[reserved]");
                listmode=2;
            }

            OALLog(L" %d", block);

            block++;
            continue;
        }

        block++;
    }

    OALLog(L" Done\r\n");

cleanUp:
    if (hFMD != NULL)
    {
        FMD_Deinit(hFMD);
    }
    return;
}

//------------------------------------------------------------------------------

VOID EraseFlash(void)
{
    WCHAR key;
    HANDLE hFMD = NULL;    
    FlashInfo flashInfo;
    BLOCK_ID block;
    UINT32 status;
    BOOL fEraseReserved = FALSE;
    BOOL fEraseBadBlock = FALSE;
    BOOL fEraseFailCont = FALSE;


    OALLog(L" Do you want to erase unreserved blocks [-/y]? ");

    // Get key
    key = OALBLMenuReadKey(TRUE);
    OALLog(L"%c\r\n", key);

    // Depending on result
    if (key != L'y' && key != L'Y') goto cleanUp;


    OALLog(L" Erase reserved block [-/y]? ");
    // Get key
    key = OALBLMenuReadKey(TRUE);
    OALLog(L"%c\r\n", key);

    // Depending on result
    if (key == L'y' || key == L'Y') 
        fEraseReserved = TRUE;

    OALLog(L" Try to erase bad blocks [-/y]? ");
    // Get key
    key = OALBLMenuReadKey(TRUE);
    OALLog(L"%c\r\n", key);

    // Depending on result
    if (key == L'y' || key == L'Y') 
        fEraseBadBlock = TRUE;
    
    OALLog(L" Erase Continue on failed [-/y]? ");
    // Get key
    key = OALBLMenuReadKey(TRUE);
    OALLog(L"%c\r\n", key);

    // Depending on result
    if (key == L'y' || key == L'Y') 
        fEraseFailCont = TRUE;

    // Open FMD    
    hFMD = FMD_Init(NULL, NULL, NULL);
    if (hFMD == NULL)
    {
        OALLog(L" Oops, can't open FMD driver\r\n");
        goto cleanUp;
    }

    if (!FMD_GetInfo(&flashInfo))
    {
        OALLog(L" Oops, can't get flash geometry info\r\n");
        goto cleanUp;
    }

    // First offset given
    block = 0;
    while (block < flashInfo.dwNumBlocks)
    {

        // If block is bad, we have to offset it
        status = FMD_GetBlockStatus(block);

        // Skip reserved blocks
        if (((status & BLOCK_STATUS_RESERVED) != 0) && (!fEraseReserved))
        {
            OALLog(L" Skip reserved block %d\r\n", block);
            block++;
            continue;
        }

        // Skip bad blocks
        if (((status & BLOCK_STATUS_BAD) != 0) && (!fEraseBadBlock))
        {
            OALLog(L" Skip bad block %d\r\n", block);
            block++;
            continue;
        }

        // Erase block
        if (!FMD_EraseBlock(block) && !fEraseFailCont)
        {
            OALLog(L" Oops, can't erase block %d\r\n", block);
            break;
        }

        block++;
        OALLog(L".");
    }

    OALLog(L"\r\nDone\r\n");

cleanUp:
    if (hFMD != NULL) FMD_Deinit(hFMD);
    return;
}


//------------------------------------------------------------------------------

VOID MenuEraseBlock(void)
{
    WCHAR key;
    HANDLE hFMD = NULL;
    FlashInfo flashInfo;
    BLOCK_ID firstblock, lastblock=0;
    WCHAR szInputLine[16];
    UINT32 status;

    OALLog(L"\r\n First Block Number: ");

    if (OALBLMenuReadLine(szInputLine, dimof(szInputLine)) == 0)
    {
        goto cleanUp;
    }

    // Get block number
    firstblock = OALStringToUINT32(szInputLine);

    OALLog(L"\r\n Last Block Number: ");

    if (OALBLMenuReadLine(szInputLine, dimof(szInputLine)) != 0)
    {
        // Get block number
        lastblock = OALStringToUINT32(szInputLine);
    }

    if (lastblock < firstblock)
    {
        lastblock=firstblock;
    }

    // Open FMD    
    hFMD = FMD_Init(NULL, NULL, NULL);
    if (hFMD == NULL)
    {
        OALLog(L" Oops, can't open FMD driver\r\n");
        goto cleanUp;
    }

    if (!FMD_GetInfo(&flashInfo))
    {
        OALLog(L" Oops, can't get flash geometry info\r\n");
        goto cleanUp;
    }

    if (lastblock >= flashInfo.dwNumBlocks)
    {
        OALLog(L" Oops, too big block number\r\n");
        goto cleanUp;
    }

    OALLog(L" Do you want erase block %d-%d [-/y]? ", firstblock, lastblock);

    // Get key
    key = OALBLMenuReadKey(TRUE);
    OALLog(L"%c\r\n", key);

    // Depending on result
    if (key != L'y' && key != L'Y')
    {
        goto cleanUp;
    }

    while (firstblock<=lastblock)
    {

        // If block is bad, we have to offset it
        status = FMD_GetBlockStatus(firstblock);

        // ask before erasing reserved blocks
        if ((status & BLOCK_STATUS_RESERVED) != 0)
        {

            OALLog(L" Do you want to erase reserved block %d [-/y]? ", firstblock);

            // Get key
            key = OALBLMenuReadKey(TRUE);
            OALLog(L"%c\r\n", key);

            // Depending on result
            if (key != L'y' && key != L'Y')
            {
                firstblock++;
                continue;
            }

        }

        // ask before erasing bad blocks
        if ((status & BLOCK_STATUS_BAD) != 0)
        {

            OALLog(L" Do you want to erase bad block %d [-/y]? ", firstblock);

            // Get key
            key = OALBLMenuReadKey(TRUE);
            OALLog(L"%c\r\n", key);

            // Depending on result
            if (key != L'y' && key != L'Y')
            {
                firstblock++;
                continue;
            }

        }

        // Erase block
        if (!FMD_EraseBlock(firstblock))
        {
            OALLog(L" Oops, can't erase block %d - mark as bad\r\n", firstblock);
            FMD_SetBlockStatus(firstblock, BLOCK_STATUS_BAD);
        }

        firstblock++;
        OALLog(L".");
    }

    OALLog(L" Done\r\n");

cleanUp:
    if (hFMD != NULL) FMD_Deinit(hFMD);
    return;
}

//------------------------------------------------------------------------------

VOID DumpFlash(void)
{
    HANDLE hFMD = NULL;
    FlashInfo flashInfo;
    SectorInfo sectorInfo;
    SECTOR_ADDR sector;
    WCHAR szInputLine[16];
    UINT8 buffer[512];
    UINT32 i, j;


    // Open FMD    
    hFMD = FMD_Init(NULL, NULL, NULL);
    if (hFMD == NULL)
    {
        OALLog(L" Oops, can't open FMD driver\r\n");
        goto cleanUp;
    }

    if (!FMD_GetInfo(&flashInfo))
    {
        OALLog(L" Oops, can't get flash geometry info\r\n");
        goto cleanUp;
    }

    if (flashInfo.wDataBytesPerSector > sizeof(buffer))
    {
        OALLog(L" Oops, sector size larger than my buffer\r\n");
        goto cleanUp;
    }

    while (TRUE)

⌨️ 快捷键说明

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