Attention is currently required from: Fred Reitberger, Jason Glenesk, Matt DeVillier, ritul guru.
Hello ritul guru,
I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/83776?usp=email
to review the following change.
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.
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 --- M src/soc/amd/common/block/psp/psp_smi_flash.c 1 file changed, 43 insertions(+), 3 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/76/83776/1
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)