[flashrom] [PATCH] dummy programmer: blacklist SPI commands

David Hendricks dhendrix at google.com
Wed Feb 8 01:49:10 CET 2012


On Mon, Feb 6, 2012 at 6:46 PM, Carl-Daniel Hailfinger <
c-d.hailfinger.devel.2006 at gmx.net> wrote:

> Repost... code cleaned, man page fixed.
>
> Add optional SPI command blacklisting and ingorelisting to the flash
> chip emulator in the dummy programmer.
>
> Usage:
> flashrom -p dummy:spi_blacklist=commandlist
> flashrom -p dummy:spi_ignorelist=commandlist
>
> If commandlist is 0302, flashrom will refuse (blacklist) or ignore
> (ignorelist) command 0x03 (READ) and command 0x02 (WRITE). The
> commandlist can be up to 512 bytes (256 commands) long.
> Specifying flash chip emulation is a good idea to get useful results.
>
> Very useful for testing corner cases if you don't own a locked down
> Intel chipset and want to simulate such a thing.
>
> Example usage:
> dd if=/dev/zeros bs=1024k count=4 of=dummy_simulator.rom
> dd if=/dev/urandom bs=1024k count=4 of=randomimage.rom
> flashrom -p
> dummy:emulate=SST25VF032B,image=dummy_simulator.rom,spi_blacklist=20,spi_ignorelist=52
> -w randomimage.rom -V
>
> The example output looks like this:
> 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
> [...]
> Initializing dummy programmer
> Requested buses are: default
> Enabling support for parallel flash.
> Enabling support for LPC flash.
> Enabling support for FWH flash.
> Enabling support for SPI flash.
> SPI blacklist is 20 , size 1
> SPI ignorelist is 52 , size 1
> Emulating SST SST25VF032B SPI flash chip (RDID, AAI write)
> Filling fake flash chip with 0xff, size 4194304
> Found persistent image dummy_simulator.rom, size 4194304 matches.
> Reading dummy_simulator.rom
> The following protocols are supported: Parallel, LPC, FWH, SPI.
> [...]
> Probing for SST SST25VF032B, 4096 kB: probe_spi_rdid_generic: id1 0xbf,
> id2 0x254a
> Chip status register is 00
> Chip status register: Block Protect Write Disable (BPL) is not set
> Chip status register: Auto Address Increment Programming (AAI) is not set
> Chip status register: Bit 5 / Block Protect 3 (BP3) is not set
> Chip status register: Bit 4 / Block Protect 2 (BP2) is not set
> Chip status register: Bit 3 / Block Protect 1 (BP1) is not set
> Chip status register: Bit 2 / Block Protect 0 (BP0) is not set
> Chip status register: Write Enable Latch (WEL) is not set
> Chip status register: Write In Progress (WIP/BUSY) is not set
> Found SST flash chip "SST25VF032B" (4096 kB, SPI) on dummy.
> [...]
> Found SST flash chip "SST25VF032B" (4096 kB, SPI).
> Reading old flash chip contents... done.
> Erasing and writing flash chip... Trying erase function 0...
> 0x000000-0x000fff:ERefusing blacklisted SPI command 0x20
> Invalid command sent to flash chip!
> spi_block_erase_20 failed during command execution at address 0x0
> Reading current flash chip contents... done. Looking for another erase
> function.
> Trying erase function 1... 0x000000-0x007fff:EIgnoring ignorelisted SPI
> command 0x52
> ERASE FAILED at 0x00000000! Expected=0xff, Read=0x00, failed byte count
> from 0x00000000-0x00007fff: 0x8000
> ERASE FAILED!
> Reading current flash chip contents... done. Looking for another erase
> function.
> 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
> Erase/write done.
> Verifying flash... VERIFIED.
> Writing dummy_simulator.rom
>
>
> Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at gmx.net>
>
> An earlier version of this patch (wthout ignorelisting) got the
> following response:
>
> Am 04.02.2011 01:42 schrieb David Hendricks:
> > Overall looks good to me. I tested it out by blacklisting read, rdid,
> write,
> > wren, and the chip erase commands in various combinations and it seems to
> > work reasonably well. SPI opcode parsing seemed to work fine as well.
> >
> > For others interested in giving this a try, here is another example of
> > syntax (courtesy of Carl-Danial on IRC) for us laymen: flashrom -p
> > dummy:emulate=SST25VF032B,image=dummy_simulator.rom,spi_blacklist=0x03
> >
> > I don't know man page formatting well, so I didn't review that part. As
> far
> > as the code, I say:
> > Acked-by: David Hendricks <dhendrix at google.com>
>
> David: Given that your review was based on a pretty different version of
> the code, I'm not including your ack unless you're OK with the new code
> as well.
>
> Index: flashrom-emulate_spi_flashchip_command_blacklist/dummyflasher.c
> ===================================================================
> --- flashrom-emulate_spi_flashchip_command_blacklist/dummyflasher.c
> (Revision 1488)
> +++ flashrom-emulate_spi_flashchip_command_blacklist/dummyflasher.c
> (Arbeitskopie)
> @@ -19,6 +19,8 @@
>
>  #include <string.h>
>  #include <stdlib.h>
> +#include <stdio.h>
> +#include <ctype.h>
>  #include "flash.h"
>  #include "chipdrivers.h"
>  #include "programmer.h"
> @@ -55,6 +57,10 @@
>  static unsigned int emu_jedec_be_d8_size = 0;
>  static unsigned int emu_jedec_ce_60_size = 0;
>  static unsigned int emu_jedec_ce_c7_size = 0;
> +unsigned char spi_blacklist[256];
> +unsigned char spi_ignorelist[256];
> +int spi_blacklist_size = 0;
> +int spi_ignorelist_size = 0;
>  #endif
>  #endif
>
> @@ -126,6 +132,7 @@
>  {
>        char *bustext = NULL;
>        char *tmp = NULL;
> +       int i;
>  #if EMULATE_CHIP
>        struct stat image_stat;
>  #endif
> @@ -170,6 +177,68 @@
>                 }
>        }
>
> +       tmp = extract_programmer_param("spi_blacklist");
> +       if (tmp) {
> +               i = strlen(tmp);
> +               if (!strncmp(tmp, "0x", 2)) {
> +                       i -= 2;
> +                       memmove(tmp, tmp + 2, i + 1);
> +               }
> +               if ((i > 512) || (i % 2)) {
> +                       msg_perr("Invalid SPI command blacklist length\n");
> +                       free(tmp);
> +                       return 1;
> +               }
> +               spi_blacklist_size = i / 2;
> +               for (i = 0; i < spi_blacklist_size * 2; i++) {
> +                       if (!isxdigit((unsigned char)tmp[i])) {
> +                               msg_perr("Invalid char \"%c\" in SPI
> command "
> +                                        "blacklist\n", tmp[i]);
> +                               free(tmp);
> +                               return 1;
> +                       }
> +               }
> +               for (i = 0; i < spi_blacklist_size; i++) {
> +                       sscanf(tmp + i * 2, "%2hhx", &spi_blacklist[i]);
> +               }
> +               msg_pdbg("SPI blacklist is ");
> +               for (i = 0; i < spi_blacklist_size; i++)
> +                       msg_pdbg("%02x ", spi_blacklist[i]);
> +               msg_pdbg(", size %i\n", spi_blacklist_size);
> +       }
> +       free(tmp);
> +
> +       tmp = extract_programmer_param("spi_ignorelist");
> +       if (tmp) {
> +               i = strlen(tmp);
> +               if (!strncmp(tmp, "0x", 2)) {
> +                       i -= 2;
> +                       memmove(tmp, tmp + 2, i + 1);
> +               }
> +               if ((i > 512) || (i % 2)) {
> +                       msg_perr("Invalid SPI command ignorelist
> length\n");
> +                       free(tmp);
> +                       return 1;
> +               }
> +               spi_ignorelist_size = i / 2;
> +               for (i = 0; i < spi_ignorelist_size * 2; i++) {
> +                       if (!isxdigit((unsigned char)tmp[i])) {
> +                               msg_perr("Invalid char \"%c\" in SPI
> command "
> +                                        "ignorelist\n", tmp[i]);
> +                               free(tmp);
> +                               return 1;
> +                       }
> +               }
> +               for (i = 0; i < spi_ignorelist_size; i++) {
> +                       sscanf(tmp + i * 2, "%2hhx", &spi_ignorelist[i]);
> +               }
> +               msg_pdbg("SPI ignorelist is ");
> +               for (i = 0; i < spi_ignorelist_size; i++)
> +                       msg_pdbg("%02x ", spi_ignorelist[i]);
> +               msg_pdbg(", size %i\n", spi_ignorelist_size);
> +       }
> +       free(tmp);
> +
>  #if EMULATE_CHIP
>        tmp = extract_programmer_param("emulate");
>        if (!tmp) {
> @@ -348,7 +417,7 @@
>                                      const unsigned char *writearr,
>                                     unsigned char *readarr)
>  {
> -       unsigned int offs;
> +       unsigned int offs, i;
>        static int unsigned aai_offs;
>         static int aai_active = 0;
>
> @@ -356,7 +425,24 @@
>                msg_perr("No command sent to the chip!\n");
>                return 1;
>        }
> -       /* TODO: Implement command blacklists here. */
> +       /* spi_blacklist has precedence before spi_ignorelist. */
> +       for (i = 0; i < spi_blacklist_size; i++) {
> +               if (writearr[0] == spi_blacklist[i]) {
> +                       msg_pdbg("Refusing blacklisted SPI command
> 0x%02x\n",
> +                                spi_blacklist[i]);
> +                       return SPI_INVALID_OPCODE;
> +               }
> +       }
> +       for (i = 0; i < spi_ignorelist_size; i++) {
> +               if (writearr[0] == spi_ignorelist[i]) {
> +                       msg_cdbg("Ignoring ignorelisted SPI command
> 0x%02x\n",
> +                                spi_ignorelist[i]);
> +                       /* Return success because the command does not
> fail,
> +                        * it is simply ignored.
> +                        */
> +                       return 0;
> +               }
> +       }
>        switch (writearr[0]) {
>        case JEDEC_RES:
>                if (emu_chip != EMULATE_ST_M25P10_RES)
> @@ -563,7 +649,7 @@
>        case EMULATE_SST_SST25VF032B:
>                if (emulate_spi_chip_response(writecnt, readcnt, writearr,
>                                              readarr)) {
> -                       msg_perr("Invalid command sent to flash chip!\n");
> +                       msg_pdbg("Invalid command sent to flash chip!\n");
>                        return 1;
>                }
>                break;
> Index: flashrom-emulate_spi_flashchip_command_blacklist/flashrom.8
> ===================================================================
> --- flashrom-emulate_spi_flashchip_command_blacklist/flashrom.8 (Revision
> 1488)
> +++ flashrom-emulate_spi_flashchip_command_blacklist/flashrom.8
> (Arbeitskopie)
> @@ -421,6 +421,28 @@
>  Example:
>  .sp
>  .B "  flashrom -p dummy:emulate=M25P10.RES,spi_write_256_chunksize=5"
> +.sp
> +To simulate a programmer which refuses to send certain SPI commands to the
> +flash chip, you can specify a blacklist of SPI commands with the
> +.sp
> +.B "  flashrom -p dummy:spi_blacklist=commandlist"
> +.sp
> +syntax where commandlist is a list of two-digit hexadecimal
> representations of
> +SPI commands. If commandlist is e.g. 0302, flashrom will behave as if the
> SPI
> +controller refuses to run command 0x03 (READ) and command 0x02 (WRITE).
> +commandlist may be up to 512 characters (256 commands) long.
> +Implementation note: flashrom will detect an error during command
> execution.
> +.sp
> +To simulate a flash chip which ignores (doesn't support) certain SPI
> commands,
> +you can specify an ignorelist of SPI commands with the
> +.sp
> +.B "  flashrom -p dummy:spi_ignorelist=commandlist"
> +.sp
> +syntax where commandlist is a list of two-digit hexadecimal
> representations of
> +SPI commands. If commandlist is e.g. 0302, the emulated flash chip will
> ignore
> +command 0x03 (READ) and command 0x02 (WRITE).  commandlist may be up to
> 512
> +characters (256 commands) long.
> +Implementation note: flashrom won't detect an error during command
> execution.
>  .TP
>  .BR "nic3com" , " nicrealtek" , " nicsmc1211" , " nicnatsemi" , "
> nicintel\
>  " , " nicintel_spi" , " gfxnvidia" , " ogp_spi" , " drkaiser" , " satasii\
>
>
> --
> http://www.hailfinger.org/
>
>
>
Looks good to me.

Acked-by: David Hendricks <dhendrix at google.com>



-- 
David Hendricks (dhendrix)
Systems Software Engineer, Google Inc.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.flashrom.org/pipermail/flashrom/attachments/20120207/2cc47022/attachment.html>


More information about the flashrom mailing list