X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fflash%2Fnor%2Fnon_cfi.c;h=7636a3670e0519f85de025cbb6dfa7b36b3fa766;hb=a252cb064d13d96763447af20eb457f1fce080e5;hp=f98b108014c621232c38b54cd583e50bb94014d2;hpb=fe9228a32db930be297d4d3b35ffb94d6de1b9ab;p=openocd.git diff --git a/src/flash/nor/non_cfi.c b/src/flash/nor/non_cfi.c index f98b108014..7636a3670e 100644 --- a/src/flash/nor/non_cfi.c +++ b/src/flash/nor/non_cfi.c @@ -17,22 +17,23 @@ * 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. * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * ***************************************************************************/ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include "non_cfi.h" +#include "imp.h" #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, @@ -42,8 +43,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) } }, @@ -56,8 +56,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) } }, @@ -70,8 +69,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) } }, @@ -84,11 +82,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, @@ -98,8 +108,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) } }, @@ -112,8 +121,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), @@ -129,8 +137,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), @@ -141,9 +148,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 */ @@ -153,8 +160,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) } }, @@ -167,8 +173,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) } }, @@ -181,8 +186,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) } }, @@ -195,8 +212,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) } }, @@ -209,8 +225,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) } }, @@ -223,11 +238,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 */ @@ -237,8 +264,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), @@ -254,8 +280,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), @@ -271,14 +296,45 @@ 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, + .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(15, 64*KB), + ERASE_REGION(1, 32*KB), + ERASE_REGION(2, 8*KB), + ERASE_REGION(1, 16*KB) + } + }, + { + .mfr = CFI_MFR_FUJITSU, + .id = 0xba, /* 29LV400BC */ + .pri_id = 0x02, + .dev_size = 512*KB, + .interface_desc = 0x1, /* x8 or x16 device w/ nBYTE */ + .max_buf_write_size = 0x00, + .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(7, 64*KB) + } + }, { .mfr = CFI_MFR_AMIC, .id = 0xb31a, /* A29L800A */ @@ -288,8 +344,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), @@ -305,8 +360,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), @@ -323,8 +377,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,14 +393,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 */ @@ -357,8 +425,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) @@ -373,8 +440,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) @@ -389,8 +455,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), @@ -405,16 +470,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 */ @@ -428,10 +496,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; @@ -451,11 +521,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'; @@ -467,7 +540,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; @@ -483,8 +555,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); }