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

📄 flash.c

📁 Windows CE 6.0 BSP for VOIPAC Board (PXA270) Version 2b.
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// 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:  flash.c
//
//  Flash routines for the Intel Mainstone II bootloader.
//
#include <windows.h>
#include <mainstoneii.h>
#include <oal_memory.h>
#include <fmd.h>
#include "loader.h"

// Defines.
//
#define FLASH_DEVICE_ID_L18_MIN    0x880C
#define FLASH_DEVICE_ID_L18_MAX    0x8810
#define FLASH_DEVICE_ID_L30_MIN    0x8812
#define FLASH_DEVICE_ID_L30_MAX    0x8815
#define FLASH_DEVICE_ID_K3_MIN     0x8801
#define FLASH_DEVICE_ID_K3_MAX     0x8803
#define FLASH_DEVICE_ID_K18_MIN    0x8805
#define FLASH_DEVICE_ID_K18_MAX    0x8807
#define FLASH_DEVICE_ID_J3_MIN     0x0016
#define FLASH_DEVICE_ID_J3_MAX     0x0018
#define FLASH_DEVICE_ID_P30_MIN    0x881a
#define FLASH_DEVICE_ID_P30_MAX    0x891c

// Type definitions.
//
#define FIOW	UINT16		// flash io width

typedef enum _FLASH_BLOCK_ARRAY_TYPE_
{
    CONSTANT_SIZE,
    BOTTOM_PARAMETER,
    TOP_PARAMETER
} FLASH_BLOCK_ARRAY_TYPE, *PFLASH_BLOC_ARRAY_TYPE;

typedef enum _FLASH_DEVICE_TYPE_
{
    NONE,
    L18, 
    L30,
    K3,
    K18,
    J3,
	P30
} FLASH_DEVICE_TYPE, *PFLASH_DEVICE_TYPE;

// Local variables.
//
static FLASH_BLOCK_ARRAY_TYPE g_BlockArrayType  = CONSTANT_SIZE;
static FLASH_DEVICE_TYPE      g_FlashDeviceType = NONE;

//#ifdef MCPII_MODULE
//static UINT32 FLASH_SIZE    = 0x04000000;       // 64MB.
//static UINT32 ERASE_BLOCKS  = 256;              // Total number of blocks (hiding parameter blocks).
//#else
static UINT32 FLASH_SIZE    = 0x02000000;       // 32MB.
static UINT32 ERASE_BLOCKS  = 256;              // Total number of blocks (hiding parameter blocks).
//#endif
static UINT32 L3_BLOCK_SIZE = 0x10000;          // 64KB per block on L3 (blocks 0 - 3).

// Global variables.
//
extern IMAGE_TYPE g_ImageType;

extern UINT16 g_UniqueDeviceID[4];


//------------------------------------------------------------------------------
//
//  Function:  OEMIsFlashAddr
//
// Checks the virtual address provided and determines if it's a flash address or not.
//
BOOL OEMIsFlashAddr(DWORD dwAddr)
{
    DWORD dwPhysAddr = (DWORD) OALVAtoPA((void*) dwAddr);
    
    if ((dwPhysAddr >= MAINSTONEII_BASE_PA_BOOT_FLASH) && (dwPhysAddr < (MAINSTONEII_BASE_PA_BOOT_FLASH + MAINSTONEII_SIZE_BOOT_FLASH )))
    {
        return(TRUE);
    }
    
    return(FALSE);
}


//------------------------------------------------------------------------------
//
//  Function:  OEMMapMemAddr
//
// Maps a flash address to a RAM address (used when temporarily caching a
// flash-destined download image to RAM).
//
LPBYTE OEMMapMemAddr (DWORD dwImageStart, DWORD dwAddr)
{

    if (OEMIsFlashAddr(dwAddr))
    {
        // The image being downloaded is a flash image - temporarily
        // cache the image in RAM until it's completely downloaded.
        //
        dwAddr -= dwImageStart;
        dwAddr += 0x80100000;
    }

    return((LPBYTE) (dwAddr));
}


