From e00790865726b6f1a6492af0833e3cbf9c215496 Mon Sep 17 00:00:00 2001 From: Nikolai Artemiev Date: Wed, 20 Oct 2021 23:34:15 +1100 Subject: flash.h,flashchips.c: add writeprotect bit layout map to chips This patch adds a register bit map `struct reg_bit_info`, with fields for storing the register, bit index, and writability of each bit that affects the chip's write protection. This allows writeprotect code to be independent of the register layout of any specific chip. The new fields have been filled out for example chips. The representation is centered around describing how bits can be accessed and modified, rather than the layout of registers. This is generally easier to work with in code that needs to access specific bits and typically requires specifying the locations of fewer bits overall. BUG=b:195381327,b:153800563 BRANCH=none TEST=flashrom --wp-{enable,disable,range,list,status} at end of patch series Change-Id: Id08d77e6d4ca5109c0d698271146d026dbc21284 Signed-off-by: Nikolai Artemiev Reviewed-on: https://review.coreboot.org/c/flashrom/+/58477 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber Reviewed-by: Anastasia Klimchuk --- flash.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ flashchips.c | 25 +++++++++++++++++++++++++ writeprotect.h | 2 ++ 3 files changed, 77 insertions(+) diff --git a/flash.h b/flash.h index cd40fa3f..b935e9bc 100644 --- a/flash.h +++ b/flash.h @@ -34,6 +34,7 @@ #include "libflashrom.h" #include "layout.h" +#include "writeprotect.h" #define KiB (1024) #define MiB (1024 * KiB) @@ -176,6 +177,24 @@ enum flash_reg { MAX_REGISTERS }; +struct reg_bit_info { + /* Register containing the bit */ + enum flash_reg reg; + + /* Bit index within register */ + uint8_t bit_index; + + /* + * Writability of the bit. RW does not guarantee the bit will be + * writable, for example if status register protection is enabled. + */ + enum { + RO, /* Read only */ + RW, /* Readable and writable */ + OTP /* One-time programmable */ + } writability; +}; + struct flashchip { const char *vendor; const char *name; @@ -255,6 +274,37 @@ struct flashchip { /* SPI specific options (TODO: Make it a union in case other bustypes get specific options.) */ uint8_t wrea_override; /**< override opcode for write extended address register */ + struct reg_bit_map { + /* Status register protection bit (SRP) */ + struct reg_bit_info srp; + + /* Status register lock bit (SRP) */ + struct reg_bit_info srl; + + /* + * Note: some datasheets refer to configuration bits that + * function like TB/SEC/CMP bits as BP bits (e.g. BP3 for a bit + * that functions like TB). + * + * As a convention, any config bit that functions like a + * TB/SEC/CMP bit should be assigned to the respective + * tb/sec/cmp field in this structure, even if the datasheet + * uses a different name. + */ + + /* Block protection bits (BP) */ + /* Extra element for terminator */ + struct reg_bit_info bp[MAX_BP_BITS + 1]; + + /* Top/bottom protection bit (TB) */ + struct reg_bit_info tb; + + /* Sector/block protection bit (SEC) */ + struct reg_bit_info sec; + + /* Complement bit (CMP) */ + struct reg_bit_info cmp; + } reg_bits; }; typedef int (*chip_restore_fn_cb_t)(struct flashctx *flash, uint8_t status); diff --git a/flashchips.c b/flashchips.c index 9e10b5d2..e12c8fce 100644 --- a/flashchips.c +++ b/flashchips.c @@ -6345,6 +6345,15 @@ const struct flashchip flashchips[] = { .write = spi_chip_write_256, .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */ .voltage = {1695, 1950}, + .reg_bits = + { + .srp = {STATUS1, 7, RW}, + .srl = {STATUS2, 0, RW}, + .bp = {{STATUS1, 2, RW}, {STATUS1, 3, RW}, {STATUS1, 4, RW}}, + .tb = {STATUS1, 5, RW}, /* Called BP3 in datasheet, acts like TB */ + .sec = {STATUS1, 6, RW}, /* Called BP4 in datasheet, acts like SEC */ + .cmp = {STATUS2, 6, RW}, + }, }, { @@ -6744,6 +6753,13 @@ const struct flashchip flashchips[] = { .write = spi_chip_write_256, .read = spi_chip_read, .voltage = {2700, 3600}, + .reg_bits = + { + .srp = {STATUS1, 7, RW}, + .srl = {STATUS2, 6, RW}, + .bp = {{STATUS1, 2, RW}, {STATUS1, 3, RW}, {STATUS1, 4, RW}, {STATUS1, 5, RW}}, + .tb = {STATUS1, 6, RW}, + }, }, { @@ -6783,6 +6799,15 @@ const struct flashchip flashchips[] = { .write = spi_chip_write_256, .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */ .voltage = {2700, 3600}, + .reg_bits = + { + .srp = {STATUS1, 7, RW}, + .srl = {STATUS2, 0, RW}, + .bp = {{STATUS1, 2, RW}, {STATUS1, 3, RW}, {STATUS1, 4, RW}}, + .tb = {STATUS1, 5, RW}, /* Called BP3 in datasheet, acts like TB */ + .sec = {STATUS1, 6, RW}, /* Called BP4 in datasheet, acts like SEC */ + .cmp = {STATUS2, 6, RW}, + }, }, { diff --git a/writeprotect.h b/writeprotect.h index 2d99897f..8510226d 100644 --- a/writeprotect.h +++ b/writeprotect.h @@ -18,4 +18,6 @@ #ifndef __WRITEPROTECT_H__ #define __WRITEPROTECT_H__ 1 +#define MAX_BP_BITS 4 + #endif /* !__WRITEPROTECT_H__ */ -- cgit v1.2.3