From febf3e26dff56d0475451f9565fa5a2e64d47f5c Mon Sep 17 00:00:00 2001 From: Felix Held Date: Mon, 5 Aug 2024 23:15:55 +0200 Subject: soc/amd/common/psp_smi_flash: add find_psp_spi_flash_device_region Add 'find_psp_spi_flash_device_region' to get a pointer to the spi_flash struct of the SPI flash used in the system and the region_device struct for the target FMAP region specified by the target NV ID from the PSP to x86 mailbox command. In order to have small patches, the newly added static 'find_psp_spi_flash_device_region' function is marked as inline; that inline will be removed in a following patch that calls this new function. This patch is a slightly reworked 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 Signed-off-by: Ritul Guru Change-Id: I64b8fba2392de46ecd4c786cef0d5b6acdbd865a Reviewed-on: https://review.coreboot.org/c/coreboot/+/83774 Reviewed-by: Martin Roth Tested-by: build bot (Jenkins) --- src/soc/amd/common/block/psp/psp_smi_flash.c | 67 ++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) (limited to 'src/soc/amd') 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 f1b9d85fbb..4c83fcd358 100644 --- a/src/soc/amd/common/block/psp/psp_smi_flash.c +++ b/src/soc/amd/common/block/psp/psp_smi_flash.c @@ -1,7 +1,11 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include +#include #include #include +#include +#include #include #include "psp_def.h" @@ -67,6 +71,69 @@ static bool is_valid_psp_spi_erase(struct mbox_pspv2_cmd_spi_erase *cmd_buf) return is_valid_psp_spi_id(read64(&cmd_buf->req.target_nv_id)); } +static const char *id_to_region_name(u64 target_nv_id) +{ + switch (target_nv_id) { + case SMI_TARGET_NVRAM: + return "PSP_NVRAM"; + case SMI_TARGET_RPMC_NVRAM: + return "PSP_RPMC_NVRAM"; + } + return NULL; +} + +/* + * Do not cache the location to cope with flash changing underneath (e.g. due + * to an update) + */ +static int lookup_store(u64 target_nv_id, struct region_device *rstore) +{ + /* read_rdev, write_rdev and store_irdev need to be static to not go out of scope when + this function returns */ + static struct region_device read_rdev, write_rdev; + static struct incoherent_rdev store_irdev; + const char *name; + struct region region; + const struct region_device *rdev; + + name = id_to_region_name(target_nv_id); + if (!name) + return -1; + + if (fmap_locate_area(name, ®ion) < 0) + return -1; + + if (boot_device_ro_subregion(®ion, &read_rdev) < 0) + return -1; + + if (boot_device_rw_subregion(®ion, &write_rdev) < 0) + return -1; + + rdev = incoherent_rdev_init(&store_irdev, ®ion, &read_rdev, &write_rdev); + if (rdev == NULL) + return -1; + + 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, + struct region_device *store, + const struct spi_flash **flash) +{ + *flash = boot_device_spi_flash(); + if (*flash == NULL) { + printk(BIOS_ERR, "PSP: Unable to find SPI device\n"); + return MBOX_PSP_COMMAND_PROCESS_ERROR; + } + + if (lookup_store(target_nv_id, store) < 0) { + printk(BIOS_ERR, "PSP: Unable to find PSP SPI region\n"); + return MBOX_PSP_COMMAND_PROCESS_ERROR; + } + + return MBOX_PSP_SUCCESS; +} + enum mbox_p2c_status psp_smi_spi_get_info(struct mbox_default_buffer *buffer) { struct mbox_pspv2_cmd_spi_info *const cmd_buf = -- cgit v1.2.3