?? flash_intel.c~
字號(hào):
/* * File: flash_intel.c * * An implementation of a flash utility specific to several Intel chipsets. * This implementation, while vendor *dependent*, exposes the vendor * *independent* flash.h interface allowing it to plug generically into the * bootloader. Please see flash.h for more info. * * See Also * flash.h * * Copyright (C) 2002 RidgeRun, Inc. * Author: RidgeRun, Inc <skranz@ridgerun.com> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. * * Please report all bugs/problems to the author or <support@dsplinux.net> * * key: RRGPLCR (do not remove) * */#include "flash.h"#include "types.h"#include "util.h"#include "io.h"#include "memconfig.h"extern unsigned long FlashLockMode; // This is a global variable that will // be tested by the flash*.c module before // erases or writes flash. If the special // code 0xBEEFFEED is not present here then // the all flash mod operations will fail // and report a flash locked state.static short TotalSectors;typedef struct { int start_addr; int end_addr;} sect_info_t;#if (BSPCONF_FLASH_TYPE == INTEL_28F128)#define NUM_SEQUENTIAL_CHIPS 1#endif#if (BSPCONF_FLASH_TYPE == INTEL_28F160)#define NUM_SEQUENTIAL_CHIPS 1#endif#if (BSPCONF_FLASH_TYPE == INTEL_28F320)#define NUM_SEQUENTIAL_CHIPS 1#endif#if (BSPCONF_FLASH_TYPE == INTEL_28F640)#define NUM_SEQUENTIAL_CHIPS 1#endif#if (BSPCONF_FLASH_TYPE == INTEL_28F320x2)#define NUM_SEQUENTIAL_CHIPS 2#endif#ifdef C5471#define TWO_16BIT_FLASH_CHIPS_INVOLVED_IN_EACH_32BIT_ACCESS /* e.g. interleaved */#endif#ifdef TWO_16BIT_FLASH_CHIPS_INVOLVED_IN_EACH_32BIT_ACCESS #define XYZ 2#else #define XYZ 1#endif#define NUM_CHIP_SECT 39static const int sect_sizes[NUM_CHIP_SECT] = { // Intel 28F160F3 (2 MBytes each) /* Avoid confusion; Values here represented in "bytes(8bits)-per-block"; data sheet shows "words(16bits)-per-block". the XYZ used below is usually a value of 1 except in cases where the h/w designers have combined two flash chips side-by-side (interleaved) instead of sequentially in the address space. In the interleaved mode a 32bit value is retrieved by the h/w by accessing 16bits from one chip and the other 16bits from the second chip. On the other hand, in a sequential flash design, a 32bit value is retrieved by the h/w by accessing 16bits from a flash chip and then incrementing to the next location within that same flash chip to get the second 16bits. In both cases it is all seamless to the s/w since the h/w SDRAM controller is performing all the necessary accesses to reference the 32bit value. The one area that is not seamless to the s/w, however, is the erase-block size. In interleaved designs the s/w needs to be aware that the minimum number of bytes that can be erased at any one time is *twice* the minimum for each individual chip. Hence the XYZ modifier below to help manage that. */ XYZ*0x2000, XYZ*0x2000, XYZ*0x2000, XYZ*0x2000, XYZ*0x2000, XYZ*0x2000, XYZ*0x2000, XYZ*0x2000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000};#define NUM_CHIP_SECT_A 71static const int sect_sizes_A[NUM_CHIP_SECT_A] = { // Intel 28F320-Top-Boot (4MBytes each) /* Avoid confusion; Values here represented in "bytes(8bits)-per-block"; data sheet shows "words(16bits)-per-block". the XYZ used below is usually a value of 1 except in cases where the h/w designers have combined two flash chips side-by-side (interleaved) instead of sequentially in the address space. In the interleaved mode a 32bit value is retrieved by the h/w by accessing 16bits from one chip and the other 16bits from the second chip. On the other hand, in a sequential flash design, a 32bit value is retrieved by the h/w by accessing 16bits from a flash chip and then incrementing to the next location within that same flash chip to get the second 16bits. In both cases it is all seamless to the s/w since the h/w SDRAM controller is performing all the necessary accesses to reference the 32bit value. The one area that is not seamless to the s/w, however, is the erase-block size. In interleaved designs the s/w needs to be aware that the minimum number of bytes that can be erased at any one time is *twice* the minimum for each individual chip. Hence the XYZ modifier below to help manage that. */ XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x10000, XYZ*0x2000, XYZ*0x2000, XYZ*0x2000, XYZ*0x2000, XYZ*0x2000, XYZ*0x2000, XYZ*0x2000, XYZ*0x2000,};#define NUM_CHIP_SECT_B 128static const int sect_sizes_B[NUM_CHIP_SECT_B] = { // Intel 28F128J3A (16MBytes each) /* Avoid confusion; Values here represented in "bytes(8bits)-per-block"; data sheet shows "words(16bits)-per-block". the XYZ used below is usually a value of 1 except in cases where the h/w designers have combined two flash chips side-by-side (interleaved) instead of sequentially in the address space. In the interleaved mode a 32bit value is retrieved by the h/w by accessing 16bits from one chip and the other 16bits from the second chip. On the other hand, in a sequential flash design, a 32bit value is retrieved by the h/w by accessing 16bits from a flash chip and then incrementing to the next location within that same flash chip to get the second 16bits. In both cases it is all seamless to the s/w since the h/w SDRAM controller is performing all the necessary accesses to reference the 32bit value. The one area that is not seamless to the s/w, however, is the erase-block size. In interleaved designs the s/w needs to be aware that the minimum number of bytes that can be erased at any one time is *twice* the minimum for each individual chip. Hence the XYZ modifier below to help manage that. */ XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000};#define NUM_CHIP_SECT_C 64static const int sect_sizes_C[NUM_CHIP_SECT_C] = { // Intel 28F640J5 (8MBytes each) XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, XYZ*0x20000, };// -----------------------// Note:// All these arrays defined so that we can have// the one we need at runtime when we've detected// the actual chip type present on the board.// -----------------------#define TOTAL_SECT (NUM_SEQUENTIAL_CHIPS*NUM_CHIP_SECT)static sect_info_t sect_info[TOTAL_SECT]; // Intel 28F160F3 Chips#define TOTAL_SECT_A (NUM_SEQUENTIAL_CHIPS*NUM_CHIP_SECT_A)static sect_info_t sect_info_A[TOTAL_SECT_A]; // Intel 28F320 Chips#define TOTAL_SECT_B (NUM_SEQUENTIAL_CHIPS*NUM_CHIP_SECT_B)static sect_info_t sect_info_B[TOTAL_SECT_B]; // Intel 28F128J3A Chips#define TOTAL_SECT_C (NUM_SEQUENTIAL_CHIPS*NUM_CHIP_SECT_C)static sect_info_t sect_info_C[TOTAL_SECT_C]; // Intel 28F640J5 Chips// -----------------------// Note:// After detecting the chip type at runtime we'll point this// at the specific array that pertains. (ie. at sect_info[]// or sect_info_B[] or ...)// -----------------------static sect_info_t *SectInfoTable; // See note above.#ifdef TWO_16BIT_FLASH_CHIPS_INVOLVED_IN_EACH_32BIT_ACCESS// This block became necessary for supporting XIP downloads// on these style boards.static unsigned long *Cached_flash_addr;static unsigned short Cached_Short_valid;static unsigned short Cached_Short;#endif/****************************** Routine: Description:******************************/static void enable_read_mode(unsigned short *block_addr){#ifdef TWO_16BIT_FLASH_CHIPS_INVOLVED_IN_EACH_32BIT_ACCESS #define READ_MODE_CODE 0x00ff00ff unsigned long *addr; addr = (unsigned long *)((unsigned long)block_addr&0xffffffc); *addr = READ_MODE_CODE;#else #define READ_MODE_CODE 0x00ff *block_addr = READ_MODE_CODE;#endif}/****************************** Routine: Description:******************************/int read_device_codes(unsigned long *Code){ #define DEV_ID_CODE ((unsigned short)0x0090) unsigned short regval; unsigned short *block_addr = (unsigned short *)BSPCONF_FLASH_BASE; *block_addr = DEV_ID_CODE; regval = *block_addr; *Code = (unsigned int)regval; *Code = (unsigned int) (regval << 16);#ifdef TWO_16BIT_FLASH_CHIPS_INVOLVED_IN_EACH_32BIT_ACCESS // Incrementing block_addr by one would take us // into the second flash chip. Incrementing by two // allows us to pick up the next 16bit value from // the same chip we got the first 16bit value from. regval = *(block_addr+2);#else regval = *(block_addr+1);#endif *Code = *Code | (regval); enable_read_mode(block_addr); return 1;}/****************************** Routine: Description: returns true if chip supports CFI. array elements from CFI_START_ADDR to CFI_END_ADDR filled with CFI read array data. Returns false if chip doesn't support CFI.******************************/int read_cfi_array(unsigned short array[], int array_size){ return(0);}/****************************** Routine: Description: returns number of sectors if chip supports CFI. sector_map contains size of each sector. Returns false if chip doesn't support CFI. WARNING: the generated sector may not be ordered correctly******************************/int build_sector_map(unsigned long sector_map[], int sector_map_size){ return(0);}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -