<div class="gmail_quote">On Mon, Feb 6, 2012 at 6:46 PM, Carl-Daniel Hailfinger <span dir="ltr"><<a href="mailto:c-d.hailfinger.devel.2006@gmx.net">c-d.hailfinger.devel.2006@gmx.net</a>></span> wrote:</div><div class="gmail_quote">

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Repost... code cleaned, man page fixed.<br>
<br>
Add optional SPI command blacklisting and ingorelisting to the flash<br>
<div class="im">chip emulator in the dummy programmer.<br>
<br>
Usage:<br>
</div>flashrom -p dummy:spi_blacklist=commandlist<br>
flashrom -p dummy:spi_ignorelist=commandlist<br>
<br>
If commandlist is 0302, flashrom will refuse (blacklist) or ignore<br>
(ignorelist) command 0x03 (READ) and command 0x02 (WRITE). The<br>
commandlist can be up to 512 bytes (256 commands) long.<br>
Specifying flash chip emulation is a good idea to get useful results.<br>
<div class="im"><br>
Very useful for testing corner cases if you don't own a locked down<br>
Intel chipset and want to simulate such a thing.<br>
<br>
</div>Example usage:<br>
dd if=/dev/zeros bs=1024k count=4 of=dummy_simulator.rom<br>
dd if=/dev/urandom bs=1024k count=4 of=randomimage.rom<br>
flashrom -p dummy:emulate=SST25VF032B,image=dummy_simulator.rom,spi_blacklist=20,spi_ignorelist=52 -w randomimage.rom -V<br>
<br>
The example output looks like this:<br>
flashrom v0.9.4-r1488 on Linux 2.6.34.10-0.6-default (i686), built with libpci 3.1.7, GCC 4.5.0 20100604 [gcc-4_5-branch revision 160292], little endian<br>
[...]<br>
Initializing dummy programmer<br>
Requested buses are: default<br>
Enabling support for parallel flash.<br>
Enabling support for LPC flash.<br>
Enabling support for FWH flash.<br>
Enabling support for SPI flash.<br>
SPI blacklist is 20 , size 1<br>
SPI ignorelist is 52 , size 1<br>
Emulating SST SST25VF032B SPI flash chip (RDID, AAI write)<br>
Filling fake flash chip with 0xff, size 4194304<br>
Found persistent image dummy_simulator.rom, size 4194304 matches.<br>
Reading dummy_simulator.rom<br>
The following protocols are supported: Parallel, LPC, FWH, SPI.<br>
[...]<br>
Probing for SST SST25VF032B, 4096 kB: probe_spi_rdid_generic: id1 0xbf, id2 0x254a<br>
Chip status register is 00<br>
Chip status register: Block Protect Write Disable (BPL) is not set<br>
Chip status register: Auto Address Increment Programming (AAI) is not set<br>
Chip status register: Bit 5 / Block Protect 3 (BP3) is not set<br>
Chip status register: Bit 4 / Block Protect 2 (BP2) is not set<br>
Chip status register: Bit 3 / Block Protect 1 (BP1) is not set<br>
Chip status register: Bit 2 / Block Protect 0 (BP0) is not set<br>
Chip status register: Write Enable Latch (WEL) is not set<br>
Chip status register: Write In Progress (WIP/BUSY) is not set<br>
Found SST flash chip "SST25VF032B" (4096 kB, SPI) on dummy.<br>
[...]<br>
Found SST flash chip "SST25VF032B" (4096 kB, SPI).<br>
Reading old flash chip contents... done.<br>
Erasing and writing flash chip... Trying erase function 0... 0x000000-0x000fff:ERefusing blacklisted SPI command 0x20<br>
Invalid command sent to flash chip!<br>
spi_block_erase_20 failed during command execution at address 0x0<br>
Reading current flash chip contents... done. Looking for another erase function.<br>
Trying erase function 1... 0x000000-0x007fff:EIgnoring ignorelisted SPI command 0x52<br>
ERASE FAILED at 0x00000000! Expected=0xff, Read=0x00, failed byte count from 0x00000000-0x00007fff: 0x8000<br>
ERASE FAILED!<br>
Reading current flash chip contents... done. Looking for another erase function.<br>
Trying erase function 2... 0x000000-0x00ffff:EW, 0x010000-0x01ffff:EW, 0x020000-0x02ffff:EW, 0x030000-0x03ffff:EW, 0x040000-0x04ffff:EW, 0x050000-0x05ffff:EW, 0x060000-0x06ffff:EW, 0x070000-0x07ffff:EW, 0x080000-0x08ffff:EW, 0x090000-0x09ffff:EW, 0x0a0000-0x0affff:EW, 0x0b0000-0x0bffff:EW, 0x0c0000-0x0cffff:EW, 0x0d0000-0x0dffff:EW, 0x0e0000-0x0effff:EW, 0x0f0000-0x0fffff:EW, 0x100000-0x10ffff:EW, 0x110000-0x11ffff:EW, 0x120000-0x12ffff:EW, 0x130000-0x13ffff:EW, 0x140000-0x14ffff:EW, 0x150000-0x15ffff:EW, 0x160000-0x16ffff:EW, 0x170000-0x17ffff:EW, 0x180000-0x18ffff:EW, 0x190000-0x19ffff:EW, 0x1a0000-0x1affff:EW, 0x1b0000-0x1bffff:EW, 0x1c0000-0x1cffff:EW, 0x1d0000-0x1dffff:EW, 0x1e0000-0x1effff:EW, 0x1f0000-0x1fffff:EW, 0x200000-0x20ffff:EW, 0x210000-0x21ffff:EW, 0x220000-0x22ffff:EW, 0x230000-0x23ffff:EW, 0x240000-0x24ffff:EW, 0x250000-0x25ffff:EW, 0x260000-0x26ffff:EW, 0x270000-0x27ffff:EW, 0x280000-0x28ffff:EW, 0x290000-0x29ffff:EW, 0x2a0000-0x2affff:EW, 0x2b0000-0x2bffff:EW, 0x2c0000-0x2cffff:EW, 0x2d0000-0x2dffff:EW, 0x2e0000-0x2effff:EW, 0x2f0000-0x2fffff:EW, 0x300000-0x30ffff:EW, 0x310000-0x31ffff:EW, 0x320000-0x32ffff:EW, 0x330000-0x33ffff:EW, 0x340000-0x34ffff:EW, 0x350000-0x35ffff:EW, 0x360000-0x36ffff:EW, 0x370000-0x37ffff:EW, 0x380000-0x38ffff:EW, 0x390000-0x39ffff:EW, 0x3a0000-0x3affff:EW, 0x3b0000-0x3bffff:EW, 0x3c0000-0x3cffff:EW, 0x3d0000-0x3dffff:EW, 0x3e0000-0x3effff:EW, 0x3f0000-0x3fffff:EW<br>


