From patchwork Fri Aug 26 07:29:07 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hatim Kanchwala X-Patchwork-Id: 663002 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from mail.coreboot.org (mail.coreboot.org [80.81.252.135]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3sLCPn6W1Kz9rxv for ; Fri, 26 Aug 2016 17:30:34 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=hatimak-me.20150623.gappssmtp.com header.i=@hatimak-me.20150623.gappssmtp.com header.b=Oy8TBPRk; dkim-atps=neutral Received: from [127.0.0.1] (helo=ra.coresystems.de) by mail.coreboot.org with esmtp (Exim 4.86_2) (envelope-from ) id 1bdBa5-0008Qz-QH; Fri, 26 Aug 2016 09:29:37 +0200 Received: from mail-pf0-f176.google.com ([209.85.192.176]) by mail.coreboot.org with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.86_2) (envelope-from ) id 1bdBZo-0008Qj-Of for flashrom@flashrom.org; Fri, 26 Aug 2016 09:29:35 +0200 Received: by mail-pf0-f176.google.com with SMTP id y134so26007318pfg.0 for ; Fri, 26 Aug 2016 00:29:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hatimak-me.20150623.gappssmtp.com; s=20150623; h=subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to; bh=lrKPBNZLj3qa8xPlNa5rBvYXqCumHjUwb0ZJ6nnqvlc=; b=Oy8TBPRkyiPsyXDb9Gq950u4OhQprRgTNERLakCVpyAYzlir8bksgqXWPYbsVm/FvN 1BSR4mEebpiETSJDv5dh2/tuQFq39ZF67AOp+rOZ0ovh1GM1ebnVt5o729HT7u3c6GZG tYFRu/8cHBJW6Fn6We+OYUcoxLD6QUAhHfOv1A2DoLeEVe7gddeEIipPJip/YKS0eFmi ry7MKA4XI8BVK6+w4mwIr/+2FoYD/tAumxnob/uxhg4XXALNh9nuNEZYmUdnxXVfYf06 Oyf4ho0zQ1x8rs9VctVduNPTYZDfi4ByvtQ9rG5DU6nYnzh40cErZ8gzGVWNkB1n69qX qlKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:cc:from:message-id:date :user-agent:mime-version:in-reply-to; bh=lrKPBNZLj3qa8xPlNa5rBvYXqCumHjUwb0ZJ6nnqvlc=; b=FY6bW62fRJKm1y9bJ3oyEbyOdvYMEmM+KyjK+V6E8Ka+hrUkYT4EgPuxt6X9BoP5Cd 4v5KSkvzEsjmjf0BXHydiWAHiU6JbTlTKsS95nClrC68M/uuC3pjZy3r0GjNrSmj39nj KDNvl8rmlsPaF5PyeST3Km3tBI0P+t264sfdkJVNKP7zmaG0n3lTcPxEvka9k5Oju5GA 2/0JhfVsCiU8XLZhF6JPwhFXwugyE+uh8mCH967aCzknUc0WDNOt+Fbqpqc29G5D9N5f 3C20OyMjqsxUFeYwhx/edMpv376ygVGPabp0PwObuyA1bXBbdIw22ALZynrfyc+KWfbF qn+w== X-Gm-Message-State: AE9vXwPUyJDat5J9t78Lj+3ovFtHqRN/nxkwLT2Lt5c9/gfyemOu3rL13cymHZs0DxJLeA== X-Received: by 10.98.89.210 with SMTP id k79mr3368729pfj.43.1472196558144; Fri, 26 Aug 2016 00:29:18 -0700 (PDT) Received: from [172.16.173.130] ([14.139.194.12]) by smtp.gmail.com with ESMTPSA id k29sm25892429pfb.2.2016.08.26.00.29.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 26 Aug 2016 00:29:17 -0700 (PDT) To: David Hendricks , Timothy Pearson References: <809516223.92250.1471987969563.JavaMail.zimbra@raptorengineeringinc.com> From: Hatim Kanchwala Message-ID: <6c4709ed-83e5-f6b3-d075-54f0169ab75b@hatimak.me> Date: Fri, 26 Aug 2016 12:59:07 +0530 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0 MIME-Version: 1.0 In-Reply-To: X-Spam-Score: 1.3 (+) Subject: Re: [flashrom] [RFC] [PATCH] Add ability to lock bootblock on Winbond Flash ROMs X-BeenThere: flashrom@flashrom.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: flashrom discussion and development mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: flashrom Errors-To: flashrom-bounces@flashrom.org Sender: "flashrom" X-Duff: Orig. Duff, Duff Lite, Duff Dry, Duff Dark, Raspberry Duff, Lady Duff, Red Duff, Tartar Control Duff Hello Timothy and David, I have attached a patch that adds support for W25Q128BV and W25Q128FV chips (I noticed Timothy needed these chips;) so I added only these for now). This patch should be applied on top of all my most recent patches. Instead of downloading and locally applying all those patches and then applying the attached one, I recommend you clone my fork of flashrom (dev branch) from GitHub (https://github.com/hatimak/flashrom/tree/dev). I have already pushed the attached patch there ;) Now, on how to use it. Once you compile and install it, have a look at the man page and the --help output. If you run --wp-list, you can see the access protection table. For you particular case you will need --wp-set-range start=0xfff000,len=4. This will lock the top 4kB of either or W25Q128BV or W25Q128FV. The man page will explain how you can set status register write protection if you need that. If it happens that you need OTP support for these chips, that is available as well :) The CLI is arguably not the best, but this is a more general solution than what you sent. I hope this is sufficient and helps you out. Feel free to reach out for any comments/feedback/help over mail or IRC (hatim on #flashrom). Thanks, Hatim On Wednesday 24 August 2016 05:42 AM, David Hendricks wrote: > Hi Timothy, > Check out Hatim's GSOC work for manipulating status register and write protect bits: > https://patchwork.coreboot.org/patch/4471/ > https://patchwork.coreboot.org/patch/4472/ > https://patchwork.coreboot.org/patch/4469/ > https://patchwork.coreboot.org/patch/4467/ > https://patchwork.coreboot.org/patch/4468/ > https://patchwork.coreboot.org/patch/4470/ > > There's also similar work done in Chromium.org fork of flashrom which might do what you need (--wp-enable command): https://chromium.googlesource.com/chromiumos/third_party/flashrom/ > Thanks David for your reply :) Seeing my work being used and recommended feels extraordinarily happy ;) > > On Tue, Aug 23, 2016 at 2:32 PM, Timothy Pearson > wrote: > > RFC PATCH > > TPM-enabled systems require an immutable (or at least very difficult to modify) CRTM, which can be provided via a locked bootblock sector. > > Add initial support for locking the upper 4K sector on Winbond Flash ROMs. Unlocking the sector after it has been locked requires hardware access to the write protect pin, satisfying the above requirements for many use cases. > > To use, pass the --lock flag to Flashrom. This flag can be used in isolation, or as part of a normal read / write / verify cycle. > Timothy, thanks for your patch :) Hope what I explained above is helpful to you. And I would gently point out that you forgot the "Signed-off-by" tag in your patch :) > Index: spi25_statusreg.c > =================================================================== > --- spi25_statusreg.c (revision 1955) > +++ spi25_statusreg.c (working copy) > @@ -123,6 +123,78 @@ > return readarr[0]; > } > > +static uint8_t spi_read_status_register_2(struct flashctx *flash) > +{ > + static const unsigned char cmd[JEDEC_RDSR_OUTSIZE] = { JEDEC_RDSR2 }; > + /* FIXME: No workarounds for driver/hardware bugs in generic code. */ > + unsigned char readarr[2]; /* JEDEC_RDSR2_INSIZE=1 but wbsio needs 2 */ > + int ret; > + > + /* Read Status Register */ > + ret = spi_send_command(flash, sizeof(cmd), sizeof(readarr), cmd, readarr); > + if (ret) > + msg_cerr("RDSR2 failed!\n"); > + > + return readarr[0]; > +} > + > +/* Winbond sector protection enable that tries to set the status register bits given. */ > +int spi_enable_sectorprotect_winbond(struct flashctx *flash, const uint8_t status_flags) > +{ > + uint8_t status, status2; > + int result; > + uint8_t lock_mask = 0x80; > + uint8_t lock2_mask = 0x1; > + > + status = spi_read_status_register(flash); > + status2 = spi_read_status_register_2(flash); > + if ((status & lock_mask) != 0) { > + msg_cdbg("\n\tNeed to disable the register lock first... "); > + if ((status2 & lock2_mask) != 0) { > + msg_cerr("Hardware protection is active, enabling write protection is impossible.\n"); > + return 1; > + } > + /* All bits except the register lock bit (often called SPRL, SRWD, WPEN) are readonly. */ > + result = spi_write_status_register(flash, status & ~lock_mask); > + if (result) { > + msg_cerr("spi_write_status_register failed.\n"); > + return result; > + } > + status = spi_read_status_register(flash); > + if ((status & lock_mask) != 0) { > + msg_cerr("Unsetting lock bit(s) failed.\n"); > + return 1; > + } > + msg_cdbg("done.\n"); > + } > + > + /* Set requested protect bits */ > + result = spi_write_status_register(flash, status | (status_flags << 2) ); > + if (result) { > + msg_cerr("spi_write_status_register failed.\n"); > + return result; > + } > + status = spi_read_status_register(flash); > + if ((status & (status_flags << 2)) != (status_flags << 2)) { > + msg_cerr("Setting lock bit(s) failed.\n"); > + return 1; > + } > + > + /* Set lock bit */ > + result = spi_write_status_register(flash, status | lock_mask); > + if (result) { > + msg_cerr("spi_write_status_register failed.\n"); > + return result; > + } > + status = spi_read_status_register(flash); > + if ((status & lock_mask) == 0) { > + msg_cerr("Setting lock bit(s) failed.\n"); > + return 1; > + } > + > + return 0; > +} > + > /* A generic block protection disable. > * Tests if a protection is enabled with the block protection mask (bp_mask) and returns success otherwise. > * Tests if the register bits are locked with the lock_mask (lock_mask). > Index: flashrom.c > =================================================================== > --- flashrom.c (revision 1955) > +++ flashrom.c (working copy) > @@ -1977,7 +1977,7 @@ > * Besides that, the function itself is a textbook example of abysmal code flow. > */ > int doit(struct flashctx *flash, int force, const char *filename, int read_it, > - int write_it, int erase_it, int verify_it) > + int write_it, int erase_it, int verify_it, int lock_it) > { > uint8_t *oldcontents; > uint8_t *newcontents; > @@ -2129,6 +2129,13 @@ > msg_cinfo("VERIFIED.\n"); > } > > + if (lock_it && flash->chip->lock) { > + msg_cinfo("Locking upper 4K (bootblock)... "); > + ret = flash->chip->lock(flash, 0x11); > + if (!ret) > + msg_cinfo("LOCKED.\n"); > + } > + > out: > free(oldcontents); > free(newcontents); > Index: cli_classic.c > =================================================================== > --- cli_classic.c (revision 1955) > +++ cli_classic.c (working copy) > @@ -49,6 +49,7 @@ > " -r | --read read flash and save to \n" > " -w | --write write to flash\n" > " -v | --verify verify flash against \n" > + " -u | --lock lock upper Flash region (typically the 4K bootblock)\n" > " -E | --erase erase flash memory\n" > " -V | --verbose more verbose output\n" > " -c | --chip probe only for specified flash chip\n" > @@ -101,18 +102,19 @@ > #if CONFIG_PRINT_WIKI == 1 > int list_supported_wiki = 0; > #endif > - int read_it = 0, write_it = 0, erase_it = 0, verify_it = 0; > + int read_it = 0, write_it = 0, erase_it = 0, verify_it = 0, lock_it = 0; > int dont_verify_it = 0, list_supported = 0, operation_specified = 0; > enum programmer prog = PROGRAMMER_INVALID; > int ret = 0; > > - static const char optstring[] = "r:Rw:v:nVEfc:l:i:p:Lzho:"; > + static const char optstring[] = "r:Rw:v:nuVEfc:l:i:p:Lzho:"; > static const struct option long_options[] = { > {"read", 1, NULL, 'r'}, > {"write", 1, NULL, 'w'}, > {"erase", 0, NULL, 'E'}, > {"verify", 1, NULL, 'v'}, > {"noverify", 0, NULL, 'n'}, > + {"lock", 0, NULL, 'u'}, > {"chip", 1, NULL, 'c'}, > {"verbose", 0, NULL, 'V'}, > {"force", 0, NULL, 'f'}, > @@ -187,6 +189,9 @@ > } > dont_verify_it = 1; > break; > + case 'u': > + lock_it = 1; > + break; > case 'c': > chip_to_probe = strdup(optarg); > break; > @@ -522,7 +527,7 @@ > goto out_shutdown; > } > > - if (!(read_it | write_it | verify_it | erase_it)) { > + if (!(read_it | write_it | verify_it | erase_it | lock_it)) { > msg_ginfo("No operations were specified.\n"); > goto out_shutdown; > } > @@ -542,7 +547,7 @@ > * Give the chip time to settle. > */ > programmer_delay(100000); > - ret |= doit(fill_flash, force, filename, read_it, write_it, erase_it, verify_it); > + ret |= doit(fill_flash, force, filename, read_it, write_it, erase_it, verify_it, lock_it); > > unmap_flash(fill_flash); > out_shutdown: > Index: flashchips.c > =================================================================== > --- flashchips.c (revision 1955) > +++ flashchips.c (working copy) > @@ -14581,6 +14581,7 @@ > }, > .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */ > .unlock = spi_disable_blockprotect, > + .lock = spi_enable_sectorprotect_winbond, > .write = spi_chip_write_256, > .read = spi_chip_read, > .voltage = {2700, 3600}, > Index: chipdrivers.h > =================================================================== > --- chipdrivers.h (revision 1955) > +++ chipdrivers.h (working copy) > @@ -73,6 +73,7 @@ > int spi_prettyprint_status_register_bp4_srwd(struct flashctx *flash); > int spi_prettyprint_status_register_bp2_bpl(struct flashctx *flash); > int spi_prettyprint_status_register_bp2_tb_bpl(struct flashctx *flash); > +int spi_enable_sectorprotect_winbond(struct flashctx *flash, const uint8_t status_flags); > int spi_disable_blockprotect(struct flashctx *flash); > int spi_disable_blockprotect_bp1_srwd(struct flashctx *flash); > int spi_disable_blockprotect_bp2_srwd(struct flashctx *flash); > Index: flash.h > =================================================================== > --- flash.h (revision 1955) > +++ flash.h (working copy) > @@ -200,6 +200,7 @@ > } block_erasers[NUM_ERASEFUNCTIONS]; > > int (*printlock) (struct flashctx *flash); > + int (*lock) (struct flashctx *flash, const uint8_t status_flags); > int (*unlock) (struct flashctx *flash); > int (*write) (struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); > int (*read) (struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); > @@ -281,7 +282,7 @@ > void print_banner(void); > void list_programmers_linebreak(int startcol, int cols, int paren); > int selfcheck(void); > -int doit(struct flashctx *flash, int force, const char *filename, int read_it, int write_it, int erase_it, int verify_it); > +int doit(struct flashctx *flash, int force, const char *filename, int read_it, int write_it, int erase_it, int verify_it, int lock_it); > int read_buf_from_file(unsigned char *buf, unsigned long size, const char *filename); > int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename); > > Index: spi.h > =================================================================== > --- spi.h (revision 1955) > +++ spi.h (working copy) > @@ -121,6 +121,11 @@ > #define JEDEC_RDSR_OUTSIZE 0x01 > #define JEDEC_RDSR_INSIZE 0x01 > > +/* Read Status Register 2 */ > +#define JEDEC_RDSR2 0x35 > +#define JEDEC_RDSR2_OUTSIZE 0x01 > +#define JEDEC_RDSR2_INSIZE 0x01 > + > /* Status Register Bits */ > #define SPI_SR_WIP (0x01 << 0) > #define SPI_SR_WEL (0x01 << 1) > > _______________________________________________ > flashrom mailing list > flashrom@flashrom.org > https://www.flashrom.org/mailman/listinfo/flashrom > > > > > -- > David Hendricks (dhendrix) > Systems Software Engineer, Google Inc. From 12bd794218573836302854675b25203d01f60bb1 Mon Sep 17 00:00:00 2001 From: Hatim Kanchwala Date: Fri, 26 Aug 2016 12:38:34 +0530 Subject: [PATCH] Add support for W25Q128BV and W25Q128FV Uses new status register, access protection and OTP infrastructure (WIP). Chip definition for "W25Q128.V" needed to be separated into 2 owing to different status register configurations of W25Q128BV and W25Q128FV. Signed-off-by: Hatim Kanchwala --- flashchips.c | 48 +++++++++++++++++++++++++++++++++++++++++++++--- otp_layouts.c | 2 +- statusreg_layouts.c | 4 ++-- writeprotect_layouts.c | 2 +- 4 files changed, 49 insertions(+), 7 deletions(-) diff --git a/flashchips.c b/flashchips.c index b946cb8..957d63c 100644 --- a/flashchips.c +++ b/flashchips.c @@ -14729,70 +14729,112 @@ const struct flashchip flashchips[] = { .eraseblocks = { {8 * 1024 * 1024, 1} }, .block_erase = spi_block_erase_60, }, { .eraseblocks = { {8 * 1024 * 1024, 1} }, .block_erase = spi_block_erase_c7, } }, .status_register = &w25q40bl_64fv_sr, .write = spi_chip_write_256, .read = spi_chip_read, .voltage = {2700, 3600}, .wp = &gd_w_wp, .otp = &gd_w256_3_otp, }, { .vendor = "Winbond", - .name = "W25Q128.V", + .name = "W25Q128BF", .bustype = BUS_SPI, .manufacture_id = WINBOND_NEX_ID, .model_id = WINBOND_NEX_W25Q128_V, .total_size = 16384, .page_size = 256, /* supports SFDP */ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44, read ID 0x4B */ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP, .tested = TEST_OK_PREW, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = { { .eraseblocks = { {4 * 1024, 4096} }, .block_erase = spi_block_erase_20, }, { .eraseblocks = { {32 * 1024, 512} }, .block_erase = spi_block_erase_52, }, { .eraseblocks = { {64 * 1024, 256} }, .block_erase = spi_block_erase_d8, }, { .eraseblocks = { {16 * 1024 * 1024, 1} }, .block_erase = spi_block_erase_60, }, { .eraseblocks = { {16 * 1024 * 1024, 1} }, .block_erase = spi_block_erase_c7, } }, - .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */ - .unlock = spi_disable_blockprotect, + .status_register = &w25q40bl_64fv_sr, + .write = spi_chip_write_256, + .read = spi_chip_read, + .voltage = {2700, 3600}, + .wp = &gd_w_wp, + .otp = &gd_w256_3_otp, + }, + + { + .vendor = "Winbond", + .name = "W25Q128FV", + .bustype = BUS_SPI, + .manufacture_id = WINBOND_NEX_ID, + .model_id = WINBOND_NEX_W25Q128_V, + .total_size = 16384, + .page_size = 256, + /* supports SFDP */ + /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44, read ID 0x4B */ + .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP, + .tested = TEST_OK_PREW, + .probe = probe_spi_rdid, + .probe_timing = TIMING_ZERO, + .block_erasers = + { + { + .eraseblocks = { {4 * 1024, 4096} }, + .block_erase = spi_block_erase_20, + }, { + .eraseblocks = { {32 * 1024, 512} }, + .block_erase = spi_block_erase_52, + }, { + .eraseblocks = { {64 * 1024, 256} }, + .block_erase = spi_block_erase_d8, + }, { + .eraseblocks = { {16 * 1024 * 1024, 1} }, + .block_erase = spi_block_erase_60, + }, { + .eraseblocks = { {16 * 1024 * 1024, 1} }, + .block_erase = spi_block_erase_c7, + } + }, + .status_register = &w25q128fw_sr, .write = spi_chip_write_256, .read = spi_chip_read, .voltage = {2700, 3600}, + .wp = &gd_w_wp, + .otp = &gd_w256_3_otp, }, { .vendor = "Winbond", .name = "W25Q20.W", .bustype = BUS_SPI, .manufacture_id = WINBOND_NEX_ID, .model_id = WINBOND_NEX_W25Q20_W, .total_size = 256, .page_size = 256, /* OTP: 256B total; read 0x48; write 0x42, erase 0x44, read ID 0x4B */ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP, .tested = TEST_UNTESTED, .probe = probe_spi_rdid, .probe_timing = TIMING_ZERO, .block_erasers = { diff --git a/otp_layouts.c b/otp_layouts.c index e19516a..5860a4a 100644 --- a/otp_layouts.c +++ b/otp_layouts.c @@ -130,35 +130,35 @@ struct otp en512_16384otp = { .region = { { .addr = 0xFFF000, .size = 512, .status_bit = SRP0, }, }, .status = &eon_status_generic, .print_status = &eon_print_status_generic, .read = &eon_read_generic, .write = &eon_write_generic, .erase = &eon_erase_generic, .lock = &eon_lock_generic, }; /* === GigaDevice and Winbond === */ // FIXME(hatim): Deal with chips with shared OTP modifier bit -/* GD25LQ16, GD25LQ80, GD25LQ40, W25Q40BL, W25Q64FV +/* GD25LQ16, GD25LQ80, GD25LQ40, W25Q40BL, W25Q64FV, W25Q128BV * (There is an additional 256 bytes security register * at 0x000000 which is reserved and can only be read.) */ // FIXME(hatim): Add support to interact with the reserved security register struct otp gd_w256_3_otp = { .region = { { .addr = 0x001000, .size = 256, .status_bit = LB1, }, { .addr = 0x002000, .size = 256, .status_bit = LB2, }, { .addr = 0x003000, .size = 256, .status_bit = LB3, diff --git a/statusreg_layouts.c b/statusreg_layouts.c index e83b1b4..cf963b9 100644 --- a/statusreg_layouts.c +++ b/statusreg_layouts.c @@ -267,35 +267,35 @@ struct status_register gd25q80b_128_sr = { }; /* === Winbond === */ /* W25Q80, W25Q16, W25Q32 */ struct status_register w25q80_16_32_sr = { .layout = { { WIP, WEL, BP0, BP1, BP2, TB, SEC, SRP0 }, { SRP1, QE, RESV, RESV, RESV, RESV, RESV, RESV }, }, .read = &spi_read_status_register_generic, .write = &spi_write_status_register_generic, .print = &spi_prettyprint_status_register_generic, .print_wp_mode = &spi_prettyprint_status_register_wp_generic, .get_wp_mode = &get_wp_mode_generic, .set_wp_mode = &set_wp_mode_generic, }; -/* W25Q40BL, W25Q64FV */ +/* W25Q40BL, W25Q64FV, W25Q128BV */ struct status_register w25q40bl_64fv_sr = { .layout = { { WIP, WEL, BP0, BP1, BP2, TB, SEC, SRP0 }, { SRP1, QE, RESV, LB1, LB2, LB3, CMP, SUS }, }, .read = &spi_read_status_register_generic, .write = &spi_write_status_register_generic, .print = &spi_prettyprint_status_register_generic, .print_wp_mode = &spi_prettyprint_status_register_wp_generic, .get_wp_mode = &get_wp_mode_generic, .set_wp_mode = &set_wp_mode_generic, }; /* === Triple status registers === */ /* === GigaDevice === */ /* GD25LQ05B, GD25LQ10B, GD25LQ20B */ struct status_register gd25lq05_10_20b_sr = { @@ -344,31 +344,31 @@ struct status_register gd25q127c_sr = { /* GD25Q128C */ struct status_register gd25q128c_sr = { .layout = { { WIP, WEL, BP0, BP1, BP2, BP3, BP4, SRP0 }, { SRP1, QE, SUS2, LB1, LB2, LB3, CMP, SUS1 }, { RESV, RESV, WPS, RESV, RESV, DRV0, DRV1, RST }, }, .read = &spi_read_status_register_generic, .write = &spi_write_status_register_generic, .print = &spi_prettyprint_status_register_generic, .print_wp_mode = &spi_prettyprint_status_register_wp_generic, .get_wp_mode = &get_wp_mode_generic, .set_wp_mode = &set_wp_mode_generic, }; /* === Winbond === */ -/* W25Q128FW */ +/* W25Q128FW, W25Q128FV */ struct status_register w25q128fw_sr = { .layout = { { WIP, WEL, BP0, BP1, BP2, TB, SEC, SRP0 }, { SRP1, QE, RESV, LB1, LB2, LB3, CMP, SUS }, { RESV, RESV, WPS, RESV, RESV, DRV0, DRV1, RST }, }, .read = &spi_read_status_register_generic, .write = &spi_write_status_register_generic, .print = &spi_prettyprint_status_register_generic, .print_wp_mode = &spi_prettyprint_status_register_wp_generic, .get_wp_mode = &get_wp_mode_generic, .set_wp_mode = &set_wp_mode_generic, }; diff --git a/writeprotect_layouts.c b/writeprotect_layouts.c index 67e59c2..d216b91 100644 --- a/writeprotect_layouts.c +++ b/writeprotect_layouts.c @@ -30,35 +30,35 @@ * int (*set_range) (struct flashctx *flash, uint32_t start, uint32_t len); * int (*disable) (struct flashctx *flash); * int (*print_table) (struct flashctx *flash); * }; */ /* A25LQ032, A25LQ32A */ struct wp a25l032_32a_wp = { .range_table = &a25l032_range_table, .bp_bitmask = &bp_bitmask_generic, .print_table = &print_table_generic, .set_range = &set_range_generic, .disable = &disable_generic, }; /* A25L080, A25LQ16, GD25LQ40, GD25LQ80, GD25LQ16, GD25Q16, GD25Q16B GD25Q32(B), * GD25Q64(B), GD25Q128B, GD25Q128C, GD25VQ16C, GD25VQ21B, GD25VQ40C, GD25VQ41B, - * GD25VQ80C, W25Q40BL, W25Q64FV */ + * GD25VQ80C, W25Q40BL, W25Q64FV, W25Q128BV, W25Q128FV */ struct wp gd_w_wp = { .range_table = &sec_block_range_pattern, .bp_bitmask = &bp_bitmask_generic, .print_table = &print_table_generic, .set_range = &set_range_generic, .disable = &disable_generic, }; /* EN25QH128 */ struct wp en25qh128_wp = { .ranges = (struct range[]){ /* BP3 effectively acts as TB bit, * BP[0..2] function normally. */ { 0x000000, 0 }, { 0xff0000, 64 }, { 0xfe0000, 128 }, { 0xfc0000, 256 }, -- Hatim Kanchwala hatim@hatimak.me