Mercurial > ecos
changeset 1210:786683319633
Add buffered writes - from Thomas Koeller
| author | gthomas |
|---|---|
| date | Wed, 10 Sep 2003 20:57:14 +0000 |
| parents | b33e882f6b64 |
| children | 4c8e032983ae |
| files | packages/devs/flash/amd/am29xxxxx/current/ChangeLog packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx.inl packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx_parts.inl |
| diffstat | 3 files changed, 213 insertions(+), 90 deletions(-) [+] |
line wrap: on
line diff
--- a/packages/devs/flash/amd/am29xxxxx/current/ChangeLog +++ b/packages/devs/flash/amd/am29xxxxx/current/ChangeLog @@ -1,8 +1,13 @@ +2003-09-09 Thomas Koeller <thomas.koeller@baslerweb.com> + + * include/flash_am29xxxxx.inl: + * include/flash_am29xxxxx_parts.inl: Added support for write + buffer programming. + 2003-09-04 Thomas Koeller <thomas.koeller@baslerweb.com> - * include/flash_am29xxxxx_parts.inl (CYGHWR_DEVS_FLASH_AMD_AM29LV128): - * cdl/flash_amd_am29xxxxx.cdl: - Add support for Am29LV128 part. + * include/flash_am29xxxxx_parts.inl (CYGHWR_DEVS_FLASH_AMD_AM29LV128): + * cdl/flash_amd_am29xxxxx.cdl: Add support for Am29LV128 part. 2003-08-17 Bart Veer <bartv@ecoscentric.com> @@ -15,9 +20,8 @@ 2003-08-17 Bart Veer <bartv@ecoscentri 2003-07-23 Chris Garry <cgarry@sweeneydesign.co.uk> - * include/flash_am29xxxxx_parts.inl (CYGHWR_DEVS_FLASH_AMD_AM29LV400): - * cdl/flash_amd_am29xxxxx.cdl: - Add support for Am29LV400 part. + * include/flash_am29xxxxx_parts.inl (CYGHWR_DEVS_FLASH_AMD_AM29LV400): + * cdl/flash_amd_am29xxxxx.cdl: Add support for Am29LV400 part. 2003-04-03 Jani Monoses <jani@iv.ro>
--- a/packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx.inl +++ b/packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx.inl @@ -68,6 +68,7 @@ #include <pkgconf/devs_flash_amd_am29xxxxx.h> #include <cyg/hal/hal_arch.h> #include <cyg/hal/hal_cache.h> +#include <cyg/hal/hal_misc.h> #include CYGHWR_MEMORY_LAYOUT_H #define _FLASH_PRIVATE_ @@ -80,6 +81,8 @@ #define FLASH_Reset FLASHWORD( 0xF0 ) #define FLASH_Program FLASHWORD( 0xA0 ) #define FLASH_Block_Erase FLASHWORD( 0x30 ) +#define FLASH_Load_Buffer FLASHWORD( 0x25 ) +#define FLASH_Flush_Buffer FLASHWORD( 0x29 ) #define FLASH_Data FLASHWORD( 0x80 ) // Data complement #define FLASH_Busy FLASHWORD( 0x40 ) // "Toggle" bit @@ -169,6 +172,7 @@ typedef struct flash_dev_info { cyg_uint32 banks[8]; // bank offsets, highest to lowest (lowest should be 0) // (only one entry for now, increase to support devices // with more banks). + cyg_uint32 bufsiz; // write buffer size in units of flash_data_t } flash_dev_info_t; static const flash_dev_info_t* flash_dev_info; @@ -187,6 +191,13 @@ int flash_program_buf(void* addr, void* __attribute__ ((section (".2ram.flash_program_buf"))); //---------------------------------------------------------------------------- +// Auxiliary functions +static flash_data_t * find_bank(volatile flash_data_t * base, void * addr, CYG_ADDRWORD * bo) + __attribute__ ((section (".2ram.find_bank"))); +static flash_data_t * find_sector(volatile flash_data_t * addr, unsigned long *remain_size) + __attribute__ ((section (".2ram.find_sector"))); + +//---------------------------------------------------------------------------- // Flash Query // // Only reads the manufacturer and part number codes for the first @@ -306,22 +317,8 @@ flash_erase_block(void* block, unsigned cyg_bool bootblock = false; cyg_uint32 *bootblocks = (cyg_uint32 *)0; CYG_ADDRWORD bank_offset; - BANK = ROM = (volatile flash_data_t*)((unsigned long)block & flash_dev_info->base_mask); - - // If this is a banked device, find the bank where commands should - // be addressed to. - if (flash_dev_info->banked) { - int b = 0; - bank_offset = (unsigned long)block & ~(flash_dev_info->block_size-1); - bank_offset -= (unsigned long) ROM; - for(;;) { - if (bank_offset >= flash_dev_info->banks[b]) { - BANK = (volatile flash_data_t*) ((unsigned long)ROM + flash_dev_info->banks[b]); - break; - } - b++; - } - } + ROM = (volatile flash_data_t*)((unsigned long)block & flash_dev_info->base_mask); + BANK = find_bank(ROM, block, &bank_offset); f_s0 = FLASH_P2V(BANK); f_s1 = FLASH_P2V(BANK + FLASH_Setup_Addr1); @@ -434,50 +431,75 @@ flash_program_buf(void* addr, void* data { volatile flash_data_t* ROM; volatile flash_data_t* BANK; + volatile flash_data_t* SECT; volatile flash_data_t* data_ptr = (volatile flash_data_t*) data; - volatile flash_data_t* addr_v; volatile flash_data_t* addr_p = (flash_data_t*) addr; + volatile flash_data_t* addr_v = FLASH_P2V(addr_p); volatile flash_data_t *f_s1, *f_s2; CYG_ADDRWORD bank_offset; int timeout; int res = FLASH_ERR_OK; + const CYG_ADDRWORD mask = + flash_dev_info->bufsiz * sizeof (flash_data_t) - 1; + unsigned long rem_sect_size; // check the address is suitably aligned if ((unsigned long)addr & (CYGNUM_FLASH_INTERLEAVE * CYGNUM_FLASH_WIDTH / 8 - 1)) return FLASH_ERR_INVALID; // Base address of device(s) being programmed. - BANK = ROM = (volatile flash_data_t*)((unsigned long)addr_p & flash_dev_info->base_mask); - - // If this is a banked device, find the bank where commands should - // be addressed to. - if (flash_dev_info->banked) { - int b = 0; - bank_offset = (unsigned long)addr & ~(flash_dev_info->block_size-1); - bank_offset -= (unsigned long) ROM; - for(;;) { - if (bank_offset >= flash_dev_info->banks[b]) { - BANK = (volatile flash_data_t*) ((unsigned long)ROM + flash_dev_info->banks[b]); - break; - } - b++; - } - } + ROM = (volatile flash_data_t*)((unsigned long)addr_p & flash_dev_info->base_mask); + BANK = find_bank(ROM, addr, &bank_offset); f_s1 = FLASH_P2V(BANK + FLASH_Setup_Addr1); f_s2 = FLASH_P2V(BANK + FLASH_Setup_Addr2); + rem_sect_size = 0; + len /= sizeof (flash_data_t); while (len > 0) { flash_data_t state; + unsigned int nwords; - addr_v = FLASH_P2V(addr_p++); + addr_v = FLASH_P2V(addr_p); + + if (flash_dev_info->bufsiz > 1) { + // Assume buffer size is power of two + unsigned int i; + + if (rem_sect_size == 0) { + SECT = find_sector(addr_v, &rem_sect_size); + rem_sect_size /= sizeof (flash_data_t); + } + + // Computer word count to write + nwords = flash_dev_info->bufsiz + - (((CYG_ADDRWORD) addr_v & mask) / sizeof (flash_data_t)); + if (nwords > len) + nwords = len; - // Program data [byte] - 4 step sequence - *f_s1 = FLASH_Setup_Code1; - *f_s2 = FLASH_Setup_Code2; - *f_s1 = FLASH_Program; - *addr_v = *data_ptr; + // Initiate buffered write + *f_s1 = FLASH_Setup_Code1; + *f_s2 = FLASH_Setup_Code2; + *SECT = FLASH_Load_Buffer; + *SECT = nwords - 1; + // Load data into write buffer, flush buffer + for(i = 0; i < nwords; i++) + *addr_v++ = *data_ptr++; + --addr_v; --data_ptr; + *SECT = FLASH_Flush_Buffer; + rem_sect_size -= nwords; + } else { + // Program data [byte] - 4 step sequence + *f_s1 = FLASH_Setup_Code1; + *f_s2 = FLASH_Setup_Code2; + *f_s1 = FLASH_Program; + *addr_v = *data_ptr; + + nwords = 1; + } + + addr_p += nwords; timeout = CYGNUM_FLASH_TIMEOUT_PROGRAM; while (true) { state = *addr_v; @@ -502,7 +524,7 @@ flash_program_buf(void* addr, void* data if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY; break; } - len -= sizeof(*data_ptr); + len -= nwords; } // Ideally, we'd want to return not only the failure code, but also @@ -510,4 +532,57 @@ flash_program_buf(void* addr, void* data return res; } +static flash_data_t * +find_bank(volatile flash_data_t * base, void * addr, CYG_ADDRWORD * bo) +{ + volatile flash_data_t * res = base; + + if (flash_dev_info->banked) { + int b = 0; + *bo = (unsigned long)addr & ~(flash_dev_info->block_size-1); + *bo -= (unsigned long) base; + for(;;) { + if (*bo >= flash_dev_info->banks[b]) { + res = (volatile flash_data_t*) ((unsigned long)base + flash_dev_info->banks[b]); + break; + } + b++; + } + } + + return res; +} + +static flash_data_t * +find_sector(volatile flash_data_t * addr, unsigned long *remain_size) +{ + const CYG_ADDRESS mask = flash_dev_info->block_size - 1; + const CYG_ADDRESS a = (CYG_ADDRESS) addr; + const CYG_ADDRESS base = a & flash_dev_info->base_mask; + const CYG_ADDRESS res = a & ~mask; + + *remain_size = flash_dev_info->block_size - (a & mask); + + if (flash_dev_info->bootblock) { + cyg_uint32 * bootblocks = flash_dev_info->bootblocks; + while (*bootblocks != _LAST_BOOTBLOCK) { + int ls = flash_dev_info->block_size; + + if (*bootblocks++ == (res - base)) { + while (res + *bootblocks < a) { + res += *bootblocks++; + } + } else { + // Skip over segment + while ((ls -= *bootblocks++) > 0) ; + } + } + + if (*bootblocks != _LAST_BOOTBLOCK) + *remain_size = *bootblocks - (a - res); + } + + return (flash_data_t *) res; +} + #endif // CYGONCE_DEVS_FLASH_AMD_AM29XXXXX_INL
--- a/packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx_parts.inl +++ b/packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx_parts.inl @@ -88,7 +88,8 @@ device_size: 0x80000 * CYGNUM_FLASH_INTERLEAVE, base_mask : ~(0x80000 * CYGNUM_FLASH_INTERLEAVE - 1), bootblock : false, - banked : false + banked : false, + bufsiz : 1 }, #endif #ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV160 @@ -106,7 +107,8 @@ 0x004000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, { // MBM29LV160-B | AM29LV160-B device_id : FLASHWORD(0x49), @@ -122,7 +124,8 @@ 0x008000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, #endif #ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV200 @@ -140,7 +143,8 @@ 0x004000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, { // AM29LV200-B device_id : FLASHWORD(0xbf), @@ -156,7 +160,8 @@ 0x008000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, #endif #ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV320D @@ -178,7 +183,8 @@ 0x002000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, { // AM29LV320D device_id : FLASHWORD(0xF9), @@ -198,7 +204,8 @@ 0x002000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, #endif #ifdef CYGHWR_DEVS_FLASH_AMD_AM29DL322D @@ -223,7 +230,8 @@ banked : true, banks : { 0x380000 * CYGNUM_FLASH_INTERLEAVE, 0 - } + }, + bufsiz : 1 }, { // AM29DL322D-B device_id : FLASHWORD(0x56), @@ -246,7 +254,8 @@ banked : true, banks : { 0x80000 * CYGNUM_FLASH_INTERLEAVE, 0 - } + }, + bufsiz : 1 }, #endif #ifdef CYGHWR_DEVS_FLASH_AMD_AM29DL323D @@ -271,7 +280,8 @@ banked : true, banks : { 0x300000 * CYGNUM_FLASH_INTERLEAVE, 0 - } + }, + bufsiz : 1 }, { // AM29DL323D-B device_id : FLASHWORD(0x53), @@ -294,7 +304,8 @@ banked : true, banks : { 0x100000 * CYGNUM_FLASH_INTERLEAVE, 0 - } + }, + bufsiz : 1 }, #endif #ifdef CYGHWR_DEVS_FLASH_AMD_AM29DL324D @@ -319,7 +330,8 @@ banked : true, banks : { 0x200000 * CYGNUM_FLASH_INTERLEAVE, 0 - } + }, + bufsiz : 1 }, { // AM29DL324D-B device_id : FLASHWORD(0x5f), @@ -342,7 +354,8 @@ banked : true, banks : { 0x200000 * CYGNUM_FLASH_INTERLEAVE, 0 - } + }, + bufsiz : 1 }, #endif #ifdef CYGHWR_DEVS_FLASH_AMD_AM29DL640D @@ -381,7 +394,8 @@ 0x0400000 * CYGNUM_FLASH_INTERLEAVE, 0x0100000 * CYGNUM_FLASH_INTERLEAVE, 0 - } + }, + bufsiz : 1 } #endif #ifdef CYGHWR_DEVS_FLASH_AMD_AM29F800 @@ -399,7 +413,8 @@ 0x04000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, { // AM29F800-B device_id : FLASHWORD(0x58), @@ -415,7 +430,8 @@ 0x008000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, #endif #ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV800 @@ -433,7 +449,8 @@ 0x04000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, { // AM29LV800-B device_id : FLASHWORD(0x5b), @@ -449,7 +466,8 @@ 0x008000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, #endif #ifdef CYGHWR_DEVS_FLASH_AMD_TC58FVB800 @@ -467,7 +485,8 @@ 0x008000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, #endif @@ -481,7 +500,8 @@ device_size: 0x1000000 * CYGNUM_FLASH_INTERLEAVE, base_mask : ~(0x1000000 * CYGNUM_FLASH_INTERLEAVE - 1), bootblock : false, - banked : false + banked : false, + bufsiz : 16 }, #endif #ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV160 @@ -499,7 +519,8 @@ 0x004000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, { // MBM29LV160-B | AM29LV160-B device_id : FLASHWORD(0x2249), @@ -515,7 +536,8 @@ 0x008000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, #endif #ifdef CYGHWR_DEVS_FLASH_AMD_AM29PL160 @@ -533,7 +555,8 @@ 0x038000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, #endif #ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV200 @@ -551,7 +574,8 @@ 0x004000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, { // AM29LV200-B device_id : FLASHWORD(0x22bf), @@ -567,7 +591,8 @@ 0x008000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, #endif #ifdef CYGHWR_DEVS_FLASH_ST_M29W200B @@ -585,7 +610,8 @@ 0x004000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, { // ST M29W200BB device_id : FLASHWORD(0x0057), @@ -601,7 +627,8 @@ 0x008000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, #endif #ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV320D @@ -623,7 +650,8 @@ 0x002000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, { // AM29LV320D device_id : FLASHWORD(0x22F9), @@ -643,7 +671,8 @@ 0x002000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, #endif #ifdef CYGHWR_DEVS_FLASH_AMD_AM29DL322D @@ -668,7 +697,8 @@ banked : true, banks : { 0x380000 * CYGNUM_FLASH_INTERLEAVE, 0 - } + }, + bufsiz : 1 }, { // AM29DL322D-B device_id : FLASHWORD(0x2256), @@ -691,7 +721,8 @@ banked : true, banks : { 0x80000 * CYGNUM_FLASH_INTERLEAVE, 0 - } + }, + bufsiz : 1 }, #endif #ifdef CYGHWR_DEVS_FLASH_AMD_AM29DL323D @@ -716,7 +747,8 @@ banked : true, banks : { 0x300000 * CYGNUM_FLASH_INTERLEAVE, 0 - } + }, + bufsiz : 1 }, { // AM29DL323D-B device_id : FLASHWORD(0x2253), @@ -739,7 +771,8 @@ banked : true, banks : { 0x100000 * CYGNUM_FLASH_INTERLEAVE, 0 - } + }, + bufsiz : 1 }, #endif #ifdef CYGHWR_DEVS_FLASH_AMD_AM29DL324D @@ -764,7 +797,8 @@ banked : true, banks : { 0x200000 * CYGNUM_FLASH_INTERLEAVE, 0 - } + }, + bufsiz : 1 }, { // AM29DL324D-B device_id : FLASHWORD(0x225f), @@ -787,7 +821,8 @@ banked : true, banks : { 0x200000 * CYGNUM_FLASH_INTERLEAVE, 0 - } + }, + bufsiz : 1 }, #endif #ifdef CYGHWR_DEVS_FLASH_AMD_AM29DL640D @@ -826,7 +861,8 @@ 0x400000 * CYGNUM_FLASH_INTERLEAVE, 0x100000 * CYGNUM_FLASH_INTERLEAVE, 0 - } + }, + bufsiz : 1 } #endif #ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV400 @@ -844,7 +880,8 @@ 0x04000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, { // AM29LV400-B device_id : FLASHWORD(0x22ba), @@ -860,7 +897,8 @@ 0x008000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, #endif #ifdef CYGHWR_DEVS_FLASH_AMD_AM29F800 @@ -878,7 +916,8 @@ 0x04000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, { // AM29F800-B device_id : FLASHWORD(0x2258), @@ -894,7 +933,8 @@ 0x008000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, #endif #ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV800 @@ -912,7 +952,8 @@ 0x04000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, { // AM29LV800-B device_id : FLASHWORD(0x225b), @@ -928,7 +969,8 @@ 0x008000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, #endif #ifdef CYGHWR_DEVS_FLASH_AMD_AM29LV640 @@ -939,7 +981,8 @@ device_size: 0x800000 * CYGNUM_FLASH_INTERLEAVE, base_mask : ~(0x800000 * CYGNUM_FLASH_INTERLEAVE - 1), bootblock : false, - banked : false + banked : false, + bufsiz : 1 }, #endif #ifdef CYGHWR_DEVS_FLASH_AMD_TC58FVB800 @@ -957,7 +1000,8 @@ 0x008000 * CYGNUM_FLASH_INTERLEAVE, _LAST_BOOTBLOCK }, - banked : false + banked : false, + bufsiz : 1 }, #endif
