X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fflash%2Fnor%2Fnon_cfi.c;h=851c0ae8193e1ddc6b6fea040c52e7458fbe7347;hp=e0ea568aea808e18b5eda4384c9e196dbe07babc;hb=b61e454869c988e7fafc1c16982ccfec04415b51;hpb=6f03e92959008708ac6808df679f5729f6683166 diff --git a/src/flash/nor/non_cfi.c b/src/flash/nor/non_cfi.c index e0ea568aea..851c0ae819 100644 --- a/src/flash/nor/non_cfi.c +++ b/src/flash/nor/non_cfi.c @@ -15,10 +15,9 @@ * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + * along with this program. If not, see . * ***************************************************************************/ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -27,13 +26,12 @@ #include "cfi.h" #include "non_cfi.h" - #define KB 1024 #define MB (1024*1024) #define ERASE_REGION(num, size) (((size/256) << 16) | (num-1)) /* non-CFI compatible flashes */ -static struct non_cfi non_cfi_flashes[] = { +static const struct non_cfi non_cfi_flashes[] = { { .mfr = CFI_MFR_SST, .id = 0xd4, @@ -43,8 +41,7 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x0, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, .num_erase_regions = 1, - .erase_region_info = - { + .erase_region_info = { ERASE_REGION(16, 4*KB) } }, @@ -57,8 +54,7 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x0, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, .num_erase_regions = 1, - .erase_region_info = - { + .erase_region_info = { ERASE_REGION(32, 4*KB) } }, @@ -71,8 +67,7 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x0, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, .num_erase_regions = 1, - .erase_region_info = - { + .erase_region_info = { ERASE_REGION(64, 4*KB) } }, @@ -85,11 +80,23 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x0, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, .num_erase_regions = 1, - .erase_region_info = - { + .erase_region_info = { ERASE_REGION(128, 4*KB) } }, + { + .mfr = CFI_MFR_AMD, /* Spansion AM29LV040B */ + .id = 0x4f, + .pri_id = 0x02, + .dev_size = 512*KB, + .interface_desc = 0x0, /* x8 only device */ + .max_buf_write_size = 0x0, + .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, + .num_erase_regions = 1, + .erase_region_info = { + ERASE_REGION(8, 64*KB) + } + }, { .mfr = CFI_MFR_SST, .id = 0x2780, @@ -99,8 +106,7 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x0, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, .num_erase_regions = 1, - .erase_region_info = - { + .erase_region_info = { ERASE_REGION(128, 4*KB) } }, @@ -113,8 +119,7 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x0, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, .num_erase_regions = 4, - .erase_region_info = - { + .erase_region_info = { ERASE_REGION(1, 16*KB), ERASE_REGION(2, 8*KB), ERASE_REGION(1, 32*KB), @@ -130,8 +135,7 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x0, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, .num_erase_regions = 4, - .erase_region_info = - { + .erase_region_info = { ERASE_REGION(7, 64*KB), ERASE_REGION(1, 32*KB), ERASE_REGION(2, 8*KB), @@ -142,9 +146,9 @@ static struct non_cfi non_cfi_flashes[] = { /* SST 39VF* do not support DQ5 status polling - this currently is only supported by the host algorithm, not by the target code using the work area. - Only true for 8-bit and 32-bit wide memories. 16-bit wide memories - without DQ5 status polling are supported by the target code. - */ + Only true for 8-bit and 32-bit wide memories. 16-bit wide memories + without DQ5 status polling are supported by the target code. + */ { .mfr = CFI_MFR_SST, .id = 0x2782, /* SST39xF160 */ @@ -154,8 +158,7 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x0, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7, .num_erase_regions = 1, - .erase_region_info = - { + .erase_region_info = { ERASE_REGION(512, 4*KB) } }, @@ -168,8 +171,7 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x0, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7, .num_erase_regions = 1, - .erase_region_info = - { + .erase_region_info = { ERASE_REGION(1024, 4*KB) } }, @@ -182,8 +184,20 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x0, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7, .num_erase_regions = 1, - .erase_region_info = - { + .erase_region_info = { + ERASE_REGION(512, 4*KB) + } + }, + { + .mfr = CFI_MFR_SST, + .id = 0x274b, /* SST39WF1601 */ + .pri_id = 0x02, + .dev_size = 2*MB, + .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ + .max_buf_write_size = 0x0, + .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7, + .num_erase_regions = 1, + .erase_region_info = { ERASE_REGION(512, 4*KB) } }, @@ -196,8 +210,7 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x0, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7, .num_erase_regions = 1, - .erase_region_info = - { + .erase_region_info = { ERASE_REGION(512, 4*KB) } }, @@ -210,8 +223,7 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x0, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7, .num_erase_regions = 1, - .erase_region_info = - { + .erase_region_info = { ERASE_REGION(1024, 4*KB) } }, @@ -224,11 +236,23 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x0, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7, .num_erase_regions = 1, - .erase_region_info = - { + .erase_region_info = { ERASE_REGION(1024, 4*KB) } }, + { + .mfr = CFI_MFR_SST, + .id = 0x236d, /* SST39VF6401B */ + .pri_id = 0x02, + .dev_size = 8*MB, + .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ + .max_buf_write_size = 0x0, + .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7, + .num_erase_regions = 1, + .erase_region_info = { + ERASE_REGION(2048, 4*KB) + } + }, { .mfr = CFI_MFR_AMD, .id = 0x22ab, /* AM29F400BB */ @@ -238,8 +262,7 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x0, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, .num_erase_regions = 4, - .erase_region_info = - { + .erase_region_info = { ERASE_REGION(1, 16*KB), ERASE_REGION(2, 8*KB), ERASE_REGION(1, 32*KB), @@ -255,8 +278,7 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x0, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, .num_erase_regions = 4, - .erase_region_info = - { + .erase_region_info = { ERASE_REGION(7, 64*KB), ERASE_REGION(1, 32*KB), ERASE_REGION(2, 8*KB), @@ -272,15 +294,14 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x0, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, .num_erase_regions = 4, - .erase_region_info = - { + .erase_region_info = { ERASE_REGION(1, 16*KB), ERASE_REGION(2, 8*KB), ERASE_REGION(1, 32*KB), ERASE_REGION(15, 64*KB) } }, - { + { .mfr = CFI_MFR_FUJITSU, .id = 0x22ea, /* MBM29SL800TE */ .pri_id = 0x02, @@ -289,8 +310,7 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x0, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, .num_erase_regions = 4, - .erase_region_info = - { + .erase_region_info = { ERASE_REGION(15, 64*KB), ERASE_REGION(1, 32*KB), ERASE_REGION(2, 8*KB), @@ -306,8 +326,7 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x00, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, .num_erase_regions = 4, - .erase_region_info = - { + .erase_region_info = { ERASE_REGION(1, 16*KB), ERASE_REGION(2, 8*KB), ERASE_REGION(1, 32*KB), @@ -323,8 +342,7 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x0, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, .num_erase_regions = 4, - .erase_region_info = - { + .erase_region_info = { ERASE_REGION(1, 16*KB), ERASE_REGION(2, 8*KB), ERASE_REGION(1, 32*KB), @@ -340,8 +358,7 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x0, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, .num_erase_regions = 4, - .erase_region_info = - { + .erase_region_info = { ERASE_REGION(1, 16*KB), ERASE_REGION(2, 8*KB), ERASE_REGION(1, 32*KB), @@ -358,8 +375,7 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x0, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, .num_erase_regions = 4, - .erase_region_info = - { + .erase_region_info = { ERASE_REGION(1, 16*KB), ERASE_REGION(2, 8*KB), ERASE_REGION(1, 32*KB), @@ -375,14 +391,29 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x0, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, .num_erase_regions = 4, - .erase_region_info = - { + .erase_region_info = { ERASE_REGION(31, 64*KB), ERASE_REGION(1, 32*KB), ERASE_REGION(2, 8*KB), ERASE_REGION(1, 16*KB) } }, + { + .mfr = CFI_MFR_EON, + .id = 0x225b, /* EN29LV800BB */ + .pri_id = 0x02, + .dev_size = 1*MB, + .interface_desc = 0x2, /* x8 or x16 device with nBYTE */ + .max_buf_write_size = 0x0, + .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, + .num_erase_regions = 4, + .erase_region_info = { + ERASE_REGION(1, 16*KB), + ERASE_REGION(2, 8*KB), + ERASE_REGION(1, 32*KB), + ERASE_REGION(15, 64*KB) + } + }, { .mfr = CFI_MFR_ATMEL, .id = 0x00c0, /* Atmel 49BV1614 */ @@ -392,8 +423,7 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x0, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, .num_erase_regions = 3, - .erase_region_info = - { + .erase_region_info = { ERASE_REGION(8, 8*KB), ERASE_REGION(2, 32*KB), ERASE_REGION(30, 64*KB) @@ -408,8 +438,7 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x0, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, .num_erase_regions = 3, - .erase_region_info = - { + .erase_region_info = { ERASE_REGION(30, 64*KB), ERASE_REGION(2, 32*KB), ERASE_REGION(8, 8*KB) @@ -424,8 +453,7 @@ static struct non_cfi non_cfi_flashes[] = { .max_buf_write_size = 0x0, .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7, .num_erase_regions = 4, - .erase_region_info = - { + .erase_region_info = { ERASE_REGION(1, 16*KB), ERASE_REGION(2, 8*KB), ERASE_REGION(1, 32*KB), @@ -440,16 +468,19 @@ static struct non_cfi non_cfi_flashes[] = { void cfi_fixup_non_cfi(struct flash_bank *bank) { + unsigned int mask; struct cfi_flash_bank *cfi_info = bank->driver_priv; - struct non_cfi *non_cfi = non_cfi_flashes; + const struct non_cfi *non_cfi = non_cfi_flashes; - for (non_cfi = non_cfi_flashes; non_cfi->mfr; non_cfi++) - { + if (cfi_info->x16_as_x8) + mask = 0xFF; + else + mask = 0xFFFF; + + for (non_cfi = non_cfi_flashes; non_cfi->mfr; non_cfi++) { if ((cfi_info->manufacturer == non_cfi->mfr) - && (cfi_info->device_id == non_cfi->id)) - { + && (cfi_info->device_id == (non_cfi->id & mask))) break; - } } /* only fixup jedec flashs found in table */ @@ -463,10 +494,12 @@ void cfi_fixup_non_cfi(struct flash_bank *bank) cfi_info->vcc_max = 0x0; cfi_info->vpp_min = 0x0; cfi_info->vpp_max = 0x0; - cfi_info->word_write_timeout_typ = 0x0; - cfi_info->buf_write_timeout_typ = 0x0; - cfi_info->block_erase_timeout_typ = 0x0; - cfi_info->chip_erase_timeout_typ = 0x0; + /* these are used for timeouts - use vales that should be long enough + for normal operation. */ + cfi_info->word_write_timeout_typ = 0x0a; + cfi_info->buf_write_timeout_typ = 0x0d; + cfi_info->block_erase_timeout_typ = 0x0d; + cfi_info->chip_erase_timeout_typ = 0x10; cfi_info->word_write_timeout_max = 0x0; cfi_info->buf_write_timeout_max = 0x0; cfi_info->block_erase_timeout_max = 0x0; @@ -486,11 +519,14 @@ void cfi_fixup_non_cfi(struct flash_bank *bank) cfi_info->max_buf_write_size = non_cfi->max_buf_write_size; cfi_info->status_poll_mask = non_cfi->status_poll_mask; cfi_info->num_erase_regions = non_cfi->num_erase_regions; - cfi_info->erase_region_info = non_cfi->erase_region_info; + size_t erase_region_info_size = sizeof(*cfi_info->erase_region_info) * + cfi_info->num_erase_regions; + cfi_info->erase_region_info = malloc(erase_region_info_size); + memcpy(cfi_info->erase_region_info, + non_cfi->erase_region_info, erase_region_info_size); cfi_info->dev_size = non_cfi->dev_size; - if (cfi_info->pri_id == 0x2) - { + if (cfi_info->pri_id == 0x2) { struct cfi_spansion_pri_ext *pri_ext = malloc(sizeof(struct cfi_spansion_pri_ext)); pri_ext->pri[0] = 'P'; @@ -502,7 +538,6 @@ void cfi_fixup_non_cfi(struct flash_bank *bank) pri_ext->SiliconRevision = 0x0; pri_ext->EraseSuspend = 0x0; - pri_ext->EraseSuspend = 0x0; pri_ext->BlkProt = 0x0; pri_ext->TmpBlkUnprotect = 0x0; pri_ext->BlkProtUnprot = 0x0; @@ -518,8 +553,7 @@ void cfi_fixup_non_cfi(struct flash_bank *bank) pri_ext->_reversed_geometry = 0; cfi_info->pri_ext = pri_ext; - } else if ((cfi_info->pri_id == 0x1) || (cfi_info->pri_id == 0x3)) - { + } else if ((cfi_info->pri_id == 0x1) || (cfi_info->pri_id == 0x3)) { LOG_ERROR("BUG: non-CFI flashes using the Intel commandset are not yet supported"); exit(-1); }