Commit 54aaa4ae authored by Stefan Tauner's avatar Stefan Tauner
Browse files

Add support for Intel S33 series flash chips


This includes:
Bottom boot block:
* 16Mb/2MB:
  QB25F160S33B8, QB25F016S33B8, QH25F160S33B8, QH25F016S33B8
* 32Mb/4MB:
  QB25F320S33B8, QH25F320S33B8
* 64Mb/8MB:
  QB25F640S33B8, QH25F640S33B8

Top boot block:
* 16Mb/2MB:
  QB25F160S33T8, QB25F016S33T8, QH25F160S33T8, QH25F016S33T8
* 32Mb/4MB:
  QB25F320S33T8, QH25F320S33T8
* 64Mb/8MB:
  QB25F640S33T8, QH25F640S33T8

At least some seem to be marketed by other vendors (too?) but also with
Intel's vendor ID.

Besides a 0xC7 chip erase and a 0xD8 uniform 64kB block erase they
support also erasing the top/bottom 8 8kB blocks with opcode 0x40.
But since this command fails for all addresses outside those ranges,
it is not easily implemented with flashrom's current code base and
hence left out.

Corresponding to flashrom svn r1636.
Signed-off-by: default avatarStefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
Acked-by: default avatarStefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
parent 9530a022
......@@ -77,6 +77,8 @@ int spi_disable_blockprotect_at25df_sec(struct flashctx *flash);
int spi_disable_blockprotect_at25f512b(struct flashctx *flash);
int spi_disable_blockprotect_at25fs010(struct flashctx *flash);
int spi_disable_blockprotect_at25fs040(struct flashctx *flash);
int spi_prettyprint_status_register_s33(struct flashctx *flash);
int spi_disable_blockprotect_s33(struct flashctx *flash);
int spi_prettyprint_status_register_sst25(struct flashctx *flash);
int spi_prettyprint_status_register_sst25vf016(struct flashctx *flash);
int spi_prettyprint_status_register_sst25vf040b(struct flashctx *flash);
......
......@@ -4420,6 +4420,240 @@ const struct flashchip flashchips[] = {
.voltage = {4500, 5500},
},
{
.vendor = "Intel",
.name = "25F160S33B8",
.bustype = BUS_SPI,
.manufacture_id = INTEL_ID,
.model_id = INTEL_25F160S33B8,
.total_size = 2048,
.page_size = 256,
/* OTP: 506B total (2x 8B, 30x 16B, 1x 10B); read 0x4B; write 0x42 */
.feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
.tested = TEST_UNTESTED,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
.block_erasers =
{
{
/* This chip supports erasing of the 8 so-called "parameter blocks" with
* opcode 0x40. Trying to access an address outside these 8 8kB blocks does
* have no effect on the memory contents, but sets a flag in the SR.
.eraseblocks = {
{8 * 1024, 8},
{64 * 1024, 31} // inaccessible
},
.block_erase = spi_block_erase_40,
}, { */
.eraseblocks = { {64 * 1024, 32} },
.block_erase = spi_block_erase_d8,
}, {
.eraseblocks = { {2 * 1024 * 1024, 1} },
.block_erase = spi_block_erase_c7,
}
},
.printlock = spi_prettyprint_status_register_s33,
.unlock = spi_disable_blockprotect_s33,
.write = spi_chip_write_256,
.read = spi_chip_read, /* also fast read 0x0B */
.voltage = {2700, 3600},
},
{
.vendor = "Intel",
.name = "25F160S33T8",
.bustype = BUS_SPI,
.manufacture_id = INTEL_ID,
.model_id = INTEL_25F160S33T8,
.total_size = 2048,
.page_size = 256,
/* OTP: 506B total (2x 8B, 30x 16B, 1x 10B); read 0x4B; write 0x42 */
.feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
.tested = TEST_UNTESTED,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
.block_erasers =
{
{
/* This chip supports erasing of the 8 so-called "parameter blocks" with
* opcode 0x40. Trying to access an address outside these 8 8kB blocks does
* have no effect on the memory contents, but sets a flag in the SR.
.eraseblocks = {
{64 * 1024, 31}, // inaccessible
{8 * 1024, 8}
},
.block_erase = spi_block_erase_40,
}, { */
.eraseblocks = { {64 * 1024, 32} },
.block_erase = spi_block_erase_d8,
}, {
.eraseblocks = { {2 * 1024 * 1024, 1} },
.block_erase = spi_block_erase_c7,
}
},
.printlock = spi_prettyprint_status_register_s33,
.unlock = spi_disable_blockprotect_s33,
.write = spi_chip_write_256,
.read = spi_chip_read, /* also fast read 0x0B */
.voltage = {2700, 3600},
},
{
.vendor = "Intel",
.name = "25F320S33B8",
.bustype = BUS_SPI,
.manufacture_id = INTEL_ID,
.model_id = INTEL_25F320S33B8,
.total_size = 4096,
.page_size = 256,
/* OTP: 506B total (2x 8B, 30x 16B, 1x 10B); read 0x4B; write 0x42 */
.feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
.tested = TEST_UNTESTED,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
.block_erasers =
{
{
/* This chip supports erasing of the 8 so-called "parameter blocks" with
* opcode 0x40. Trying to access an address outside these 8 8kB blocks does
* have no effect on the memory contents, but sets a flag in the SR.
.eraseblocks = {
{8 * 1024, 8},
{64 * 1024, 63} // inaccessible
},
.block_erase = spi_block_erase_40,
}, { */
.eraseblocks = { {64 * 1024, 64} },
.block_erase = spi_block_erase_d8,
}, {
.eraseblocks = { {4 * 1024 * 1024, 1} },
.block_erase = spi_block_erase_c7,
}
},
.printlock = spi_prettyprint_status_register_s33,
.unlock = spi_disable_blockprotect_s33,
.write = spi_chip_write_256,
.read = spi_chip_read, /* also fast read 0x0B */
.voltage = {2700, 3600},
},
{
.vendor = "Intel",
.name = "25F320S33T8",
.bustype = BUS_SPI,
.manufacture_id = INTEL_ID,
.model_id = INTEL_25F320S33T8,
.total_size = 4096,
.page_size = 256,
/* OTP: 506B total (2x 8B, 30x 16B, 1x 10B); read 0x4B; write 0x42 */
.feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
.tested = TEST_UNTESTED,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
.block_erasers =
{
{
/* This chip supports erasing of the 8 so-called "parameter blocks" with
* opcode 0x40. Trying to access an address outside these 8 8kB blocks does
* have no effect on the memory contents, but sets a flag in the SR.
.eraseblocks = {
{64 * 1024, 63}, // inaccessible
{8 * 1024, 8}
},
.block_erase = spi_block_erase_40,
}, { */
.eraseblocks = { {64 * 1024, 64} },
.block_erase = spi_block_erase_d8,
}, {
.eraseblocks = { {4 * 1024 * 1024, 1} },
.block_erase = spi_block_erase_c7,
}
},
.printlock = spi_prettyprint_status_register_s33,
.unlock = spi_disable_blockprotect_s33,
.write = spi_chip_write_256,
.read = spi_chip_read, /* also fast read 0x0B */
.voltage = {2700, 3600},
},
{
.vendor = "Intel",
.name = "25F640S33B8",
.bustype = BUS_SPI,
.manufacture_id = INTEL_ID,
.model_id = INTEL_25F640S33B8,
.total_size = 8192,
.page_size = 256,
/* OTP: 506B total (2x 8B, 30x 16B, 1x 10B); read 0x4B; write 0x42 */
.feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
.tested = TEST_UNTESTED,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
.block_erasers =
{
{
/* This chip supports erasing of the 8 so-called "parameter blocks" with
* opcode 0x40. Trying to access an address outside these 8 8kB blocks does
* have no effect on the memory contents, but sets a flag in the SR.
.eraseblocks = {
{8 * 1024, 8},
{64 * 1024, 127} // inaccessible
},
.block_erase = spi_block_erase_40,
}, { */
.eraseblocks = { {64 * 1024, 128} },
.block_erase = spi_block_erase_d8,
}, {
.eraseblocks = { {8 * 1024 * 1024, 1} },
.block_erase = spi_block_erase_c7,
}
},
.printlock = spi_prettyprint_status_register_s33,
.unlock = spi_disable_blockprotect_s33,
.write = spi_chip_write_256,
.read = spi_chip_read, /* also fast read 0x0B */
.voltage = {2700, 3600},
},
{
.vendor = "Intel",
.name = "25F640S33T8",
.bustype = BUS_SPI,
.manufacture_id = INTEL_ID,
.model_id = INTEL_25F640S33T8,
.total_size = 8192,
.page_size = 256,
/* OTP: 506B total (2x 8B, 30x 16B, 1x 10B); read 0x4B; write 0x42 */
.feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
.tested = TEST_UNTESTED,
.probe = probe_spi_rdid,
.probe_timing = TIMING_ZERO,
.block_erasers =
{
{
/* This chip supports erasing of the 8 so-called "parameter blocks" with
* opcode 0x40. Trying to access an address outside these 8 8kB blocks does
* have no effect on the memory contents, but sets a flag in the SR.
.eraseblocks = {
{64 * 1024, 127}, // inaccessible
{8 * 1024, 8}
},
.block_erase = spi_block_erase_40,
}, { */
.eraseblocks = { {64 * 1024, 128} },
.block_erase = spi_block_erase_d8,
}, {
.eraseblocks = { {8 * 1024 * 1024, 1} },
.block_erase = spi_block_erase_c7,
}
},
.printlock = spi_prettyprint_status_register_s33,
.unlock = spi_disable_blockprotect_s33,
.write = spi_chip_write_256,
.read = spi_chip_read, /* also fast read 0x0B */
.voltage = {2700, 3600},
},
{
.vendor = "Intel",
.name = "28F001BN/BX-B",
......
......@@ -364,6 +364,12 @@
#define INTEL_28F008B3B 0xD3 /* 28F008B3-B */
#define INTEL_28F004B3T 0xD4 /* 28F004B3-T */
#define INTEL_28F004B3B 0xD5 /* 28F004B3-B */
#define INTEL_25F160S33B8 0x8911 /* Same as 25F016S33B8 */
#define INTEL_25F320S33B8 0x8912
#define INTEL_25F640S33B8 0x8913
#define INTEL_25F160S33T8 0x8915 /* Same as 25F016S33T8 */
#define INTEL_25F320S33T8 0x8916
#define INTEL_25F640S33T8 0x8917
#define SHARP_LH28F008SA 0xA2 /* Sharp chip, Intel Vendor ID */
#define SHARP_LH28F008SC 0xA6 /* Sharp chip, Intel Vendor ID */
......
......@@ -468,6 +468,29 @@ int spi_disable_blockprotect_at25fs040(struct flashctx *flash)
return spi_disable_blockprotect_generic(flash, 0x7C, 1 << 7, 0);
}
/* === Intel === */
/* TODO: Clear P_FAIL and E_FAIL with Clear SR Fail Flags Command (30h) here? */
int spi_disable_blockprotect_s33(struct flashctx *flash)
{
return spi_disable_blockprotect_generic(flash, 0x1C, 1 << 7, 0);
}
int spi_prettyprint_status_register_s33(struct flashctx *flash)
{
uint8_t status = spi_read_status_register(flash);
msg_cdbg("Chip status register is %02x\n", status);
spi_prettyprint_status_register_srwd(status);
msg_cdbg("Chip status register: Program Fail Flag (P_FAIL) is %sset\n",
(status & (1 << 6)) ? "" : "not ");
msg_cdbg("Chip status register: Erase Fail Flag (E_FAIL) is %sset\n",
(status & (1 << 5)) ? "" : "not ");
spi_prettyprint_status_register_bp(status, 2);
spi_prettyprint_status_register_welwip(status);
return 0;
}
/* === SST === */
static void spi_prettyprint_status_register_sst25_common(uint8_t status)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment