From patchwork Tue Jul 5 20:28:04 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hatim Kanchwala X-Patchwork-Id: 644997 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 3rkb8r1FRNz9s5g for ; Wed, 6 Jul 2016 06:29:48 +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=EB+zksKb; 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 1bKWxb-0007hP-R6; Tue, 05 Jul 2016 22:28:47 +0200 Received: from mail-pa0-f67.google.com ([209.85.220.67]) by mail.coreboot.org with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.86_2) (envelope-from ) id 1bKWxI-0007dy-Vm for flashrom@flashrom.org; Tue, 05 Jul 2016 22:28:44 +0200 Received: by mail-pa0-f67.google.com with SMTP id ts6so19227028pac.0 for ; Tue, 05 Jul 2016 13:28:28 -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=EVhQTVC9KICVYRAIdhZk04UKWhbGKsmr/1Mv+hL/FQk=; b=EB+zksKb0fT+BNBOD4/5kbzwtegSmYigcdcB4IDSsnkb8Jhmb4i5hQYZcr4RN7jLlS PpAYm19u6YS7IHvlQfzdG7dOb/jeVFgcfc+ln4jOOrOJ2jJHaGXUf1eyEGtMm3pgDz4N 8tnbw4tc0CBtJhdG22TW8UqySHSfiEzdXBfCaSZ9jX5d+DGlG37PB0sq7XWhfg2sQntM +wQPZ+8KsWnDX/HNCM0LZiQe2f0Oj9opbdQuq5V/C5sT9lyJhEw81RgU0QEi0oiKDWZ9 dD6UGrLhXLXZJJE4TaqjpE/G8ecQ6tx2TckrfjugDBkgZ55RDsYyI+dHobPkDHZIJ8QJ 7oZA== 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=EVhQTVC9KICVYRAIdhZk04UKWhbGKsmr/1Mv+hL/FQk=; b=JU94dFGdiSD+gVfxZca9wIGP7AlXLfh02Mz3qzNn9MtL3dSeAU1+6j/T1aflYDGiH8 Y1MXzkqYpSuBrknhHD37wdRGvs5cgk/fWcLW4VWtHswcb5QmwV6gP+LP11V5AfAGAL5G UxV589kd3UQ1vXADeoqhh97NwA1XZhB4gCIWse953Zc9XWAlEP4lfqUGOBJrVB6z7kIk 1HOEzzWENm5zsM4wqyezkwRazbsHtpc0NL6or1BS1a5Jj4UjQYHNqZNNHPXp14PEbyA2 eWBPYOgpt4VZvGSuLQLrwKJGh5kCtzNQn0qQoPyq1j4Cy+dsGxHBNtAjSs7svT7h1gGN OxhQ== X-Gm-Message-State: ALyK8tKW/PMYYXqFdTOXp+fcAqhKw9qb9meGIrcgcBq1algG62KJb8s3ABVGPxgl/gPOeA== X-Received: by 10.66.156.9 with SMTP id wa9mr35024863pab.64.1467750506063; Tue, 05 Jul 2016 13:28:26 -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.23 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 05 Jul 2016 13:28:25 -0700 (PDT) From: Hatim Kanchwala To: flashrom@flashrom.org Date: Wed, 6 Jul 2016 01:58:04 +0530 Message-Id: <1467750485-29158-6-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: -0.6 (/) Subject: [flashrom] [PATCH 5/6] Integrate new infrastructure with existing codebase 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 - New infrastructure is used to read status register (for chips that have support for struct status_register) throughout spi25.c. - New infrastructure is used to prettyprint status register and write protection mode of status register (for chips that have support for struct status_register) in flashrom.c. - New disable from access protection infrastructure is used (for chips that have support for struct wp) in flashrom.c Signed-off-by: Hatim Kanchwala --- flashrom.c | 17 +++++-- spi25.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 145 insertions(+), 36 deletions(-) diff --git a/flashrom.c b/flashrom.c index 25e53f2..3e19cd6 100644 --- a/flashrom.c +++ b/flashrom.c @@ -26,26 +26,27 @@ #ifndef __LIBPAYLOAD__ #include #include #endif #include #include #include #include #include #include #if HAVE_UTSNAME == 1 #include #endif +#include "chipdrivers.h" #include "flash.h" #include "flashchips.h" #include "programmer.h" #include "hwaccess.h" const char flashrom_version[] = FLASHROM_VERSION; const char *chip_to_probe = NULL; static enum programmer programmer = PROGRAMMER_INVALID; static const char *programmer_param = NULL; /* * Programmers supporting multiple buses can have differing size limits on @@ -1250,29 +1251,37 @@ notfound: msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) ", force ? "Assuming" : "Found", flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp); free(tmp); #if CONFIG_INTERNAL == 1 if (programmer_table[programmer].map_flash_region == physmap) msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n", PRIxPTR_WIDTH, flash->physical_memory); else #endif msg_cinfo("on %s.\n", programmer_table[programmer].name); /* Flash registers may more likely not be mapped if the chip was forced. * Lock info may be stored in registers, so avoid lock info printing. */ - if (!force) - if (flash->chip->printlock) + if (!force) { + if (flash->chip->status_register) { + for (enum status_register_num SRn = SR1; SRn <= top_status_register(flash); SRn++) + flash->chip->status_register->print(flash, SRn); + flash->chip->status_register->print_wp_mode(flash); + if (flash->chip->wp) + print_range_generic(flash); + } else if (flash->chip->printlock) { flash->chip->printlock(flash); + } + } /* Get out of the way for later runs. */ unmap_flash(flash); /* Return position of matching chip. */ return chip - flashchips; } int read_buf_from_file(unsigned char *buf, unsigned long size, const char *filename) { #ifdef __LIBPAYLOAD__ msg_gerr("Error: No file I/O support in libpayload\n"); @@ -1988,27 +1997,29 @@ int doit(struct flashctx *flash, int force, const char *filename, int read_it, if (chip_safety_check(flash, force, read_it, write_it, erase_it, verify_it)) { msg_cerr("Aborting.\n"); return 1; } if (normalize_romentries(flash)) { msg_cerr("Requested regions can not be handled. Aborting.\n"); return 1; } /* Given the existence of read locks, we want to unlock for read, * erase and write. */ - if (flash->chip->unlock) + if (flash->chip->wp) + flash->chip->wp->disable(flash); + else if (flash->chip->unlock) flash->chip->unlock(flash); if (read_it) { return read_flash_to_file(flash, filename); } oldcontents = malloc(size); if (!oldcontents) { msg_gerr("Out of memory!\n"); exit(1); } /* Assume worst case: All bits are 0. */ memset(oldcontents, 0x00, size); diff --git a/spi25.c b/spi25.c index af4b6db..51db4c8 100644 --- a/spi25.c +++ b/spi25.c @@ -341,29 +341,35 @@ int spi_chip_erase_60(struct flashctx *flash) .readcnt = 0, .readarr = NULL, }}; result = spi_send_multicommand(flash, cmds); if (result) { msg_cerr("%s failed during command execution\n", __func__); return result; } /* Wait until the Write-In-Progress bit is cleared. * This usually takes 1-85 s, so wait in 1 s steps. */ - /* FIXME: We assume spi_read_status_register will never fail. */ - while (spi_read_status_register(flash) & SPI_SR_WIP) - programmer_delay(1000 * 1000); + /* FIXME: We assume reading status register(s) will never fail. */ + // TODO(hatim): Switch to newer infrastructure completely after integration + if (flash->chip->status_register) { + while (flash->chip->status_register->read(flash, SR1) & SPI_SR_WIP) + programmer_delay(1000 * 1000); + } else { + while (spi_read_status_register(flash) & SPI_SR_WIP) + programmer_delay(1000 * 1000); + } /* FIXME: Check the status register for errors. */ return 0; } int spi_chip_erase_62(struct flashctx *flash) { int result; struct spi_command cmds[] = { { .writecnt = JEDEC_WREN_OUTSIZE, .writearr = (const unsigned char[]){ JEDEC_WREN }, .readcnt = 0, .readarr = NULL, @@ -378,29 +384,35 @@ int spi_chip_erase_62(struct flashctx *flash) .readcnt = 0, .readarr = NULL, }}; result = spi_send_multicommand(flash, cmds); if (result) { msg_cerr("%s failed during command execution\n", __func__); return result; } /* Wait until the Write-In-Progress bit is cleared. * This usually takes 2-5 s, so wait in 100 ms steps. */ - /* FIXME: We assume spi_read_status_register will never fail. */ - while (spi_read_status_register(flash) & SPI_SR_WIP) - programmer_delay(100 * 1000); + /* FIXME: We assume reading status register(s) will never fail. */ + // TODO(hatim): Switch to newer infrastructure completely after integration + if (flash->chip->status_register) { + while (flash->chip->status_register->read(flash, SR1) & SPI_SR_WIP) + programmer_delay(100 * 1000); + } else { + while (spi_read_status_register(flash) & SPI_SR_WIP) + programmer_delay(100 * 1000); + } /* FIXME: Check the status register for errors. */ return 0; } int spi_chip_erase_c7(struct flashctx *flash) { int result; struct spi_command cmds[] = { { .writecnt = JEDEC_WREN_OUTSIZE, .writearr = (const unsigned char[]){ JEDEC_WREN }, .readcnt = 0, .readarr = NULL, @@ -414,29 +426,35 @@ int spi_chip_erase_c7(struct flashctx *flash) .writearr = NULL, .readcnt = 0, .readarr = NULL, }}; result = spi_send_multicommand(flash, cmds); if (result) { msg_cerr("%s failed during command execution\n", __func__); return result; } /* Wait until the Write-In-Progress bit is cleared. * This usually takes 1-85 s, so wait in 1 s steps. */ - /* FIXME: We assume spi_read_status_register will never fail. */ - while (spi_read_status_register(flash) & SPI_SR_WIP) - programmer_delay(1000 * 1000); + /* FIXME: We assume reading status register(s) will never fail. */ + // TODO(hatim): Switch to newer infrastructure completely after integration + if (flash->chip->status_register) { + while (flash->chip->status_register->read(flash, SR1) & SPI_SR_WIP) + programmer_delay(1000 * 1000); + } else { + while (spi_read_status_register(flash) & SPI_SR_WIP) + programmer_delay(1000 * 1000); + } /* FIXME: Check the status register for errors. */ return 0; } int spi_block_erase_52(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { int result; struct spi_command cmds[] = { { .writecnt = JEDEC_WREN_OUTSIZE, .writearr = (const unsigned char[]){ JEDEC_WREN }, .readcnt = 0, @@ -457,28 +475,35 @@ int spi_block_erase_52(struct flashctx *flash, unsigned int addr, .readcnt = 0, .readarr = NULL, }}; result = spi_send_multicommand(flash, cmds); if (result) { msg_cerr("%s failed during command execution at address 0x%x\n", __func__, addr); return result; } /* Wait until the Write-In-Progress bit is cleared. * This usually takes 100-4000 ms, so wait in 100 ms steps. */ - while (spi_read_status_register(flash) & SPI_SR_WIP) - programmer_delay(100 * 1000); + /* FIXME: We assume reading status register(s) will never fail. */ + // TODO(hatim): Switch to newer infrastructure completely after integration + if (flash->chip->status_register) { + while (flash->chip->status_register->read(flash, SR1) & SPI_SR_WIP) + programmer_delay(100 * 1000); + } else { + while (spi_read_status_register(flash) & SPI_SR_WIP) + programmer_delay(100 * 1000); + } /* FIXME: Check the status register for errors. */ return 0; } /* Block size is usually * 32M (one die) for Micron */ int spi_block_erase_c4(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { int result; struct spi_command cmds[] = { { .writecnt = JEDEC_WREN_OUTSIZE, @@ -500,28 +525,35 @@ int spi_block_erase_c4(struct flashctx *flash, unsigned int addr, unsigned int b .writearr = NULL, .readcnt = 0, .readarr = NULL, }}; result = spi_send_multicommand(flash, cmds); if (result) { msg_cerr("%s failed during command execution at address 0x%x\n", __func__, addr); return result; } /* Wait until the Write-In-Progress bit is cleared. * This usually takes 240-480 s, so wait in 500 ms steps. */ - while (spi_read_status_register(flash) & SPI_SR_WIP) - programmer_delay(500 * 1000 * 1000); + /* FIXME: We assume reading status register(s) will never fail. */ + // TODO(hatim): Switch to newer infrastructure completely after integration + if (flash->chip->status_register) { + while (flash->chip->status_register->read(flash, SR1) & SPI_SR_WIP) + programmer_delay(500 * 1000); + } else { + while (spi_read_status_register(flash) & SPI_SR_WIP) + programmer_delay(500 * 1000); + } /* FIXME: Check the status register for errors. */ return 0; } /* Block size is usually * 64k for Macronix * 32k for SST * 4-32k non-uniform for EON */ int spi_block_erase_d8(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { int result; @@ -547,28 +579,35 @@ int spi_block_erase_d8(struct flashctx *flash, unsigned int addr, .readcnt = 0, .readarr = NULL, }}; result = spi_send_multicommand(flash, cmds); if (result) { msg_cerr("%s failed during command execution at address 0x%x\n", __func__, addr); return result; } /* Wait until the Write-In-Progress bit is cleared. * This usually takes 100-4000 ms, so wait in 100 ms steps. */ - while (spi_read_status_register(flash) & SPI_SR_WIP) - programmer_delay(100 * 1000); + /* FIXME: We assume reading status register(s) will never fail. */ + // TODO(hatim): Switch to newer infrastructure completely after integration + if (flash->chip->status_register) { + while (flash->chip->status_register->read(flash, SR1) & SPI_SR_WIP) + programmer_delay(100 * 1000); + } else { + while (spi_read_status_register(flash) & SPI_SR_WIP) + programmer_delay(100 * 1000); + } /* FIXME: Check the status register for errors. */ return 0; } /* Block size is usually * 4k for PMC */ int spi_block_erase_d7(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { int result; struct spi_command cmds[] = { { @@ -592,28 +631,35 @@ int spi_block_erase_d7(struct flashctx *flash, unsigned int addr, .readcnt = 0, .readarr = NULL, }}; result = spi_send_multicommand(flash, cmds); if (result) { msg_cerr("%s failed during command execution at address 0x%x\n", __func__, addr); return result; } /* Wait until the Write-In-Progress bit is cleared. * This usually takes 100-4000 ms, so wait in 100 ms steps. */ - while (spi_read_status_register(flash) & SPI_SR_WIP) - programmer_delay(100 * 1000); + /* FIXME: We assume reading status register(s) will never fail. */ + // TODO(hatim): Switch to newer infrastructure completely after integration + if (flash->chip->status_register) { + while (flash->chip->status_register->read(flash, SR1) & SPI_SR_WIP) + programmer_delay(100 * 1000); + } else { + while (spi_read_status_register(flash) & SPI_SR_WIP) + programmer_delay(100 * 1000); + } /* FIXME: Check the status register for errors. */ return 0; } /* Page erase (usually 256B blocks) */ int spi_block_erase_db(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { int result; struct spi_command cmds[] = { { .writecnt = JEDEC_WREN_OUTSIZE, .writearr = (const unsigned char[]){ JEDEC_WREN }, .readcnt = 0, @@ -633,28 +679,35 @@ int spi_block_erase_db(struct flashctx *flash, unsigned int addr, unsigned int b .writearr = NULL, .readcnt = 0, .readarr = NULL, } }; result = spi_send_multicommand(flash, cmds); if (result) { msg_cerr("%s failed during command execution at address 0x%x\n", __func__, addr); return result; } /* Wait until the Write-In-Progress bit is cleared. * This takes up to 20 ms usually (on worn out devices up to the 0.5s range), so wait in 1 ms steps. */ - while (spi_read_status_register(flash) & SPI_SR_WIP) - programmer_delay(1 * 1000); + /* FIXME: We assume reading status register(s) will never fail. */ + // TODO(hatim): Switch to newer infrastructure completely after integration + if (flash->chip->status_register) { + while (flash->chip->status_register->read(flash, SR1) & SPI_SR_WIP) + programmer_delay(1 * 1000); + } else { + while (spi_read_status_register(flash) & SPI_SR_WIP) + programmer_delay(1 * 1000); + } /* FIXME: Check the status register for errors. */ return 0; } /* Sector size is usually 4k, though Macronix eliteflash has 64k */ int spi_block_erase_20(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { int result; struct spi_command cmds[] = { { .writecnt = JEDEC_WREN_OUTSIZE, .writearr = (const unsigned char[]){ JEDEC_WREN }, @@ -676,28 +729,35 @@ int spi_block_erase_20(struct flashctx *flash, unsigned int addr, .readcnt = 0, .readarr = NULL, }}; result = spi_send_multicommand(flash, cmds); if (result) { msg_cerr("%s failed during command execution at address 0x%x\n", __func__, addr); return result; } /* Wait until the Write-In-Progress bit is cleared. * This usually takes 15-800 ms, so wait in 10 ms steps. */ - while (spi_read_status_register(flash) & SPI_SR_WIP) - programmer_delay(10 * 1000); + /* FIXME: We assume reading status register(s) will never fail. */ + // TODO(hatim): Switch to newer infrastructure completely after integration + if (flash->chip->status_register) { + while (flash->chip->status_register->read(flash, SR1) & SPI_SR_WIP) + programmer_delay(10 * 1000); + } else { + while (spi_read_status_register(flash) & SPI_SR_WIP) + programmer_delay(10 * 1000); + } /* FIXME: Check the status register for errors. */ return 0; } int spi_block_erase_50(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { int result; struct spi_command cmds[] = { { /* .writecnt = JEDEC_WREN_OUTSIZE, .writearr = (const unsigned char[]){ JEDEC_WREN }, .readcnt = 0, .readarr = NULL, @@ -716,28 +776,35 @@ int spi_block_erase_50(struct flashctx *flash, unsigned int addr, unsigned int b .writearr = NULL, .readcnt = 0, .readarr = NULL, }}; result = spi_send_multicommand(flash, cmds); if (result) { msg_cerr("%s failed during command execution at address 0x%x\n", __func__, addr); return result; } /* Wait until the Write-In-Progress bit is cleared. * This usually takes 10 ms, so wait in 1 ms steps. */ - while (spi_read_status_register(flash) & SPI_SR_WIP) - programmer_delay(1 * 1000); + /* FIXME: We assume reading status register(s) will never fail. */ + // TODO(hatim): Switch to newer infrastructure completely after integration + if (flash->chip->status_register) { + while (flash->chip->status_register->read(flash, SR1) & SPI_SR_WIP) + programmer_delay(1 * 1000); + } else { + while (spi_read_status_register(flash) & SPI_SR_WIP) + programmer_delay(1 * 1000); + } /* FIXME: Check the status register for errors. */ return 0; } int spi_block_erase_81(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { int result; struct spi_command cmds[] = { { /* .writecnt = JEDEC_WREN_OUTSIZE, .writearr = (const unsigned char[]){ JEDEC_WREN }, .readcnt = 0, .readarr = NULL, @@ -756,28 +823,35 @@ int spi_block_erase_81(struct flashctx *flash, unsigned int addr, unsigned int b .writearr = NULL, .readcnt = 0, .readarr = NULL, }}; result = spi_send_multicommand(flash, cmds); if (result) { msg_cerr("%s failed during command execution at address 0x%x\n", __func__, addr); return result; } /* Wait until the Write-In-Progress bit is cleared. * This usually takes 8 ms, so wait in 1 ms steps. */ - while (spi_read_status_register(flash) & SPI_SR_WIP) - programmer_delay(1 * 1000); + /* FIXME: We assume reading status register(s) will never fail. */ + // TODO(hatim): Switch to newer infrastructure completely after integration + if (flash->chip->status_register) { + while (flash->chip->status_register->read(flash, SR1) & SPI_SR_WIP) + programmer_delay(1 * 1000); + } else { + while (spi_read_status_register(flash) & SPI_SR_WIP) + programmer_delay(1 * 1000); + } /* FIXME: Check the status register for errors. */ return 0; } int spi_block_erase_60(struct flashctx *flash, unsigned int addr, unsigned int blocklen) { if ((addr != 0) || (blocklen != flash->chip->total_size * 1024)) { msg_cerr("%s called with incorrect arguments\n", __func__); return -1; } return spi_chip_erase_60(flash); @@ -1004,54 +1078,66 @@ int spi_write_chunked(struct flashctx *flash, const uint8_t *buf, unsigned int s * page as well, the loop condition uses <=. */ for (i = start / page_size; i <= (start + len - 1) / page_size; i++) { /* Byte position of the first byte in the range in this page. */ /* starthere is an offset to the base address of the chip. */ starthere = max(start, i * page_size); /* Length of bytes in the range in this page. */ lenhere = min(start + len, (i + 1) * page_size) - starthere; for (j = 0; j < lenhere; j += chunksize) { towrite = min(chunksize, lenhere - j); rc = spi_nbyte_program(flash, starthere + j, buf + starthere - start + j, towrite); if (rc) break; - while (spi_read_status_register(flash) & SPI_SR_WIP) - programmer_delay(10); + // TODO(hatim): Switch to newer infrastructure completely after integration + if (flash->chip->status_register) { + while (flash->chip->status_register->read(flash, SR1) & SPI_SR_WIP) + programmer_delay(10); + } else { + while (spi_read_status_register(flash) & SPI_SR_WIP) + programmer_delay(10); + } } if (rc) break; } return rc; } /* * Program chip using byte programming. (SLOW!) * This is for chips which can only handle one byte writes * and for chips where memory mapped programming is impossible * (e.g. due to size constraints in IT87* for over 512 kB) */ /* real chunksize is 1, logical chunksize is 1 */ int spi_chip_write_1(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len) { unsigned int i; int result = 0; for (i = start; i < start + len; i++) { result = spi_byte_program(flash, i, buf[i - start]); if (result) return 1; - while (spi_read_status_register(flash) & SPI_SR_WIP) - programmer_delay(10); + // TODO(hatim): Switch to newer infrastructure completely after integration + if (flash->chip->status_register) { + while (flash->chip->status_register->read(flash, SR1) & SPI_SR_WIP) + programmer_delay(10); + } else { + while (spi_read_status_register(flash) & SPI_SR_WIP) + programmer_delay(10); + } } return 0; } int default_spi_write_aai(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len) { uint32_t pos = start; int result; unsigned char cmd[JEDEC_AAI_WORD_PROGRAM_CONT_OUTSIZE] = { JEDEC_AAI_WORD_PROGRAM, }; struct spi_command cmds[] = { @@ -1120,43 +1206,55 @@ int default_spi_write_aai(struct flashctx *flash, const uint8_t *buf, unsigned i if (len % 2) { msg_cerr("%s: total write length not even! Please report a " "bug at flashrom@flashrom.org\n", __func__); /* Do not return an error for now. */ //return SPI_GENERIC_ERROR; } result = spi_send_multicommand(flash, cmds); if (result != 0) { msg_cerr("%s failed during start command execution: %d\n", __func__, result); goto bailout; } - while (spi_read_status_register(flash) & SPI_SR_WIP) - programmer_delay(10); + // TODO(hatim): Switch to newer infrastructure completely after integration + if (flash->chip->status_register) { + while (flash->chip->status_register->read(flash, SR1) & SPI_SR_WIP) + programmer_delay(10); + } else { + while (spi_read_status_register(flash) & SPI_SR_WIP) + programmer_delay(10); + } /* We already wrote 2 bytes in the multicommand step. */ pos += 2; /* Are there at least two more bytes to write? */ while (pos < start + len - 1) { cmd[1] = buf[pos++ - start]; cmd[2] = buf[pos++ - start]; result = spi_send_command(flash, JEDEC_AAI_WORD_PROGRAM_CONT_OUTSIZE, 0, cmd, NULL); if (result != 0) { msg_cerr("%s failed during followup AAI command execution: %d\n", __func__, result); goto bailout; } - while (spi_read_status_register(flash) & SPI_SR_WIP) - programmer_delay(10); + // TODO(hatim): Switch to newer infrastructure completely after integration + if (flash->chip->status_register) { + while (flash->chip->status_register->read(flash, SR1) & SPI_SR_WIP) + programmer_delay(10); + } else { + while (spi_read_status_register(flash) & SPI_SR_WIP) + programmer_delay(10); + } } /* Use WRDI to exit AAI mode. This needs to be done before issuing any other non-AAI command. */ result = spi_write_disable(flash); if (result != 0) { msg_cerr("%s failed to disable AAI mode.\n", __func__); return SPI_GENERIC_ERROR; } /* Write remaining byte (if any). */ if (pos < start + len) { if (spi_chip_write_1(flash, buf + pos - start, pos, pos % 2)) return SPI_GENERIC_ERROR;