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

📄 nor.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 C
📖 第 1 页 / 共 3 页
字号:
//-----------------------------------------------------------------------------
//
//  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.
//
//-----------------------------------------------------------------------------
//
//  Copyright (C) 2004, Motorola Inc. All Rights Reserved
//
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
//
//  File:  nor.c
//
//  Provides the implementation of the NOR flash library interface layer.
//
//  IMPORTANT!
//  ==========
//  
//  1. The flash library is not meant to be run XIP in flash. If not already
//  residing out of flash, the library user should allocate some buffer 
//  (use NORGetRelocateCodeSize() to get max required buffer size) and pass
//  address of this buffer in NORLibInit() to relocate the flash functions.
//  This may not be needed for flash parts that support simultaneous
//	read/write/erase. 
//   
//  2. WinCE linker orders functions randomly, the following line must
//  be added in the sources file of the exe or dll using the libraty to force 
//  function ordering for relocation. Eg. see eboot/sources 
//
//  LDEFINES=$(LDEFINES) /ORDER:@$(_TARGETPLATROOT)\SRC\DRIVERS\BLOCK\NORFMD\NORFLASHLIB\linkorder.txt 
//
//  3. If relocation is required, no msg printout is allowed. ie DEBUG MODE 
//	MUST BE OFF! To debug the flash libraries, run it in RAM.
//
//  4. The flash library can make use of OS wait services in order to reduce
//  use of polling if USE_OS_SERVICES is defined. However, in this case 
//  RELOCATION CANNOT be USED since the flash programming codes will no longer
//	be self contained!
//
//-----------------------------------------------------------------------------
#include <windows.h>

#include "nor.h"
#include "amd.h"
#include "strata.h"

//------------------------------------------------------------------------------
// External Variables

//------------------------------------------------------------------------------
// Defines
#define MAX_SUPPORTED_FLASH_DRIVERS   \
    (sizeof(g_LowLevelDrivers) / sizeof(NOR_FLASH_DRIVER))

#define MAX(a, b)   ( ((a) > (b))? (a) : (b) )
#define MIN(a, b)   ( ((a) < (b))? (a) : (b) )
//------------------------------------------------------------------------------
// Types

//------------------------------------------------------------------------------
// Global Variables

//------------------------------------------------------------------------------
// Local Variables
// Table of supported lower level flash drivers.
static const NOR_FLASH_DRIVER g_LowLevelDrivers[] = {
    {
        AMDx16_RelocateBegin,
        AMDx16_IsFlashSupported,
        AMDx16_Program,
        AMDx16_EraseSector,
        AMDx16_EraseChip,
        AMDx16_RelocateEnd,
        AMDx16_LockSector,
        AMDx16_UnlockSector,        
        AMDx16_IsSectorLocked,
        L"AMD/Spansion x16 Flash Driver",
    },
    {
        StrataX16_RelocateBegin,
        StrataX16_IsFlashSupported,
        StrataX16_Program,
        StrataX16_EraseSector,
        NULL,
        StrataX16_RelocateEnd,
        StrataX16_LockSector,
        StrataX16_UnlockSector,        
        NULL,
        L"Intel Strata x16 Flash Driver",
    },
    // Add more low level flash drivers here
};


static NOR_FLASH_DRIVER g_FlashDriver;
static DWORD g_dwFlashDriverID = -1;
static NOR_FLASH_DESC g_FlashDesc;

static BOOL g_bShowProgress = FALSE;
static ULONG g_ulBytePerStep = 0;

//------------------------------------------------------------------------------
// Local Functions
static void PrintCFIData(NOR_FLASH_DESC *pFlashDesc);
static void PrintFlashID(NOR_FLASH_DESC *pFlashDesc);
static BOOL NORFindSector(ULONG *pulFlashAddr, ULONG *pulSectorSize);

