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

📄 flash.c

📁 flash驱动程序,Nor flash类型
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ############################################################################ (c) Copyright Virata Limited 2001## Virata Limited Confidential and Proprietary## The following software source code ("Software") is strictly confidential and# is proprietary to Virata Limited ("Virata").  It may only be read, used,# copied, adapted, modified or otherwise dealt with by you if you have# entered into a confidentiality agreement with Virata and then subject to the# terms of that confidentiality agreement and any other applicable agreement# between you and Virata.  If you are in any doubt as to whether you are# entitled to access, read, use, copy, adapt, modify or otherwise deal with# the Software or whether you are entitled to disclose the Software to any# other person you should contact Virata.  If you have not entered into a# confidentiality agreement with Virata granting access to this Software you# should forthwith return all media, copies and printed listings containing# the Software to Virata.## Virata reserves the right to take legal action against you should you breach# the above provisions.## If you are unsure, or to report violations, please contact# support@virata.com# ##########################################################################*//*********************************************************************** *                                                                     * *    ATMOS Flash Filing System support code                           * *                                                                     * *    FLASH.C                                                          * *                                                                     * ***********************************************************************//*** To add a new FLASH device...**** 1.   Define an ID.** 2.   Add an entry to the flash type table.** 3.   Write sector, byte and erase routines as required (many chips**      can actually use the same one).** 4.   Update read_chip_id_info () to handle the new chip, particularly**      with respect to sector protection.***//*** Notes about the FLASH_AMD_NO_SWAP macro**** Some reference designs need to share GPIO lines between the flash and** other system components. (An example is the RD6400.) Thus we may need to** ensure that all flash reads/writes are atomic in nature, especially if ** the other system components in question are used very often.  For AMD** flash parts, defining the FLASH_AMD_NO_SWAP macro in the hardware file** allows this to happen (by lengthening the FIQ critical section as ** necessary). **** DEVELOPER BEWARE:** The design choice implied by this change should only be used IF tying** up the system for flash reads/writes is acceptable (e.g. only occurring at** start-of-day and/or during flashfs updates/rewrites). **** Note: we may wish to consider changing this macro to FLASH_NO_SWAP,** if another design using non-AMD parts finds this tactic useful.  Note** that .hw files defining this macro would also need to be changed.*/#include <stdlib.h>#include <string.h>#include <atypes.h>#include <rom.h>#include <assert.h>#if !defined (BOOT_ROM) || !defined (NO_CONFIGINFO_FLASH)#include <timelib.h>#endif#include "config.h"#include "flash.h"#include "stdio.h"/*====================================================================*//* Type and  macro definitions                                        *//*====================================================================*//*** Some systems have windowed flash where a large FLASH device is accessed through** a series of smaller windows. (1 << FLASH_WINDOW_BITS) defines the size of the** window in bytes.**** All FLASH devices are assumed to be accessed through the *same* window which** is assumed to be the same size. Windowed access is slower than direct access.*//*The following should be defined as necessary when using windowed flash:FLASH_WINDOW_BITS             - Number of bits in window (ie 1Mb => 20 bits)FLASH_WINDOW_SELECT_REGISTER  - Address of window select registerFLASH_WINDOW_REGISTER_OFFSET  - Offset of window select bits in registerFLASH_WINDOW_REGISTER_SHARED  - Define if register is shared (ie only some                                of the bits are for the flash select and other bits                                are for other functions.  If dedictated register                                don't define this.FLASH_WINDOW_REGISTER_BITS    - Number of bits in register used to select windowFLASH_WINDOW_REGISTER_SIZE    - Size (type) of window register (BYTE, WORD, etc) FLASH_COMBINED_PAGE_WINDOW_REGISTER    - A combined window/select register (that is write-only)*/#ifdef  FLASH_WINDOW_BITS#define WINDOWED_FLASH     1/*** Just check that it *is* possible to select a flash window.*/#ifndef FLASH_WINDOW_SELECT_REGISTER#error "No register defined for selection of the flash window but windowed flash required."#endif/* If size not specified assume the window register has size 1 byte */#ifndef FLASH_WINDOW_REGISTER_SIZE    #define FLASH_WINDOW_REGISTER_SIZE  BYTE#endif/* Check to see if bit-offset in register is specified */                      #ifndef FLASH_WINDOW_REGISTER_OFFSET    #define FLASH_WINDOW_REGISTER_OFFSET    0#endif/* Use number of bits and bit offset to define bit mask for window register */#ifdef FLASH_WINDOW_REGISTER_BITS    #define FLASH_WINDOW_REGISTER_MASK  (((1 << FLASH_WINDOW_REGISTER_BITS) -1) << FLASH_WINDOW_REGISTER_OFFSET)#else    #ifdef FLASH_WINDOW_REGISTER_SHARED    #error "No flash window register bits specified, using default mask"    #endif    #define FLASH_WINDOW_REGISTER_MASK  0xffffffff#endif#if defined (FLASH_WINDOW_REGISTER_SHARED) && defined (FLASH_COMBINED_PAGE_WINDOW_REGISTER)#error "Read/write combined window/page register unsupported"#endif#define FLASH_WINDOW_SIZE   (1 << FLASH_WINDOW_BITS)#define FLASH_WINDOW_MASK   (FLASH_WINDOW_SIZE - 1)/* If the window register is shared we must perform a read/modify/write operation.   in this case we call a function due to complexity of critical sections etc.    If the register is not shared we will use a macro for speed  */#if defined (FLASH_WINDOW_REGISTER_SHARED)    #define FLASH_WINDOW_SELECT(addr)  flash_window_select(addr)   #elif defined (FLASH_COMBINED_PAGE_WINDOW_REGISTER)    #define FLASH_WINDOW_SELECT(addr)   (* (FLASH_WINDOW_REGISTER_SIZE *) FLASH_WINDOW_SELECT_REGISTER = \                                    pageRegister | \                                    ((addr) >> (FLASH_WINDOW_BITS - FLASH_WINDOW_REGISTER_OFFSET) & \                                    FLASH_WINDOW_REGISTER_MASK) )#else    #define FLASH_WINDOW_SELECT(addr)   (* (FLASH_WINDOW_REGISTER_SIZE *) FLASH_WINDOW_SELECT_REGISTER = \                                    ((addr) >> (FLASH_WINDOW_BITS - FLASH_WINDOW_REGISTER_OFFSET) & \                                    FLASH_WINDOW_REGISTER_MASK) )#endif#endif/* ID's read from the supported FLASH chips in the system */#define UNKNOWN_CHIP_ID         (0xffff)    /* Anything but one of the following */#define AT29C040_CHIP_ID        (0x1f5b)#define AT29C040A_CHIP_ID       (0x1fa4)#define AT29C1024_CHIP_ID       (0x1f25)#define AT49BV1614_CHIP_ID      (0x1fc0)#define AT49BV1614T_CHIP_ID     (0x1fc2)#define AM29F040_CHIP_ID        (0x01a4)#define AM29LV081B_CHIP_ID      (0x0138)#define AM29LV040B_CHIP_ID      (0x014F)#define AM29LV017B_CHIP_ID      (0x01c8)#define AM29LV116BB_CHIP_ID     (0x014c)#define AM29LV116BT_CHIP_ID     (0x01c7)#define AM29LV800BB_CHIP_ID		(0x015b)#define AM29LV800BT_CHIP_ID		(0x01da)#define AM29LV160BB_CHIP_ID		(0x0149)#define AM29LV160BT_CHIP_ID		(0x01c4)#define MT28F008B3B_CHIP_ID     (0x8999)#define MT28F008B3T_CHIP_ID     (0x8998)#define INT28F800B5B_CHIP_ID    (0x899d)#define INT28F320J5_CHIP_ID     (0x8914)#define W29C040_CHIP_ID         (0xda46)#define MX29L1611B_CHIP_ID      (0xc2f8)#define M29W008T_CHIP_ID        (0x20D2)#define M29W008B_CHIP_ID        (0x20DC)#define M29W040B_CHIP_ID        (0x20E3)#define M29W800AT_CHIP_ID       (0x20D7)#define M29W800AB_CHIP_ID       (0x205B)#define BM29F040_CHIP_ID        (0xAD40) #define MX29F040_CHIP_ID        (0xC2A4) #define EN29F040_CHIP_ID        (0x7F7F) #define AC29F040_CHIP_ID        (0x3786) #define MX29F800B_CHIP_ID       (0xC258) #define SST39VF080Q_CHIP_ID     (0xBFD8) #define SST39VF016Q_CHIP_ID     (0xBFD9) #define SST28SF040A_CHIP_ID     (0xBF04)  #define LH28F160BVE_CHIP_ID     (0xb049)/* 'tuning' variables used in loops to cause the Atmos kernel to schedule   *//* other runnable proccesses.  This keeps the 'world alive' during updates. */#define AMD_BYTES_PER_KEEP_ALIVE    2048  /* every 2k bytes, wake up others */#define MICRON_BYTES_PER_KEEP_ALIVE 2048  /* every 2k bytes, wake up others */#define ATMEL_SECTORS_PER_KEEP_ALIVE  10  /* a little less than 10ms / sector */#define SST_SECTORS_PER_KEEP_ALIVE  10    /* a little less than 10ms / sector *//*** The number of bytes, on chips that support single writes to anywhere in** flash, that can be written without having to change the flash sector. ** (This is an optimisation which can save having to erase and rewrite a ** complete sector, for example AMD chips but not Atmel PEROMs.)*/#define SMALL_WRITE_LIMIT           25/*** Name:    FlashSector**** Flash chips are commonly divided into sectors. Some chips have all** sectors one size, others have small sectors at one or both ends to provide** BOOT ROM capability.*/typedef struct flash_sector_tag{    /*    ** The size of a sector within a flash chip. Much of the code assumes    ** that sectors are a power of two in length.    */    U32             size;    U32             numberSectors;} FlashSector;/*** Increase as required: the number of different sized blocks of ** sectors within a flash device.*/#define NUMBER_DIFFERENT_SECTOR_SIZES    4/*** Name:    FlashType**** The characteristics of each supported flash device type. Unused sector** definitions should be zero. The sum of sector.size * sector.numberSectors** should equal size. The sector sizes should be in the order that they occur** within the device.**** The function pointers remove chip dependencies within the main body of the code.*/typedef struct flash_type_tag{    BITS            id;    BOOL            is16Bit;    /* 16 bit device operating in 8 bit mode */    BOOL            true16;     /* 16 bit device operating in 16 bit mode */    U32             size;    const char *    manufacturer;    const char *    partname;    FlashSector     sectors [NUMBER_DIFFERENT_SECTOR_SIZES];    /*    ** Required: program a sector    */    int     (*program_sector) (U32 logicalAddress, BYTE *source, U32 length);    /*    ** Optional (may be NULL): program single byte, if absent    ** the whole sector is read and rewritten. If the flash chip    ** supports writing a single byte it can save needless sector     ** reprogramming and is, therefore, faster. To support this    ** operation the flash is expected to be erased to 0xff and    ** single bits may be reset.    */    int     (*program_byte) (U32 logicalAddress, BYTE value);    /*    ** Optional: erase a sector to 0xff, if absent  program_sector    ** called with source of buffer filled with 0xff.     ** IMPORTANT: length <= LARGEST_PEROM_SECTOR_SIZE    */    int     (*erase_sector) (U32 logicalAddress, U32 length);} FlashType;/*** Name:    FlashDevice**** The compile-time configuration of a flash device in memory.*/typedef struct flash_device_tag{    /* Is this a 16-bit device? */    BOOL Is16; /* 0 == 8 bit, 1 == 16 bit */    /*    ** From where to read FLASH    */    volatile BYTE * physicalBaseRead;    /*    ** Where to write FLASH. Presented as a different address to read,    ** though it may be the same, because the hardware may have subtlely    ** different timing when writing (e.g. WRITE may go low before CS which    ** on some FLASH chips violates timings).    */    volatile BYTE * physicalBaseWrite;    U32             size;    BYTE            flashPage;    U32             logicalBase;} FlashDevice;/*** Name:    ActualFlashType**** The actual configuration of a flash device in memory. Although this** could be merged with FlashDevice that would mean that the "fixed" and** "variable" elements were mixed unnecesarily.*/typedef struct actual_flash_type_tag{    /*    ** Index into flashTypes, set to NUMBER_FLASH_TYPES after flash_initialise    ** has been called.    */    BYTE            typeIndex;    /*    ** A bit mask of protected BOOT blocks, etc. set to one (1) when the relevant    ** sector is protected.     ** NB The current definition assumes that flash chips have a maximum of    **    thirty-two protectable sectors in them.    */    U32             writeMask;} ActualFlashType;/*** Macro to read one byte of flash, this can be replaced during simulation** Note that _addr is offset within the device.*/#ifdef  WINDOWED_FLASH#define FLASH_READ_RAW(_addr, _device)  (FLASH_WINDOW_SELECT(_addr), \                                        flashDevices [_device].physicalBaseRead [_addr & FLASH_WINDOW_MASK])#else#define FLASH_READ_RAW(_addr, _device)  flashDevices [_device].physicalBaseRead [_addr]#endif#define FLASH_READ_RAW16(_addr, _device)  *(volatile U16*)(flashDevices [_device].physicalBaseRead + (_addr & ~1))#ifdef ETHER8X10                       /* Macro to write one byte to flash  */    /* On the StrongArm, bytes come out on the appropriate data byte lane and   */    /* are not, as on the ARM610, replicated across all lanes. So the hardware  */    /* maps A0:A1 from A22:A23 on write only.                                   */    #define FLASH_WRITE_RAW(_byte, _addr, _device)    flashDevices [_device].physicalBaseWrite [((_addr) & ~3) | (((_addr) & 3) << 22)] = _byte#else /* ETHER8X10 */#ifdef  WINDOWED_FLASH    #define FLASH_WRITE_RAW(_byte, _addr, _device)    (FLASH_WINDOW_SELECT (_addr), \                                                      flashDevices [_device].physicalBaseWrite [_addr & FLASH_WINDOW_MASK] = _byte)#else    #define FLASH_WRITE_RAW(_byte, _addr, _device)    flashDevices [_device].physicalBaseWrite [_addr] = _byte#endif#endif /* ETHER8X10 */#define FLASH_WRITE_RAW16(_word, _addr, _device)  *(volatile U16*)(flashDevices[_device].physicalBaseWrite + (_addr & ~1)) = _word/*====================================================================*//* Forward definitions of procedures in this module                   *//*====================================================================*//*** Chip specific write/erase routines.*/#ifndef FLASH_NO_AMD_SUPPORTstatic int  program_AMD_sector(U32 addr, BYTE *source, U32 sectorSize);static int  erase_AMD_sector(U32 addr, U32 sectorSize);static int  program_AMD_byte(U32 addr, BYTE byte);static int  program_AMD_sector16(U32 addr, BYTE *source, U32 sectorSize);		// Added by APSstatic int  erase_AMD_sector16(U32 addr, U32 sectorSize);						// Added by APSstatic int  program_AMD_word(U32 addr, U16 data);								// Added by APS#endif#ifndef FLASH_NO_ATMEL_SUPPORTstatic int  program_ATMEL_sector(U32 addr, BYTE *source, U32 sector);static int  program_ATMEL_sector16(U32 addr, BYTE *source, U32 sector);#endif#ifndef FLASH_NO_INTEL_SUPPORT

⌨️ 快捷键说明

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