Erase/write done.<br>
Verifying flash... VERIFIED.<br>
Writing dummy_simulator.rom<br>
<br>
<br>
Signed-off-by: Carl-Daniel Hailfinger <<a href="mailto:c-d.hailfinger.devel.2006@gmx.net">c-d.hailfinger.devel.2006@gmx.net</a>><br>
<br>
An earlier version of this patch (wthout ignorelisting) got the<br>
following response:<br>
<br>
Am 04.02.2011 01:42 schrieb David Hendricks:<br>
<div class="im">> Overall looks good to me. I tested it out by blacklisting read, rdid, write,<br>
> wren, and the chip erase commands in various combinations and it seems to<br>
> work reasonably well. SPI opcode parsing seemed to work fine as well.<br>
><br>
> For others interested in giving this a try, here is another example of<br>
> syntax (courtesy of Carl-Danial on IRC) for us laymen: flashrom -p<br>
> dummy:emulate=SST25VF032B,image=dummy_simulator.rom,spi_blacklist=0x03<br>
><br>
> I don't know man page formatting well, so I didn't review that part. As far<br>
> as the code, I say:<br>
> Acked-by: David Hendricks <<a href="mailto:dhendrix@google.com">dhendrix@google.com</a>><br>
<br>
</div>David: Given that your review was based on a pretty different version of<br>
the code, I'm not including your ack unless you're OK with the new code<br>
as well.<br>
<br>
Index: flashrom-emulate_spi_flashchip_command_blacklist/dummyflasher.c<br>
===================================================================<br>
--- flashrom-emulate_spi_flashchip_command_blacklist/dummyflasher.c     (Revision 1488)<br>
+++ flashrom-emulate_spi_flashchip_command_blacklist/dummyflasher.c     (Arbeitskopie)<br>
@@ -19,6 +19,8 @@<br>
<div class="im"><br>
 #include <string.h><br>
 #include <stdlib.h><br>
+#include <stdio.h><br>
</div>+#include <ctype.h><br>
<div class="im"> #include "flash.h"<br>
 #include "chipdrivers.h"<br>
 #include "programmer.h"<br>
