Nikolai Artemiev has uploaded this change for review. ( https://review.coreboot.org/c/flashrom/+/58479 )
Change subject: [RFC] writeprotect: add functions to write and print chip wp state ......................................................................
[RFC] writeprotect: add functions to write and print chip wp state
BUG=b:195381327,b:153800563 TEST=writeprotect commands BRANCH=none
Change-Id: I3ad25708c3321b8fb0216c3eaf6ffc07616537ad Signed-off-by: Nikolai Artemiev nartemiev@google.com --- M writeprotect.c 1 file changed, 84 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/79/58479/1
diff --git a/writeprotect.c b/writeprotect.c index 24239db..fa347f8 100644 --- a/writeprotect.c +++ b/writeprotect.c @@ -24,6 +24,21 @@ #include "writeprotect.h"
+static void print_wp_chip_state(struct wp_chip_state *wpst) +{ + for (int i = wpst->srp_bit_count - 1; i >= 0; i--) { + msg_ginfo("SRP%d=%u ", i, wpst->srp[i]); + } + + if (wpst->cmp_bit_present) msg_ginfo("CMP=%u ", wpst->cmp); + if (wpst->sec_bit_present) msg_ginfo("SEC=%u ", wpst->sec); + if (wpst->tb_bit_present) msg_ginfo("TB=%u ", wpst->tb); + + for (int i = wpst->bp_bit_count - 1; i >= 0; i--) { + msg_ginfo("BP%d=%u ", i, wpst->bp[i]); + } +} + static int read_reg_bit( const struct flashctx *flash, const struct reg_bit_info bit, @@ -71,6 +86,75 @@ } void *suppress_unused_warning_for_read_wp_chip_state = read_wp_chip_state;
+static void set_reg_bit( + uint8_t *reg_values, uint8_t *write_masks, + struct reg_bit_info bit, uint8_t value) +{ + if (bit.reg != INVALID_REG) { + reg_values[bit.reg] |= value << bit.bit_index; + write_masks[bit.reg] |= 1 << bit.bit_index; + } +} + +static int write_wp_chip_state(struct flashctx *flash, struct wp_chip_state *wpst) +{ + const struct reg_bit_map *bits = &flash->chip->reg_bits; + + /* Convert wp_chip_state to register values / write masks */ + uint8_t reg_values[MAX_REGISTERS] = {0}; + uint8_t write_masks[MAX_REGISTERS] = {0}; + + for (size_t i = 0; i < wpst->srp_bit_count; i++) { + set_reg_bit(reg_values, write_masks, bits->srp[i], wpst->srp[i]); + } + for (size_t i = 0; i < wpst->bp_bit_count; i++) { + set_reg_bit(reg_values, write_masks, bits->bp[i], wpst->bp[i]); + } + set_reg_bit(reg_values, write_masks, bits->tb, wpst->tb); + set_reg_bit(reg_values, write_masks, bits->sec, wpst->sec); + set_reg_bit(reg_values, write_masks, bits->cmp, wpst->cmp); + + /* Write each register */ + for (enum flash_reg reg = INVALID_REG; reg < MAX_REGISTERS; reg++) { + if (!write_masks[reg]) + continue; + + uint8_t value = 0; + int ret = spi_read_register(flash, reg, &value); + + value = (value & ~write_masks[reg]) | + (reg_values[reg] & write_masks[reg]); + + if (!ret) + spi_write_register(flash, reg, value); + + if (ret) { + msg_gerr("Writing wp configuration to chip failed!\n"); + return 1; + } + } + + /* Verify */ + struct wp_chip_state wpst_readback; + if (read_wp_chip_state(flash, &wpst_readback)) { + return 1; + } + + if (memcmp(wpst, &wpst_readback, sizeof(wpst_readback))) { + msg_gerr("Writing wp configuration to chip failed during " + "verification:\nExpected: "); + print_wp_chip_state(wpst); + msg_gerr("\nActual: "); + print_wp_chip_state(&wpst_readback); + msg_gerr("\n"); + + return 1; + } + + return 0; +} +void *suppress_unused_warning_for_write_wp_chip_state = write_wp_chip_state; + bool wp_supported(struct flashctx *flash) { /* TODO */