From 935404da1157d606b913eff6c2635ae898e9980a Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Thu, 1 May 2014 14:39:28 -0700 Subject: [PATCH] broadwell: Add function to read WPSR from SPI Add a function to the romstage SPI code to read and return the WPSR to determine the software write protect status at boot. BUG=chrome-os-partner:28234 TEST=None Change-Id: Ia68c02317ed1c2149fd9de1f60598b6f101d9686 Signed-off-by: Duncan Laurie Reviewed-on: https://chromium-review.googlesource.com/199190 Reviewed-by: Aaron Durbin --- src/soc/intel/broadwell/romstage/romstage.c | 9 ++++++ src/soc/intel/broadwell/romstage/spi.c | 34 +++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/src/soc/intel/broadwell/romstage/romstage.c b/src/soc/intel/broadwell/romstage/romstage.c index 9a9501198f..d22ec52d89 100644 --- a/src/soc/intel/broadwell/romstage/romstage.c +++ b/src/soc/intel/broadwell/romstage/romstage.c @@ -249,3 +249,12 @@ void ramstage_cache_invalid(struct ramstage_cache *cache) #endif } #endif + +#if CONFIG_CHROMEOS +int vboot_get_sw_write_protect(void) +{ + u8 status; + /* Return unprotected status if status read fails. */ + return (early_spi_read_wpsr(&status) ? 0 : !!(status & 0x80)); +} +#endif diff --git a/src/soc/intel/broadwell/romstage/spi.c b/src/soc/intel/broadwell/romstage/spi.c index f79de43cca..710c546d41 100644 --- a/src/soc/intel/broadwell/romstage/spi.c +++ b/src/soc/intel/broadwell/romstage/spi.c @@ -111,3 +111,37 @@ int early_spi_read(u32 offset, u32 size, u8 *buffer) return 0; } + +/* + * Minimal set of commands to read WPSR from SPI. + * Don't use this code outside romstage -- it trashes the opmenu table. + * Returns 0 on success, < 0 on failure. + */ +int early_spi_read_wpsr(u8 *sr) +{ + int retry; + + /* No address associated with rdsr */ + SPIBAR8(SPIBAR_OPTYPE) = 0x0; + /* Setup opcode[0] = read wpsr */ + SPIBAR8(SPIBAR_OPMENU_LOWER) = 0x5; + + /* Start transaction */ + SPIBAR16(SPIBAR_SSFC) = SPIBAR_SSFC_DATA | SPIBAR_SSFC_GO; + + /* Wait for error / complete status */ + for (retry = SPI_RETRY; retry; retry--) { + u16 status = SPIBAR16(SPIBAR_SSFS); + if (status & SPIBAR_SSFS_ERROR) { + printk(BIOS_ERR, "SPI rdsr failed\n"); + return -1; + } else if (status & SPIBAR_SSFS_DONE) { + break; + } + + udelay(SPI_DELAY); + } + + *sr = SPIBAR32(SPIBAR_FDATA(0)) & 0xff; + return 0; +}