diff options
author | Marshall Dawson <marshalldawson3rd@gmail.com> | 2017-10-12 16:04:08 -0600 |
---|---|---|
committer | Aaron Durbin <adurbin@chromium.org> | 2017-11-08 21:58:59 +0000 |
commit | 596ecec009d722aebbfc16074b89bc78dc9ede26 (patch) | |
tree | d9722ff5cb487f65e7eb91c27cb237deed33295c | |
parent | 154239aff1602e0ae27f9ce1f2df0647e4aef0a8 (diff) |
soc/amd/common/psp: Add command to load fw blobs
An upcoming PSP firmware change will allow coreboot to load the two
SMU firmware blobs (one runs in SRAM and the other in DRAM). The
traditional method is for the PSP to control most of the process,
e.g. loading the SRAM version prior to releasing the x86 reset.
Add a new command that can instruct the PSP to load a firmware blob
from a location in the flash.
The definition for commands 19 and 1a differ from others in that they
do not use a command/response buffer. Instead, the PSP will look in
the command/response pointer registers directly for the blob's
address.
BUG=b:66339938
Change-Id: I8431af341930f45ac74f471628b4dc4ede7735f4
Signed-off-by: Marshall Dawson <marshalldawson3rd@gmail.com>
Reviewed-on: https://review.coreboot.org/22056
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
-rw-r--r-- | src/soc/amd/common/block/include/amdblocks/psp.h | 14 | ||||
-rw-r--r-- | src/soc/amd/common/block/psp/Kconfig | 12 | ||||
-rw-r--r-- | src/soc/amd/common/block/psp/psp.c | 57 |
3 files changed, 83 insertions, 0 deletions
diff --git a/src/soc/amd/common/block/include/amdblocks/psp.h b/src/soc/amd/common/block/include/amdblocks/psp.h index d210498502..74ea73f7f7 100644 --- a/src/soc/amd/common/block/include/amdblocks/psp.h +++ b/src/soc/amd/common/block/include/amdblocks/psp.h @@ -32,6 +32,8 @@ #define MBOX_BIOS_CMD_CLEAR_S3_STS 0x07 #define MBOX_BIOS_CMD_C3_DATA_INFO 0x08 #define MBOX_BIOS_CMD_NOP 0x09 +#define MBOX_BIOS_CMD_SMU_FW 0x19 +#define MBOX_BIOS_CMD_SMU_FW2 0x1a #define MBOX_BIOS_CMD_ABORT 0xfe /* generic PSP interface status */ @@ -79,11 +81,23 @@ struct mbox_default_buffer { /* command-response buffer unused by command */ #define PSPSTS_SEND_ERROR 4 #define PSPSTS_INIT_TIMEOUT 5 #define PSPSTS_CMD_TIMEOUT 6 +/* other error codes */ +#define PSPSTS_UNSUPPORTED 7 +#define PSPSTS_INVALID_NAME 8 +#define PSPSTS_INVALID_BLOB 9 #define PSP_INIT_TIMEOUT 10000 /* 10 seconds */ #define PSP_CMD_TIMEOUT 1000 /* 1 second */ /* BIOS-to-PSP functions return 0 if successful, else negative value */ + int psp_notify_dram(void); +/* + * type: identical to the corresponding PSP command, e.g. pass + * MBOX_BIOS_CMD_SMU_FW2 to load SMU FW2 blob. + * name: cbfs file name + */ +int psp_load_named_blob(int type, const char *name); + #endif /* __AMD_PSP_H__ */ diff --git a/src/soc/amd/common/block/psp/Kconfig b/src/soc/amd/common/block/psp/Kconfig index 69958f21aa..0517a2f33f 100644 --- a/src/soc/amd/common/block/psp/Kconfig +++ b/src/soc/amd/common/block/psp/Kconfig @@ -4,3 +4,15 @@ config SOC_AMD_COMMON_BLOCK_PSP help This option builds in the Platform Security Processor initialization functions. + +config SOC_AMD_PSP_SELECTABLE_SMU_FW + bool + default n + help + Some PSP implementations allow storing SMU firmware into cbfs and + calling the PSP to load the blobs at the proper time. + + The soc/<codename> should select this if its PSP supports the feature + and each mainboard can choose to select an appropriate fanless or + fanned set of blobs. Ask your AMD representative whether your APU + is considered fanless. 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; +} |