summaryrefslogtreecommitdiffstats
path: root/spi4ba.c
diff options
context:
space:
mode:
authorBoris Baykov <dev@borisbaykov.com>2016-06-08 12:23:55 +0200
committerCédric Le Goater <clg@kaod.org>2016-06-08 12:23:55 +0200
commit21e39c9087d8974b877f859a4d9cb0b283d48fd0 (patch)
tree89a0fc0ced1235d98f97d7fbee90b9ebdcafc249 /spi4ba.c
parentde6a59ef0a1122b805de3cd7ffb3e06ae07b9e38 (diff)
downloadflashrom-21e39c9087d8974b877f859a4d9cb0b283d48fd0.zip
flashrom-21e39c9087d8974b877f859a4d9cb0b283d48fd0.tar.gz
4BA: SFDP 1.6 parser for compliance with JESD216B
More than a year ago JEDEC released new standard JESD216 (revision B) which describes in detail how to receive 4-bytes addressing settings from the chip. This patch provides new code to add compliance to JESD216B to Flashrom. This means that Flashrom now can automatically detect 4-bytes addressing features of large flash chips and use them to access data. However not all things are so good. Unfortunately JESD216B had come to manufacturer's production lines just 2-3 months ago. So, we have many chips that have large size requires 32-bit addressing but their SFDP tables have revision lower than 1.6 (described in JESD216B standard). For example my W25Q256FV returns SFDP info with revision 1.0, first one :-) This situation leads us to requirement to try to work now without new SFDP info. And it's implemented in the patch too. Also I have to make an excuse about testing of SFDP rev 1.6 parser. I've tested it as good as I can using the simulation code which is in the next patch but I don't have ability to test it on real flash chips because I don't have a chip complied to JESD216B with SFDP 1.6 now. This code should be tested later. Patched files ------------- chipdrivers.h + added functions declarations for spi4ba.c flash.h + feature definitions added + added type field to block_eraser structure sfdp.c + added compliance to JEDEC JESD216B standard (SFDP revision 1.6) + added parse of SFDP 4-Bytes Addressing features (probe_spi_sfdp,sfdp_fill_flash) + added parse of SFDP 4-Bytes Addressing Instruction Table (sfdp_parse_4ba_table) + added choosing of block_erasers for 4-bytes addressing (sfdp_*_uniform_eraser*) + added exact flash page_size recognision from 11th dword in SFDP rev 1.6 spi4ba.h + definitions for 16th dword bits of SFDP Basic Flash Param Table (JESD216B) + definitions for SFDP 4-Bytes Addressing Instruction Table (JESD216B) + functions declarations from spi4ba.c (same as in chipdrivers.h, just to see) spi4ba.c + functions to choose block_eraser by opcode for 4-bytes addressing for sfdp.c + functions to select proper block_eraser (ext.reg or 4-bytes addr) for sfdp.c Signed-off-by: Boris Baykov <dev@borisbaykov.com>, Russia, Jan 2014 [clg: ported from https://www.flashrom.org/pipermail/flashrom/2015-January/013196.html ] Signed-off-by: Cédric Le Goater <clg@kaod.org>
Diffstat (limited to 'spi4ba.c')
-rw-r--r--spi4ba.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/spi4ba.c b/spi4ba.c
index 6e1cc9b..709f5f5 100644
--- a/spi4ba.c
+++ b/spi4ba.c
@@ -918,3 +918,103 @@ int spi_block_erase_dc_4ba_direct(struct flashctx *flash, unsigned int addr,
/* FIXME: Check the status register for errors. */
return 0;
}
+
+/* Selector for 4k eraser that chooses between 4-bytes addressing mode
+ and use of Extended Address Register from 3-bytes addressing mode */
+int spi_block_erase_20_4ba_selector(struct flashctx *flash, unsigned int addr,
+ unsigned int blocklen)
+{
+ msg_trace("-> %s\n", __func__);
+
+ return (flash->chip->feature_bits & FEATURE_4BA_EXTENDED_ADDR_REG) ?
+ spi_block_erase_20_4ba_ereg(flash, addr, blocklen) :
+ spi_block_erase_20_4ba(flash, addr, blocklen);
+}
+
+/* Selector for 32k eraser that chooses between 4-bytes addressing mode
+ and use of Extended Address Register from 3-bytes addressing mode */
+int spi_block_erase_52_4ba_selector(struct flashctx *flash, unsigned int addr,
+ unsigned int blocklen)
+{
+ msg_trace("-> %s\n", __func__);
+
+ return (flash->chip->feature_bits & FEATURE_4BA_EXTENDED_ADDR_REG) ?
+ spi_block_erase_52_4ba_ereg(flash, addr, blocklen) :
+ spi_block_erase_52_4ba(flash, addr, blocklen);
+}
+
+/* Selector for 64k eraser that chooses between 4-bytes addressing mode
+ and use of Extended Address Register from 3-bytes addressing mode */
+int spi_block_erase_d8_4ba_selector(struct flashctx *flash, unsigned int addr,
+ unsigned int blocklen)
+{
+ msg_trace("-> %s\n", __func__);
+
+ return (flash->chip->feature_bits & FEATURE_4BA_EXTENDED_ADDR_REG) ?
+ spi_block_erase_d8_4ba_ereg(flash, addr, blocklen) :
+ spi_block_erase_d8_4ba(flash, addr, blocklen);
+}
+
+/* Chooser for erase function by instruction opcode for block eraser instructions
+ to work with 4-bytes addressing flash chips. This chooser is called from sfdp.c
+ during parse of 8th & 9th dwords of SFDP Basic Flash Parameter Table */
+erasefunc_t *spi_get_erasefn_from_opcode_4ba(uint8_t opcode)
+{
+ msg_trace("-> %s\n", __func__);
+
+ switch(opcode){
+ case 0xff:
+ case 0x00:
+ /* Not specified, assuming "not supported". */
+ return NULL;
+ case 0x20:
+ return &spi_block_erase_20_4ba_selector; /* selector */
+ case 0x52:
+ return &spi_block_erase_52_4ba_selector; /* selector */
+ case 0x60:
+ return &spi_block_erase_60;
+ case 0x62:
+ return &spi_block_erase_62;
+ case 0xc7:
+ return &spi_block_erase_c7;
+ case 0xd8:
+ return &spi_block_erase_d8_4ba_selector; /* selector */
+ case 0x50:
+ case 0x81:
+ case 0xc4:
+ case 0xd7:
+ case 0xdb:
+ msg_cinfo("%s: erase opcode (0x%02x) doesn't have its 4-bytes addressing version."
+ " Please report this at flashrom@flashrom.org\n", __func__, opcode);
+ return NULL;
+ default:
+ msg_cinfo("%s: unknown erase opcode (0x%02x). Please report "
+ "this at flashrom@flashrom.org\n", __func__, opcode);
+ return NULL;
+ }
+}
+
+/* Chooser for erase function by instruction opcode for block eraser instructions
+ which can be used from ANY mode (3-bytes or 4-bytes). This chooser is called
+ from sfdp.c during parse of SFDP 4-Bytes Address Instruction Table (JESD216B) */
+erasefunc_t *spi_get_erasefn_from_opcode_4ba_direct(uint8_t opcode)
+{
+ msg_trace("-> %s\n", __func__);
+
+ switch(opcode){
+ case 0xff:
+ case 0x00:
+ /* Not specified, assuming "not supported". */
+ return NULL;
+ case 0x21:
+ return &spi_block_erase_21_4ba_direct; /* direct */
+ case 0x5C:
+ return &spi_block_erase_5c_4ba_direct; /* direct */
+ case 0xdc:
+ return &spi_block_erase_dc_4ba_direct; /* direct */
+ default:
+ msg_cinfo("%s: unknown erase opcode (0x%02x). Please report "
+ "this at flashrom@flashrom.org\n", __func__, opcode);
+ return NULL;
+ }
+}
OpenPOWER on IntegriCloud