--- devs/flash/intel/strata/current/ChangeLog 29 May 2003 10:52:54 -0000 1.1.1.1 +++ devs/flash/intel/strata/current/ChangeLog 19 Jun 2003 13:10:23 -0000 1.3 @@ -1,3 +1,8 @@ +2003-06-19 Ian Campbell + + * src/*: s/HAL_FLASH_WRITE/CYGHWR_STRATA_WRITE/ and + s/HAL_FLASH_READ/CYGHWR_STRATA_READ/. Made work with newest flash interface. + 2003-05-02 Jani Monoses * src/strata.c: Switch to using generic flash_query_dev. @@ -22,6 +27,27 @@ * src/flash_query.c (flash_query): * src/flash_program_buf.c (flash_program_buf): Cache enabling and disabling are already handled by generic flash + +2002-09-26 Ian Campbell + + * src/flash_erase_block.c: + * src/flash_lock_block.c: + * src/flash_program_buf.c: Use CYGNUM_FLASH_BANK_MASK in + place of CYGNUM_FLASH_BASE_MASK to find the start of the chip. + + * src/flash_query.c: flash_query should return void not int. + + * src/flash_unlock_block.c: Use CYGNUM_FLASH_BANK_MASK and + CYGNUM_FLASH_BANKS to unlock the correct chip. + + * src/strata.c: Account for multiple banks specified by + CYGNUM_FLASH_BANKS. + + * src/strata.h: Document CYGNUM_FLASH_BANK_MASK and + CYGNUM_FLASH_BANKS and setup defaults such that a single bank is + used. Remove an extra ; from the definition of FLASHWORD in + certain configurations. Fix a typo which ignored + CYGNUM_FLASH_DEVICES == 4 because == 2 was tested twice. 2002-08-12 Mark Salter --- devs/flash/intel/strata/current/cdl/flash_strata.cdl 29 May 2003 10:52:54 -0000 1.1.1.1 +++ devs/flash/intel/strata/current/cdl/flash_strata.cdl 29 May 2003 13:26:30 -0000 1.2 @@ -55,6 +55,7 @@ cdl_package CYGPKG_DEVS_FLASH_STRATA { parent CYGPKG_IO_FLASH active_if CYGPKG_IO_FLASH + implements CYGHWR_IO_FLASH_DEVICE_V2 implements CYGHWR_IO_FLASH_DEVICE # implements CYGHWR_IO_FLASH_DEVICE_NOT_IN_RAM @@ -90,8 +91,8 @@ cdl_package CYGPKG_DEVS_FLASH_STRATA { $(REPOSITORY)/$(PACKAGE)/src/strata.h $(CC) -S $(INCLUDE_PATH) $(CFLAGS) -g0 -fno-function-sections $(REPOSITORY)/$(PACKAGE)/src/flash_erase_block.c echo " .text" >>flash_erase_block.s - echo " .globl flash_erase_block_end" >>flash_erase_block.s - echo "flash_erase_block_end:" >>flash_erase_block.s + echo " .globl strata_flash_erase_block_end" >>flash_erase_block.s + echo "strata_flash_erase_block_end:" >>flash_erase_block.s $(CC) $(CFLAGS) -c -o flash_erase_block.o flash_erase_block.s $(AR) rcs $(PREFIX)/lib/libtarget.a flash_erase_block.o } @@ -100,8 +101,8 @@ cdl_package CYGPKG_DEVS_FLASH_STRATA { $(REPOSITORY)/$(PACKAGE)/src/strata.h $(CC) -S $(INCLUDE_PATH) $(CFLAGS) -g0 -fno-function-sections $(REPOSITORY)/$(PACKAGE)/src/flash_program_buf.c echo " .text" >>flash_program_buf.s - echo " .globl flash_program_buf_end" >>flash_program_buf.s - echo "flash_program_buf_end:" >>flash_program_buf.s + echo " .globl strata_flash_program_buf_end" >>flash_program_buf.s + echo "strata_flash_program_buf_end:" >>flash_program_buf.s $(CC) $(CFLAGS) -c -o flash_program_buf.o flash_program_buf.s $(AR) rcs $(PREFIX)/lib/libtarget.a flash_program_buf.o } @@ -110,8 +111,8 @@ cdl_package CYGPKG_DEVS_FLASH_STRATA { $(REPOSITORY)/$(PACKAGE)/src/strata.h $(CC) -S $(INCLUDE_PATH) $(CFLAGS) -g0 -fno-function-sections $(REPOSITORY)/$(PACKAGE)/src/flash_query.c echo " .text" >>flash_query.s - echo " .globl flash_query_end" >>flash_query.s - echo "flash_query_end:" >>flash_query.s + echo " .globl strata_flash_query_hwr_end" >>flash_query.s + echo "strata_flash_query_hwr_end:" >>flash_query.s $(CC) $(CFLAGS) -c -o flash_query.o flash_query.s $(AR) rcs $(PREFIX)/lib/libtarget.a flash_query.o } @@ -126,8 +127,8 @@ cdl_package CYGPKG_DEVS_FLASH_STRATA { $(REPOSITORY)/$(PACKAGE)/src/strata.h $(CC) -S $(INCLUDE_PATH) $(CFLAGS) -g0 -fno-function-sections $(REPOSITORY)/$(PACKAGE)/src/flash_lock_block.c echo " .text" >>flash_lock_block.s - echo " .globl flash_lock_block_end" >>flash_lock_block.s - echo "flash_lock_block_end:" >>flash_lock_block.s + echo " .globl strata_flash_lock_block_end" >>flash_lock_block.s + echo "strata_flash_lock_block_end:" >>flash_lock_block.s $(CC) $(CFLAGS) -c -o flash_lock_block.o flash_lock_block.s $(AR) rcs $(PREFIX)/lib/libtarget.a flash_lock_block.o } @@ -136,8 +137,8 @@ cdl_package CYGPKG_DEVS_FLASH_STRATA { $(REPOSITORY)/$(PACKAGE)/src/strata.h $(CC) -S $(INCLUDE_PATH) $(CFLAGS) -g0 -fno-function-sections $(REPOSITORY)/$(PACKAGE)/src/flash_unlock_block.c echo " .text" >>flash_unlock_block.s - echo " .globl flash_unlock_block_end" >>flash_unlock_block.s - echo "flash_unlock_block_end:" >>flash_unlock_block.s + echo " .globl strata_flash_unlock_block_end" >>flash_unlock_block.s + echo "strata_flash_unlock_block_end:" >>flash_unlock_block.s $(CC) $(CFLAGS) -c -o flash_unlock_block.o flash_unlock_block.s $(AR) rcs $(PREFIX)/lib/libtarget.a flash_unlock_block.o } --- devs/flash/intel/strata/current/src/flash_erase_block.c 29 May 2003 10:52:54 -0000 1.1.1.1 +++ devs/flash/intel/strata/current/src/flash_erase_block.c 19 Jun 2003 13:10:23 -0000 1.3 @@ -55,23 +55,22 @@ #include #include +#include + // // CAUTION! This code must be copied to RAM before execution. Therefore, // it must not contain any code which might be position dependent! // - -int flash_erase_block(volatile flash_t *block, unsigned int block_size) +int strata_flash_erase_block(struct flash_info *flash_info, cyg_flash_offset_t block) { - volatile flash_t *ROM; flash_t stat = 0; int timeout = 50000; int len, block_len, erase_block_size; - volatile flash_t *eb; + unsigned long eb = block; + unsigned long ca = block & CYGNUM_FLASH_BANK_MASK; // Get base address and map addresses to virtual addresses - ROM = FLASH_P2V(CYGNUM_FLASH_BASE_MASK & (unsigned int)block); - eb = block = FLASH_P2V(block); - block_len = block_size; + block_len = flash_info->block_size; #ifdef CYGOPT_FLASH_IS_BOOTBLOCK #define BLOCKSIZE (0x10000*CYGNUM_FLASH_DEVICES) @@ -83,35 +82,38 @@ int flash_erase_block(volatile flash_t * erase_block_size = block_size; } #else - erase_block_size = block_size; + erase_block_size = flash_info->block_size; #endif // Clear any error conditions - ROM[0] = FLASH_Clear_Status; + CYGHWR_STRATA_WRITE(ca, FLASH_Clear_Status); // Erase block while (block_len > 0) { - ROM[0] = FLASH_Block_Erase; - *eb = FLASH_Confirm; + CYGHWR_STRATA_WRITE(eb, FLASH_Block_Erase); + CYGHWR_STRATA_WRITE(eb, FLASH_Confirm); timeout = 5000000; - while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { + CYGHWR_STRATA_READ(ca, stat); + while((stat & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) break; + CYGHWR_STRATA_READ(ca, stat); } block_len -= erase_block_size; - eb = FLASH_P2V((unsigned int)eb + erase_block_size); + eb = eb + erase_block_size; } // Restore ROM to "normal" mode - ROM[0] = FLASH_Reset; + CYGHWR_STRATA_WRITE(ca, FLASH_Reset); // If an error was reported, see if the block erased anyway if (stat & FLASH_ErrorMask ) { - len = block_size; - while (len > 0) { - if (*block++ != FLASH_BlankValue ) break; - len -= sizeof(*block); + int i; + for (i = block; i < block + flash_info->block_size; i+=sizeof(flash_t)) { + flash_t t; + CYGHWR_STRATA_READ(i, t); + if (t != FLASH_BlankValue) break; } - if (len == 0) stat = 0; + if (i == block + flash_info->block_size) stat = 0; } return stat; --- devs/flash/intel/strata/current/src/flash_lock_block.c 29 May 2003 10:52:54 -0000 1.1.1.1 +++ devs/flash/intel/strata/current/src/flash_lock_block.c 19 Jun 2003 13:10:23 -0000 1.3 @@ -53,34 +53,33 @@ #include "strata.h" +#include + // // CAUTION! This code must be copied to RAM before execution. Therefore, // it must not contain any code which might be position dependent! // int -flash_lock_block(volatile flash_t *block) +strata_flash_lock_block(struct flash_info *flash_info, cyg_flash_offset_t block) { - volatile flash_t *ROM; flash_t stat; int timeout = 5000000; - - // Get base address and map addresses to virtual addresses - ROM = FLASH_P2V(CYGNUM_FLASH_BASE_MASK & (unsigned int)block); - block = FLASH_P2V(block); + unsigned long ca = block & CYGNUM_FLASH_BANK_MASK; // Clear any error conditions - ROM[0] = FLASH_Clear_Status; + CYGHWR_STRATA_WRITE(ca, FLASH_Clear_Status); // Set lock bit - block[0] = FLASH_Set_Lock; - block[0] = FLASH_Set_Lock_Confirm; // Confirmation - while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { + CYGHWR_STRATA_WRITE(block, FLASH_Set_Lock); + CYGHWR_STRATA_WRITE(block, FLASH_Set_Lock_Confirm); // Confirmation + CYGHWR_STRATA_READ(ca, stat); + while((stat & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) break; } // Restore ROM to "normal" mode - ROM[0] = FLASH_Reset; + CYGHWR_STRATA_WRITE(ca, FLASH_Reset); return stat; } --- devs/flash/intel/strata/current/src/flash_program_buf.c 29 May 2003 10:52:54 -0000 1.1.1.1 +++ devs/flash/intel/strata/current/src/flash_program_buf.c 19 Jun 2003 13:10:23 -0000 1.3 @@ -53,6 +53,9 @@ #include "strata.h" #include + +#include + #include // @@ -61,24 +64,21 @@ // int -flash_program_buf(volatile flash_t *addr, flash_t *data, int len, - unsigned long block_mask, int buffer_size) +strata_flash_program_buf(struct flash_info *flash_info, + cyg_flash_offset_t offset, CYG_ADDRESS data, int len, + int buffer_size) { - volatile flash_t *ROM; - volatile flash_t *BA; flash_t stat = 0; int timeout = 50000; #ifdef FLASH_Write_Buffer int i, wc; #endif + unsigned long block_offset; - // Get base address and map addresses to virtual addresses - ROM = FLASH_P2V( CYGNUM_FLASH_BASE_MASK & (unsigned int)addr ); - BA = FLASH_P2V( block_mask & (unsigned int)addr ); - addr = FLASH_P2V(addr); + block_offset = offset & ~(flash_info->block_size-1); /* address of block */ // Clear any error conditions - ROM[0] = FLASH_Clear_Status; + CYGHWR_STRATA_WRITE(0, FLASH_Clear_Status); #ifdef FLASH_Write_Buffer // Write any big chunks first @@ -88,68 +88,88 @@ flash_program_buf(volatile flash_t *addr len -= wc; // convert 'wc' in bytes to 'wc' in 'flash_t' wc = wc / sizeof(flash_t); // Word count - *BA = FLASH_Write_Buffer; + + CYGHWR_STRATA_WRITE(block_offset, FLASH_Write_Buffer); timeout = 5000000; - while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { + CYGHWR_STRATA_READ(0, stat); + while((stat & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) { goto bad; } - *BA = FLASH_Write_Buffer; + CYGHWR_STRATA_WRITE(block_offset, FLASH_Write_Buffer); + CYGHWR_STRATA_READ(0, stat); } - *BA = FLASHWORD(wc-1); // Count is 0..N-1 + CYGHWR_STRATA_WRITE(block_offset, FLASHWORD(wc-1)); // Count is 0..N-1 for (i = 0; i < wc; i++) { -#ifdef CYGHWR_FLASH_WRITE_ELEM - CYGHWR_FLASH_WRITE_ELEM(addr+i, data+i); +#ifdef CYGHWR_STRATA_WRITE_ELEM + CYGHWR_STRATA_WRITE_ELEM(offset+i, data+i); #else - *(addr+i) = *(data+i); + CYGHWR_STRATA_WRITE(offset + i*sizeof(flash_t), *(flash_t*)((unsigned long)data+i*sizeof(flash_t))); #endif } - *BA = FLASH_Confirm; + CYGHWR_STRATA_WRITE(block_offset, FLASH_Confirm); - ROM[0] = FLASH_Read_Status; + CYGHWR_STRATA_WRITE(0, FLASH_Read_Status); timeout = 5000000; - while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { + + CYGHWR_STRATA_READ(0, stat); + while((stat & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) { goto bad; } + CYGHWR_STRATA_READ(0, stat); } // Jump out if there was an error if (stat & FLASH_ErrorMask) { goto bad; } + // And verify the data - also increments the pointers. - *BA = FLASH_Reset; + CYGHWR_STRATA_WRITE(block_offset, FLASH_Reset); for (i = 0; i < wc; i++) { - if ( *addr++ != *data++ ) { + flash_t verf; + CYGHWR_STRATA_READ(offset, verf); + if ( verf != *(flash_t*)data ) { stat = FLASH_ErrorNotVerified; goto bad; } + offset += sizeof(flash_t); + ((flash_t *)data)++; } } #endif while (len > 0) { - ROM[0] = FLASH_Program; -#ifdef CYGHWR_FLASH_WRITE_ELEM - CYGHWR_FLASH_WRITE_ELEM(addr, data); + flash_t verf; + + CYGHWR_STRATA_WRITE(0, FLASH_Program); +#ifdef CYGHWR_STRATA_WRITE_ELEM + CYGHWR_STRATA_WRITE_ELEM(offset, data); #else - *addr = *data; + CYGHWR_STRATA_WRITE(offset, *(flash_t*)data); #endif timeout = 5000000; - while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { + CYGHWR_STRATA_READ(0, stat); + while((stat & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) { goto bad; } + CYGHWR_STRATA_READ(0, stat); } if (stat & FLASH_ErrorMask) { break; } - ROM[0] = FLASH_Reset; - if (*addr++ != *data++) { - stat = FLASH_ErrorNotVerified; + CYGHWR_STRATA_WRITE(0, FLASH_Reset); + CYGHWR_STRATA_READ(offset, verf); + if (verf != *(flash_t*)data) { + stat = FLASH_ErrorNotVerified+1; break; } + + offset += sizeof(flash_t); + data += sizeof(flash_t); len -= sizeof( flash_t ); + } // Restore ROM to "normal" mode @@ -154,7 +174,7 @@ flash_program_buf(volatile flash_t *addr // Restore ROM to "normal" mode bad: - ROM[0] = FLASH_Reset; + CYGHWR_STRATA_WRITE(0, FLASH_Reset); return stat; } --- devs/flash/intel/strata/current/src/flash_query.c 29 May 2003 10:52:54 -0000 1.1.1.1 +++ devs/flash/intel/strata/current/src/flash_query.c 19 Jun 2003 13:10:23 -0000 1.3 @@ -56,46 +56,52 @@ #include #include CYGHWR_MEMORY_LAYOUT_H +#include + // // CAUTION! This code must be copied to RAM before execution. Therefore, // it must not contain any code which might be position dependent! -// +// i.e. don't call diag_printf. #define CNT 20*1000*10 // Approx 20ms int -flash_query(unsigned char *data) +strata_flash_query_hwr(struct flash_info *flash_info, CYG_ADDRESS d) { - volatile flash_t *ROM; int i, cnt; + unsigned long offset; + unsigned char *data = (unsigned char *)d; + flash_t tmp; // Get base address and map addresses to virtual addresses - ROM = FLASH_P2V( CYGNUM_FLASH_BASE ); #ifdef CYGOPT_FLASH_IS_BOOTBLOCK // BootBlock flash does not support full Read_Query - we have do a // table oriented thing above, after getting just two bytes of results: - ROM[0] = FLASH_Read_ID; + CYGHWR_STRATA_WRITE(0, FLASH_Read_ID); i = 2; #else // StrataFlash supports the full Read_Query op: - ROM[0] = FLASH_Read_Query; + CYGHWR_STRATA_WRITE(0, FLASH_Read_Query); i = sizeof(struct FLASH_query); #endif // Not CYGOPT_FLASH_IS_BOOTBLOCK for (cnt = CNT; cnt > 0; cnt--) ; + offset = 0; for ( /* i */; i > 0; i-- ) { // It is very deliberate that data is chars NOT flash_t: // The info comes out in bytes regardless of device. - *data++ = (unsigned char) (*ROM++); + CYGHWR_STRATA_READ(offset, tmp); + *data++ = (unsigned char)tmp; + offset += sizeof(flash_t) / sizeof (unsigned char); #ifndef CYGOPT_FLASH_IS_BOOTBLOCK # if 8 == CYGNUM_FLASH_WIDTH // strata flash with 'byte-enable' contains the configuration data // at even addresses - ++ROM; + ++offset; # endif #endif } - ROM[0] = FLASH_Reset; + CYGHWR_STRATA_WRITE(0, FLASH_Reset); return 0; } --- devs/flash/intel/strata/current/src/flash_unlock_block.c 29 May 2003 10:52:54 -0000 1.1.1.1 +++ devs/flash/intel/strata/current/src/flash_unlock_block.c 19 Jun 2003 13:10:23 -0000 1.3 @@ -52,6 +52,9 @@ #include "strata.h" +#include + +#include // // CAUTION! This code must be copied to RAM before execution. Therefore, @@ -68,77 +71,87 @@ #define MAX_FLASH_BLOCKS 128 -int -flash_unlock_block(volatile flash_t *block, int block_size, int blocks) +int strata_flash_unlock_block(struct flash_info *flash_info, cyg_flash_offset_t block, int blocks) { - volatile flash_t *ROM; flash_t stat; int timeout = 5000000; + unsigned long ca; #ifndef CYGOPT_FLASH_IS_SYNCHRONOUS int i; - volatile flash_t *bp, *bpv; + unsigned long ba; unsigned char is_locked[MAX_FLASH_BLOCKS]; #endif - // Get base address and map addresses to virtual addresses - ROM = FLASH_P2V( CYGNUM_FLASH_BASE_MASK & (unsigned int)block ); - block = FLASH_P2V(block); + ca = block & CYGNUM_FLASH_BANK_MASK; /* address of chip */ // Clear any error conditions - ROM[0] = FLASH_Clear_Status; + CYGHWR_STRATA_WRITE(ca, FLASH_Clear_Status); #ifdef CYGOPT_FLASH_IS_SYNCHRONOUS // Clear lock bit - block[0] = FLASH_Clear_Locks; - block[0] = FLASH_Clear_Locks_Confirm; // Confirmation - while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { + CYGHWR_STRATA_WRITE(block, FLASH_Clear_Locks); + CYGHWR_STRATA_WRITE(block, FLASH_Clear_Locks_Confirm); // Confirmation + CYGHWR_STRATA_READ(ca, stat); + while((stat & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) break; + CYGHWR_STRATA_READ(ca, stat); } #else +#if 0 /* TODO */ // Get current block lock state. This needs to access each block on // the device so currently locked blocks can be re-locked. - bp = ROM; - for (i = 0; i < blocks; i++) { - bpv = FLASH_P2V( bp ); - *bpv = FLASH_Read_Query; - if (bpv == block) { - is_locked[i] = 0; - } else { + ba = ca; + for (i = 0; i < ( blocks / CYGNUM_FLASH_BANKS ); i++) { + CYGHWR_STRATA_WRITE(ba, FLASH_Read_Query); +#warning NOT SURE THIS IS CORRECT -- IJC + CYGHWR_STRATA_READ(ba+4, is_locked[i]); +#if 0 #if 8 == CYGNUM_FLASH_WIDTH - is_locked[i] = bpv[4]; + CYGHWR_STRATA_READ(ba+4, is_locked[i]); #else - is_locked[i] = bpv[2]; + CYGHWR_STRATA_READ(ba+2, is_locked[i]); # endif +# endif + if (ba == block) { + is_locked[i] = 0; } - bp += block_size / sizeof(*bp); + ba += flash_info->block_size; } +#endif // Clears all lock bits - ROM[0] = FLASH_Clear_Locks; - ROM[0] = FLASH_Clear_Locks_Confirm; // Confirmation + CYGHWR_STRATA_WRITE(ca, FLASH_Clear_Locks); + CYGHWR_STRATA_WRITE(ca, FLASH_Clear_Locks_Confirm); // Confirmation timeout = 5000000; - while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { + CYGHWR_STRATA_READ(ca, stat); + while((stat & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) break; + CYGHWR_STRATA_READ(ca, stat); } +#if 0 /* TODO */ // Restore the lock state - bp = ROM; - for (i = 0; i < blocks; i++) { - bpv = FLASH_P2V( bp ); + ba = 0; + for (i = 0; i < ( blocks / CYGNUM_FLASH_BANKS ); i++) { if (is_locked[i]) { - *bpv = FLASH_Set_Lock; - *bpv = FLASH_Set_Lock_Confirm; // Confirmation + diag_printf("Locking: %p\n", ba); + CYGHWR_STRATA_WRITE(ba, FLASH_Set_Lock); + CYGHWR_STRATA_WRITE(ba, FLASH_Set_Lock_Confirm); // Confirmation timeout = 5000000; - while(((stat = ROM[0]) & FLASH_Status_Ready) != FLASH_Status_Ready) { + CYGHWR_STRATA_READ(ca, stat); + while((stat & FLASH_Status_Ready) != FLASH_Status_Ready) { if (--timeout == 0) break; + CYGHWR_STRATA_READ(ca, stat); } } - bp += block_size / sizeof(*bp); + ba += flash_info->block_size; } +#endif + #endif // CYGOPT_FLASH_IS_SYNCHRONOUS // Restore ROM to "normal" mode - ROM[0] = FLASH_Reset; + CYGHWR_STRATA_WRITE(ca, FLASH_Reset); return stat; } --- devs/flash/intel/strata/current/src/strata.c 29 May 2003 10:52:54 -0000 1.1.1.1 +++ devs/flash/intel/strata/current/src/strata.c 19 Jun 2003 13:10:23 -0000 1.4 @@ -66,13 +67,27 @@ extern void diag_dump_buf(void *buf, CYG extern int strncmp(const char *s1, const char *s2, size_t len); extern void *memcpy( void *, const void *, size_t ); +static bool strata_flash_code_overlaps(struct flash_info *flash_info, cyg_flash_offset_t start, cyg_flash_offset_t end); +static int strata_flash_hwr_map_error(struct flash_info *flash_info, int err); +static int strata_flash_read(struct flash_info *flash_info, CYG_ADDRESS ram_base, cyg_flash_offset_t flash_base, cyg_flash_offset_t len, cyg_flash_offset_t *err_addr); + int -flash_hwr_init(void) +strata_flash_query(struct cyg_flashdevtab_entry *tab) { + struct flash_info *flash_info = tab->info; struct FLASH_query data, *qp; int num_regions, region_size, buffer_size; + extern char + strata_flash_query_hwr_end[], + strata_flash_erase_block_end[], + strata_flash_lock_block_end[], + strata_flash_unlock_block_end[], + strata_flash_program_buf_end[]; + + flash_info->query_hwr = strata_flash_query_hwr; + flash_info->query_hwr_length = (CYG_ADDRESS)&strata_flash_query_hwr_end - (CYG_ADDRESS)&strata_flash_query_hwr; + cyg_flash_dev_query(flash_info, (CYG_ADDRESS)&data); - flash_dev_query(&data); qp = &data; if ( (qp->manuf_code == FLASH_Intel_code) #ifdef CYGOPT_FLASH_IS_BOOTBLOCK @@ -115,30 +130,44 @@ flash_hwr_init(void) } #endif // Not CYGOPT_FLASH_IS_BOOTBLOCK - flash_info.block_size = region_size*CYGNUM_FLASH_DEVICES; - flash_info.buffer_size = buffer_size; - flash_info.blocks = num_regions; - flash_info.start = (void *)CYGNUM_FLASH_BASE; - flash_info.end = (void *)(CYGNUM_FLASH_BASE + - (num_regions*region_size*CYGNUM_FLASH_DEVICES)); -#ifdef CYGNUM_FLASH_BASE_MASK + flash_info->block_size = region_size*CYGNUM_FLASH_DEVICES; + flash_info->buffer_size = buffer_size; + flash_info->blocks = num_regions*CYGNUM_FLASH_BANKS; + flash_info->base_address = CYGNUM_FLASH_BASE; + flash_info->size = (num_regions*region_size*CYGNUM_FLASH_DEVICES*CYGNUM_FLASH_BANKS); + + flash_info->erase_block = &strata_flash_erase_block; + flash_info->program = &strata_flash_program_buf; + flash_info->lock_block = &strata_flash_lock_block; + flash_info->unlock_block = &strata_flash_unlock_block; + + flash_info->erase_block_length = (CYG_ADDRESS)&strata_flash_erase_block_end - (CYG_ADDRESS)&strata_flash_erase_block; + flash_info->lock_block_length = (CYG_ADDRESS)&strata_flash_lock_block_end - (CYG_ADDRESS)&strata_flash_lock_block; + flash_info->unlock_block_length = (CYG_ADDRESS)&strata_flash_unlock_block_end - (CYG_ADDRESS)&strata_flash_unlock_block; + flash_info->program_length = (CYG_ADDRESS)&strata_flash_program_buf_end - (CYG_ADDRESS)&strata_flash_program_buf; + + flash_info->code_overlaps = &strata_flash_code_overlaps; + flash_info->map_error = &strata_flash_hwr_map_error; + flash_info->read = &strata_flash_read; + +#ifdef CYGNUM_FLASH_BASE_MASK_DISABLE // IJC -- what does this do? // Then this gives us a maximum size for the (visible) device. // This is to cope with oversize devices fitted, with some high // address lines ignored. - if ( ((unsigned int)flash_info.start & CYGNUM_FLASH_BASE_MASK) != - (((unsigned int)flash_info.end - 1) & CYGNUM_FLASH_BASE_MASK ) ) { + if ( ((unsigned int)flash_info->start & CYGNUM_FLASH_BASE_MASK) != + (((unsigned int)flash_info->end - 1) & CYGNUM_FLASH_BASE_MASK ) ) { // then the size of the device appears to span >1 device-worth! unsigned int x; x = (~(CYGNUM_FLASH_BASE_MASK)) + 1; // expected device size - x += (unsigned int)flash_info.start; - if ( x < (unsigned int)flash_info.end ) { // 2nd sanity check - (*flash_info.pf)("\nFLASH: Oversized device! End addr %p changed to %p\n", - flash_info.end, (void *)x ); - flash_info.end = (void *)x; + x += (unsigned int)flash_info->start; + if ( x < (unsigned int)flash_info->end ) { // 2nd sanity check + (*flash_info->pf)("\nFLASH: Oversized device! End addr %p changed to %p\n", + flash_info->end, (void *)x ); + flash_info->end = (void *)x; // Also adjust the block count else unlock crashes! - x = ((cyg_uint8 *)flash_info.end - (cyg_uint8 *)flash_info.start) - / flash_info.block_size; - flash_info.blocks = x; + x = ((cyg_uint8 *)flash_info->end - (cyg_uint8 *)flash_info->start) + / flash_info->block_size; + flash_info->blocks = x; } } #endif // CYGNUM_FLASH_BASE_MASK @@ -148,18 +177,28 @@ flash_hwr_init(void) #ifdef CYGOPT_FLASH_IS_BOOTBLOCK flash_type_unknown: #endif - (*flash_info.pf)("Can't identify FLASH, sorry, man %x, dev %x, id [%4s] \n", + (*flash_info->pf)("Can't identify FLASH, sorry, man %x, dev %x, id [%4s]\n", qp->manuf_code, qp->device_code, qp->id ); diag_dump_buf(qp, sizeof(data)); return FLASH_ERR_HWR; } +static int +strata_flash_read(struct flash_info *flash_info, CYG_ADDRESS ram_base, cyg_flash_offset_t flash_base, cyg_flash_offset_t len, cyg_flash_offset_t *err_addr) +{ + int i; + flash_t *data = (flash_t *)ram_base; + for ( i = 0 ; i < len ; i += sizeof(flash_t) ) { + CYGHWR_STRATA_READ(flash_base+i, *data++); + } + return FLASH_ERR_OK; +} + // Map a hardware status to a package error -int -flash_hwr_map_error(int err) +static int strata_flash_hwr_map_error(struct flash_info *flash_info, int err) { if (err & FLASH_ErrorMask) { - (*flash_info.pf)("Err = %x\n", err); + (*flash_info->pf)("Err = %x\n", err); if (err & FLASH_ErrorProgram) return FLASH_ERR_PROGRAM; else if (err & FLASH_ErrorErase) @@ -172,15 +211,24 @@ flash_hwr_map_error(int err) } // See if a range of FLASH addresses overlaps currently running code -bool -flash_code_overlaps(void *start, void *end) +static bool +strata_flash_code_overlaps(struct flash_info *flash_info, cyg_flash_offset_t start, cyg_flash_offset_t end) { extern char _stext[], _etext[]; +#ifdef CYGNUM_FLASH_IS_PAGED + return false; +#else + start += CYGNUM_FLASH_BASE; + end += CYGNUM_FLASH_BASE; + +// diag_printf("code_overlaps(%p, 0x%08x, 0x%08x)\n", flash_info, start, end); +// diag_printf(" text = 0x%08x -- 0x%08x\n", _stext, _etext); - return ((((unsigned long)&_stext >= (unsigned long)start) && - ((unsigned long)&_stext < (unsigned long)end)) || - (((unsigned long)&_etext >= (unsigned long)start) && - ((unsigned long)&_etext < (unsigned long)end))); + return ((((cyg_flash_offset_t)&_stext >= start) && + ((cyg_flash_offset_t)&_stext < end)) || + (((cyg_flash_offset_t)&_etext >= start) && + ((cyg_flash_offset_t)&_etext < end))); +#endif } // EOF strata.c --- devs/flash/intel/strata/current/src/strata.h 29 May 2003 10:52:54 -0000 1.1.1.1 +++ devs/flash/intel/strata/current/src/strata.h 19 Jun 2003 13:10:23 -0000 1.3 @@ -54,6 +54,20 @@ #include #include +#include + +// ------------------------------------------------------------------------ + +externC int strata_flash_query(struct cyg_flashdevtab_entry *tab); +externC int strata_flash_query_hwr(struct flash_info *flash_info, CYG_ADDRESS d); + +externC int strata_flash_lock_block(struct flash_info *flash_info, cyg_flash_offset_t block); +externC int strata_flash_unlock_block(struct flash_info *flash_info, cyg_flash_offset_t block, int blocks); +externC int strata_flash_erase_block(struct flash_info *flash_info, cyg_flash_offset_t block); +externC int strata_flash_program_buf(struct flash_info *flash_info, + cyg_flash_offset_t offset, CYG_ADDRESS data, int len, + int buffer_size); + #include CYGDAT_DEVS_FLASH_STRATA_INL // ------------------------------------------------------------------------ @@ -83,6 +97,9 @@ // CYGNUM_FLASH_BLANK 1 if blank is allones, 0 if 0 // CYGNUM_FLASH_BASE base address // CYGNUM_FLASH_BASE_MASK a mask to get base address from any +// CYGNUM_FLASH_BANKS number of devices up the databus +// CYGNUM_FLASH_BANK_MASK a mask to get base address of the +// bank containing an address // // for example, a 32-bit memory could be made from 1x32bit, 2x16bit or // 4x8bit devices; usually 16bit ones are chosen in practice, so we would @@ -91,12 +108,50 @@ // Some CPUs can handle a single 16bit device as 32bit memory "by magic". // In that case, CYGNUM_FLASH_DEVICES = 1 and CYGNUM_FLASH_WIDTH = 16, and // the device is managed using only 16bit bus operations. +// +// If you had two consecutive 32bit devices of size 32Mb to give a total of 64Mb +// at memory address 0 then you would define CYGNUM_FLASH_BANKS as 2 and +// CYGNUM_FLASH_BANK_MASK as 0xFE000000u to give the base of the bank and +// CYGNUM_FLASH_BASE_MASK as 0xFC000000 #define CYGNUM_FLASH_INTERLEAVE CYGNUM_FLASH_DEVICES #define _FLASH_PRIVATE_ #include +// ------------------------------------------------------------------------ +// +// No mapping on this target - but these casts would be needed if some +// manipulation did occur. An example of this might be: +// // First 4K page of flash at physical address zero is +// // virtually mapped at address 0xa0000000. +// #define FLASH_P2V(x) ((volatile flash_t *)(((unsigned)(x) < 0x1000) ? +// ((unsigned)(x) | 0xa0000000) : +// (unsigned)(x))) + +#ifndef FLASH_P2V +#define FLASH_P2V( _a_ ) ((volatile flash_t *)((unsigned int)(_a_))) +#endif + +// ------------------------------------------------------------------------- +// +// If the board has not defined multiple banks then assume only one bank +// exists +// +#ifndef CYGNUM_FLASH_BANKS +#define CYGNUM_FLASH_BANKS (1) +#endif + +#ifndef CYGNUM_FLASH_BANK_MASK +#define CYGNUM_FLASH_BANK_MASK CYGNUM_FLASH_BASE_MASK +#endif + +#if CYGNUM_FLASH_BANKS > 1 && defined(CYGOPT_FLASH_IS_BOOTBLOCK) +#error "Can't handle multiple flash banks with bootblock flash" +#endif + + #define flash_t flash_data_t + // ------------------------------------------------------------------------ // // This generic code is intended to deal with all shapes and orientations @@ -114,7 +169,6 @@ // An exception is the test for succesfully erased data. // // ------------------------------------------------------------------------ -// ------------------------------------------------------------------------ #define FLASH_Read_ID FLASHWORD( 0x90 ) #ifndef CYGOPT_FLASH_IS_BOOTBLOCK @@ -171,6 +225,23 @@ struct FLASH_query { unsigned char num_regions[2]; unsigned char region_size[2]; }; + +// ------------------------------------------------------------------------ + +#ifndef CYGHWR_STRATA_READ +#define CYGHWR_STRATA_READ(__OFFSET__, __VALUE__) \ +CYG_MACRO_START \ +__VALUE__ = *(volatile flash_t *)((cyg_uint8*)FLASH_P2V(CYGNUM_FLASH_BASE)+(__OFFSET__));\ +CYG_MACRO_END +#endif + +#ifndef CYGHWR_STRATA_WRITE +#define CYGHWR_STRATA_WRITE(__OFFSET__, __VALUE__) \ +CYG_MACRO_START \ +*(volatile flash_t *)((cyg_uint8*)FLASH_P2V(CYGNUM_FLASH_BASE)+(__OFFSET__)) = (__VALUE__); \ +CYG_MACRO_END +#endif + #endif // CYGONCE_DEVS_FLASH_INTEL_STRATA_FLASH_H // ------------------------------------------------------------------------