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 <kramasub@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/76587
Reviewed-by: Martin Roth <martin.roth@amd.corp-partner.google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Karthikeyan Ramasubramanian 2023-07-17 12:43:14 -06:00 committed by Martin L Roth
parent abaca2a399
commit 97e57cfd51
3 changed files with 14 additions and 6 deletions

View File

@ -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);

View File

@ -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);

View File

@ -13,6 +13,7 @@
#include <security/vboot/misc.h>
#include <security/vboot/vbnv.h>
#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);