//------------------------------------------------------------------------------
//
//  Function:  OEMStartEraseFlash
//
// Begins the flash erase procedure.
//
BOOL OEMStartEraseFlash (DWORD dwStartAddr, DWORD dwLength)
{
    return(TRUE);
}


//------------------------------------------------------------------------------
//
//  Function:  main
//
// Continues the flash erase procedure (erases are incrementally done during
// download to speed up the overall flash operation from the user's perspective).
//
void OEMContinueEraseFlash(void)
{
}


//------------------------------------------------------------------------------
//
//  Function:  OEMFinishEraseFlash
//
// Finished the flash erase procedure.
//
BOOL OEMFinishEraseFlash(void)
{
    return(TRUE);
}


BOOL OEMWriteFlash(DWORD dwImageStart, DWORD dwImageLength)
{
    BOOL  retVal = FALSE;
    UINT8 *pDataBuffer = (UINT8 *) OEMMapMemAddr(dwImageStart, dwImageStart);

    // FlashWrite uses virtual uncached addresses
    // dwImageStart could be either virtual uncached (eboot.bin) or virtual cached (nk.bin)
    dwImageStart = (DWORD) OALCAtoUA(dwImageStart);

    retVal = FlashWrite(dwImageStart, pDataBuffer, dwImageLength);

    // If we just wrote the bootloader to flash, halt and require the system to be rebooted.
    if (g_ImageType == IMAGE_TYPE_BOOTLOADER)
    {
        KITLOutputDebugString("INFO: bootloader image stored successfully.\r\n");
        KITLOutputDebugString("Reboot the system manually.  ");
        SpinForever();
    }

    return(retVal);

}


// START: these routines will be replaced by the FMD when it's done.
static FLASH_DEVICE_TYPE DetectFlashDevice(UINT32 FlashBaseAddress)
{
    UINT32 nDeviceID = 0;
    volatile FIOW *pFlash = (volatile FIOW *)(FlashBaseAddress);

    // Get the flash part ID.
    //
    *pFlash   = (FIOW) 0x00900090;
    nDeviceID = (*(pFlash + 1) & 0xFFFF);

    // Get the flash part Unique ID and store for later use
    g_UniqueDeviceID[0] = *(pFlash + 0x81);
    g_UniqueDeviceID[1] = *(pFlash + 0x82);
    g_UniqueDeviceID[2] = *(pFlash + 0x83);
    g_UniqueDeviceID[3] = *(pFlash + 0x84);

    // Put the flash part in read array mode.
    //
    *pFlash   = (FIOW) 0x00FF00FF;

    if ((nDeviceID >= FLASH_DEVICE_ID_L18_MIN) && (nDeviceID <= FLASH_DEVICE_ID_L18_MAX))
    {
        //KITLOutputDebugString("INFO: DetectFlashDevice: flash type is L18.\r\n");
        return(L18);
    }
    if ((nDeviceID >= FLASH_DEVICE_ID_L30_MIN) && (nDeviceID <= FLASH_DEVICE_ID_L30_MAX))
    {
        //KITLOutputDebugString("INFO: DetectFlashDevice: flash type is L30.\r\n");
        return(L30);
    }
    if ((nDeviceID >= FLASH_DEVICE_ID_K3_MIN) && (nDeviceID <= FLASH_DEVICE_ID_K3_MAX))
    {
        //KITLOutputDebugString("INFO: DetectFlashDevice: flash type is K3.\r\n");
        return(K3);
    }
    if ((nDeviceID >= FLASH_DEVICE_ID_K18_MIN) && (nDeviceID <= FLASH_DEVICE_ID_K18_MAX))
    {
        //KITLOutputDebugString("INFO: DetectFlashDevice: flash type is K18.\r\n");
        return(K18);
    }
    if ((nDeviceID >= FLASH_DEVICE_ID_J3_MIN) && (nDeviceID <= FLASH_DEVICE_ID_J3_MAX))
    {
        //KITLOutputDebugString("INFO: DetectFlashDevice: flash type is J3.\r\n");
        return(J3);
    }
    if ((nDeviceID >= FLASH_DEVICE_ID_P30_MIN) && (nDeviceID <= FLASH_DEVICE_ID_P30_MAX))
    {
//        KITLOutputDebugString("INFO: DetectFlashDevice: flash type is P30.\r\n");
        return(P30);
    }

    KITLOutputDebugString("INFO: DetectFlashDevice: flash type is undetermined.\r\n");
    return(NONE);
}