</div>@@ -55,6 +57,10 @@<br>
 static unsigned int emu_jedec_be_d8_size = 0;<br>
 static unsigned int emu_jedec_ce_60_size = 0;<br>
 static unsigned int emu_jedec_ce_c7_size = 0;<br>
+unsigned char spi_blacklist[256];<br>
+unsigned char spi_ignorelist[256];<br>
+int spi_blacklist_size = 0;<br>
+int spi_ignorelist_size = 0;<br>
 #endif<br>
 #endif<br>
<br>
@@ -126,6 +132,7 @@<br>
<div class="im"> {<br>
        char *bustext = NULL;<br>
        char *tmp = NULL;<br>
</div><div class="im">+       int i;<br>
 #if EMULATE_CHIP<br>
        struct stat image_stat;<br>
 #endif<br>
</div>@@ -170,6 +177,68 @@<br>
<div class="im">                }<br>
        }<br>
<br>
+       tmp = extract_programmer_param("spi_blacklist");<br>
+       if (tmp) {<br>
</div>+               i = strlen(tmp);<br>
+               if (!strncmp(tmp, "0x", 2)) {<br>
+                       i -= 2;<br>
+                       memmove(tmp, tmp + 2, i + 1);<br>
+               }<br>
<div class="im">+               if ((i > 512) || (i % 2)) {<br>
</div>+                       msg_perr("Invalid SPI command blacklist length\n");<br>
<div class="im">+                       free(tmp);<br>
+                       return 1;<br>
+               }<br>
</div><div class="im">+               spi_blacklist_size = i / 2;<br>
</div>+               for (i = 0; i < spi_blacklist_size * 2; i++) {<br>
+                       if (!isxdigit((unsigned char)tmp[i])) {<br>
+                               msg_perr("Invalid char \"%c\" in SPI command "<br>
+                                        "blacklist\n", tmp[i]);<br>
<div class="im">+                               free(tmp);<br>
+                               return 1;<br>
+                       }<br>
</div>+               }<br>
<div class="im">+               for (i = 0; i < spi_blacklist_size; i++) {<br>
</div>+                       sscanf(tmp + i * 2, "%2hhx", &spi_blacklist[i]);<br>
<div class="im">+               }<br>
+               msg_pdbg("SPI blacklist is ");<br>
+               for (i = 0; i < spi_blacklist_size; i++)<br>
+                       msg_pdbg("%02x ", spi_blacklist[i]);<br>
+               msg_pdbg(", size %i\n", spi_blacklist_size);<br>
+       }<br>
+       free(tmp);<br>
+<br>
</div>+       tmp = extract_programmer_param("spi_ignorelist");<br>
+       if (tmp) {<br>
+               i = strlen(tmp);<br>
+               if (!strncmp(tmp, "0x", 2)) {<br>
+                       i -= 2;<br>
+                       memmove(tmp, tmp + 2, i + 1);<br>
+               }<br>
<div class="im">+               if ((i > 512) || (i % 2)) {<br>
</div>+                       msg_perr("Invalid SPI command ignorelist length\n");<br>
<div class="im">+                       free(tmp);<br>
+                       return 1;<br>
+               }<br>
</div>+               spi_ignorelist_size = i / 2;<br>
+               for (i = 0; i < spi_ignorelist_size * 2; i++) {<br>
+                       if (!isxdigit((unsigned char)tmp[i])) {<br>
+                               msg_perr("Invalid char \"%c\" in SPI command "<br>
+                                        "ignorelist\n", tmp[i]);<br>
<div class="im">+                               free(tmp);<br>
+                               return 1;<br>
+                       }<br>
</div>+               }<br>
+               for (i = 0; i < spi_ignorelist_size; i++) {<br>
+                       sscanf(tmp + i * 2, "%2hhx", &spi_ignorelist[i]);<br>
+               }<br>
+               msg_pdbg("SPI ignorelist is ");<br>
+               for (i = 0; i < spi_ignorelist_size; i++)<br>
+                       msg_pdbg("%02x ", spi_ignorelist[i]);<br>
+               msg_pdbg(", size %i\n", spi_ignorelist_size);<br>
<div class="im">+       }<br>
+       free(tmp);<br>
+<br>
 #if EMULATE_CHIP<br>
        tmp = extract_programmer_param("emulate");<br>
        if (!tmp) {<br>
</div>@@ -348,7 +417,7 @@<br>
<div class="im">                                     const unsigned char *writearr,<br>
                                     unsigned char *readarr)<br>
 {<br>
</div>-       unsigned int offs;<br>
+       unsigned int offs, i;<br>
        static int unsigned aai_offs;<br>
<div class="im">        static int aai_active = 0;<br>
<br>
</div>@@ -356,7 +425,24 @@<br>
                msg_perr("No command sent to the chip!\n");<br>
                return 1;<br>
        }<br>
