Felix Held has submitted this change. ( https://review.coreboot.org/c/coreboot/+/83776?usp=email )
(
1 is the latest approved patch-set. No files were changed between the latest approved patch-set and the submitted one. )Change subject: soc/amd/common/psp_smi_flash: implement SPI info command ......................................................................
soc/amd/common/psp_smi_flash: implement SPI info command
Detect the block size of the SPI flash and number of flash blocks reserved for the flash region corresponding to the 'target_nv_id' field in the command buffer. This information is then written to the corresponding fields in the command buffer. Since detecting the flash chip still might result in accesses to it, make sure that it's available for use and not currently used by an OS driver. Since this code is inside the SMI handler, we don't have to worry about this code to be interrupted, so we don't need to set some bit to tell other code that we're currently using the SPI controller in the SMI handler.
This patch is a modified version of parts of CB:65523.
Document #55758 Rev. 2.04 was used as a reference.
Test=When selecting SOC_AMD_COMMON_BLOCK_PSP_SMI, Mandolin still builds
Signed-off-by: Felix Held felix-coreboot@felixheld.de Signed-off-by: Ritul Guru ritul.bits@gmail.com Change-Id: I19041a27a9e8f901d42c3f60af834df625455ea6 Reviewed-on: https://review.coreboot.org/c/coreboot/+/83776 Reviewed-by: Martin Roth martin.roth@amd.corp-partner.google.com Tested-by: build bot (Jenkins) no-reply@coreboot.org --- M src/soc/amd/common/block/psp/psp_smi_flash.c 1 file changed, 43 insertions(+), 3 deletions(-)
Approvals: Martin Roth: Looks good to me, approved build bot (Jenkins): Verified
diff --git a/src/soc/amd/common/block/psp/psp_smi_flash.c b/src/soc/amd/common/block/psp/psp_smi_flash.c index 367baef..420fb94 100644 --- a/src/soc/amd/common/block/psp/psp_smi_flash.c +++ b/src/soc/amd/common/block/psp/psp_smi_flash.c @@ -72,6 +72,19 @@ return is_valid_psp_spi_id(read64(&cmd_buf->req.target_nv_id)); }
+static u64 get_psp_spi_info_id(struct mbox_pspv2_cmd_spi_info *cmd_buf) +{ + return read64(&cmd_buf->req.target_nv_id); +} + +static void set_psp_spi_info(struct mbox_pspv2_cmd_spi_info *cmd_buf, + u64 lba, u64 block_size, u64 num_blocks) +{ + write64(&cmd_buf->req.lba, lba); + write64(&cmd_buf->req.block_size, block_size); + write64(&cmd_buf->req.num_blocks, num_blocks); +} + static const char *id_to_region_name(u64 target_nv_id) { switch (target_nv_id) { @@ -117,7 +130,7 @@ return rdev_chain(rstore, rdev, 0, region_device_sz(rdev)); }
-static inline enum mbox_p2c_status find_psp_spi_flash_device_region(u64 target_nv_id, +static enum mbox_p2c_status find_psp_spi_flash_device_region(u64 target_nv_id, struct region_device *store, const struct spi_flash **flash) { @@ -135,7 +148,7 @@ return MBOX_PSP_SUCCESS; }
-static inline bool spi_controller_available(void) +static bool spi_controller_available(void) { return !(spi_read8(SPI_MISC_CNTRL) & SPI_SEMAPHORE_DRIVER_LOCKED); } @@ -144,13 +157,40 @@ { struct mbox_pspv2_cmd_spi_info *const cmd_buf = (struct mbox_pspv2_cmd_spi_info *)buffer; + const struct spi_flash *flash; + struct region_device store; + u64 target_nv_id; + u64 block_size; + u64 num_blocks; + enum mbox_p2c_status ret;
printk(BIOS_SPEW, "PSP: SPI info request\n");
if (!is_valid_psp_spi_info(cmd_buf)) return MBOX_PSP_COMMAND_PROCESS_ERROR;
- return MBOX_PSP_UNSUPPORTED; + if (!spi_controller_available()) { + printk(BIOS_NOTICE, "PSP: SPI controller busy\n"); + return MBOX_PSP_SPI_BUSY; + } + + target_nv_id = get_psp_spi_info_id(cmd_buf); + + ret = find_psp_spi_flash_device_region(target_nv_id, &store, &flash); + + if (ret != MBOX_PSP_SUCCESS) + return ret; + + block_size = flash->sector_size; + + if (!block_size) + return MBOX_PSP_COMMAND_PROCESS_ERROR; + + num_blocks = region_device_sz(&store) / block_size; + + set_psp_spi_info(cmd_buf, 0, block_size, num_blocks); + + return MBOX_PSP_SUCCESS; }
enum mbox_p2c_status psp_smi_spi_read(struct mbox_default_buffer *buffer)