summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/drivers/spi/Kconfig6
-rw-r--r--src/drivers/spi/Makefile.mk1
-rw-r--r--src/drivers/spi/spi_flash.c5
-rw-r--r--src/drivers/spi/spi_flash_internal.h3
-rw-r--r--src/drivers/spi/spi_flash_rpmc.c32
-rw-r--r--src/include/spi_flash.h9
6 files changed, 56 insertions, 0 deletions
diff --git a/src/drivers/spi/Kconfig b/src/drivers/spi/Kconfig
index 72fcec5e93..5d9698e16a 100644
--- a/src/drivers/spi/Kconfig
+++ b/src/drivers/spi/Kconfig
@@ -194,6 +194,12 @@ config SPI_FLASH_SFDP
help
Include serial flash discoverable parameters (SFDP) support.
+config SPI_FLASH_RPMC
+ bool
+ select SPI_FLASH_SFDP
+ help
+ Include replay-protected monotonic counter (RPMC) support.
+
endif # SPI_FLASH
config HAVE_EM100PRO_SPI_CONSOLE_SUPPORT
diff --git a/src/drivers/spi/Makefile.mk b/src/drivers/spi/Makefile.mk
index d873c90627..3310b968c3 100644
--- a/src/drivers/spi/Makefile.mk
+++ b/src/drivers/spi/Makefile.mk
@@ -32,6 +32,7 @@ $(1)-$(CONFIG_SPI_FLASH_STMICRO) += stmicro.c
$(1)-$(CONFIG_SPI_FLASH_WINBOND) += winbond.c
$(1)-$(CONFIG_SPI_FLASH_ISSI) += issi.c
$(1)-$(CONFIG_SPI_FLASH_SFDP) += spi_flash_sfdp.c
+$(1)-$(CONFIG_SPI_FLASH_RPMC) += spi_flash_rpmc.c
endef
$(eval $(call add_spi_stage,bootblock,_EARLY))
diff --git a/src/drivers/spi/spi_flash.c b/src/drivers/spi/spi_flash.c
index 6ecd29f773..b7a024c4c2 100644
--- a/src/drivers/spi/spi_flash.c
+++ b/src/drivers/spi/spi_flash.c
@@ -569,6 +569,11 @@ int spi_flash_probe(unsigned int bus, unsigned int cs, struct spi_flash *flash)
spi_flash_cmd(&flash->spi, CMD_EXIT_4BYTE_ADDR_MODE, NULL, 0);
}
+ /* TODO: only do this in stages that will need to call those functions? */
+ if (CONFIG(SPI_FLASH_RPMC)) {
+ spi_flash_fill_rpmc_caps(flash);
+ }
+
return 0;
}
diff --git a/src/drivers/spi/spi_flash_internal.h b/src/drivers/spi/spi_flash_internal.h
index 830a178e97..a30f58f9a5 100644
--- a/src/drivers/spi/spi_flash_internal.h
+++ b/src/drivers/spi/spi_flash_internal.h
@@ -159,4 +159,7 @@ struct sfdp_rpmc_info {
enum cb_err spi_flash_get_sfdp_rpmc(const struct spi_flash *flash,
struct sfdp_rpmc_info *rpmc_info);
+/* Fill rpmc_caps field in spi_flash struct with RPMC config from SFDP */
+void spi_flash_fill_rpmc_caps(struct spi_flash *flash);
+
#endif /* SPI_FLASH_INTERNAL_H */
diff --git a/src/drivers/spi/spi_flash_rpmc.c b/src/drivers/spi/spi_flash_rpmc.c
new file mode 100644
index 0000000000..148e3bb8a1
--- /dev/null
+++ b/src/drivers/spi/spi_flash_rpmc.c
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <console/console.h>
+#include <spi-generic.h>
+#include <spi_flash.h>
+#include <string.h>
+#include <timer.h>
+#include <types.h>
+
+#include "spi_flash_internal.h"
+
+void spi_flash_fill_rpmc_caps(struct spi_flash *flash)
+{
+ struct sfdp_rpmc_info rpmc_info;
+
+ flash->rpmc_caps.rpmc_available = false;
+
+ if (spi_flash_get_sfdp_rpmc(flash, &rpmc_info) != CB_SUCCESS)
+ return;
+
+ if (rpmc_info.monotonic_counter_size != SFDP_RPMC_COUNTER_BITS_32) {
+ printk(BIOS_WARNING, "RPMC: unexpected counter size\n");
+ return;
+ }
+
+ flash->rpmc_caps.poll_op2_ext_stat = rpmc_info.busy_polling_method ==
+ SFDP_RPMC_POLL_OP2_EXTENDED_STATUS;
+ flash->rpmc_caps.number_of_counters = rpmc_info.number_of_counters;
+ flash->rpmc_caps.op1_write_cmd = rpmc_info.op1_write_command;
+ flash->rpmc_caps.op2_read_cmd = rpmc_info.op2_read_command;
+ flash->rpmc_caps.rpmc_available = true;
+}
diff --git a/src/include/spi_flash.h b/src/include/spi_flash.h
index 7736a940f5..76c33be5ea 100644
--- a/src/include/spi_flash.h
+++ b/src/include/spi_flash.h
@@ -95,6 +95,14 @@ struct spi_flash_protection_ops {
struct spi_flash_part_id;
+struct spi_flash_rpmc_cap {
+ bool rpmc_available;
+ bool poll_op2_ext_stat;
+ unsigned int number_of_counters;
+ uint8_t op1_write_cmd;
+ uint8_t op2_read_cmd;
+};
+
struct spi_flash {
struct spi_slave spi;
u8 vendor;
@@ -118,6 +126,7 @@ struct spi_flash {
/* If !NULL all protection callbacks exist. */
const struct spi_flash_protection_ops *prot_ops;
const struct spi_flash_part_id *part;
+ struct spi_flash_rpmc_cap rpmc_caps;
};
void lb_spi_flash(struct lb_header *header);