cfi02: Custom unlock addresses
RFC PATCH 1/4 cfi02: Custom unlock addresses
Some cfi02 flash chips use different unlock addresses than the currently hard-coded 0x555/0x2AA pair. So let's make those two customizable during flash initialization.
Not sure what the situation with cfi01 is, but if this is considered to be a useful extension for the latter as well, let me know and I would extend that interface, too.
Signed-off-by Jan Kiszka <[email protected]>
--- hw/flash.h | 3 ++- hw/pflash_cfi02.c | 18 +++++++++++------- hw/ppc405_boards.c | 6 +++--- 3 files changed, 16 insertions(+), 11 deletions(-)
hw/flash.h +2 -1
@@ -13,7 +13,8 @@ pflash_t *pflash_cfi02_register(target_p BlockDriverState *bs, uint32_t sector_len, int nb_blocs, int width, uint16_t id0, uint16_t id1, - uint16_t id2, uint16_t id3); + uint16_t id2, uint16_t id3, + uint16_t unlock_addr0, uint16_t unlock_addr1);/* nand.c */ struct nand_flash_s ;
hw/pflash_cfi02.c +11 -7
@@ -63,6 +63,7 @@ struct pflash_t {uint8_t cmd;uint8_t status;uint16_t ident[4 ]; +uint16_t unlock_addr[2 ];uint8_t cfi_len;uint8_t cfi_table[0x52 ];QEMUTimer *timer;
@@ -246,9 +247,9 @@ static void pflash_write (pflash_t *pfl, pfl->cmd =0x98 ;return ; } -if (boff !=0x555 || cmd !=0xAA ) { +if (boff != pfl->unlock_addr[0 ] || cmd !=0xAA ) {DPRINTF ("%s: unlock0 failed " TARGET_FMT_lx" %02x %04x\n" , - __func__, boff, cmd,0x555 ); + __func__, boff, cmd, pfl->unlock_addr[0 ]); goto reset_flash; }DPRINTF ("%s: unlock sequence started\n" , __func__);
@@ -256,7 +257,7 @@ static void pflash_write (pflash_t *pfl,case 1 :/* We started an unlock sequence */ check_unlock1: -if (boff !=0x2AA || cmd !=0x55 ) { +if (boff != pfl->unlock_addr[1 ] || cmd !=0x55 ) {DPRINTF ("%s: unlock1 failed " TARGET_FMT_lx" %02x\n" , __func__, boff, cmd); goto reset_flash;
@@ -265,7 +266,7 @@ static void pflash_write (pflash_t *pfl,break ;case 2 :/* We finished an unlock sequence */ -if (!pfl->bypass && boff !=0x555 ) { +if (!pfl->bypass && boff != pfl->unlock_addr[0 ]) {DPRINTF ("%s: command failed " TARGET_FMT_lx" %02x\n" , __func__, boff, cmd); goto reset_flash;
@@ -361,7 +362,7 @@ static void pflash_write (pflash_t *pfl,case 5 :switch (cmd) {case 0x10 : -if (boff !=0x555 ) { +if (boff != pfl->unlock_addr[0 ]) {DPRINTF ("%s: chip erase: invalid address " TARGET_FMT_lx"\n" , __func__, offset); goto reset_flash;
@@ -528,7 +529,8 @@ pflash_t *pflash_cfi02_register(target_p BlockDriverState *bs, uint32_t sector_len, int nb_blocs, int width, uint16_t id0, uint16_t id1, - uint16_t id2, uint16_t id3) + uint16_t id2, uint16_t id3, + uint16_t unlock_addr0, uint16_t unlock_addr1) { pflash_t *pfl;int32_t total_len;
@@ -573,6 +575,8 @@ pflash_t *pflash_cfi02_register(target_p pfl->ident[1 ] = id1; pfl->ident[2 ] = id2; pfl->ident[3 ] = id3; + pfl->unlock_addr[0 ] = unlock_addr0; + pfl->unlock_addr[1 ] = unlock_addr1;/* Hardcoded CFI table (mostly from SG29 Spansion flash) */ pfl->cfi_len =0x52 ;/* Standard "QRY" string */
@@ -601,7 +605,7 @@ pflash_t *pflash_cfi02_register(target_p pfl->cfi_table[0x1E ] =0x00 ;/* Reserved */ pfl->cfi_table[0x1F ] =0x07 ; -/* Timeout for min size buffer write (16 ??s) */ +/* Timeout for min size buffer write (16 us) */ pfl->cfi_table[0x20 ] =0x04 ;/* Typical timeout for block erase (512 ms) */ pfl->cfi_table[0x21 ] =0x09 ;
hw/ppc405_boards.c +3 -3
@@ -236,7 +236,7 @@ static void ref405ep_init (int ram_size,#endif pflash_cfi02_register ((uint32_t )(-bios_size), bios_offset, drives_table[index].bdrv,65536 , fl_sectors,2 , -0x0001 ,0x22DA ,0x0000 ,0x0000 ); +0x0001 ,0x22DA ,0x0000 ,0x0000 ,0x555 ,0x2AA ); fl_idx++; } else#endif
@@ -553,7 +553,7 @@ static void taihu_405ep_init(int ram_siz#endif pflash_cfi02_register ((uint32_t )(-bios_size), bios_offset, drives_table[index].bdrv,65536 , fl_sectors,4 , -0x0001 ,0x22DA ,0x0000 ,0x0000 ); +0x0001 ,0x22DA ,0x0000 ,0x0000 ,0x555 ,0x2AA ); fl_idx++; } else#endif
@@ -589,7 +589,7 @@ static void taihu_405ep_init(int ram_siz#endif pflash_cfi02_register (0xfc000000 , bios_offset, drives_table[index].bdrv,65536 , fl_sectors,4 , -0x0001 ,0x22DA ,0x0000 ,0x0000 ); +0x0001 ,0x22DA ,0x0000 ,0x0000 ,0x555 ,0x2AA ); fl_idx++; }/* Register CLPD & LCD display */