//-----------------------------------------------------------------------------
// EXPORTED FUNCTIONS
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//
// Function: NORLibInit
//
// Function NOR library initialization.
// 
// Parameters:
//      ulFlashBase
//          [in] flash base address
//
//      ulRelocateBase
//          [in] address of buffer to relocate codes. codes will be relocated
//              if this parameter is non zero.
//				NOTE: This must be an address to uncached memory!
//
//      ulRelocSize
//          [in] size of buffer to relocate codes.
//
// Returns:
//      FALSE on failure
//
//-----------------------------------------------------------------------------
BOOL NORLibInit(ULONG ulFlashBase, ULONG ulRelocateBase, ULONG ulRelocSize)
{
    ULONG i;
    ULONG ulRelocLen;
    BOOL bSuccess;
    BOOL (*pIsFlashSupported)(NOR_FLASH_DESC *pFlashDesc);

    DEBUGMSG(ZONE_FUNCTION, (TEXT("NORLibInit+0x%x 0x%x\r\n"), ulFlashBase, ulRelocateBase));

    if(ulRelocateBase != 0 && ulRelocSize < NORGetRelocateCodeSize())
    {
        ERRORMSG(ZONE_ERROR, (TEXT("ERROR: Insufficient relocation size! Expected 0x%x\r\n"),
                                NORGetRelocateCodeSize()));
        return FALSE;
    }
    else
    {
        DEBUGMSG(ZONE_FUNCTION, (TEXT("Init relocate base 0x%x 0x%x\r\n"), ulRelocateBase, ulRelocSize));
        memset((void *)ulRelocateBase, 0, ulRelocSize);
        DEBUGMSG(ZONE_FUNCTION, (TEXT("done relocate base 0x%x 0x%x\r\n"), ulRelocateBase, ulRelocSize));
    }

    memset(&g_FlashDesc, 0, sizeof(NOR_FLASH_DESC));
    g_dwFlashDriverID = -1;
    for(i = 0; i < MAX_SUPPORTED_FLASH_DRIVERS; i++)
    {
        pIsFlashSupported = g_LowLevelDrivers[i].IsFlashSupported;
        if(ulRelocateBase != 0)
        {
            // Relocate flash detection codes cos flash will not be accessible then.
            ulRelocLen = (ULONG)g_LowLevelDrivers[i].RelocateEnd - (ULONG)g_LowLevelDrivers[i].RelocateBegin;

            DEBUGMSG(ZONE_FUNCTION, (TEXT("INFO: Relocate 0x%x to 0x%x.\r\n"), *(ULONG *)&g_LowLevelDrivers[i].RelocateBegin, ulRelocateBase));
            DEBUGMSG(ZONE_FUNCTION, (TEXT("%s detection code size 0x%x\r\n"), g_LowLevelDrivers[i].lpszName, ulRelocLen));

            memcpy((BYTE *)ulRelocateBase, (BYTE *)g_LowLevelDrivers[i].RelocateBegin, ulRelocLen);
            *(ULONG *)&pIsFlashSupported = ((ULONG)g_LowLevelDrivers[i].IsFlashSupported - (ULONG)g_LowLevelDrivers[i].RelocateBegin + (ULONG)ulRelocateBase);
            DEBUGMSG(ZONE_FUNCTION, (TEXT("pIsFlashSupported 0x%x\r\n"), pIsFlashSupported));
        }
        g_FlashDesc.FlashBase = ulFlashBase;
        bSuccess = pIsFlashSupported(&g_FlashDesc);
        DEBUGMSG(ZONE_FUNCTION, (TEXT("pIsFlashSupported %c\r\n"), bSuccess? 'T':'F'));
        if(bSuccess == TRUE)
        {
            memcpy(&g_FlashDriver, &g_LowLevelDrivers[i], sizeof(NOR_FLASH_DRIVER));
            g_dwFlashDriverID = i;
            break;
        }
    }
    if(g_dwFlashDriverID == -1  || g_dwFlashDriverID >= MAX_SUPPORTED_FLASH_DRIVERS 
        || g_FlashDriver.Program == NULL || g_FlashDriver.EraseSector == NULL) 
    {
        ERRORMSG(ZONE_ERROR, (TEXT("ERROR: No supported NOR flash found!\r\n")));
        return FALSE;
    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("ll driver index: %d\r\n"), i));
    if(ulRelocateBase != 0 && bSuccess == TRUE)
    {
        ulRelocLen = (ULONG)g_LowLevelDrivers[i].RelocateEnd - (ULONG)g_LowLevelDrivers[i].RelocateBegin;
        memcpy((BYTE *)ulRelocateBase, (BYTE *)g_LowLevelDrivers[i].RelocateBegin, ulRelocLen);

        DEBUGMSG(ZONE_FUNCTION, (TEXT("INFO: Relocate 0x%x to 0x%x.\r\n"), *(ULONG *)&g_LowLevelDrivers[i].RelocateBegin, ulRelocateBase));
        DEBUGMSG(ZONE_FUNCTION, (TEXT("%s relocate code size 0x%x\r\n"), g_LowLevelDrivers[i].lpszName, ulRelocLen));

        // Overwrite function pointer to point to relocated codes
        *(ULONG *)&g_FlashDriver.IsFlashSupported = (ulRelocateBase + (ULONG)g_FlashDriver.IsFlashSupported - (ULONG)g_FlashDriver.RelocateBegin);;
        *(ULONG *)&g_FlashDriver.Program = (ulRelocateBase + (ULONG)g_FlashDriver.Program - (ULONG)g_FlashDriver.RelocateBegin);
        *(ULONG *)&g_FlashDriver.EraseSector = (ulRelocateBase + (ULONG)g_FlashDriver.EraseSector - (ULONG)g_FlashDriver.RelocateBegin);
        if(g_FlashDriver.EraseChip != NULL)
            *(ULONG *)&g_FlashDriver.EraseChip = (ulRelocateBase + (ULONG)g_FlashDriver.EraseChip - (ULONG)g_FlashDriver.RelocateBegin);

        DEBUGMSG(ZONE_FUNCTION, (TEXT("Relocated IsFlashSupported: 0x%x\r\n"), (ULONG)g_FlashDriver.IsFlashSupported));
        DEBUGMSG(ZONE_FUNCTION, (TEXT("Relocated Program: 0x%x\r\n"), (ULONG)g_FlashDriver.Program));
        DEBUGMSG(ZONE_FUNCTION, (TEXT("Relocated EraseSector: 0x%x\r\n"), (ULONG)g_FlashDriver.EraseSector));
        DEBUGMSG(ZONE_FUNCTION, (TEXT("Relocated EraseChip: 0x%x\r\n"), (ULONG)g_FlashDriver.EraseChip));
    }
    PrintCFIData(&g_FlashDesc);
    PrintFlashID(&g_FlashDesc);
    
    DEBUGMSG(ZONE_FUNCTION, (TEXT("NORLibInit-\r\n")));

    return bSuccess;
}

