diff options
author | Nikolai Artemiev <nartemiev@google.com> | 2022-12-05 12:49:14 +1100 |
---|---|---|
committer | Edward O'Callaghan <quasisec@chromium.org> | 2023-01-19 12:41:58 +0000 |
commit | 673cb357d411e6d95be7cbf31513b46615355e12 (patch) | |
tree | 20deb2eb0aef676695d49ca8fd52dff1a80a9ebc | |
parent | 7cab790a46f8459789e258a106e743275e306a2d (diff) | |
download | flashrom-673cb357d411e6d95be7cbf31513b46615355e12.tar.gz flashrom-673cb357d411e6d95be7cbf31513b46615355e12.tar.bz2 flashrom-673cb357d411e6d95be7cbf31513b46615355e12.zip |
tree/: Change chip restore data type from uint8_t to void ptr
Chip restore callbacks currently are used by
- spi25_statusreg.c unlock functions to restore status register 1.
- s25f.c to restore config register 3.
Both of these cases only need to save a single uint8_t value to restore
the original chip state, however storing a void pointer will allow more
flexible chip restore behaviour. In particular, it will allow
flashrom_wp_cfg objects to be saved and restored, enabling
writeprotect-based unlocking.
BUG=b:237485865,b:247421511
BRANCH=none
TEST=Tested on grunt DUT (prog: sb600spi, flash: W25Q128.W):
`flashrom --wp-range 0x0,0x1000000 \
flashrom --wp-status # Result: range=0x0,0x1000000 \
flashrom -w random.bin # Result: success \
flashrom -v random.bin # Result: success \
flashrom --wp-status # Result: range=0x0,0x1000000`
Change-Id: I311b468a4b0349f4da9584c12b36af6ec2394527
Signed-off-by: Nikolai Artemiev <nartemiev@google.com>
Reviewed-on: https://review.coreboot.org/c/flashrom/+/70349
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Edward O'Callaghan <quasisec@chromium.org>
Reviewed-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
Reviewed-by: Anastasia Klimchuk <aklm@chromium.org>
-rw-r--r-- | flashrom.c | 6 | ||||
-rw-r--r-- | include/flash.h | 6 | ||||
-rw-r--r-- | s25f.c | 15 | ||||
-rw-r--r-- | spi25_statusreg.c | 15 |
4 files changed, 32 insertions, 10 deletions
@@ -94,7 +94,7 @@ int register_shutdown(int (*function) (void *data), void *data) } int register_chip_restore(chip_restore_fn_cb_t func, - struct flashctx *flash, uint8_t status) + struct flashctx *flash, void *data) { if (flash->chip_restore_fn_count >= MAX_CHIP_RESTORE_FUNCTIONS) { msg_perr("Tried to register more than %i chip restore" @@ -102,7 +102,7 @@ int register_chip_restore(chip_restore_fn_cb_t func, return 1; } flash->chip_restore_fn[flash->chip_restore_fn_count].func = func; - flash->chip_restore_fn[flash->chip_restore_fn_count].status = status; + flash->chip_restore_fn[flash->chip_restore_fn_count].data = data; flash->chip_restore_fn_count++; return 0; @@ -115,7 +115,7 @@ static int deregister_chip_restore(struct flashctx *flash) while (flash->chip_restore_fn_count > 0) { int i = --flash->chip_restore_fn_count; rc |= flash->chip_restore_fn[i].func( - flash, flash->chip_restore_fn[i].status); + flash, flash->chip_restore_fn[i].data); } return rc; diff --git a/include/flash.h b/include/flash.h index fcefc422..3db38d25 100644 --- a/include/flash.h +++ b/include/flash.h @@ -509,7 +509,7 @@ struct flashchip { enum decode_range_func decode_range; }; -typedef int (*chip_restore_fn_cb_t)(struct flashctx *flash, uint8_t status); +typedef int (*chip_restore_fn_cb_t)(struct flashctx *flash, void *data); struct flashrom_flashctx { struct flashchip *chip; @@ -544,7 +544,7 @@ struct flashrom_flashctx { int chip_restore_fn_count; struct chip_restore_func_data { chip_restore_fn_cb_t func; - uint8_t status; + void *data; } chip_restore_fn[MAX_CHIP_RESTORE_FUNCTIONS]; /* Progress reporting */ flashrom_progress_callback *progress_callback; @@ -618,7 +618,7 @@ int read_buf_from_file(unsigned char *buf, unsigned long size, const char *filen int write_buf_to_file(const unsigned char *buf, unsigned long size, const char *filename); int prepare_flash_access(struct flashctx *, bool read_it, bool write_it, bool erase_it, bool verify_it); void finalize_flash_access(struct flashctx *); -int register_chip_restore(chip_restore_fn_cb_t func, struct flashctx *flash, uint8_t status); +int register_chip_restore(chip_restore_fn_cb_t func, struct flashctx *flash, void *data); int check_block_eraser(const struct flashctx *flash, int k, int log); unsigned int count_usable_erasers(const struct flashctx *flash); int need_erase(const uint8_t *have, const uint8_t *want, unsigned int len, enum write_granularity gran, const uint8_t erased_value); @@ -21,6 +21,7 @@ * TODO: Implement fancy hybrid sector architecture helpers. */ +#include <stdlib.h> #include <string.h> #include "chipdrivers.h" @@ -230,10 +231,13 @@ static int s25fs_write_cr(const struct flashctx *flash, return s25f_poll_status(flash); } -static int s25fs_restore_cr3nv(struct flashctx *flash, uint8_t cfg) +static int s25fs_restore_cr3nv(struct flashctx *flash, void *data) { int ret = 0; + uint8_t cfg = *(uint8_t *)data; + free(data); + msg_cdbg("Restoring CR3NV value to 0x%02x\n", cfg); ret |= s25fs_write_cr(flash, CR3NV_ADDR, cfg); ret |= s25fs_software_reset(flash); @@ -285,8 +289,15 @@ int s25fs_block_erase_d8(struct flashctx *flash, unsigned int addr, unsigned int msg_cdbg("\n%s: CR3NV updated (0x%02x -> 0x%02x)\n", __func__, cfg, s25fs_read_cr(flash, CR3NV_ADDR)); + /* Restore CR3V when flashrom exits */ - register_chip_restore(s25fs_restore_cr3nv, flash, cfg); + uint8_t *data = calloc(sizeof(uint8_t), 1); + if (!data) { + msg_cerr("Out of memory!\n"); + return 1; + } + *data = cfg; + register_chip_restore(s25fs_restore_cr3nv, flash, data); } cr3nv_checked = 1; diff --git a/spi25_statusreg.c b/spi25_statusreg.c index 726ca8cc..ec2c101c 100644 --- a/spi25_statusreg.c +++ b/spi25_statusreg.c @@ -17,6 +17,8 @@ * GNU General Public License for more details. */ +#include <stdlib.h> + #include "flash.h" #include "chipdrivers.h" #include "programmer.h" @@ -263,8 +265,11 @@ int spi_read_register(const struct flashctx *flash, enum flash_reg reg, uint8_t return 0; } -static int spi_restore_status(struct flashctx *flash, uint8_t status) +static int spi_restore_status(struct flashctx *flash, void *data) { + uint8_t status = *(uint8_t *)data; + free(data); + msg_cdbg("restoring chip status (0x%02x)\n", status); return spi_write_register(flash, STATUS1, status); } @@ -304,7 +309,13 @@ static int spi_disable_blockprotect_generic(struct flashctx *flash, uint8_t bp_m } /* Restore status register content upon exit in finalize_flash_access(). */ - register_chip_restore(spi_restore_status, flash, status); + uint8_t *data = calloc(sizeof(uint8_t), 1); + if (!data) { + msg_cerr("Out of memory!\n"); + return 1; + } + *data = status; + register_chip_restore(spi_restore_status, flash, data); msg_cdbg("Some block protection in effect, disabling... "); if ((status & lock_mask) != 0) { |