Testing Output:
Calibrating delay loop... 686M loops per second, 100 myus = 184 us. OK. No coreboot table found. Found chipset "Intel ICH7/ICH7R", enabling flash write... BIOS Lock Enable: enabled, BIOS Write Enable: disabled, BIOS_CNTL is 0x2 tried to set 0xdc to 0x3 on Intel ICH7/ICH7R failed (WARNING ONLY)
Root Complex Register Block address = 0xfed1c000 GCS = 0x464: BIOS Interface Lock-Down: disabled, BOOT BIOS Straps: 0x1 (SPI) Top Swap : not enabled SPIBAR = 0xfed1c000 + 0x3020 0x00: 0x8004 (SPIS) 0x02: 0x4030 (SPIC) 0x04: 0x00000000 (SPIA) 0x08: 0x0000000e (SPID0) 0x0c: 0x00000000 (SPID0+4) 0x10: 0x00000000 (SPID1) 0x14: 0x00000000 (SPID1+4) 0x18: 0x00000000 (SPID2) 0x1c: 0x00000000 (SPID2+4) 0x20: 0x00000000 (SPID3) 0x24: 0x00000000 (SPID3+4) 0x28: 0x00000000 (SPID4) 0x2c: 0x00000000 (SPID4+4) 0x30: 0x00000000 (SPID5) 0x34: 0x00000000 (SPID5+4) 0x38: 0x00000000 (SPID6) 0x3c: 0x00000000 (SPID6+4) 0x40: 0x00000000 (SPID7) 0x44: 0x00000000 (SPID7+4) 0x50: 0x00f80000 (BBAR) 0x54: 0x5006 (PREOP) 0x56: 0x123b (OPTYPE) 0x58: 0x05200302 (OPMENU) 0x5c: 0x000100ab (OPMENU+4) 0x60: 0x00000000 (PBR0) 0x64: 0x00000000 (PBR1) 0x68: 0x00000000 (PBR2) 0x6c: 0x00000000 (PBR3)
WARNING: SPI Configuration Lockdown activated. SPI Read Configuration: prefetching disabled, caching enabled, FAILED! Probing for SST SST25LF040A, 512 KB: Generating OPCODES... done SPIC before going: 0x4140 test_sst25lf040a: id1 0xbf, id2 0x44. SPIC before going: 0x4030 SPIC before going: 0x406c Transaction error! run OPCODE 0x01 failed SPIC before going: 0x4030 status register: old value = 0x0e, new value = 0x0e. test_sst25lf040a: *** TEST FAILED! *** Found chip "SST SST25LF040A" (512 KB) at physical address 0xfff80000. === This flash part has status UNTESTED for operations: PROBE READ ERASE WRITE Please email a report to flashrom@coreboot.org if any of the above operations work correctly for you with this flash part. Please include the full output from the program, including chipset found. Thank you for your help! === No operations were specified.
--------------------------------------------------------------------------------
Comment on the above output:
Despite the "TEST FAILED!" warning, the testing is actually successful, for -
1. The command '0x01'(WRSR) is executed. It is in the existing opmenu(see 0x5c in the well formatted ICH SPI registers) but not in the hardcoded O_ST_M25P.
2. The control register for the ready-to-go WRSR command is assembled correctly with the atomic bit and the index of its required preop EWSR set. See the 2nd "SPIC before going".
The flash chip is probed at 0xfff80000, because the vendor BIOS has put the flash chip at the top of the 24-bit address space.
--------------------------------------------------------------------------------
diff -uN flashrom/flashchips.c flashrom_test/flashchips.c --- flashrom/flashchips.c 2008-12-08 01:30:19.000000000 +0800 +++ flashrom_test/flashchips.c 2008-12-08 01:24:20.000000000 +0800 @@ -21,6 +21,9 @@ */
#include "flash.h" +#include "spi.h" + +struct preop_opcode_pair pop_sst25lf040a[];
/** * List of supported flash ROM chips. @@ -107,6 +110,7 @@ {"PMC", "Pm49FL004", PMC_ID_NOPREFIX,PMC_49FL004, 512, 64 * 1024, TEST_OK_PREW, probe_49fl00x, erase_49fl00x, write_49fl00x}, {"Sharp", "LHF00L04", SHARP_ID, SHARP_LHF00L04, 1024, 64 * 1024, TEST_UNTESTED, probe_lhf00l04, erase_lhf00l04, write_lhf00l04}, {"Spansion", "S25FL016A", SPANSION_ID, SPANSION_S25FL016A, 2048, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, + {"SST", "SST25LF040A", SST_ID, SST_25LF040A_REMS, 512, 256, TEST_UNTESTED, test_sst25lf040a, NULL, NULL, NULL, pop_sst25lf040a}, {"SST", "SST25VF016B", SST_ID, SST_25VF016B, 2048, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, {"SST", "SST25VF032B", SST_ID, SST_25VF032B, 4096, 256, TEST_OK_PREW, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, {"SST", "SST25VF040B", SST_ID, SST_25VF040B, 512, 256, TEST_UNTESTED, probe_spi_rdid, spi_chip_erase_c7, spi_chip_write, spi_chip_read}, @@ -193,3 +197,13 @@
{NULL,} }; + +struct preop_opcode_pair pop_sst25lf040a[] = { + {JEDEC_WREN, JEDEC_BYTE_PROGRAM}, + {JEDEC_WREN, 0xaf}, /* AAI */ + {JEDEC_WREN, 0x20}, /* sector erase */ + {JEDEC_WREN, 0x52}, /* block erase */ + {JEDEC_WREN, 0x60}, /* chip erase */ + {JEDEC_EWSR, JEDEC_WRSR}, + {0,} +}; diff -uN flashrom/flash.h flashrom_test/flash.h --- flashrom/flash.h 2008-12-08 01:45:24.000000000 +0800 +++ flashrom_test/flash.h 2008-12-08 01:24:20.000000000 +0800 @@ -294,6 +294,7 @@ * byte of device ID is related to log(bitsize) at least for some chips. */ #define SST_ID 0xBF /* SST */ +#define SST_25LF040A_REMS 0x44 /* REMS or RES opcode */ #define SST_25WF512 0x2501 #define SST_25WF010 0x2502 #define SST_25WF020 0x2503 @@ -577,6 +578,9 @@ void data_polling_lhf00l04(volatile uint8_t *dst, uint8_t data); void protect_lhf00l04(volatile uint8_t *bios);
+/* sst25lf040a.c */ +int test_sst25lf040a(struct flashchip *flash); + /* sst28sf040.c */ int probe_28sf040(struct flashchip *flash); int erase_28sf040(struct flashchip *flash); diff -uN flashrom/ichspi.c flashrom_test/ichspi.c --- flashrom/ichspi.c 2008-12-08 01:24:48.000000000 +0800 +++ flashrom_test/ichspi.c 2008-12-08 01:24:20.000000000 +0800 @@ -441,6 +441,9 @@ } }
+ /* DELETE ME! */ + printf_debug("SPIC before going: 0x%04x\n", temp16); + /* Start */ temp16 |= SPIC_SCGO;
diff -uN flashrom/Makefile flashrom_test/Makefile --- flashrom/Makefile 2008-12-08 01:30:19.000000000 +0800 +++ flashrom_test/Makefile 2008-12-08 01:24:20.000000000 +0800 @@ -29,7 +29,7 @@ w49f002u.o 82802ab.o pm49fl00x.o sst49lf040.o en29f002a.o \ sst49lfxxxc.o sst_fwhub.o layout.o cbtable.o flashchips.o \ flashrom.o w39v080fa.o sharplhf00l04.o w29ee011.o spi.o it87spi.o \ - ichspi.o w39v040c.o sb600spi.o + ichspi.o w39v040c.o sb600spi.o sst25lf040a.o
all: pciutils dep $(PROGRAM)
diff -uN flashrom/sst25lf040a.c flashrom_test/sst25lf040a.c --- flashrom/sst25lf040a.c 1970-01-01 08:00:00.000000000 +0800 +++ flashrom_test/sst25lf040a.c 2008-12-08 01:12:47.000000000 +0800 @@ -0,0 +1,56 @@ +#include <stdio.h> +#include <stdint.h> +#include "flash.h" +#include "spi.h" + +int ich_check_opcodes(struct flashchip *flash); + +int test_sst25lf040a(struct flashchip *flash) +{ + uint8_t readarr[2]; + const uint8_t cmd[JEDEC_RES_OUTSIZE] = { JEDEC_RES, 0xf8, 0, 0 }; + const uint8_t cmd_rdsr[JEDEC_RDSR_OUTSIZE] = {JEDEC_RDSR}; + const uint8_t cmd_wrsr[JEDEC_WRSR_OUTSIZE] = {JEDEC_WRSR}; + + switch (flashbus) { + case BUS_TYPE_ICH7_SPI: + case BUS_TYPE_ICH9_SPI: + case BUS_TYPE_VIA_SPI: + + ich_check_opcodes(flash); /* example usage of ich_check_opcodes */ + + if (spi_command(sizeof(cmd), 2, cmd, readarr)) + return 0; + + printf_debug("%s: id1 0x%x, id2 0x%x.\n", __FUNCTION__, readarr[0], + readarr[1]); + + if (readarr[0] != flash->manufacture_id + || readarr[1] != flash->model_id) + return 0; + + /* read current status register */ + spi_command(sizeof(cmd_rdsr), 1, cmd_rdsr, readarr); + + /* try to change the status register */ + readarr[1] = readarr[0] ^ 0x80; /* BPL - block protection lock-down */ + spi_command(sizeof(cmd_wrsr), 1, cmd_wrsr, readarr + 1); + + /* read again */ + spi_command(sizeof(cmd_rdsr), 1, cmd_rdsr, readarr + 1); + + printf_debug("status register: old value = 0x%02x, new value = 0x%02x.\n", readarr[0], readarr[1]); + + printf_debug("%s: *** TEST ", __FUNCTION__); + if (readarr[0] == readarr[1]) + printf_debug("FAILED! ") + else + printf_debug("PASSED! "); + printf_debug("***\n"); + + return 1; + + default: + return 0; + } +} Common subdirectories: flashrom/.svn and flashrom_test/.svn