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>
This commit is contained in:
Marshall Dawson 2017-10-12 16:04:08 -06:00 committed by Aaron Durbin
parent 154239aff1
commit 596ecec009
3 changed files with 83 additions and 0 deletions

View File

@ -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__ */

View File

@ -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.

View File

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