static BOOL FlashErase(UINT32 FlashStart, UINT32 FlashLength)
{
    UINT32 j;
    UINT32 num_blocks;
    UINT32 num_blocks_to_erase;
    UINT32 num_l3_blocks_to_erase = 0;
    UINT32 num_l3_blocks_erased;
    UINT32 flash_start_address = (UINT32) OALPAtoVA(MAINSTONEII_BASE_PA_BOOT_FLASH, FALSE);
    volatile FIOW *pFlash;
    FIOW status;
    UINT32 BLOCK_SIZE = (FLASH_SIZE / ERASE_BLOCKS);

    // Make sure we know what kind of flash part we have.
    //
    if (g_FlashDeviceType == NONE)
    {
        KITLOutputDebugString("ERROR: FlashErase: unrecognized flash part.\r\n");
        return(FALSE);
    }

    FlashStart = (UINT32) OALCAtoUA(FlashStart);
    // Determine the number of blocks to erase.
    num_blocks = (FlashLength / (BLOCK_SIZE));
    if (FlashLength % (BLOCK_SIZE))
    {
        num_blocks++;
    }

    if (num_blocks < 1)
    {
        num_blocks = 1;
        KITLOutputDebugString("WARNING: FlashErase: calculation error.  Erase blocks = %d\n\r", num_blocks);
    }

    else if (num_blocks > ERASE_BLOCKS)
    {
        num_blocks = ERASE_BLOCKS;
        KITLOutputDebugString("WARNING: FlashErase: calculation error.  Erase blocks = %d\n\r", num_blocks);
    }

    // If flash, need to change block count based on if we're in the first 4 blocks
    // as the first 4 blocks are 16KWords (vs. 64KWords/block)
    if ((g_FlashDeviceType == L18) || (g_FlashDeviceType == L30))
    {
        // Is start address within the first 4 blocks.  As there are 2 devices in parallel,
        // are we within the first 128KWords (2 x 64KWords)?  If so, we need to account for
        // increased number of blocks - which is the first 256K of addy range
        if ((FlashStart >= flash_start_address) && (FlashStart < (flash_start_address + 0x40000)))
        {
            // If we're within the first 128K words (256K), we need to treat the block as a special case
            num_l3_blocks_to_erase = 4;
            num_blocks--; // Decrease the num_blocks count, as it assumes the first block is 64K

            // Now add the # of L3 blocks to the # blocks calc.'ed at the beginning to get total
            // # of blocks to erase on a given L3 device INCLUDING the first 4 16kWord blocks
            num_blocks = num_blocks + num_l3_blocks_to_erase;
        }
    }

    pFlash = (volatile FIOW *)(FlashStart);

    // Issue the clear lock bits and confirm command.
    if (g_FlashDeviceType == J3)
    {
        // For J3 FLASH, unlock all blocks at once with one command
        num_blocks_to_erase = 1;
    }
    else if ((g_FlashDeviceType == K3) || (g_FlashDeviceType == K18)||
		(g_FlashDeviceType == L18) || (g_FlashDeviceType == L30) || (g_FlashDeviceType == P30))
    {
        // For K3/K18 FLASH, unlock individual blocks one at a time
        num_blocks_to_erase = num_blocks;
    }

    // For L3, need to set for use within the FOR loop
    num_l3_blocks_erased = num_l3_blocks_to_erase;

    for (j = 0; j < num_blocks_to_erase; j++)
    {

⌨️ 快捷键说明

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