diff options
Diffstat (limited to 'src/soc/amd/common/block/psp/psp_gen1.c')
-rw-r--r-- | src/soc/amd/common/block/psp/psp_gen1.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/soc/amd/common/block/psp/psp_gen1.c b/src/soc/amd/common/block/psp/psp_gen1.c index 0e5aa30154..b707933553 100644 --- a/src/soc/amd/common/block/psp/psp_gen1.c +++ b/src/soc/amd/common/block/psp/psp_gen1.c @@ -2,8 +2,11 @@ /* This file is part of the coreboot project. */ #include <device/mmio.h> +#include <cbfs.h> +#include <region_file.h> #include <timer.h> #include <bootstate.h> +#include <console/console.h> #include <amdblocks/psp.h> #include <soc/iomap.h> #include <soc/northbridge.h> @@ -91,3 +94,54 @@ int send_psp_command(u32 command, void *buffer) return 0; } + +/* + * Tell the PSP to load a firmware blob from a location in the BIOS image. + */ +int psp_load_named_blob(enum psp_blob_type type, const char *name) +{ + int cmd_status; + u32 command; + void *blob; + struct cbfsf cbfs_file; + struct region_device rdev; + + switch (type) { + case BLOB_SMU_FW: + command = MBOX_BIOS_CMD_SMU_FW; + break; + case BLOB_SMU_FW2: + command = MBOX_BIOS_CMD_SMU_FW2; + break; + default: + printk(BIOS_ERR, "BUG: Invalid PSP blob type %x\n", type); + return -PSPSTS_INVALID_BLOB; + } + + /* type can only be BLOB_SMU_FW or BLOB_SMU_FW2 here, so don't re-check for this */ + if (!CONFIG(SOC_AMD_PSP_SELECTABLE_SMU_FW)) { + printk(BIOS_ERR, "BUG: Selectable firmware is not supported\n"); + return -PSPSTS_UNSUPPORTED; + } + + if (cbfs_boot_locate(&cbfs_file, name, NULL)) { + printk(BIOS_ERR, "BUG: Cannot locate blob for PSP loading\n"); + return -PSPSTS_INVALID_NAME; + } + + cbfs_file_data(&rdev, &cbfs_file); + blob = rdev_mmap_full(&rdev); + if (!blob) { + printk(BIOS_ERR, "BUG: Cannot map blob for PSP loading\n"); + return -PSPSTS_INVALID_NAME; + } + + printk(BIOS_DEBUG, "PSP: Load blob type %x from @%p... ", type, blob); + + /* Blob commands use the buffer registers as data, not pointer to buf */ + cmd_status = send_psp_command(command, blob); + psp_print_cmd_status(cmd_status, NULL); + + rdev_munmap(&rdev, blob); + return cmd_status; +} |