📄 flash.c
字号:
static int program_MICRON_sector(U32 addr, BYTE *source, U32 sectorSize);static int erase_MICRON_sector(U32 addr, U32 sectorSize);static int program_MICRON_byte(U32 addr, BYTE byte);static int program_MICRON16_sector(U32 addr, BYTE *source, U32 sectorSize);static int erase_MICRON16_sector(U32 addr, U32 sectorSize);#endif#ifndef FLASH_NO_SST_SUPPORTstatic int program_SST_sector(U32 addr, BYTE *source, U32 sectorSize); static int erase_SST_sector(U32 addr, U32 sectorSize); static int program_SST_byte(U32 addr, BYTE byte); #endif/*** Miscellaneous routines*/#if !defined (BOOT_ROM) || !defined (NO_CONFIGINFO_FLASH)static U32 flash_find_sector_size (U32 typeIndex, U32 chipOffset, U32 *sectorStartOffset);static int modify_sector(BYTE **srcp, U32 *dstp, U32 *nump);static int set_new_sector(U32 dst);static int overwrite_flash_bytes (BYTE **srcp, U32 *dstp, U32 *nump);static int flash_identify_chips (void);static U32 read_chip_id_info (U32 chip, U32 *pid, U32 *protectMask);#endif#ifdef FLASH_WINDOW_REGISTER_SHAREDstatic void flash_window_select(U32 _addr);#endif/*====================================================================*//* Variables *//*====================================================================*//*** Global data*/#if !defined (BOOT_ROM)U32 flashfsTraceLevel = 0;#endif/*** Private data*/#if !defined (BOOT_ROM) || !defined (NO_CONFIGINFO_FLASH)static BYTE *flashSectorCopy = NULL;static U32 currentSector = ~0; /* no sector to date */static U32 currentSectorSize;static BITS currentType;static U32 currentTypeIndex;static BOOL flashChipsChecked = FALSE;static BOOL flashChipsBad = TRUE; /* By default */static U32 largestSectorSize = 0UL;#ifndef FLASH_NO_ATMEL_SUPPORTstatic U32 atmel_keep_alive_ctr = 0;#endif#ifndef FLASH_NO_SST_SUPPORTstatic U32 sst_keep_alive_ctr = 0;#endif#endif#if NUM_FLASH_DEVICES < 1#error "Must have at least one flash device to compile this module"#endif/*** Supported FLASH types (note that the number of flash types does *not* include the** unknown one).**** Comment out types as required - memory allocated at run-time according to the** the largest sector size in this table. */static const FlashType flashTypes [] ={#ifndef FLASH_NO_ATMEL_SUPPORT { AT29C1024_CHIP_ID, FALSE, TRUE, 512UL * 256UL, "Atmel", "AT29C1024", { {256UL, 512UL}, {0UL, 0UL}, {0UL, 0UL}, {0UL, 0UL}}, program_ATMEL_sector16, NULL, NULL }, { AT29C040_CHIP_ID, FALSE, FALSE, 512UL * 1024UL, "Atmel", "AT29C040", { {512UL, 1024UL}, {0UL, 0UL}, {0UL, 0UL}, {0UL, 0UL}}, program_ATMEL_sector, NULL, NULL }, { AT29C040A_CHIP_ID, FALSE, FALSE, 512UL * 1024UL, "Atmel", "AT29C040A", { {256UL, 2048UL}, {0UL, 0UL}, {0UL, 0UL}, {0UL, 0UL}}, program_ATMEL_sector, NULL, NULL }, { W29C040_CHIP_ID, FALSE, FALSE, 512UL * 1024UL, "Winbond","W29C040", { {256UL, 2048UL}, {0UL, 0UL}, {0UL, 0UL}, {0UL, 0UL}}, program_ATMEL_sector, NULL, NULL },#endif#ifndef FLASH_NO_AMD_SUPPORT { AT49BV1614_CHIP_ID, TRUE, FALSE, 2048UL * 1024UL, "Atmel", "AT49BV1614", { {8192UL, 8UL}, {32768UL, 2UL}, {65536UL, 30UL}}, program_AMD_sector, program_AMD_byte, erase_AMD_sector }, { AT49BV1614T_CHIP_ID, TRUE, TRUE, 2048UL * 1024UL, "Atmel", "AT49BV1614T", { {65536UL, 30UL}, {32768UL, 2UL}, {8192UL, 8UL}}, program_AMD_sector16, NULL, erase_AMD_sector16 }, { AM29F040_CHIP_ID, FALSE, FALSE, 512UL * 1024UL, "AMD", "29F040", { {65536UL, 8UL}, {0UL, 0UL}, {0UL, 0UL}, {0UL, 0UL}}, program_AMD_sector, program_AMD_byte, erase_AMD_sector }, { AM29LV081B_CHIP_ID, FALSE, FALSE, 1024UL * 1024UL, "AMD", "29LV081B", { {65536UL, 16UL}, {0UL, 0UL}, {0UL, 0UL}, {0UL, 0UL}}, program_AMD_sector, program_AMD_byte, erase_AMD_sector }, { AM29LV040B_CHIP_ID, FALSE, FALSE, 512UL * 1024UL, "AMD", "29LV040", { {65536UL, 8UL}, {0UL, 0UL}, {0UL, 0UL}, {0UL, 0UL}}, program_AMD_sector, program_AMD_byte, erase_AMD_sector }, { AM29LV017B_CHIP_ID, FALSE, FALSE, 2048UL * 1024UL, "AMD", "29LV017B", { {65536UL, 32UL}, {0UL, 0UL}, {0UL, 0UL}, {0UL, 0UL}}, program_AMD_sector, program_AMD_byte, erase_AMD_sector }, { AM29LV116BB_CHIP_ID, FALSE, FALSE, 2048UL * 1024UL, "AMD", "29LV116BB", { {16384UL, 1UL}, {8192UL, 2UL}, {32768UL, 1UL}, {65536UL, 31UL}}, program_AMD_sector, program_AMD_byte, erase_AMD_sector }, { AM29LV116BT_CHIP_ID, FALSE, FALSE, 2048UL * 1024UL, "AMD", "29LV116BT", { {65536UL, 31UL}, {32768UL, 1UL}, {8192UL, 2UL}, {16384UL, 1UL}}, program_AMD_sector, program_AMD_byte, erase_AMD_sector }, { AM29LV800BB_CHIP_ID, TRUE, FALSE, 1024UL * 1024UL, "AMD", "29LV800BB", { {16384UL, 1UL}, {8192UL, 2UL}, {32768UL, 1UL}, {65536UL, 15UL}}, program_AMD_sector, program_AMD_byte, erase_AMD_sector }, { AM29LV800BT_CHIP_ID, TRUE, FALSE, 1024UL * 1024UL, "AMD", "29LV800BT", { {65536UL, 15UL}, {32768UL, 1UL}, {8192UL, 2UL}, {16384UL, 1UL}}, program_AMD_sector, program_AMD_byte, erase_AMD_sector }, { AM29LV160BB_CHIP_ID, TRUE, FALSE, 2048UL * 1024UL, "AMD", "29LV160BB", { {16384UL, 1UL}, {8192UL, 2UL}, {32768UL, 1UL}, {65536UL, 31UL}}, program_AMD_sector, program_AMD_byte, erase_AMD_sector }, { AM29LV160BT_CHIP_ID, TRUE, FALSE, 2048UL * 1024UL, "AMD", "29LV160BT", { {65536UL, 31UL}, {32768UL, 1UL}, {8192UL, 2UL}, {16384UL, 1UL}}, program_AMD_sector, program_AMD_byte, erase_AMD_sector }, { MX29F040_CHIP_ID, FALSE, FALSE, 512UL * 1024UL, "MXIC", "29F040", { {65536UL, 8UL}, {0UL, 0UL}, {0UL, 0UL}, {0UL, 0UL}}, program_AMD_sector, program_AMD_byte, erase_AMD_sector }, { MX29F800B_CHIP_ID, TRUE, FALSE, 1024UL * 1024UL, "MXIC", "29F800B", { {16384UL, 1UL}, {8192UL, 2UL}, {32768UL, 1UL}, {65536UL, 15UL}}, program_AMD_sector, program_AMD_byte, erase_AMD_sector }, { M29W008T_CHIP_ID, FALSE, FALSE, 1024UL * 1024UL, "ST", "M29W008T", { {65536UL, 15UL}, {32768UL, 1UL}, {8192UL, 2UL}, {16384UL, 1UL}}, program_AMD_sector, program_AMD_byte, erase_AMD_sector }, { M29W008B_CHIP_ID, FALSE, FALSE, 1024UL * 1024UL, "ST", "M29W008B", { {16384UL, 1UL}, {8192UL, 2UL}, {32768UL, 1UL}, {65536UL, 15UL}}, program_AMD_sector, program_AMD_byte, erase_AMD_sector }, { M29W040B_CHIP_ID, FALSE, FALSE, 512UL * 1024UL, "ST", "M29W040B", { {65536UL, 8UL}, {0UL, 0UL}, {0UL, 0UL}, {0UL, 0UL}}, program_AMD_sector, program_AMD_byte, erase_AMD_sector }, { M29W800AT_CHIP_ID, TRUE, FALSE, 1024UL * 1024UL, "ST", "M29W800AT", { {65536UL, 15UL}, {32768UL, 1UL}, {8192UL, 2UL}, {16384UL, 1UL} }, program_AMD_sector, program_AMD_byte, erase_AMD_sector }, { M29W800AB_CHIP_ID, TRUE, FALSE, 1024UL * 1024UL, "ST", "M29W800AB", { {16384UL, 1UL}, {8192UL, 2UL}, {32768UL, 1UL}, {65536UL, 15UL} }, program_AMD_sector, program_AMD_byte, erase_AMD_sector }, { BM29F040_CHIP_ID, FALSE, FALSE, 512UL * 1024UL, "BRIGHT", "29F040", { {65536UL, 8UL}, {0UL, 0UL}, {0UL, 0UL}, {0UL, 0UL}}, program_AMD_sector, program_AMD_byte, erase_AMD_sector }, { EN29F040_CHIP_ID, FALSE, FALSE, 512UL * 1024UL, "EONC", "29F040", { {65536UL, 8UL}, {0UL, 0UL}, {0UL, 0UL}, {0UL, 0UL}}, program_AMD_sector, program_AMD_byte, erase_AMD_sector }, { AC29F040_CHIP_ID, FALSE, FALSE, 512UL * 1024UL, "AMIC", "29F040", { {65536UL, 8UL}, {0UL, 0UL}, {0UL, 0UL}, {0UL, 0UL}}, program_AMD_sector, program_AMD_byte, erase_AMD_sector }, { SST39VF080Q_CHIP_ID, FALSE, FALSE, 1024UL * 1024UL, "SST", "39VF080Q", { {4096UL, 256UL}, {0UL, 0UL}, {0UL, 0UL}, {0UL, 0UL}}, program_AMD_sector, program_AMD_byte, erase_AMD_sector }, { SST39VF016Q_CHIP_ID, FALSE, FALSE, 2048UL * 1024UL, "SST", "39VF016Q", { {4096UL, 512UL}, {0UL, 0UL}, {0UL, 0UL}, {0UL, 0UL}}, program_AMD_sector, program_AMD_byte, erase_AMD_sector },#endif#ifndef FLASH_NO_INTEL_SUPPORT { MX29L1611B_CHIP_ID, TRUE, FALSE, 2048UL * 1024UL, "MXIC", "29L1611", { {65536UL, 32UL}, {0UL, 0UL}, {0UL, 0UL}, {0UL, 0UL}}, program_MICRON16_sector, NULL, erase_MICRON16_sector }, { MT28F008B3B_CHIP_ID, FALSE, FALSE, 1024UL * 1024UL, "Micron", "28F008B3-B", { {16384UL, 1UL}, {8192UL, 2UL}, {98304UL, 1UL}, {131072UL, 7UL}}, program_MICRON_sector, program_MICRON_byte, erase_MICRON_sector }, { MT28F008B3T_CHIP_ID, FALSE, FALSE, 1024UL * 1024UL, "Micron", "28F008B3-T", { {131072UL, 7UL}, {98304UL, 1UL}, {8192UL, 2UL}, {16384UL, 1UL}}, program_MICRON_sector, program_MICRON_byte, erase_MICRON_sector }, { INT28F800B5B_CHIP_ID, TRUE, FALSE, 1024UL * 1024UL, "Intel", "28F800B", { {16384UL, 1UL}, {8192UL, 2UL}, {98304UL, 1UL}, {131072UL, 7UL}}, program_MICRON_sector, program_MICRON_byte, erase_MICRON_sector }, { INT28F320J5_CHIP_ID, TRUE, FALSE, 4096UL * 1024UL, "Intel", "28F320J5", { {131072UL,32UL}, {0UL, 0UL}, {0UL, 0UL}, {0UL, 0UL}}, program_MICRON_sector, program_MICRON_byte, erase_MICRON_sector }, { LH28F160BVE_CHIP_ID, TRUE, FALSE, 2048UL * 1024UL, "Sharp", "LH28F160", { {8192UL, 8UL}, {65536L, 31UL}, {0UL, 0UL}, {0UL, 0UL}}, program_MICRON_sector, program_MICRON_byte, erase_MICRON_sector },#endif#ifndef FLASH_NO_SST_SUPPORT { SST28SF040A_CHIP_ID, FALSE, FALSE, 512UL * 1024UL, "SST", "28SF040A", { {256UL, 2048UL}, {0UL, 0UL}, {0UL, 0UL}, {0UL, 0UL}}, program_SST_sector, program_SST_byte, erase_SST_sector },#endif /* ** Special entry for use when reporting types. */ { UNKNOWN_CHIP_ID, FALSE, FALSE, 0UL, "UNKNOWN", "?", { {0UL, 0UL},{0UL, 0UL}, {0UL, 0UL},{0UL, 0UL}}, NULL, NULL, NULL }};#define NUMBER_FLASH_TYPES ((sizeof (flashTypes) / sizeof (flashTypes [0])) - 1)/*** SMALLEST_FLASH_SIZE must be the lowest common denominator of the sizes of the** chips in the table above, excluding the unknown device.*/#define SMALLEST_FLASH_SHIFT (17) /* 128k */#define SMALLEST_FLASH_SIZE (1 << SMALLEST_FLASH_SHIFT)/*** LARGEST_PEROM_SECTOR_SIZE defines the size of the largest sector for a ** PEROM (e.g. as manufactured by Atmel). At present the only use for this is** when erasing memory and the allocation occurs on the stack (avoiding malloc).** Any significant change in size should either allocate a buffer at start-up** or share the flashSectorCopy buffer.*/#define LARGEST_PEROM_SECTOR_SIZE 512UL/*** Assumes that flash chips are a power of two long (shifts** are faster than a division).*/#define FLASH_DEVICE(_a) (deviceLutTable [(_a) >> SMALLEST_FLASH_SHIFT])/*** How to select a flash device for reading: note that the presence of paged** flash doesn't mandate that all the flash in the system is paged.*/#if defined(PAGED_FLASH) && !defined(SIMULATOR)#if defined (FLASH_COMBINED_PAGE_WINDOW_REGISTER)/*** A combined paging and windowing register. Simply store the current page until flash is actually addressed.*/static BYTE pageRegister; #define SELECT_FLASH_DEVICE(_device) assert (_device < NUM_FLASH_DEVICES); \ if (FLASH_NOPAGE != flashDevices [_device].flashPage) \ { \ pageRegister = flashDevices [_device].flashPage; \ }#else #define SELECT_FLASH_DEVICE(_device) assert (_device < NUM_FLASH_DEVICES); \ if (FLASH_NOPAGE != flashDevices [_device].flashPage) \ { \ (*(volatile BYTE *)FLASH_SELECT_REGISTER) = flashDevices [_device].flashPage; \ }#endif#else #define SELECT_FLASH_DEVICE(_device)#endif/*** Simulator definitions that override previous definitions.*/#ifdef SIMULATOR#include "sim_flash.h"#undef FLASH_READ_RAW#define FLASH_READ_RAW(_addr, _device) simulator_flash_read_byte(_addr, _device)#undef FLASH_WRITE_RAW#define FLASH_WRITE_RAW(_byte, _addr, _device) simulator_flash_write_byte(_byte, _addr, _device)#undef FLASH_READ_RAW16#define FLASH_READ_RAW16(_addr, _device) (U16)((simulator_flash_read_byte(_addr, _device) << 8) + simulator_flash_read_byte((_addr) + 1, _device))#undef FLASH_WRITE_RAW16#define FLASH_WRITE_RAW16(_halfword, _addr, _device) { simulator_flash_write_byte(((_halfword) >> 8) & 0xff, _addr, _device); simulator_flash_write_byte((_halfword) & 0xff, (_addr) + 1, _device); } #endif /* SIMULATOR *//*** Configuration of flash memory within the system*/static const FlashDevice flashDevices [NUM_FLASH_DEVICES] = {#ifdef FLASH0 { FLASH0_16, (volatile BYTE *) FLASH0, (volatile BYTE *) FLASH0WRITE, FLASH0_SIZE, FLASH0_PAGE, 0UL },#endif#ifdef FLASH1 { FLASH1_16, (volatile BYTE *) FLASH1, (volatile BYTE *) FLASH1WRITE, FLASH1_SIZE, FLASH1_PAGE, FLASH0_SIZE },#endif#ifdef FLASH2 { FLASH2_16, (volatile BYTE *) FLASH2, (volatile BYTE *) FLASH2WRITE, FLASH2_SIZE, FLASH2_PAGE, FLASH0_SIZE + FLASH1_SIZE },#endif#ifdef FLASH3 { FLASH3_16, (volatile BYTE *) FLASH3, (volatile BYTE *) FLASH3WRITE, FLASH3_SIZE, FLASH3_PAGE, FLASH0_SIZE + FLASH1_SIZE + FLASH2_SIZE },#endif#ifdef FLASH4 { FLASH4_16, (volatile BYTE *) FLASH4, (volatile BYTE *) FLASH4WRITE, FLASH4_SIZE, FLASH4_PAGE, FLASH0_SIZE + FLASH1_SIZE + FLASH2_SIZE + FLASH3_SIZE },#endif};static ActualFlashType actualFlashTypes [NUM_FLASH_DEVICES];/*** Look-up table of logical address to device id*/static BYTE deviceLutTable [TOTAL_FLASH_SIZE / SMALLEST_FLASH_SIZE];/*** Whether the system has been initialised.*/static BOOL initialised = FALSE;/*====================================================================*//* Implementation *//*====================================================================*//*** Name: flash_window_select**** Selects flash window using a read/modify/write of the window select ** register. We do this in a critical section because the register** is shared. */#ifdef FLASH_WINDOW_REGISTER_SHAREDstatic void flash_window_select(U32 _addr){ FLASH_WINDOW_REGISTER_SIZE *window_ptr, window_reg; BITS fiqcrit; fiqcrit = atmos_startfiqcritical(); window_ptr = (FLASH_WINDOW_REGISTER_SIZE *) FLASH_WINDOW_SELECT_REGISTER; window_reg = *window_ptr & ~FLASH_WINDOW_REGISTER_MASK; *window_ptr = (((_addr) >> (FLASH_WINDOW_BITS - FLASH_WINDOW_REGISTER_OFFSET)) & FLASH_WINDOW_REGISTER_MASK) | window_reg; atmos_endfiqcritical(fiqcrit);}#endif/*** Name: flash_initialise**** Purpose: Initialise the lowest level of the flash support system**** THIS MUST BE CALLED BEFORE CALLING ANY OTHER FLASH ROUTINE** ** Arguments:** allocateAllowed Allowed to allocate scratch buffer**** Result:** <Nothing>***/void flash_initialise (BOOL allocateAllowed){ /* ** Initialise run-time tables */ if (!initialised) { U32 i; BYTE index = 0; U32 base = 0UL; /* ** Initialise the lookup table (for mapping logical addresses to physical ** chips). */ for (i = 0; i < NUM_FLASH_DEVICES; i++) { U32 limit = flashDevices [i].logicalBase + flashDevices [i].size; while (base < limit) { deviceLutTable [index++] = i; base += SMALLEST_FLASH_SIZE; assert (index <= sizeof (deviceLutTable)); } assert (flashDevices [i].physicalBaseRead != 0); assert (flashDevices [i].physicalBaseWrite != 0); /* ** As yet the types of chips in the system are unknown as is their ** protection state. */ actualFlashTypes [i].typeIndex = NUMBER_FLASH_TYPES; actualFlashTypes [i].writeMask = 0; } /* ** Determine size of largest supported FLASH sector */ for (i = 0; i < NUMBER_FLASH_TYPES; i++) { U32 j;#ifdef DEBUG U32 sum = 0;#endif /* ** Some debug checking of compiled parameters */ assert (flashTypes [i].size >= SMALLEST_FLASH_SIZE); assert ((flashTypes [i].size % SMALLEST_FLASH_SIZE) == 0); /* Not LCD */ assert (flashTypes [i].sectors [0].size != 0); /* First entry must be defined */ assert (flashTypes [i].sectors [0].numberSectors != 0); /* ** Find the largest sector size and allocate that much memory for the (cached) ** sector. */ for (j = 0; j < NUMBER_DIFFERENT_SECTOR_SIZES; j++) { if (flashTypes [i].sectors [j].size > largestSectorSize) { largestSectorSize = flashTypes [i].sectors [j].size; }#ifdef DEBUG sum += flashTypes [i].sectors [j].size * flashTypes [i].sectors [j].numberSectors;#endif }#ifdef DEBUG assert (sum == flashTypes [i].size);#endif }#if defined (BOOT_ROM) /* ** "Relocate" function pointers into uncached space - avoids problems in ** some chips when cache is unused. */ for (i = 0; i < NUMBER_FLASH_TYPES; i++) { U32 *addr; addr = (U32 *) &flashTypes [i].program_sector; if (*addr != 0) { *addr += UNCACHEDRAMOFFSET; } addr = (U32 *) &flashTypes [i].program_byte; if (*addr != 0) { *addr += UNCACHEDRAMOFFSET; } addr = (U32 *) &flashTypes [i].erase_sector; if (*addr != 0) { *addr += UNCACHEDRAMOFFSET; } }#endif initialised = TRUE; }#if defined (BOOT_ROM) && defined (NO_CONFIGINFO_FLASH) UNUSED (allocateAllowed);#else /* ** Allocate memory for "cache" buffer if permissible. */ if (allocateAllowed && (NULL == flashSectorCopy)) { if (largestSectorSize != 0) { flashSectorCopy = (BYTE *) malloc(largestSectorSize); if (NULL == flashSectorCopy) { TRACE1 ("%C: warning - No memory (%d bytes) for programming buffer failed, no flash updates possible\n", largestSectorSize); } } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -