Nikolai Artemiev has uploaded this change for review.
[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 */
To view, visit change 58479. To unsubscribe, or for help writing mail filters, visit settings.