diff --git a/chipdrivers.h b/chipdrivers.h index 57b134082..4ece42e3b 100644 --- a/chipdrivers.h +++ b/chipdrivers.h @@ -139,6 +139,7 @@ uint8_t oddparity(uint8_t val); void toggle_ready_jedec(const struct flashctx *flash, chipaddr dst); void data_polling_jedec(const struct flashctx *flash, chipaddr dst, uint8_t data); int probe_jedec(struct flashctx *flash); +int probe_jedec_29gl(struct flashctx *flash); int write_jedec(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); int write_jedec_1(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); int erase_sector_jedec(struct flashctx *flash, unsigned int page, unsigned int pagesize); diff --git a/flashchips.c b/flashchips.c index e8ac78930..a1166e07a 100644 --- a/flashchips.c +++ b/flashchips.c @@ -4891,6 +4891,120 @@ const struct flashchip flashchips[] = { .voltage = {2700, 3600}, }, + { + .vendor = "Eon", + .name = "EN29GL064(A)B", + .bustype = BUS_PARALLEL, + .manufacture_id = EON_ID, + .model_id = EON_EN29GL064B, + .total_size = 8192, + .page_size = 128 * 1024, /* actual page size is 16 */ + .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec_29gl, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { + {8 * 1024, 8}, + {64 * 1024, 127}, + }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {8 * 1024 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + }, + }, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {2700, 3600}, + }, + + { + .vendor = "Eon", + .name = "EN29GL064(A)T", + .bustype = BUS_PARALLEL, + .manufacture_id = EON_ID, + .model_id = EON_EN29GL064T, + .total_size = 8192, + .page_size = 128 * 1024, /* actual page size is 16 */ + .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec_29gl, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { + {64 * 1024, 127}, + {8 * 1024, 8}, + }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {8 * 1024 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + }, + }, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {2700, 3600}, + }, + + { + .vendor = "Eon", + .name = "EN29GL064H/L", + .bustype = BUS_PARALLEL, + .manufacture_id = EON_ID, + .model_id = EON_EN29GL064HL, + .total_size = 8192, + .page_size = 128 * 1024, /* actual page size is 16 */ + .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec_29gl, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { {64 * 1024, 128} }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {8 * 1024 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + }, + }, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {2700, 3600}, + }, + + { + .vendor = "Eon", + .name = "EN29GL128", + .bustype = BUS_PARALLEL, + .manufacture_id = EON_ID, + .model_id = EON_EN29GL128HL, + .total_size = 16384, + .page_size = 128 * 1024, /* actual page size is 16 */ + .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec_29gl, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { {128 * 1024, 128} }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {16 * 1024 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + }, + }, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {2700, 3600}, + }, + { .vendor = "Fujitsu", .name = "MBM29F004BC", @@ -6092,6 +6206,120 @@ const struct flashchip flashchips[] = { .voltage = {3000, 3600}, }, + { + .vendor = "ISSI", + .name = "IS29GL064B", + .bustype = BUS_PARALLEL, + .manufacture_id = ISSI_ID, + .model_id = ISSI_PMC_IS29GL064B, + .total_size = 8192, + .page_size = 128 * 1024, /* actual page size is 16 */ + .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec_29gl, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { + {8 * 1024, 8}, + {64 * 1024, 127}, + }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {8 * 1024 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + }, + }, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {2700, 3600}, + }, + + { + .vendor = "ISSI", + .name = "IS29GL064T", + .bustype = BUS_PARALLEL, + .manufacture_id = ISSI_ID, + .model_id = ISSI_PMC_IS29GL064T, + .total_size = 8192, + .page_size = 128 * 1024, /* actual page size is 16 */ + .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec_29gl, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { + {64 * 1024, 127}, + {8 * 1024, 8}, + }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {8 * 1024 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + }, + }, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {2700, 3600}, + }, + + { + .vendor = "ISSI", + .name = "IS29GL064H/L", + .bustype = BUS_PARALLEL, + .manufacture_id = ISSI_ID, + .model_id = ISSI_PMC_IS29GL064HL, + .total_size = 8192, + .page_size = 128 * 1024, /* actual page size is 16 */ + .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec_29gl, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { {64 * 1024, 128} }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {8 * 1024 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + }, + }, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {2700, 3600}, + }, + + { + .vendor = "ISSI", + .name = "IS29GL128H/L", + .bustype = BUS_PARALLEL, + .manufacture_id = ISSI_ID, + .model_id = ISSI_PMC_IS29GL128HL, + .total_size = 16384, + .page_size = 128 * 1024, /* actual page size is 16 */ + .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec_29gl, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { {128 * 1024, 128} }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {16 * 1024 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + }, + }, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {2700, 3600}, + }, + { .vendor = "Macronix", .name = "MX23L3254", @@ -7197,6 +7425,207 @@ const struct flashchip flashchips[] = { .voltage = {4500, 5500}, }, + { + .vendor = "Macronix", + .name = "MX29GL320EB", + .bustype = BUS_PARALLEL, + .manufacture_id = MACRONIX_ID, + .model_id = MACRONIX_MX29GL320EB, + .total_size = 4096, + .page_size = 128 * 1024, /* actual page size is 16 */ + .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec_29gl, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { + {8 * 1024, 8}, + {64 * 1024, 63}, + }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {4 * 1024 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + }, + }, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {2700, 3600}, + }, + + { + .vendor = "Macronix", + .name = "MX29GL320ET", + .bustype = BUS_PARALLEL, + .manufacture_id = MACRONIX_ID, + .model_id = MACRONIX_MX29GL320ET, + .total_size = 4096, + .page_size = 128 * 1024, /* actual page size is 16 */ + .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec_29gl, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { + {64 * 1024, 63}, + {8 * 1024, 8}, + }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {4 * 1024 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + }, + }, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {2700, 3600}, + }, + + { + .vendor = "Macronix", + .name = "MX29GL320EH/L", + .bustype = BUS_PARALLEL, + .manufacture_id = MACRONIX_ID, + .model_id = MACRONIX_MX29GL320EHL, + .total_size = 4096, + .page_size = 128 * 1024, /* actual page size is 16 */ + .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec_29gl, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { {64 * 1024, 64} }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {4 * 1024 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + }, + }, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {2700, 3600}, + }, + + { + .vendor = "Macronix", + .name = "MX29GL640EB", + .bustype = BUS_PARALLEL, + .manufacture_id = MACRONIX_ID, + .model_id = MACRONIX_MX29GL640EB, + .total_size = 8192, + .page_size = 128 * 1024, /* actual page size is 16 */ + .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec_29gl, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { + {8 * 1024, 8}, + {64 * 1024, 127}, + }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {8 * 1024 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + }, + }, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {2700, 3600}, + }, + + { + .vendor = "Macronix", + .name = "MX29GL640ET", + .bustype = BUS_PARALLEL, + .manufacture_id = MACRONIX_ID, + .model_id = MACRONIX_MX29GL640ET, + .total_size = 8192, + .page_size = 128 * 1024, /* actual page size is 16 */ + .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec_29gl, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { + {64 * 1024, 127}, + {8 * 1024, 8}, + }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {8 * 1024 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + }, + }, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {2700, 3600}, + }, + + { + .vendor = "Macronix", + .name = "MX29GL640EH/L", + .bustype = BUS_PARALLEL, + .manufacture_id = MACRONIX_ID, + .model_id = MACRONIX_MX29GL640EHL, + .total_size = 8192, + .page_size = 128 * 1024, /* actual page size is 16 */ + .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec_29gl, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { {64 * 1024, 128} }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {8 * 1024 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + }, + }, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {2700, 3600}, + }, + + { + .vendor = "Macronix", + .name = "MX29GL128F", + .bustype = BUS_PARALLEL, + .manufacture_id = MACRONIX_ID, + .model_id = MACRONIX_MX29GL128F, + .total_size = 16384, + .page_size = 128 * 1024, /* actual page size is 16 */ + .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec_29gl, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { {128 * 1024, 128} }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {16 * 1024 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + }, + }, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {2700, 3600}, + }, + { .vendor = "Macronix", .name = "MX29LV040", @@ -13053,6 +13482,207 @@ const struct flashchip flashchips[] = { .voltage = {4500, 5500}, }, + { + .vendor = "Winbond", + .name = "W29GL032CB", + .bustype = BUS_PARALLEL, + .manufacture_id = AMD_ID, /* WTF: "Industry Standard compatible Manufacturer ID code of 01h" */ + .model_id = WINBOND_W29GL032CB, + .total_size = 4096, + .page_size = 128 * 1024, /* actual page size is 16 */ + .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec_29gl, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { + {8 * 1024, 8}, + {64 * 1024, 63}, + }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {4 * 1024 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + }, + }, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {2700, 3600}, + }, + + { + .vendor = "Winbond", + .name = "W29GL032CT", + .bustype = BUS_PARALLEL, + .manufacture_id = AMD_ID, /* WTF: "Industry Standard compatible Manufacturer ID code of 01h" */ + .model_id = WINBOND_W29GL032CT, + .total_size = 4096, + .page_size = 128 * 1024, /* actual page size is 16 */ + .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec_29gl, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { + {64 * 1024, 63}, + {8 * 1024, 8}, + }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {4 * 1024 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + }, + }, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {2700, 3600}, + }, + + { + .vendor = "Winbond", + .name = "W29GL032CH/L", + .bustype = BUS_PARALLEL, + .manufacture_id = AMD_ID, /* WTF: "Industry Standard compatible Manufacturer ID code of 01h" */ + .model_id = WINBOND_W29GL032CHL, + .total_size = 4096, + .page_size = 128 * 1024, /* actual page size is 16 */ + .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec_29gl, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { {64 * 1024, 64} }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {4 * 1024 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + }, + }, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {2700, 3600}, + }, + + { + .vendor = "Winbond", + .name = "W29GL064CB", + .bustype = BUS_PARALLEL, + .manufacture_id = AMD_ID, /* WTF: "Industry Standard compatible Manufacturer ID code of 01h" */ + .model_id = WINBOND_W29GL064CB, + .total_size = 8192, + .page_size = 128 * 1024, /* actual page size is 16 */ + .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec_29gl, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { + {8 * 1024, 8}, + {64 * 1024, 127}, + }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {8 * 1024 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + }, + }, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {2700, 3600}, + }, + + { + .vendor = "Winbond", + .name = "W29GL064CT", + .bustype = BUS_PARALLEL, + .manufacture_id = AMD_ID, /* WTF: "Industry Standard compatible Manufacturer ID code of 01h" */ + .model_id = WINBOND_W29GL064CT, + .total_size = 8192, + .page_size = 128 * 1024, /* actual page size is 16 */ + .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec_29gl, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { + {64 * 1024, 127}, + {8 * 1024, 8}, + }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {8 * 1024 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + }, + }, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {2700, 3600}, + }, + + { + .vendor = "Winbond", + .name = "W29GL064CH/L", + .bustype = BUS_PARALLEL, + .manufacture_id = AMD_ID, /* WTF: "Industry Standard compatible Manufacturer ID code of 01h" */ + .model_id = WINBOND_W29GL064CHL, + .total_size = 8192, + .page_size = 128 * 1024, /* actual page size is 16 */ + .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec_29gl, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { {64 * 1024, 128} }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {8 * 1024 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + }, + }, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {2700, 3600}, + }, + + { + .vendor = "Winbond", + .name = "W29GL128C", + .bustype = BUS_PARALLEL, + .manufacture_id = AMD_ID, /* WTF: "Industry Standard compatible Manufacturer ID code of 01h" */ + .model_id = WINBOND_W29GL128CHL, + .total_size = 16384, + .page_size = 128 * 1024, /* actual page size is 16 */ + .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, + .tested = TEST_UNTESTED, + .probe = probe_jedec_29gl, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { {128 * 1024, 128} }, + .block_erase = erase_sector_jedec, + }, { + .eraseblocks = { {16 * 1024 * 1024, 1} }, + .block_erase = erase_chip_block_jedec, + }, + }, + .write = write_jedec_1, + .read = read_memmapped, + .voltage = {2700, 3600}, + }, + { .vendor = "Winbond", .name = "W39F010", diff --git a/flashchips.h b/flashchips.h index 558971401..029bae81d 100644 --- a/flashchips.h +++ b/flashchips.h @@ -29,9 +29,9 @@ * entry of each section should be the manufacturer ID, followed by the * list of devices from that manufacturer (sorted by device IDs). * - * All LPC/FWH parts (parallel flash) have 8-bit device IDs if there is no + * Most LPC/FWH parts (parallel flash) have 8-bit device IDs if there is no * continuation code. - * SPI parts have 16-bit device IDs if they support RDID. + * SPI parts have at least 16-bit device IDs if they support RDID. */ #define GENERIC_MANUF_ID 0xFFFF /* Check if there is a vendor ID */ @@ -290,6 +290,11 @@ #define EON_EN29LV640B 0xCB #define EON_EN29F002T 0x7F92 /* Same as EN29F002A */ #define EON_EN29F002B 0x7F97 /* Same as EN29F002AN */ +#define EON_EN29GL064HL 0x7E0C01 /* Uniform Sectors, WP protects Top OR Bottom sector */ +#define EON_EN29GL064T 0x7E1001 /* Same ID as EN29GL064AT */ +#define EON_EN29GL064B 0x7E1000 /* Same ID as EN29GL064AB */ +#define EON_EN29GL128HL 0x7F2101 /* Uniform Sectors, WP protects Top OR Bottom sector */ +#define EON_EN29GL256HL 0x7F2201 /* Uniform Sectors, WP protects Top OR Bottom sector */ #define EXCEL_ID 0x7F7F7F7F4A /* Excel Semiconductor Inc. (ESI) resides in bank 5 */ #define EXCEL_ID_NOPREFIX 0x4A /* ESI, missing 0x7F prefix */ @@ -356,6 +361,7 @@ #define GIGADEVICE_GD25LQ32 0x6016 #define GIGADEVICE_GD25LQ64 0x6017 /* Same as GD25LQ64B (which is faster) */ #define GIGADEVICE_GD25LQ128 0x6018 +#define GIGADEVICE_GD29GL064CAB 0x7E0601 #define HYUNDAI_ID 0xAD /* Hyundai */ #define HYUNDAI_HY29F400T 0x23 /* Same as HY29F400AT */ @@ -424,7 +430,14 @@ #define SHARP_LH28F008SA 0xA2 /* Sharp chip, Intel Vendor ID */ #define SHARP_LH28F008SC 0xA6 /* Sharp chip, Intel Vendor ID */ -#define ISSI_ID 0xD5 /* ISSI Integrated Silicon Solutions */ +#define ISSI_ID 0xD5 /* ISSI Integrated Silicon Solutions, see also PMC. */ +#define ISSI_PMC_IS29GL032B 0xF9 +#define ISSI_PMC_IS29GL032T 0xF6 +#define ISSI_PMC_IS29GL064B 0x7E1000 +#define ISSI_PMC_IS29GL064T 0x7E1001 +#define ISSI_PMC_IS29GL064HL 0x7E0C01 +#define ISSI_PMC_IS29GL128HL 0x7E2101 +#define ISSI_PMC_IS29GL256HL 0x7E2201 #define MACRONIX_ID 0xC2 /* Macronix (MX) */ /* Mask ROMs */ @@ -468,6 +481,16 @@ #define MACRONIX_MX29F400T 0x23 /* Same as MX29F400CT */ #define MACRONIX_MX29F800B 0x58 #define MACRONIX_MX29F800T 0xD6 +#define MACRONIX_MX29GL320EB 0x7E1A00 +#define MACRONIX_MX29GL320ET 0x7E1A01 +#define MACRONIX_MX29GL320EHL 0x7E1D00 +#define MACRONIX_MX29GL640EB 0x7E1000 +#define MACRONIX_MX29GL640ET 0x7E1001 +#define MACRONIX_MX29GL640EHL 0x7E0C01 +#define MACRONIX_MX29GL128F 0x7E2101 /* Same as MX29GL128E */ +#define MACRONIX_MX29GL256F 0x7E2201 /* Same as MX29GL256E */ +#define MACRONIX_MX29GL512F 0x7E2301 +#define MACRONIX_MX68GL1G0F 0x7E2801 #define MACRONIX_MX29LV002CB 0x5A #define MACRONIX_MX29LV002CT 0x59 #define MACRONIX_MX29LV004B 0xB6 /* Same as MX29LV004CB */ @@ -506,8 +529,9 @@ /* * Programmable Micro Corp is listed in JEP106W in bank 2, so it should * have a 0x7F continuation code prefix. - * Apparently this name is owned by "Chingis Technology Corporation" http://www.chingistek.com which is now a - * subsidiary of ISSI. They continue to use the PMC manufacturer ID nevertheless. + * Apparently PMC was renamed to "Chingis Technology Corporation" http://www.chingistek.com which is now a + * subsidiary of ISSI. They continue to use the PMC manufacturer ID (instead of ISSI's) nevertheless, even for + * new chips with IS* model numbers. */ #define PMC_ID 0x7F9D /* PMC */ #define PMC_ID_NOPREFIX 0x9D /* PMC, missing 0x7F prefix */ @@ -557,12 +581,10 @@ #define SHARP_LHF00L02 0xC9 /* Same as LHF00L06/LHF00L07 */ #define SHARP_LHF00L04 0xCF /* Same as LHF00L03/LHF00L05 */ -/* - * Spansion was previously a joint venture of AMD and Fujitsu. - * S25 chips are SPI. The first device ID byte is memory type and - * the second device ID byte is memory capacity. - */ +/* Spansion was previously a joint venture of AMD and Fujitsu. */ #define SPANSION_ID 0x01 /* Spansion, same ID as AMD */ +/* S25 chips are SPI. The first device ID byte is memory type and + * the second device ID byte is memory capacity. */ #define SPANSION_S25FL004A 0x0212 #define SPANSION_S25FL008A 0x0213 #define SPANSION_S25FL016A 0x0214 @@ -577,6 +599,40 @@ #define SPANSION_S25FL132K 0x4016 #define SPANSION_S25FL164K 0x4017 +/* Spansion 29GL families got a suffix indicating the process technology but share the same 3-Byte IDs. They can + * however be differentiated by CFI byte 45h. Some versions exist which have special top or bottom boot sectors + * and various WP configurations (not heeded in the table below). + * + * Suf. Process Sector Sz Rd Page Wr Page Data Width OTP Sz Min Size Max Size + * A 200 nm 64 kB 8 B 32 B x8/x16 256 B 16Mb/ 2MB 64Mb/ 8MB + * M 230 nm 64 kB 8 B 32 B x8/x16 256 B 32Mb/ 4MB 256Mb/ 32MB + * N* 110 nm 64 kB 16 B 32 B x8/x16 256 B 32Mb/ 4MB 64Mb/ 8MB + * N* 110 nm 128 kB 16 B 32 B x8/x16 256 B 128Mb/16MB 256Mb/ 64MB + * P 90 nm 128 kB 16 B 64 B x8/x16 256 B 128Mb/16MB 2Gb/256MB + * S 65 nm 128 kB 32 B 512 B x8 only 512 B 128Mb/16MB 2Gb/256MB + * + * For the N series there are two subgroups: the 4 and 8MB devices (S29GL032N, S29GL064N) have 64 kB erase + * sectors while the bigger chips got 128 kB sectors. + * Each series includes multiple models varying in speedgrade, boot block configurations etc. + */ +#define SPANSION_S29GL016_1 0xC4 /* Top Boot Sector, WP protects Top 2 sectors */ +#define SPANSION_S29GL016_2 0x49 /* Bottom Boot Sector, WP protects Bottom 2 sectors */ +/* Same IDs for S29GL032A, S29GL032M, S29GL032N (variations) */ +#define SPANSION_S29GL032_1289 0x7E1D00 /* Uniform Sectors, WP protects Top OR Bottom sector */ +#define SPANSION_S29GL032_3 0x7E1A01 /* Top Boot Sector, WP protects Top 2 sectors */ +#define SPANSION_S29GL032_4 0x7E1A00 /* Bottom Boot Sector, WP protects Bottom 2 sectors */ +/* Same IDs for S29GL064A, S29GL064M, S29GL064N, S29GL064S (variations) */ +#define SPANSION_S29GL064_1289 0x7E0C01 /* Uniform Sectors, WP protects Top OR Bottom sector */ +#define SPANSION_S29GL064_3 0x7E1001 /* Top Boot Sector, WP protects Top 2 sectors */ +#define SPANSION_S29GL064_4 0x7E1000 /* Bottom Boot Sector, WP protects Bottom 2 sectors */ +#define SPANSION_S29GL064_567 0x7E1301 /* x16 only, Uniform Sectors */ + +#define SPANSION_S29GL128 0x7E2101 /* Same ID for S29GL128M, S29GL128N, S29GL128P, S29GL128S */ +#define SPANSION_S29GL256 0x7E2201 /* Same ID for S29GL256M, S29GL256N, S29GL256P, S29GL256S */ +#define SPANSION_S29GL512 0x7E2301 /* Same ID for S29GL512P, S29GL512S */ +#define SPANSION_S29GL01G 0x7E2801 /* Same ID for S29GL01GP, S29GL01GS */ +#define SPANSION_S70GL02G 0x7E4801 /* Same ID for S70GL02GP, S70GL02GS; based on two S29GL01G dies respectively */ + /* * SST25 chips are SPI, first byte of device ID is memory type, second * byte of device ID is related to log(bitsize) at least for some chips. @@ -776,6 +832,14 @@ #define WINBOND_W29C020 0x45 /* Same as W29C020C, W29C022 and ASD AE29F2008 */ #define WINBOND_W29C040 0x46 /* Same as W29C040P */ #define WINBOND_W29C512A 0xC8 /* Same as W29EE512 */ +#define WINBOND_W29GL032CHL 0x7E1D01 /* Uniform Sectors, WP protects Top OR Bottom sector */ +#define WINBOND_W29GL032CB 0x7E1A00 /* Top Boot Sector, WP protects Top 2 sectors */ +#define WINBOND_W29GL032CT 0x7E1A01 /* Bottom Boot Sector, WP protects Bottom 2 sectors */ +#define WINBOND_W29GL064CHL 0x7E0C01 /* Uniform Sectors, WP protects Top OR Bottom sector */ +#define WINBOND_W29GL064CB 0x7E1000 /* Top Boot Sector, WP protects Top 2 sectors */ +#define WINBOND_W29GL064CT 0x7E1001 /* Bottom Boot Sector, WP protects Bottom 2 sectors */ +#define WINBOND_W29GL128CHL 0x7E2101 /* Uniform Sectors, WP protects Top OR Bottom sector */ +#define WINBOND_W29GL256HL 0x7E2201 /* Same ID for W29GL0256P and W29GL0256S; uniform Sectors, WP protects Top OR Bottom sector */ #define WINBOND_W39F010 0xA1 #define WINBOND_W39L010 0x31 #define WINBOND_W39L020 0xB5 diff --git a/jedec.c b/jedec.c index 29fdae856..59bec6f35 100644 --- a/jedec.c +++ b/jedec.c @@ -121,6 +121,55 @@ static void start_program_jedec_common(const struct flashctx *flash, unsigned in chip_writeb(flash, 0xA0, bios + (0x5555 & mask)); } +int probe_jedec_29gl(struct flashctx *flash) +{ + unsigned int mask = getaddrmask(flash->chip); + chipaddr bios = flash->virtual_memory; + const struct flashchip *chip = flash->chip; + + /* Reset chip to a clean slate */ + chip_writeb(flash, 0xF0, bios + (0x5555 & mask)); + + /* Issue JEDEC Product ID Entry command */ + chip_writeb(flash, 0xAA, bios + (0x5555 & mask)); + chip_writeb(flash, 0x55, bios + (0x2AAA & mask)); + chip_writeb(flash, 0x90, bios + (0x5555 & mask)); + + /* Read product ID */ + // FIXME: Continuation loop, second byte is at word 0x100/byte 0x200 + uint32_t man_id = chip_readb(flash, bios + 0x00); + uint32_t dev_id = (chip_readb(flash, bios + 0x01) << 16) | + (chip_readb(flash, bios + 0x0E) << 8) | + (chip_readb(flash, bios + 0x0F) << 0); + + /* Issue JEDEC Product ID Exit command */ + chip_writeb(flash, 0xF0, bios + (0x5555 & mask)); + + msg_cdbg("%s: man_id 0x%02x, dev_id 0x%06x", __func__, man_id, dev_id); + if (!oddparity(man_id)) + msg_cdbg(", man_id parity violation"); + + /* Read the product ID location again. We should now see normal flash contents. */ + uint32_t flashcontent1 = chip_readb(flash, bios + 0x00); // FIXME: Continuation loop + uint32_t flashcontent2 = (chip_readb(flash, bios + 0x01) << 16) | + (chip_readb(flash, bios + 0x0E) << 8) | + (chip_readb(flash, bios + 0x0F) << 0); + + if (man_id == flashcontent1) + msg_cdbg(", man_id seems to be normal flash content"); + if (dev_id == flashcontent2) + msg_cdbg(", dev_id seems to be normal flash content"); + + msg_cdbg("\n"); + if (man_id != chip->manufacture_id || dev_id != chip->model_id) + return 0; + + if (chip->feature_bits & FEATURE_REGISTERMAP) + map_flash_registers(flash); + + return 1; +} + static int probe_jedec_common(struct flashctx *flash, unsigned int mask) { chipaddr bios = flash->virtual_memory;