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

📄 flash.c

📁 PXA27X裸机测试程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// 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.
//
//------------------------------------------------------------------------------
//
//  File:  flash.c
//
//  Flash routines for the Emdoor XSBASE270_G bootloader.
//
//#include <windows.h>
#include <XSBASE270_G.h>
#include "flash.h"
#include "bulverde_uart.h"
//#include <oal_memory.h>
//#include <fmd.h>
//#include "loader.h"

void* OALPAtoVA(UINT32 pa, bool cached)
{
    return (void *) (pa | (cached? 0x80000000 : 0xa0000000));
}

// Defines.
//

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

static UINT32 FLASH_SIZE    = (16777216 * 2);   // Paired 16MB parts.
static UINT32 ERASE_BLOCKS  = 128;              // Total number of blocks (hiding parameter blocks).
static UINT32 L3_BLOCK_SIZE = 65536;            // 64KB per block on L3 (blocks 0 - 3).

// Global variables.
//
//extern IMAGE_TYPE g_ImageType;


//------------------------------------------------------------------------------
//
//  Function:  OEMIsFlashAddr
//
// Checks the address provided and determines if it's a flash address or not.
//
bool OEMIsFlashAddr(UINT32 dwAddr)
{
    UINT32 dwVirtFlashStart = (UINT32) OALPAtoVA(XSBASE270_G_BASE_PA_BOOT_FLASH, true);

    if ((dwAddr >= dwVirtFlashStart) && (dwAddr <= (dwVirtFlashStart + XSBASE270_G_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).
//
UINT8 * OEMMapMemAddr (UINT32 dwImageStart, UINT32 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;
        //TODO - constant.
        dwAddr += 0x80100000;
    }

    return((UINT8 *) (dwAddr));
}


//------------------------------------------------------------------------------
//
//  Function:  OEMStartEraseFlash
//
// Begins the flash erase procedure.
//
bool OEMStartEraseFlash (UINT32 dwStartAddr, UINT32 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(UINT32 dwImageStart, UINT32 dwImageLength)
{
    bool  retVal = false;
    UINT8 *pDataBuffer = (UINT8 *) OEMMapMemAddr(dwImageStart, dwImageStart);

    dwImageStart |= CACHED_TO_UNCACHED_OFFSET;

    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)
    {
        EdbgOutputDebugString("INFO: bootloader image stored successfully.\r\n");
        EdbgOutputDebugString("Reboot the system manually.  ");
        SpinForever();
    }
*/
    return(retVal);

}


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

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

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

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


static bool FlashErase(UINT32 FlashStart, UINT32 FlashLength)
{
    UINT32 i,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(XSBASE270_G_BASE_PA_BOOT_FLASH, false);
    volatile UINT32 *pFlash;
    UINT32 status;
    UINT32 BLOCK_SIZE = (FLASH_SIZE / ERASE_BLOCKS);

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

    // 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;
        //EdbgOutputDebugString("WARNING: FlashErase: calculation error.  Erase blocks = %d\n\r", num_blocks);
    }

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

    // If Tyax 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 UINT32 *)(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++)
    {
        *pFlash = 0x00600060;
        *pFlash = 0x00d000d0;

        i = 0;
        while ((i & 0x00800080) != 0x00800080)
        {
            i = *pFlash;
        }

        if ((i & 0x00000008) == 0x00000008)
           // EdbgOutputDebugString("ERROR: FlashErase: voltage range error ... lower flash.\r\n");
        if ((i & 0x00080000) == 0x00080000)
           // EdbgOutputDebugString("ERROR: FlashErase: voltage range error ... upper flash.\r\n");

        if ((i & 0x00000030) == 0x00000030)
            //EdbgOutputDebugString("ERROR: FlashErase: command sequence error ... lower flash.\r\n");
        if ((i & 0x00300000) == 0x00300000)
           // EdbgOutputDebugString("ERROR: FlashErase: command sequence error ... upper flash.\r\n");

        if ((i & 0x00000020) == 0x00000020)
            //EdbgOutputDebugString("ERROR: FlashErase: clear lock bits error ... lower flash.\r\n");
        if ((i & 0x00200000) == 0x00200000)
            //EdbgOutputDebugString("ERROR: FlashErase: clear lock bits error ... upper flash.\r\n");

        if (i != 0x00800080)

⌨️ 快捷键说明

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