util/amdfwtool: Split type field for PSP entries

Separate the type field for the PSP directory table to better match the
AMD Platform Security Processor BIOS Architecture Guide (order #55758,
NDA only).  Instead of a 32-bit type, change to an 8-bit value and an
8-bit subprogram field to allow for a more generic application across
family/model products.

This patch also eliminates the "fanless" types, previously added for
stoneyridge, and converts the --smufnfirmware and --smufnfirmware2
arguments to use a subprogram value of 1.

Subsequent patches will change the stoneyridge makefile to use the
new option, and eliminate the fanless arguments.

TEST=Boot google/grunt, confirm no difference in amdfw.rom file.
BUG=b:126691068

Change-Id: If8f33000c31cba21f286f54459de185c21e46268
Signed-off-by: Marshall Dawson <marshalldawson3rd@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/31735
Reviewed-by: Martin Roth <martinroth@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Marshall Dawson 2019-03-04 10:31:03 -07:00 committed by Martin Roth
parent 2794a86b1b
commit dbae632fec
1 changed files with 67 additions and 29 deletions

View File

@ -173,6 +173,7 @@ static void usage(void)
printf(" offset able to support combo directory\n"); printf(" offset able to support combo directory\n");
printf("-p | --pubkey <FILE> Add pubkey\n"); printf("-p | --pubkey <FILE> Add pubkey\n");
printf("-b | --bootloader <FILE> Add bootloader\n"); printf("-b | --bootloader <FILE> Add bootloader\n");
printf("-S | --subprogram <number> Sets subprogram field for the next firmware\n");
printf("-s | --smufirmware <FILE> Add smufirmware\n"); printf("-s | --smufirmware <FILE> Add smufirmware\n");
printf("-j | --smufnfirmware <FILE> Add fanless smufirmware\n"); printf("-j | --smufnfirmware <FILE> Add fanless smufirmware\n");
printf("-r | --recovery <FILE> Add recovery\n"); printf("-r | --recovery <FILE> Add recovery\n");
@ -194,13 +195,10 @@ static void usage(void)
printf("-h | --help show this help\n"); printf("-h | --help show this help\n");
} }
#define FANLESS_FW 0x100 /* type[15:8]: 0=non-fanless OPNs, 1=fanless */
typedef enum _amd_fw_type { typedef enum _amd_fw_type {
AMD_FW_PSP_PUBKEY = 0, AMD_FW_PSP_PUBKEY = 0,
AMD_FW_PSP_BOOTLOADER = 1, AMD_FW_PSP_BOOTLOADER = 1,
AMD_FW_PSP_SMU_FIRMWARE = 8, AMD_FW_PSP_SMU_FIRMWARE = 8,
AMD_FW_PSP_SMU_FN_FIRMWARE = FANLESS_FW + AMD_FW_PSP_SMU_FIRMWARE,
AMD_FW_PSP_RECOVERY = 3, AMD_FW_PSP_RECOVERY = 3,
AMD_FW_PSP_RTM_PUBKEY = 5, AMD_FW_PSP_RTM_PUBKEY = 5,
AMD_FW_PSP_SECURED_OS = 2, AMD_FW_PSP_SECURED_OS = 2,
@ -209,7 +207,6 @@ typedef enum _amd_fw_type {
AMD_FW_PSP_TRUSTLETS = 12, AMD_FW_PSP_TRUSTLETS = 12,
AMD_FW_PSP_TRUSTLETKEY = 13, AMD_FW_PSP_TRUSTLETKEY = 13,
AMD_FW_PSP_SMU_FIRMWARE2 = 18, AMD_FW_PSP_SMU_FIRMWARE2 = 18,
AMD_FW_PSP_SMU_FN_FIRMWARE2 = FANLESS_FW + AMD_FW_PSP_SMU_FIRMWARE2,
AMD_PSP_FUSE_CHAIN = 11, AMD_PSP_FUSE_CHAIN = 11,
AMD_FW_PSP_SMUSCS = 95, AMD_FW_PSP_SMUSCS = 95,
@ -221,6 +218,7 @@ typedef enum _amd_fw_type {
typedef struct _amd_fw_entry { typedef struct _amd_fw_entry {
amd_fw_type type; amd_fw_type type;
uint8_t subprog;
char *filename; char *filename;
} amd_fw_entry; } amd_fw_entry;
@ -235,8 +233,8 @@ static amd_fw_entry amd_psp_fw_table[] = {
{ .type = AMD_FW_PSP_SECURED_DEBUG }, { .type = AMD_FW_PSP_SECURED_DEBUG },
{ .type = AMD_FW_PSP_TRUSTLETS }, { .type = AMD_FW_PSP_TRUSTLETS },
{ .type = AMD_FW_PSP_TRUSTLETKEY }, { .type = AMD_FW_PSP_TRUSTLETKEY },
{ .type = AMD_FW_PSP_SMU_FN_FIRMWARE }, { .type = AMD_FW_PSP_SMU_FIRMWARE, .subprog = 1 },
{ .type = AMD_FW_PSP_SMU_FN_FIRMWARE2 }, { .type = AMD_FW_PSP_SMU_FIRMWARE2, .subprog = 1 },
{ .type = AMD_FW_PSP_SMU_FIRMWARE2 }, { .type = AMD_FW_PSP_SMU_FIRMWARE2 },
{ .type = AMD_FW_PSP_SMUSCS }, { .type = AMD_FW_PSP_SMUSCS },
{ .type = AMD_PSP_FUSE_CHAIN }, { .type = AMD_PSP_FUSE_CHAIN },
@ -267,7 +265,9 @@ typedef struct _psp_directory_header {
} __attribute__((packed, aligned(16))) psp_directory_header; } __attribute__((packed, aligned(16))) psp_directory_header;
typedef struct _psp_directory_entry { typedef struct _psp_directory_entry {
uint32_t type; /* b[15:8] may be a modifier, e.g. subprogram */ uint8_t type;
uint8_t subprog;
uint16_t rsvd;
uint32_t size; uint32_t size;
uint64_t addr; /* or a value in some cases */ uint64_t addr; /* or a value in some cases */
} __attribute__((packed)) psp_directory_entry; } __attribute__((packed)) psp_directory_entry;
@ -449,6 +449,8 @@ static void integrate_psp_firmwares(context *ctx,
for (i = 0, count = 0; fw_table[i].type != AMD_FW_INVALID; i++) { for (i = 0, count = 0; fw_table[i].type != AMD_FW_INVALID; i++) {
if (fw_table[i].type == AMD_PSP_FUSE_CHAIN) { if (fw_table[i].type == AMD_PSP_FUSE_CHAIN) {
pspdir->entries[count].type = fw_table[i].type; pspdir->entries[count].type = fw_table[i].type;
pspdir->entries[count].subprog = fw_table[i].subprog;
pspdir->entries[count].rsvd = 0;
pspdir->entries[count].size = 0xFFFFFFFF; pspdir->entries[count].size = 0xFFFFFFFF;
pspdir->entries[count].addr = 1; pspdir->entries[count].addr = 1;
count++; count++;
@ -461,6 +463,8 @@ static void integrate_psp_firmwares(context *ctx,
} }
pspdir->entries[count].type = fw_table[i].type; pspdir->entries[count].type = fw_table[i].type;
pspdir->entries[count].subprog = fw_table[i].subprog;
pspdir->entries[count].rsvd = 0;
pspdir->entries[count].size = (uint32_t)bytes; pspdir->entries[count].size = (uint32_t)bytes;
pspdir->entries[count].addr = RUN_CURRENT(*ctx); pspdir->entries[count].addr = RUN_CURRENT(*ctx);
@ -481,7 +485,7 @@ static void integrate_psp_firmwares(context *ctx,
fill_dir_header(pspdir, count, PSP_COOKIE); fill_dir_header(pspdir, count, PSP_COOKIE);
} }
static const char *optstring = "x:i:g:Ap:b:s:r:k:c:n:d:t:u:w:e:j:m:o:f:l:h"; static const char *optstring = "x:i:g:AS:p:b:s:r:k:c:n:d:t:u:w:e:j:m:o:f:l:h";
static struct option long_options[] = { static struct option long_options[] = {
{"xhci", required_argument, 0, 'x' }, {"xhci", required_argument, 0, 'x' },
@ -489,6 +493,7 @@ static struct option long_options[] = {
{"gec", required_argument, 0, 'g' }, {"gec", required_argument, 0, 'g' },
/* PSP */ /* PSP */
{"combo-capable", no_argument, 0, 'A' }, {"combo-capable", no_argument, 0, 'A' },
{"subprogram", required_argument, 0, 'S' },
{"pubkey", required_argument, 0, 'p' }, {"pubkey", required_argument, 0, 'p' },
{"bootloader", required_argument, 0, 'b' }, {"bootloader", required_argument, 0, 'b' },
{"smufirmware", required_argument, 0, 's' }, {"smufirmware", required_argument, 0, 's' },
@ -511,7 +516,7 @@ static struct option long_options[] = {
{NULL, 0, 0, 0 } {NULL, 0, 0, 0 }
}; };
static void register_fw_filename(amd_fw_type type, char filename[]) static void register_fw_filename(amd_fw_type type, uint8_t sub, char filename[])
{ {
unsigned int i; unsigned int i;
@ -523,7 +528,10 @@ static void register_fw_filename(amd_fw_type type, char filename[])
} }
for (i = 0; i < sizeof(amd_psp_fw_table) / sizeof(amd_fw_entry); i++) { for (i = 0; i < sizeof(amd_psp_fw_table) / sizeof(amd_fw_entry); i++) {
if (amd_psp_fw_table[i].type == type) { if (amd_psp_fw_table[i].type != type)
continue;
if (amd_psp_fw_table[i].subprog == sub) {
amd_psp_fw_table[i].filename = filename; amd_psp_fw_table[i].filename = filename;
return; return;
} }
@ -547,6 +555,7 @@ int main(int argc, char **argv)
uint32_t dir_location = 0; uint32_t dir_location = 0;
uint32_t romsig_offset; uint32_t romsig_offset;
uint32_t rom_base_address; uint32_t rom_base_address;
uint8_t sub = 0;
while (1) { while (1) {
int optindex = 0; int optindex = 0;
@ -558,60 +567,89 @@ int main(int argc, char **argv)
switch (c) { switch (c) {
case 'x': case 'x':
register_fw_filename(AMD_FW_XHCI, optarg); register_fw_filename(AMD_FW_XHCI, sub, optarg);
sub = 0; /* subprogram is N/A but clear anyway */
break; break;
case 'i': case 'i':
register_fw_filename(AMD_FW_IMC, optarg); register_fw_filename(AMD_FW_IMC, sub, optarg);
sub = 0; /* subprogram is N/A but clear anyway */
break; break;
case 'g': case 'g':
register_fw_filename(AMD_FW_GEC, optarg); register_fw_filename(AMD_FW_GEC, sub, optarg);
sub = 0; /* subprogram is N/A but clear anyway */
break; break;
case 'A': case 'A':
comboable = 1; comboable = 1;
break; break;
case 'S':
sub = (uint8_t)strtoul(optarg, &tmp, 16);
break;
case 'p': case 'p':
register_fw_filename(AMD_FW_PSP_PUBKEY, optarg); register_fw_filename(AMD_FW_PSP_PUBKEY, sub, optarg);
sub = 0;
break; break;
case 'b': case 'b':
register_fw_filename(AMD_FW_PSP_BOOTLOADER, optarg); register_fw_filename(AMD_FW_PSP_BOOTLOADER,
sub, optarg);
sub = 0;
break; break;
case 's': case 's':
register_fw_filename(AMD_FW_PSP_SMU_FIRMWARE, optarg); register_fw_filename(AMD_FW_PSP_SMU_FIRMWARE,
sub, optarg);
sub = 0;
break; break;
case 'j': case 'j':
register_fw_filename(AMD_FW_PSP_SMU_FN_FIRMWARE, /* todo: remove the fanless option */
optarg); register_fw_filename(AMD_FW_PSP_SMU_FIRMWARE,
1, optarg);
sub = 0;
break; break;
case 'r': case 'r':
register_fw_filename(AMD_FW_PSP_RECOVERY, optarg); register_fw_filename(AMD_FW_PSP_RECOVERY, sub, optarg);
sub = 0;
break; break;
case 'k': case 'k':
register_fw_filename(AMD_FW_PSP_RTM_PUBKEY, optarg); register_fw_filename(AMD_FW_PSP_RTM_PUBKEY,
sub, optarg);
sub = 0;
break; break;
case 'c': case 'c':
register_fw_filename(AMD_FW_PSP_SECURED_OS, optarg); register_fw_filename(AMD_FW_PSP_SECURED_OS,
sub, optarg);
sub = 0;
break; break;
case 'n': case 'n':
register_fw_filename(AMD_FW_PSP_NVRAM, optarg); register_fw_filename(AMD_FW_PSP_NVRAM, sub, optarg);
sub = 0;
break; break;
case 'd': case 'd':
register_fw_filename(AMD_FW_PSP_SECURED_DEBUG, optarg); register_fw_filename(AMD_FW_PSP_SECURED_DEBUG,
sub, optarg);
sub = 0;
break; break;
case 't': case 't':
register_fw_filename(AMD_FW_PSP_TRUSTLETS, optarg); register_fw_filename(AMD_FW_PSP_TRUSTLETS, sub, optarg);
sub = 0;
break; break;
case 'u': case 'u':
register_fw_filename(AMD_FW_PSP_TRUSTLETKEY, optarg); register_fw_filename(AMD_FW_PSP_TRUSTLETKEY,
sub, optarg);
sub = 0;
break; break;
case 'w': case 'w':
register_fw_filename(AMD_FW_PSP_SMU_FIRMWARE2, optarg); register_fw_filename(AMD_FW_PSP_SMU_FIRMWARE2,
sub, optarg);
sub = 0;
break; break;
case 'e': case 'e':
register_fw_filename(AMD_FW_PSP_SMU_FN_FIRMWARE2, /* todo: remove the fanless option */
optarg); register_fw_filename(AMD_FW_PSP_SMU_FIRMWARE2,
1, optarg);
sub = 0;
break; break;
case 'm': case 'm':
register_fw_filename(AMD_FW_PSP_SMUSCS, optarg); register_fw_filename(AMD_FW_PSP_SMUSCS, sub, optarg);
sub = 0;
break; break;
case 'o': case 'o':
output = optarg; output = optarg;