Edward O'Callaghan has uploaded this change for review. ( https://review.coreboot.org/c/flashrom/+/64540 )
Change subject: ichspi.c: Implement read_write_status for wp ......................................................................
ichspi.c: Implement read_write_status for wp
The ichspi hwseq path has a opaque master specialisation that allows for reading and writing STATUS1 registers. Hook the callbacks with a implementation to allow for this so that writeprotect maybe supported though this path.
Change-Id: I7ecbe8491ecea3697922c91af26ca62276e86317 Signed-off-by: Edward O'Callaghan quasisec@google.com --- M ichspi.c 1 file changed, 73 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/40/64540/1
diff --git a/ichspi.c b/ichspi.c index ce7004b..6b4e582 100644 --- a/ichspi.c +++ b/ichspi.c @@ -118,6 +118,16 @@ #define ICH9_REG_HSFC 0x06 /* 16 Bits Hardware Sequencing Flash Control */ #define HSFC_FGO_OFF 0 /* 0: Flash Cycle Go */ #define HSFC_FGO (0x1 << HSFC_FGO_OFF) + +/* FIXME(quasisec): Port to new macros? - Control bits */ +#define HSFSC_FGO_OFF 16 /* 0: Flash Cycle Go */ +#define HSFSC_FGO (0x1 << HSFSC_FGO_OFF) +#define HSFSC_FCYCLE_OFF 17 /* 17-20: FLASH Cycle */ +#define HSFSC_FCYCLE (0xf << HSFSC_FCYCLE_OFF) +#define HSFSC_FDBC_OFF 24 /* 24-29 : Flash Data Byte Count */ +#define HSFSC_FDBC (0x3f << HSFSC_FDBC_OFF) +/*******/ + /* * 2 bits to represents the FCYCLE operation for ICH9 as: * 0: SPI Read @@ -1336,6 +1346,67 @@ return 0; }
+static int ich_hwseq_read_status(const struct flashctx *flash, enum flash_reg reg_, uint8_t *value) +{ + uint32_t hsfc; + int len = 1; + + msg_pdbg("Reading Status register\n"); + + /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */ + REGWRITE32(ICH9_REG_HSFS, REGREAD32(ICH9_REG_HSFS)); + + hsfc = REGREAD32(ICH9_REG_HSFS); + hsfc &= ~HSFSC_FCYCLE; /* set read operation */ + + /* read status register */ + hsfc |= (0x8 << HSFSC_FCYCLE_OFF); + + hsfc &= ~HSFSC_FDBC; /* clear byte count */ + /* set byte count */ + hsfc |= (((len - 1) << HSFSC_FDBC_OFF) & HSFSC_FDBC); + hsfc |= HSFSC_FGO; /* start */ + REGWRITE32(ICH9_REG_HSFS, hsfc); + if (ich_hwseq_wait_for_cycle_complete(len, ich_generation)) { + msg_perr("Reading Status register failed\n!!"); + return -1; + } + ich_read_data(value, len, ICH9_REG_FDATA0); + + return 0; +} + +static int ich_hwseq_write_status(const struct flashctx *flash, enum flash_reg reg_, uint8_t value) +{ + uint32_t hsfc; + int len = 1; + + msg_pdbg("Writing status register\n"); + + /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */ + REGWRITE32(ICH9_REG_HSFS, REGREAD32(ICH9_REG_HSFS)); + + ich_fill_data(&value, len, ICH9_REG_FDATA0); + hsfc = REGREAD32(ICH9_REG_HSFS); + hsfc &= ~HSFSC_FCYCLE; /* clear operation */ + + /* write status register */ + hsfc |= (0x7 << HSFSC_FCYCLE_OFF); + hsfc &= ~HSFSC_FDBC; /* clear byte count */ + + /* set byte count */ + hsfc |= (((len - 1) << HSFSC_FDBC_OFF) & HSFSC_FDBC); + hsfc |= HSFSC_FGO; /* start */ + REGWRITE32(ICH9_REG_HSFS, hsfc); + + if (ich_hwseq_wait_for_cycle_complete(len, ich_generation)) { + msg_perr("Writing Status register failed\n!!"); + return -1; + } + + return 0; +} + static int ich_hwseq_probe(struct flashctx *flash) { uint32_t total_size, boundary; @@ -1744,6 +1815,8 @@ .read = ich_hwseq_read, .write = ich_hwseq_write, .erase = ich_hwseq_block_erase, + .read_status = ich_hwseq_read_status, + .write_status = ich_hwseq_write_status, };
static int init_ich7_spi(void *spibar, enum ich_chipset ich_gen)