summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Tauner <stefan.tauner@alumni.tuwien.ac.at>2012-12-29 15:04:12 +0000
committerStefan Tauner <stefan.tauner@alumni.tuwien.ac.at>2012-12-29 15:04:12 +0000
commit54aaa4ae2bb4026ae7acbf3e0aafe8542aaff2a4 (patch)
treeb394950b3bd52b2490e1da77a1c497516d6bfd06
parent9530a02212bd48aca32752250c4e2ec91e24d3b6 (diff)
downloadast2050-flashrom-54aaa4ae2bb4026ae7acbf3e0aafe8542aaff2a4.zip
ast2050-flashrom-54aaa4ae2bb4026ae7acbf3e0aafe8542aaff2a4.tar.gz
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: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at> Acked-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at>
-rw-r--r--chipdrivers.h2
-rw-r--r--flashchips.c234
-rw-r--r--flashchips.h6
-rw-r--r--spi25_statusreg.c23
4 files changed, 265 insertions, 0 deletions
diff --git a/chipdrivers.h b/chipdrivers.h
index fe1e598..04ffda6 100644
--- a/chipdrivers.h
+++ b/chipdrivers.h
@@ -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);
diff --git a/flashchips.c b/flashchips.c
index 5e036ac..9dd045e 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -4422,6 +4422,240 @@ const struct flashchip flashchips[] = {
{
.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",
.bustype = BUS_PARALLEL,
.manufacture_id = INTEL_ID,
diff --git a/flashchips.h b/flashchips.h
index f10fbae..073f4eb 100644
--- a/flashchips.h
+++ b/flashchips.h
@@ -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 */
diff --git a/spi25_statusreg.c b/spi25_statusreg.c
index 84e8f63..2e01c06 100644
--- a/spi25_statusreg.c
+++ b/spi25_statusreg.c
@@ -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)
OpenPOWER on IntegriCloud