From patchwork Tue Jul 5 20:28:03 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hatim Kanchwala X-Patchwork-Id: 644996 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 3rkb8d1L99z9s5g for ; Wed, 6 Jul 2016 06:29:37 +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=GY/UXuUP; 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 1bKWxW-0007fu-6I; Tue, 05 Jul 2016 22:28:42 +0200 Received: from mail-pa0-f65.google.com ([209.85.220.65]) by mail.coreboot.org with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.86_2) (envelope-from ) id 1bKWxG-0007dk-JK for flashrom@flashrom.org; Tue, 05 Jul 2016 22:28:39 +0200 Received: by mail-pa0-f65.google.com with SMTP id ts6so19226988pac.0 for ; Tue, 05 Jul 2016 13:28:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hatimak-me.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references; bh=uDvgH0E2GrBkBaBJb9sFnfOclfWhX4Bm+SMLVIaluLQ=; b=GY/UXuUP8BfuGV4G/aORQ2EA1pBMMXR/RGpIw8KsFjLFvwCbenxLfDe5XvsOilzH6V jadArMQS4mem16z6WUbVrKnW2oXUMgAFQ4t0SKcXIXFHNLHpFpJSK83omQS/VmHK322u iO0nw8tn37GJC1Kx4+1xVoFMxKtKFN32aAG0AceJWtHVbSOzetzJlbcyn5dr/BUBDu30 xgVZ9N//hyZWu5gqhdex5tpoZk/8jlXUSZl5yqzzg/mtZHiGOx5J3bDZav6AQRmRqSRL EHKs6j7CiV5qS4BLckKExHFayxFBd6T3n+z1ityf3K8YysJiYPc1HcLzujnm2eZoyPA0 LeWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=uDvgH0E2GrBkBaBJb9sFnfOclfWhX4Bm+SMLVIaluLQ=; b=cs3O9VYUtLWYUf/GG1nnCHjWvtPoH8M1BIwGWHH5RBUfLu+3tfvuSfDRTew+C6wIcK iabrIfCi+94bwNMfUF/xg72GtwmLOdR4He2YjoZnyp+pL/e+z6c2L3gEo1HthIBDR4lC Jm0Vv2QSHE7u7rEa25KznsM1kYzAb5Kx4fssUKSoOdLX9rvMrKtVNRbx3tg2PxQtwHQ/ 0Scpjc3DcQcheeh6UnyxmoGL1l8NxWN74I+Mx388ERUbHlQEd11XcgIFFZtSMkfFz/GW YB0BrA8l8GGZEIYvvqXeq6f8iwy+nopwJ6r4RgcJ5pmcFqmSfK0pevlipY6VikGnpIZg qIGA== X-Gm-Message-State: ALyK8tL4QQkRUpzKONxVJcT/zH69PQsqrYIyhQGyln0PXadiJM9E1Y2fDN++j2F4jOIDJg== X-Received: by 10.67.8.69 with SMTP id di5mr35146923pad.123.1467750503603; Tue, 05 Jul 2016 13:28:23 -0700 (PDT) Received: from ubuntu-lenovo-z580.domain.name ([103.240.193.150]) by smtp.gmail.com with ESMTPSA id f10sm7219958pfc.79.2016.07.05.13.28.22 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 05 Jul 2016 13:28:23 -0700 (PDT) From: Hatim Kanchwala To: flashrom@flashrom.org Date: Wed, 6 Jul 2016 01:58:03 +0530 Message-Id: <1467750485-29158-5-git-send-email-hatim@hatimak.me> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1467750485-29158-1-git-send-email-hatim@hatimak.me> References: <1467750485-29158-1-git-send-email-hatim@hatimak.me> X-Spam-Score: 5.1 (+++++) X-Spam-Report: Spam detection software, running on the system "ra.coresystems.de", has identified this incoming email as possible spam. The original message has been attached to this so you can view it (if it isn't spam) or label similar future email. If you have any questions, see info@coresystems.de for details. Content analysis details: (5.1 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 3.5 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: hatimak.me] 1.9 RCVD_IN_MCAFEE RBL: Listed at cidr.bl.mcafee.com [103.240.193.150 listed in cidr.bl.mcafee.com] 1.9 RCVD_IN_CHILE RBL: Listed at dnsblchile [103.240.193.150 listed in dnsblchile.org] 1.9 RCVD_IN_APEWS RBL: Listed at APEWS [103.240.193.150 listed in l2.apews.org] 1.9 RCVD_IN_UCEPROTECT2 RBL: Network listed in dnsbl-2.uceprotect.net [Net 103.240.192.0/22 is UCEPROTECT-Level2 listed] [because 42 abusers are hosted by /AS132453] [there. See: ] -6.0 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-Spam-Flag: YES Subject: [flashrom] [PATCH 4/6] WIP: Add support for access protection infrastructure to existing chips 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: , MIME-Version: 1.0 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 - struct wp defines added for the following chips (21 in total) - - AMIC(4) : A25LQ032, A25LQ32A, A25L080, A25LQ16 - Macronix(12) : MX25L1605D, MX25L1608D, MX25L1673E, MX25L6406E, MX25L6408E, MX25L6405D, MX25L3205D, MX25L3208D, MX25L6436E, MX25L6445E, MX25L6465E, MX25L6473E - GigaDevice(5) : GD25LQ40, GD25LQ80, GD25LQ16, GD25Q16, GD25Q16B - All of the above support new infrastructure (in flashchips.c) (WIP) - 6 unique struct definitions were required to represent all of the above chips Signed-off-by: Hatim Kanchwala --- Makefile | 6 +- chipdrivers.h | 1 + flashchips.c | 39 +++++------- writeprotect.c | 19 ++++++ writeprotect.h | 7 +++ writeprotect_layouts.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 212 insertions(+), 26 deletions(-) create mode 100644 writeprotect_layouts.c diff --git a/Makefile b/Makefile index ed4979e..c274e79 100644 --- a/Makefile +++ b/Makefile @@ -502,29 +502,29 @@ else override CONFIG_SATAMV = no endif ifeq ($(CONFIG_IT8212), yes) UNSUPPORTED_FEATURES += CONFIG_IT8212=yes else override CONFIG_IT8212 = no endif endif ############################################################################### # Flash chip drivers and bus support infrastructure. CHIP_OBJS = jedec.o stm50.o w39.o w29ee011.o \ - sst28sf040.o 82802ab.o \ - sst49lfxxxc.o sst_fwhub.o flashchips.o spi.o spi25.o spi25_statusreg.o \ - writeprotect.o statusreg_layouts.o opaque.o sfdp.o en29lv640b.o at45db.o + sst28sf040.o 82802ab.o sst49lfxxxc.o sst_fwhub.o flashchips.o spi.o \ + spi25.o spi25_statusreg.o writeprotect.o statusreg_layouts.o \ + writeprotect_layouts.o opaque.o sfdp.o en29lv640b.o at45db.o ############################################################################### # Library code. LIB_OBJS = layout.o flashrom.o udelay.o programmer.o helpers.o ############################################################################### # Frontend related stuff. CLI_OBJS = cli_classic.o cli_output.o cli_common.o print.o # Set the flashrom version string from the highest revision number of the checked out flashrom files. # Note to packagers: Any tree exported with "make export" or "make tarball" diff --git a/chipdrivers.h b/chipdrivers.h index c60aff8..d3b27cc 100644 --- a/chipdrivers.h +++ b/chipdrivers.h @@ -116,26 +116,27 @@ int spi_prettyprint_status_register_sst25vf040b(struct flashctx *flash); /* writeprotect.c */ struct range *sec_block_range_pattern(struct flashctx *flash); char get_cmp(struct flashctx *flash); int set_cmp(struct flashctx *flash, uint8_t cmp); uint32_t bp_bitmask_generic(struct flashctx *flash); struct range *bp_to_range(struct flashctx *flash, unsigned char bp_config); int range_to_bp_bitfield(struct flashctx *flash, uint32_t start, uint32_t len); int print_range_generic(struct flashctx *flash); int print_table_generic(struct flashctx *flash); int set_range_generic(struct flashctx *flash, uint32_t start, uint32_t len); int disable_generic(struct flashctx *flash); struct range *range_table_global(struct flashctx *flash); +struct range *a25l032_range_table(struct flashctx *flash); /* sfdp.c */ int probe_spi_sfdp(struct flashctx *flash); /* opaque.c */ int probe_opaque(struct flashctx *flash); int read_opaque(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len); int write_opaque(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len); int erase_opaque(struct flashctx *flash, unsigned int blockaddr, unsigned int blocklen); /* at45db.c */ int probe_spi_at45db(struct flashctx *flash); int spi_prettyprint_status_register_at45db(struct flashctx *flash); diff --git a/flashchips.c b/flashchips.c index 0afd297..725a9e2 100644 --- a/flashchips.c +++ b/flashchips.c @@ -16,26 +16,27 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "flash.h" #include "flashchips.h" #include "chipdrivers.h" #include "spi25_statusreg.h" +#include "writeprotect.h" /** * List of supported flash chips. * * Please keep the list sorted by vendor name and chip family, so that the output of 'flashrom -L' is roughly * alphabetically sorted. Within families keep them in order of density. */ const struct flashchip flashchips[] = { /* * .vendor = Vendor name * .name = Chip name * .bustype = Supported flash bus types (Parallel, LPC...) @@ -1156,32 +1157,31 @@ const struct flashchip flashchips[] = { .block_erasers = { { .eraseblocks = { { 4 * 1024, 256 } }, .block_erase = spi_block_erase_20, }, { .eraseblocks = { { 64 * 1024, 16 } }, .block_erase = spi_block_erase_d8, }, { .eraseblocks = { { 1024 * 1024, 1 } }, .block_erase = spi_block_erase_c7, } }, - /* TODO: Read/write 2nd status register */ .status_register = &a25l080_sr, - .unlock = spi_disable_blockprotect, .write = spi_chip_write_256, .read = spi_chip_read, .voltage = {2700, 3600}, + .wp = &gd25_a25l080_q16_32a_wp, }, { .vendor = "AMIC", .name = "A25L016", .bustype = BUS_SPI, .manufacture_id = AMIC_ID_NOPREFIX, .model_id = AMIC_A25L016, .total_size = 2048, .page_size = 256, .feature_bits = FEATURE_WRSR_WREN, .tested = TEST_UNTESTED, .probe = probe_spi_rdid, @@ -1267,32 +1267,31 @@ const struct flashchip flashchips[] = { .eraseblocks = { { 64 * 1024, 32 } }, .block_erase = spi_block_erase_52, }, { .eraseblocks = { { 64 * 1024, 32 } }, .block_erase = spi_block_erase_d8, }, { .eraseblocks = { { 2048 * 1024, 1 } }, .block_erase = spi_block_erase_60, }, { .eraseblocks = { { 2048 * 1024, 1 } }, .block_erase = spi_block_erase_c7, } }, - /* TODO: Read/write 2nd status register */ .status_register = &a25lq16_32a_sr, - .unlock = spi_disable_blockprotect_bp2_srwd, .write = spi_chip_write_256, .read = spi_chip_read, .voltage = {2700, 3600}, + .wp = &gd25_a25l080_q16_32a_wp, }, { .vendor = "AMIC", .name = "A25LQ032", .bustype = BUS_SPI, .manufacture_id = AMIC_ID_NOPREFIX, .model_id = AMIC_A25LQ032, .total_size = 4096, .page_size = 256, /* A25LQ32A supports SFDP */ /* OTP: 64B total; read 0x4B, 0x48; write 0x42 */ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP, @@ -1308,32 +1307,31 @@ const struct flashchip flashchips[] = { .eraseblocks = { { 64 * 1024, 64 } }, .block_erase = spi_block_erase_52, }, { .eraseblocks = { { 64 * 1024, 64 } }, .block_erase = spi_block_erase_d8, }, { .eraseblocks = { { 4096 * 1024, 1 } }, .block_erase = spi_block_erase_60, }, { .eraseblocks = { { 4096 * 1024, 1 } }, .block_erase = spi_block_erase_c7, } }, - /* TODO: Read/write 2nd status register */ .status_register = &a25l032_sr, - .unlock = spi_disable_blockprotect_bp2_srwd, .write = spi_chip_write_256, .read = spi_chip_read, .voltage = {2700, 3600}, + .wp = &a25l032_32a_wp, }, { .vendor = "AMIC", .name = "A25LQ32A", .bustype = BUS_SPI, .manufacture_id = AMIC_ID_NOPREFIX, .model_id = AMIC_A25LQ032, .total_size = 4096, .page_size = 256, /* A25LQ32A supports SFDP */ /* OTP: 64B total; read 0x4B, 0x48; write 0x42 */ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP, @@ -1350,30 +1348,30 @@ const struct flashchip flashchips[] = { .block_erase = spi_block_erase_52, }, { .eraseblocks = { { 64 * 1024, 64 } }, .block_erase = spi_block_erase_d8, }, { .eraseblocks = { { 4096 * 1024, 1 } }, .block_erase = spi_block_erase_60, }, { .eraseblocks = { { 4096 * 1024, 1 } }, .block_erase = spi_block_erase_c7, } }, .status_register = &a25lq16_32a_sr, - .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: 2nd status reg (read with 0x35) */ .write = spi_chip_write_256, .read = spi_chip_read, .voltage = {2700, 3600}, + .wp = &a25l032_32a_wp, }, { .vendor = "AMIC", .name = "A25LQ64", .bustype = BUS_SPI, .manufacture_id = AMIC_ID_NOPREFIX, .model_id = AMIC_A25LQ64, .total_size = 8192, .page_size = 256, /* supports SFDP */ /* OTP: 512B total; enter 0xB1, exit 0xC1 */ /* QPI enable 0x35, disable 0xF5 */ @@ -5704,32 +5702,31 @@ const struct flashchip flashchips[] = { .eraseblocks = { {32 * 1024, 16} }, .block_erase = spi_block_erase_52, }, { .eraseblocks = { {64 * 1024, 8} }, .block_erase = spi_block_erase_d8, }, { .eraseblocks = { {512 * 1024, 1} }, .block_erase = spi_block_erase_60, }, { .eraseblocks = { {512 * 1024, 1} }, .block_erase = spi_block_erase_c7, } }, - /* TODO: Read/write 2nd status register */ .status_register = &gd25lq_sr, - .unlock = spi_disable_blockprotect_bp4_srwd, .write = spi_chip_write_256, .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */ .voltage = {1695, 1950}, + .wp = &gd25_a25l080_q16_32a_wp, }, { .vendor = "GigaDevice", .name = "GD25LQ80", .bustype = BUS_SPI, .manufacture_id = GIGADEVICE_ID, .model_id = GIGADEVICE_GD25LQ80, .total_size = 1024, .page_size = 256, /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 */ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP, .tested = TEST_UNTESTED, @@ -5744,32 +5741,31 @@ const struct flashchip flashchips[] = { .eraseblocks = { {32 * 1024, 32} }, .block_erase = spi_block_erase_52, }, { .eraseblocks = { {64 * 1024, 16} }, .block_erase = spi_block_erase_d8, }, { .eraseblocks = { {1 * 1024 * 1024, 1} }, .block_erase = spi_block_erase_60, }, { .eraseblocks = { {1 * 1024 * 1024, 1} }, .block_erase = spi_block_erase_c7, } }, - /* TODO: Read/write 2nd status register*/ .status_register = &gd25lq_sr, - .unlock = spi_disable_blockprotect_bp4_srwd, .write = spi_chip_write_256, .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */ .voltage = {1695, 1950}, + .wp = &gd25_a25l080_q16_32a_wp, }, { .vendor = "GigaDevice", .name = "GD25LQ16", .bustype = BUS_SPI, .manufacture_id = GIGADEVICE_ID, .model_id = GIGADEVICE_GD25LQ16, .total_size = 2048, .page_size = 256, /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 */ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP, .tested = TEST_UNTESTED, @@ -5784,32 +5780,31 @@ const struct flashchip flashchips[] = { .eraseblocks = { {32 * 1024, 64} }, .block_erase = spi_block_erase_52, }, { .eraseblocks = { {64 * 1024, 32} }, .block_erase = spi_block_erase_d8, }, { .eraseblocks = { {2 * 1024 * 1024, 1} }, .block_erase = spi_block_erase_60, }, { .eraseblocks = { {2 * 1024 * 1024, 1} }, .block_erase = spi_block_erase_c7, } }, - /* TODO: Read/write 2nd status register */ .status_register = &gd25lq_sr, - .unlock = spi_disable_blockprotect_bp4_srwd, .write = spi_chip_write_256, .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */ .voltage = {1695, 1950}, + .wp = &gd25_a25l080_q16_32a_wp, }, { .vendor = "GigaDevice", .name = "GD25LQ32", .bustype = BUS_SPI, .manufacture_id = GIGADEVICE_ID, .model_id = GIGADEVICE_GD25LQ32, .total_size = 4096, .page_size = 256, /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 */ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP, .tested = TEST_OK_PREW, @@ -6126,32 +6121,31 @@ const struct flashchip flashchips[] = { .eraseblocks = { {32 * 1024, 64} }, .block_erase = spi_block_erase_52, }, { .eraseblocks = { {64 * 1024, 32} }, .block_erase = spi_block_erase_d8, }, { .eraseblocks = { {2 * 1024 * 1024, 1} }, .block_erase = spi_block_erase_60, }, { .eraseblocks = { {2 * 1024 * 1024, 1} }, .block_erase = spi_block_erase_c7, } }, - /* TODO: Read/write 2nd status register */ .status_register = &gd25q10_20_40_80_sr, - .unlock = spi_disable_blockprotect_bp4_srwd, .write = spi_chip_write_256, .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */ .voltage = {2700, 3600}, + .wp = &gd25_a25l080_q16_32a_wp, }, { .vendor = "GigaDevice", .name = "GD25Q16B", .bustype = BUS_SPI, .manufacture_id = GIGADEVICE_ID, .model_id = GIGADEVICE_GD25Q16, .total_size = 2048, .page_size = 256, /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 (B version only) */ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP, .tested = TEST_OK_PREW, @@ -6166,32 +6160,31 @@ const struct flashchip flashchips[] = { .eraseblocks = { {32 * 1024, 64} }, .block_erase = spi_block_erase_52, }, { .eraseblocks = { {64 * 1024, 32} }, .block_erase = spi_block_erase_d8, }, { .eraseblocks = { {2 * 1024 * 1024, 1} }, .block_erase = spi_block_erase_60, }, { .eraseblocks = { {2 * 1024 * 1024, 1} }, .block_erase = spi_block_erase_c7, } }, - /* TODO: Read/write 2nd status register */ .status_register = &gd25q16_32_64b_sr, - .unlock = spi_disable_blockprotect_bp4_srwd, .write = spi_chip_write_256, .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */ .voltage = {2700, 3600}, + .wp = &gd25_a25l080_q16_32a_wp, }, { .vendor = "GigaDevice", .name = "GD25Q32(B)", .bustype = BUS_SPI, .manufacture_id = GIGADEVICE_ID, .model_id = GIGADEVICE_GD25Q32, .total_size = 4096, .page_size = 256, /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 */ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP, .tested = TEST_OK_PREW, @@ -7629,30 +7622,30 @@ const struct flashchip flashchips[] = { .block_erase = spi_block_erase_20, }, { .eraseblocks = { {64 * 1024, 32} }, .block_erase = spi_block_erase_d8, }, { .eraseblocks = { {2 * 1024 * 1024, 1} }, .block_erase = spi_block_erase_60, }, { .eraseblocks = { {2 * 1024 * 1024, 1} }, .block_erase = spi_block_erase_c7, }, }, .status_register = &mx25lx5d_sr, - .unlock = spi_disable_blockprotect_bp3_srwd, .write = spi_chip_write_256, .read = spi_chip_read, /* Fast read (0x0B), dual I/O supported */ .voltage = {2700, 3600}, + .wp = &mx25l16xd_wp, }, { .vendor = "Macronix", .name = "MX25L1673E", .bustype = BUS_SPI, .manufacture_id = MACRONIX_ID, .model_id = MACRONIX_MX25L1605, .total_size = 2048, .page_size = 256, .feature_bits = FEATURE_WRSR_WREN, .tested = TEST_OK_PREW, .probe = probe_spi_rdid, @@ -7664,30 +7657,30 @@ const struct flashchip flashchips[] = { .block_erase = spi_block_erase_20, }, { .eraseblocks = { {64 * 1024, 32} }, .block_erase = spi_block_erase_d8, }, { .eraseblocks = { {2 * 1024 * 1024, 1} }, .block_erase = spi_block_erase_60, }, { .eraseblocks = { {2 * 1024 * 1024, 1} }, .block_erase = spi_block_erase_c7, }, }, .status_register = &mx25lx65e_sr, - .unlock = spi_disable_blockprotect_bp3_srwd, .write = spi_chip_write_256, .read = spi_chip_read, /* Fast read (0x0B), dual I/O supported */ .voltage = {2700, 3600}, + .wp = &mx25l16xd_wp, }, { .vendor = "Macronix", .name = "MX25L1635D", .bustype = BUS_SPI, .manufacture_id = MACRONIX_ID, .model_id = MACRONIX_MX25L1635D, .total_size = 2048, .page_size = 256, /* OTP: 64B total; enter 0xB1, exit 0xC1 */ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP, .tested = TEST_UNTESTED, @@ -7807,30 +7800,30 @@ const struct flashchip flashchips[] = { .block_erase = spi_block_erase_20, }, { .eraseblocks = { {64 * 1024, 64} }, .block_erase = spi_block_erase_d8, }, { .eraseblocks = { {4 * 1024 * 1024, 1} }, .block_erase = spi_block_erase_60, }, { .eraseblocks = { {4 * 1024 * 1024, 1} }, .block_erase = spi_block_erase_c7, }, }, .status_register = &mx25lx5d_sr, - .unlock = spi_disable_blockprotect_bp3_srwd, .write = spi_chip_write_256, .read = spi_chip_read, /* Fast read (0x0B) and dual I/O supported */ .voltage = {2700, 3600}, + .wp = &mx25lx5d_wp, }, { .vendor = "Macronix", .name = "MX25L3206E/MX25L3208E", .bustype = BUS_SPI, .manufacture_id = MACRONIX_ID, .model_id = MACRONIX_MX25L3205, .total_size = 4096, .page_size = 256, /* OTP: 64B total; enter 0xB1, exit 0xC1 */ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP, .tested = TEST_OK_PREW, @@ -7993,30 +7986,30 @@ const struct flashchip flashchips[] = { .block_erase = spi_block_erase_20, }, { .eraseblocks = { {64 * 1024, 128} }, .block_erase = spi_block_erase_d8, }, { .eraseblocks = { {8 * 1024 * 1024, 1} }, .block_erase = spi_block_erase_60, }, { .eraseblocks = { {8 * 1024 * 1024, 1} }, .block_erase = spi_block_erase_c7, } }, .status_register = &mx25lx5d_sr, - .unlock = spi_disable_blockprotect_bp3_srwd, .write = spi_chip_write_256, .read = spi_chip_read, /* Fast read (0x0B), dual I/O read (0xBB) supported */ .voltage = {2700, 3600}, + .wp = &mx25l6405d_wp, }, { .vendor = "Macronix", .name = "MX25L6406E/MX25L6408E", .bustype = BUS_SPI, .manufacture_id = MACRONIX_ID, .model_id = MACRONIX_MX25L6405, .total_size = 8192, .page_size = 256, /* MX25L6406E supports SFDP */ /* OTP: 06E 64B total; enter 0xB1, exit 0xC1 */ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP, @@ -8033,30 +8026,30 @@ const struct flashchip flashchips[] = { .block_erase = spi_block_erase_52, }, { .eraseblocks = { {64 * 1024, 128} }, .block_erase = spi_block_erase_d8, }, { .eraseblocks = { {8 * 1024 * 1024, 1} }, .block_erase = spi_block_erase_60, }, { .eraseblocks = { {8 * 1024 * 1024, 1} }, .block_erase = spi_block_erase_c7, } }, .status_register = &mx25l64xe_sr, - .unlock = spi_disable_blockprotect_bp3_srwd, .write = spi_chip_write_256, .read = spi_chip_read, /* Fast read (0x0B), dual I/O read supported */ .voltage = {2700, 3600}, + .wp = &mx25l6405d_wp, }, { .vendor = "Macronix", .name = "MX25L6436E/MX25L6445E/MX25L6465E/MX25L6473E", .bustype = BUS_SPI, .manufacture_id = MACRONIX_ID, .model_id = MACRONIX_MX25L6405, .total_size = 8192, .page_size = 256, /* supports SFDP */ /* OTP: 512B total; enter 0xB1, exit 0xC1 */ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP, @@ -8078,30 +8071,30 @@ 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, } }, /* FIXME: MX25L6473E has an additional configuration register (which behaves like * a 2nd status register). * FIXME: Datasheet for MX25L6473E indicates bit 7 is RESV (instead * of SRWD), but similar chips have SRWD. */ .status_register = &mx25lx65e_sr, - .unlock = spi_disable_blockprotect_bp3_srwd, .write = spi_chip_write_256, .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */ .voltage = {2700, 3600}, + .wp = &mx25lx65e_wp, }, { .vendor = "Macronix", .name = "MX25L12805D", .bustype = BUS_SPI, .manufacture_id = MACRONIX_ID, .model_id = MACRONIX_MX25L12805D, .total_size = 16384, .page_size = 256, /* OTP: 64B total; enter 0xB1, exit 0xC1 */ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP, .tested = TEST_OK_PREW, diff --git a/writeprotect.c b/writeprotect.c index e256ae4..3ea6add 100644 --- a/writeprotect.c +++ b/writeprotect.c @@ -374,13 +374,32 @@ int disable_generic(struct flashctx *flash) { if (result) { msg_cerr("%s failed\n", __func__); return result; } status_sr1 = flash->chip->status_register->read(flash, SR1); if (status_sr1 & bitmask) { msg_cdbg("Could not write configuration to status register to disable block protection\n"); msg_cerr("%s failed\n", __func__); return 1; } msg_cdbg("Disabled any block protection in effect\n"); return result; } + +/* === Chip specific range_table generators === */ +/* === AMIC === */ +/* A25L032 */ +struct range *a25l032_range_table(struct flashctx *flash) { + struct range *table = sec_block_range_pattern(flash); + /* CMP=0 */ + table[0x16].start = 0x3f0000; + table[0x16].len = 64; + table[0x1e].start = 0x000000; + table[0x1e].len = 64; + /* CMP=1 */ + table[1 << 5 | 0x16].start = 0x000000; + table[1 << 5 | 0x16].len = 4032; + table[1 << 5 | 0x1e].start = 0x010000; + table[1 << 5 | 0x1e].len = 4032; + + return table; +} diff --git a/writeprotect.h b/writeprotect.h index 41d9cf0..41dbc7c 100644 --- a/writeprotect.h +++ b/writeprotect.h @@ -20,14 +20,21 @@ #ifndef __WRITEPROTECT_H__ #define __WRITEPROTECT_H__ 1 #include "flash.h" #define LEN_RANGES 64 struct range { uint32_t start; uint32_t len; /* in kB */ }; +extern struct wp a25l032_32a_wp; +extern struct wp gd25_a25l080_q16_32a_wp; +extern struct wp mx25l16xd_wp; +extern struct wp mx25l6405d_wp; +extern struct wp mx25lx5d_wp; +extern struct wp mx25lx65e_wp; + #endif /* !__WRITEPROTECT_H__ */ diff --git a/writeprotect_layouts.c b/writeprotect_layouts.c new file mode 100644 index 0000000..f5ac2ec --- /dev/null +++ b/writeprotect_layouts.c @@ -0,0 +1,166 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2016 Hatim Kanchwala + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "chipdrivers.h" +#include "flash.h" +#include "writeprotect.h" + +/* + * struct wp { + * struct range *ranges; + * struct range *(*range_table) (struct flashctx *flash); + * uint32_t (*bp_bitmask) (struct flashctx *flash); + * 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 */ +struct wp gd25_a25l080_q16_32a_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, +}; + +/* MX25L1605D, MX25L1608D, MX25L1673E */ +struct wp mx25l16xd_wp = { + .ranges = (struct range[]){ + /* BP3 effectively acts as CMP bit, + * BP[0..2] function normally. */ + { 0x000000, 0 }, + { 0x1f0000, 64 }, + { 0x1e0000, 128 }, + { 0x1c0000, 256 }, + { 0x180000, 512 }, + { 0x100000, 1024 }, + { 0x000000, 2048 }, + { 0x000000, 2048 }, + + { 0x000000, 2048 }, + { 0x000000, 2048 }, + { 0x000000, 1024 }, + { 0x000000, 1536 }, + { 0x000000, 1792 }, + { 0x000000, 1920 }, + { 0x000000, 1984 }, + { 0x000000, 2048 }, + }, + .bp_bitmask = &bp_bitmask_generic, + .print_table = &print_table_generic, + .set_range = &set_range_generic, + .disable = &disable_generic, +}; + +/* MX25L6406E, MX25L6408E, MX25L6405D */ +struct wp mx25l6405d_wp = { + /* BP3 effectively acts as CMP bit, + * BP[0..2] function normally. */ + .ranges = (struct range[]){ + { 0x000000, 0 }, + { 0x7e0000, 128 }, + { 0x7c0000, 256 }, + { 0x780000, 512 }, + { 0x700000, 1024 }, + { 0x600000, 2048 }, + { 0x400000, 4096 }, + { 0x000000, 8192 }, + + { 0x000000, 8192 }, + { 0x000000, 4096 }, + { 0x000000, 6144 }, + { 0x000000, 7168 }, + { 0x000000, 7680 }, + { 0x000000, 7936 }, + { 0x000000, 8064 }, + { 0x000000, 8192 }, + }, + .bp_bitmask = &bp_bitmask_generic, + .print_table = &print_table_generic, + .set_range = &set_range_generic, + .disable = &disable_generic, +}; + +/* MX25L3205D, MX25L3208D */ +struct wp mx25lx5d_wp = { + .ranges = (struct range[]){ + /* BP3 effectively acts as CMP bit, + * BP[0..2] function normally. */ + { 0x000000, 0 }, + { 0x3f0000, 64 }, + { 0x3e0000, 128 }, + { 0x3c0000, 256 }, + { 0x380000, 512 }, + { 0x300000, 1024 }, + { 0x200000, 2048 }, + { 0x000000, 4096 }, + + { 0x000000, 4096 }, + { 0x000000, 2048 }, + { 0x000000, 3072 }, + { 0x000000, 3584 }, + { 0x000000, 3840 }, + { 0x000000, 3968 }, + { 0x000000, 4032 }, + { 0x000000, 4096 }, + }, + .bp_bitmask = &bp_bitmask_generic, + .print_table = &print_table_generic, + .set_range = &set_range_generic, + .disable = &disable_generic, +}; + +/* MX25L6436E, MX25L6445E, MX25L6465E, MX25L6473E */ +struct wp mx25lx65e_wp = { + .ranges = (struct range[]){ + { 0x000000, 0 }, + { 0x7e0000, 128 }, + { 0x7c0000, 256 }, + { 0x780000, 512 }, + { 0x700000, 1024 }, + { 0x600000, 2048 }, + { 0x400000, 4096 }, + { 0x000000, 8192 }, + + { 0x000000, 8192 }, + { 0x000000, 8192 }, + { 0x000000, 8192 }, + { 0x000000, 8192 }, + { 0x000000, 8192 }, + { 0x000000, 8192 }, + { 0x000000, 8192 }, + { 0x000000, 8192 }, + }, + .bp_bitmask = &bp_bitmask_generic, + .print_table = &print_table_generic, + .set_range = &set_range_generic, + .disable = &disable_generic, +};