<div class="im">-       /* TODO: Implement command blacklists here. */<br>
</div>+       /* spi_blacklist has precedence before spi_ignorelist. */<br>
<div class="im">+       for (i = 0; i < spi_blacklist_size; i++) {<br>
+               if (writearr[0] == spi_blacklist[i]) {<br>
</div>+                       msg_pdbg("Refusing blacklisted SPI command 0x%02x\n",<br>
+                                spi_blacklist[i]);<br>
+                       return SPI_INVALID_OPCODE;<br>
+               }<br>
+       }<br>
+       for (i = 0; i < spi_ignorelist_size; i++) {<br>
+               if (writearr[0] == spi_ignorelist[i]) {<br>
+                       msg_cdbg("Ignoring ignorelisted SPI command 0x%02x\n",<br>
+                                spi_ignorelist[i]);<br>
+                       /* Return success because the command does not fail,<br>
+                        * it is simply ignored.<br>
<div class="im">+                        */<br>
+                       return 0;<br>
+               }<br>
+       }<br>
        switch (writearr[0]) {<br>
        case JEDEC_RES:<br>
                if (emu_chip != EMULATE_ST_M25P10_RES)<br>
</div>@@ -563,7 +649,7 @@<br>
        case EMULATE_SST_SST25VF032B:<br>
                if (emulate_spi_chip_response(writecnt, readcnt, writearr,<br>
                                              readarr)) {<br>
-                       msg_perr("Invalid command sent to flash chip!\n");<br>
+                       msg_pdbg("Invalid command sent to flash chip!\n");<br>
                        return 1;<br>
                }<br>
                break;<br>
Index: flashrom-emulate_spi_flashchip_command_blacklist/flashrom.8<br>
===================================================================<br>
--- flashrom-emulate_spi_flashchip_command_blacklist/flashrom.8 (Revision 1488)<br>
+++ flashrom-emulate_spi_flashchip_command_blacklist/flashrom.8 (Arbeitskopie)<br>
@@ -421,6 +421,28 @@<br>
 Example:<br>
 .sp<br>
 .B "  flashrom -p dummy:emulate=M25P10.RES,spi_write_256_chunksize=5"<br>
+.sp<br>
+To simulate a programmer which refuses to send certain SPI commands to the<br>
+flash chip, you can specify a blacklist of SPI commands with the<br>
+.sp<br>
+.B "  flashrom -p dummy:spi_blacklist=commandlist"<br>
+.sp<br>
+syntax where commandlist is a list of two-digit hexadecimal representations of<br>
+SPI commands. If commandlist is e.g. 0302, flashrom will behave as if the SPI<br>
+controller refuses to run command 0x03 (READ) and command 0x02 (WRITE).<br>
+commandlist may be up to 512 characters (256 commands) long.<br>
+Implementation note: flashrom will detect an error during command execution.<br>
+.sp<br>
+To simulate a flash chip which ignores (doesn't support) certain SPI commands,<br>
+you can specify an ignorelist of SPI commands with the<br>
+.sp<br>
+.B "  flashrom -p dummy:spi_ignorelist=commandlist"<br>
+.sp<br>
+syntax where commandlist is a list of two-digit hexadecimal representations of<br>
+SPI commands. If commandlist is e.g. 0302, the emulated flash chip will ignore<br>
+command 0x03 (READ) and command 0x02 (WRITE).  commandlist may be up to 512<br>
+characters (256 commands) long.<br>
+Implementation note: flashrom won't detect an error during command execution.<br>
 .TP<br>
 .BR "nic3com" , " nicrealtek" , " nicsmc1211" , " nicnatsemi" , " nicintel\<br>
 " , " nicintel_spi" , " gfxnvidia" , " ogp_spi" , " drkaiser" , " satasii\<br>
<span class="HOEnZb"><font color="#888888"><br>
<br>
--<br>
<a href="http://www.hailfinger.org/" target="_blank">http://www.hailfinger.org/</a><br>
<br>
<br>
</font></span></blockquote></div><div class="gmail_quote"><br></div><div class="gmail_quote">Looks good to me.</div><div class="gmail_quote"><br></div><div class="gmail_quote">Acked-by: David Hendricks <<a href="mailto:dhendrix@google.com">dhendrix@google.com</a>></div>

<div><br></div><br clear="all"><div><br></div>-- <br>David Hendricks (dhendrix)<br>Systems Software Engineer, Google Inc.<br>