From 97e57cfd51578dee7d3e29d5e39f31855294ed4e Mon Sep 17 00:00:00 2001 From: Karthikeyan Ramasubramanian Date: Mon, 17 Jul 2023 12:43:14 -0600 Subject: [PATCH] soc/amd/common/psp_verstage: Support multiple hash tables Currently PSP verstage updates PSP bootloader with one unified hash table containing hashes for all the signed PSP binaries to be validated. With growing number of PSP binaries to validate and memory constraints in PSP, there is a requirement to split and update the hash table into multiple smaller chunks. Hence change the update_psp_fw_hash_table() signature such that the hash tables are updated in a chipset specific way. BUG=b:277292697 TEST=Build and boot to OS in Myst with PSP verstage enabled. Build the Skyrim BIOS image and confirm that the hash table is identical before and after this change. Change-Id: I75aac5bc5e7f61069be25d801d0838fdf565d3d1 Signed-off-by: Karthikeyan Ramasubramanian Reviewed-on: https://review.coreboot.org/c/coreboot/+/76587 Reviewed-by: Martin Roth Tested-by: build bot (Jenkins) --- .../amd/common/psp_verstage/include/psp_verstage.h | 2 +- src/soc/amd/common/psp_verstage/psp_verstage.c | 5 +---- src/soc/amd/mendocino/psp_verstage/chipset.c | 13 ++++++++++++- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/soc/amd/common/psp_verstage/include/psp_verstage.h b/src/soc/amd/common/psp_verstage/include/psp_verstage.h index 0663c4a5f8..39059b8c5c 100644 --- a/src/soc/amd/common/psp_verstage/include/psp_verstage.h +++ b/src/soc/amd/common/psp_verstage/include/psp_verstage.h @@ -38,7 +38,7 @@ int platform_set_sha_op(enum vb2_hash_algorithm hash_alg, struct sha_generic_data *sha_op); void platform_report_mode(int developer_mode_enabled); -void update_psp_fw_hash_table(const char *fname); +void update_psp_fw_hash_tables(void); void report_prev_boot_status_to_vboot(void); diff --git a/src/soc/amd/common/psp_verstage/psp_verstage.c b/src/soc/amd/common/psp_verstage/psp_verstage.c index c9092f4f42..8e643a5d5a 100644 --- a/src/soc/amd/common/psp_verstage/psp_verstage.c +++ b/src/soc/amd/common/psp_verstage/psp_verstage.c @@ -73,7 +73,6 @@ static uint32_t update_boot_region(struct vb2_context *ctx) uint32_t psp_dir_addr, bios_dir_addr; uint32_t *psp_dir_in_spi, *bios_dir_in_spi; const char *fname; - const char *hash_fname; void *amdfw_location; struct region fw_slot; void *map_base = NULL; @@ -86,13 +85,11 @@ static uint32_t update_boot_region(struct vb2_context *ctx) if (vboot_is_firmware_slot_a(ctx)) { fname = "apu/amdfw_a"; - hash_fname = "apu/amdfw_a_hash"; if (!fmap_locate_area("FW_MAIN_A", &fw_slot)) map_base = rdev_mmap(boot_device_ro(), fw_slot.offset, fw_slot.size); } else { fname = "apu/amdfw_b"; - hash_fname = "apu/amdfw_b_hash"; if (!fmap_locate_area("FW_MAIN_B", &fw_slot)) map_base = rdev_mmap(boot_device_ro(), fw_slot.offset, fw_slot.size); } @@ -158,7 +155,7 @@ static uint32_t update_boot_region(struct vb2_context *ctx) } if (CONFIG(SEPARATE_SIGNED_PSPFW)) - update_psp_fw_hash_table(hash_fname); + update_psp_fw_hash_tables(); cbfs_unmap(amdfw_location); rdev_munmap(boot_device_ro(), amdfw_location); diff --git a/src/soc/amd/mendocino/psp_verstage/chipset.c b/src/soc/amd/mendocino/psp_verstage/chipset.c index 282ad21227..2ff0367d68 100644 --- a/src/soc/amd/mendocino/psp_verstage/chipset.c +++ b/src/soc/amd/mendocino/psp_verstage/chipset.c @@ -13,6 +13,7 @@ #include #include +#define PSP_FW_HASH_FILE_NAME(slot) "apu/amdfw_" slot "_hash" /* * We can't pass pointer to hash table in the SPI. * The AMD PSP team specifically required that whole hash table @@ -24,7 +25,7 @@ static struct psp_fw_hash_table hash_table; static struct psp_fw_entry_hash_256 hash_256[MAX_NUM_HASH_ENTRIES]; static struct psp_fw_entry_hash_384 hash_384[MAX_NUM_HASH_ENTRIES]; -void update_psp_fw_hash_table(const char *fname) +static void update_one_psp_fw_hash_table(const char *fname) { void *hash_file = cbfs_map(fname, NULL); uint8_t *spi_ptr = (uint8_t *)hash_file; @@ -77,6 +78,16 @@ void update_psp_fw_hash_table(const char *fname) rdev_munmap(boot_device_ro(), hash_file); } +void update_psp_fw_hash_tables(void) +{ + struct vb2_context *ctx = vboot_get_context(); + + if (vboot_is_firmware_slot_a(ctx)) + update_one_psp_fw_hash_table(PSP_FW_HASH_FILE_NAME("a")); + else + update_one_psp_fw_hash_table(PSP_FW_HASH_FILE_NAME("b")); +} + uint32_t update_psp_bios_dir(uint32_t *psp_dir_offset, uint32_t *bios_dir_offset) { return svc_update_psp_bios_dir(psp_dir_offset, bios_dir_offset);