//-----------------------------------------------------------------------------
//
// Function: NORProgram
//
// Program the flash starting from the given address.
//
// Parameters:
//      ulStartAddress
//          [in] address to start writing from
//
//      pData
//          [in] ptr to data buffer to write
//
//      ulSize
//          [in] size of data to program
//
//      bIgnore0to1
//          [in] ignores programming 0 to 1 errors if TRUE
//
// Returns:
//      FALSE on failure
//
//-----------------------------------------------------------------------------
BOOL NORProgram(ULONG ulStartAddress, UCHAR *pData, ULONG ulSize, BOOL bIgnore0to1)
{
    BOOL bSuccess;
    BOOL bIsPaired;
    DWORD dwBusWidth;
    ULONG ulprogSize;


    DEBUGMSG(ZONE_FUNCTION, (TEXT("NORProgram+ 0x%x 0x%x 0x%x\r\n"),
            ulStartAddress, pData, ulSize));

    bIsPaired = g_FlashDesc.PairedFlash;
    dwBusWidth = bIsPaired? g_FlashDesc.DeviceWidth >> 2 : g_FlashDesc.DeviceWidth >> 3;

    // Check address is bus width aligned
    if((ulStartAddress % dwBusWidth) != 0)
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: Unaligned start address for program: 0x%x buswith: %d\r\n"), 
                                    ulStartAddress, dwBusWidth));
        return FALSE;
    }
    // Check data size aligned wrt buswidth
    if((ulSize % dwBusWidth) != 0)
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: Unaligned data size for program: 0x%x buswith: %d\r\n"), 
                                ulSize, dwBusWidth));
        return FALSE;
    }

    if(g_bShowProgress)
    {
        while(ulSize)
        {
            ulprogSize = MIN(ulSize, g_ulBytePerStep);
        	DEBUGMSG(ZONE_FUNCTION, (TEXT("ulprogSize 0x%x ulSize 0x%x\r\n"), ulprogSize, ulSize));
            bSuccess = g_FlashDriver.Program(&g_FlashDesc, ulStartAddress, pData, ulprogSize, bIgnore0to1);
            if(bSuccess)
            {
                PROGRESSMSG(g_bShowProgress, (TEXT("P")));
                ulSize -= ulprogSize;
                ulStartAddress += ulprogSize;
                pData += ulprogSize;
            }
            else
                break;
        }
    }
    else
        bSuccess = g_FlashDriver.Program(&g_FlashDesc, ulStartAddress, pData, ulSize, bIgnore0to1);

    PROGRESSMSG(g_bShowProgress, (TEXT("\r\n")));

    DEBUGMSG(ZONE_FUNCTION, (TEXT("NORProgram- %c \r\n"), bSuccess? 'T' : 'F'));
    return bSuccess;
}

//-----------------------------------------------------------------------------
//
// Function: NORErase
//
// Erases the flash starting from the given address. 
//
// Note:
// All sectors overlapping the desired region is erased. 
//
// Parameters:
//      ulStartAddress
//          [in] address to start erase
//
//      ulLen
//          [in] size of region to erase
//
// Returns:
//      actual erase size on success or 0 on failure
//
//-----------------------------------------------------------------------------
ULONG NORErase(ULONG ulStartAddress, ULONG ulLen)
{

⌨️ 快捷键说明

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