aboutsummaryrefslogtreecommitdiff
path: root/src/soc/amd/common/block/psp/psp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/amd/common/block/psp/psp.c')
-rw-r--r--src/soc/amd/common/block/psp/psp.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/src/soc/amd/common/block/psp/psp.c b/src/soc/amd/common/block/psp/psp.c
index 8b3605e6fa..5aedfc138f 100644
--- a/src/soc/amd/common/block/psp/psp.c
+++ b/src/soc/amd/common/block/psp/psp.c
@@ -14,6 +14,8 @@
*/
#include <arch/io.h>
+#include <cbfs.h>
+#include <region_file.h>
#include <timer.h>
#include <device/pci_def.h>
#include <console/console.h>
@@ -199,3 +201,58 @@ int psp_notify_dram(void)
return cmd_status;
}
+
+/*
+ * Tell the PSP to load a firmware blob from a location in the BIOS image.
+ */
+static int psp_load_blob(int type, void *addr)
+{
+ int cmd_status;
+
+ if (!IS_ENABLED(CONFIG_SOC_AMD_PSP_SELECTABLE_SMU_FW)) {
+ printk(BIOS_ERR, "BUG: Selectable firmware is not supported\n");
+ return PSPSTS_UNSUPPORTED;
+ }
+
+ /* only two types currently supported */
+ if (type != MBOX_BIOS_CMD_SMU_FW && type != MBOX_BIOS_CMD_SMU_FW2) {
+ printk(BIOS_ERR, "BUG: Invalid PSP blob type %x\n", type);
+ return PSPSTS_INVALID_BLOB;
+ }
+
+ printk(BIOS_DEBUG, "PSP: Load blob type %x from @%p... ", type, addr);
+
+ /* Blob commands use the buffer registers as data, not pointer to buf */
+ cmd_status = send_psp_command(type, addr);
+
+ if (cmd_status)
+ printk(BIOS_DEBUG, "%s\n", status_to_string(cmd_status));
+ else
+ printk(BIOS_DEBUG, "OK\n");
+
+ return cmd_status;
+}
+
+int psp_load_named_blob(int type, const char *name)
+{
+ void *blob;
+ struct cbfsf cbfs_file;
+ struct region_device rdev;
+ int r;
+
+ 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) {
+ r = psp_load_blob(type, blob);
+ rdev_munmap(&rdev, blob);
+ } else {
+ printk(BIOS_ERR, "BUG: Cannot map blob for PSP loading\n");
+ return PSPSTS_INVALID_NAME;
+ }
+ return r;
+}