summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util/amdfwtool/amdfwtool.c312
1 files changed, 68 insertions, 244 deletions
diff --git a/util/amdfwtool/amdfwtool.c b/util/amdfwtool/amdfwtool.c
index 673f31d79e..58069d30c1 100644
--- a/util/amdfwtool/amdfwtool.c
+++ b/util/amdfwtool/amdfwtool.c
@@ -83,18 +83,21 @@
#define PSP2_COOKIE 0x50535032 /* 'PSP2' */
/*
- Reserved for future.
- TODO: PSP2 is for Combo BIOS, which is the idea that one image supports 2
- kinds of APU.
-*/
-#define PSP2 1
-#if PSP2
-/* Use PSP combo directory or not.
- * Currently we dont have to squeeze 3 PSP directories into 1 image. So
- * we skip the combo directory.
+ * Beginning with Family 15h Models 70h-7F, a.k.a Stoney Ridge, the PSP
+ * can support an optional "combo" implementation. If the PSP sees the
+ * PSP2 cookie, it interprets the table as a roadmap to additional PSP
+ * tables. Using this, support for multiple product generations may be
+ * built into one image. If the PSP$ cookie is found, the table is a
+ * normal directory table.
+ *
+ * Modern generations supporting the combo directories require the
+ * pointer to be at offset 0x14 of the Embedded Firmware Structure,
+ * regardless of the type of directory used. The --combo-capable
+ * argument enforces this placement.
+ *
+ * TODO: Future work may require fully implementing the PSP_COMBO feature.
*/
- #define PSP_COMBO 0
-#endif
+#define PSP_COMBO 0
typedef unsigned long long int uint64_t;
typedef unsigned int uint32_t;
@@ -180,25 +183,6 @@ static void usage(void)
printf("-w | --smufirmware2 <FILE> Add smufirmware2\n");
printf("-e | --smufnfirmware2 <FILE> Add fanless smufirmware2\n");
printf("-m | --smuscs <FILE> Add smuscs\n");
-
-#if PSP2
- printf("\nPSP2 options:\n");
- printf("-P | --pubkey2 <FILE> Add pubkey\n");
- printf("-B | --bootloader2 <FILE> Add bootloader\n");
- printf("-S | --smufirmware_2 <FILE> Add smufirmware\n");
- printf("-L | --smufnfirmware_2 <FILE> Add fanless smufirmware\n");
- printf("-R | --recovery2 <FILE> Add recovery\n");
- printf("-K | --rtmpubkey2 <FILE> Add rtmpubkey\n");
- printf("-C | --secureos2 <FILE> Add secureos\n");
- printf("-N | --nvram2 <FILE> Add nvram\n");
- printf("-D | --securedebug2 <FILE> Add securedebug\n");
- printf("-T | --trustlets2 <FILE> Add trustlets\n");
- printf("-U | --trustletkey2 <FILE> Add trustletkey\n");
- printf("-W | --smufirmware2_2 <FILE> Add smufirmware2\n");
- printf("-E | --smufnfirmware2_2 <FILE> Add fanless smufirmware2\n");
- printf("-M | --smuscs2 <FILE> Add smuscs\n");
-#endif
-
printf("\n-o | --output <filename> output filename\n");
printf("-f | --flashsize <HEX_VAL> ROM size in bytes\n");
printf(" size must be larger than %dKB\n",
@@ -206,7 +190,6 @@ static void usage(void)
printf(" and must a multiple of 1024\n");
printf("-l | --location Location of Directory\n");
printf("-h | --help show this help\n");
-
}
#define FANLESS_FW 0x100 /* type[15:8]: 0=non-fanless OPNs, 1=fanless */
@@ -258,27 +241,6 @@ static amd_fw_entry amd_psp_fw_table[] = {
{ .type = AMD_FW_INVALID },
};
-#if PSP2
-static amd_fw_entry amd_psp2_fw_table[] = {
- { .type = AMD_FW_PSP_PUBKEY },
- { .type = AMD_FW_PSP_BOOTLOADER },
- { .type = AMD_FW_PSP_SMU_FIRMWARE },
- { .type = AMD_FW_PSP_RECOVERY },
- { .type = AMD_FW_PSP_RTM_PUBKEY },
- { .type = AMD_FW_PSP_SECURED_OS },
- { .type = AMD_FW_PSP_NVRAM },
- { .type = AMD_FW_PSP_SECURED_DEBUG },
- { .type = AMD_FW_PSP_TRUSTLETS },
- { .type = AMD_FW_PSP_TRUSTLETKEY },
- { .type = AMD_FW_PSP_SMU_FN_FIRMWARE },
- { .type = AMD_FW_PSP_SMU_FN_FIRMWARE2 },
- { .type = AMD_FW_PSP_SMU_FIRMWARE2 },
- { .type = AMD_FW_PSP_SMUSCS },
- { .type = AMD_PSP_FUSE_CHAIN },
- { .type = AMD_FW_INVALID },
-};
-#endif
-
static amd_fw_entry amd_fw_table[] = {
{ .type = AMD_FW_XHCI },
{ .type = AMD_FW_IMC },
@@ -476,12 +438,7 @@ static uint32_t integrate_psp_firmwares(char *base, uint32_t pos,
return pos;
}
-#if PSP2
-static const char *optstring =
- "x:i:g:Ap:b:s:r:k:c:n:d:t:u:w:e:j:m:P:B:S:L:R:K:C:N:D:T:U:W:E:M:o:f:l:h";
-#else
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";
-#endif
static struct option long_options[] = {
{"xhci", required_argument, 0, 'x' },
@@ -503,25 +460,6 @@ static struct option long_options[] = {
{"smufirmware2", required_argument, 0, 'w' },
{"smufnfirmware2", required_argument, 0, 'e' },
{"smuscs", required_argument, 0, 'm' },
-
- /* TODO: PSP2 */
-#if PSP2
- {"pubkey2", required_argument, 0, 'P' },
- {"bootloader2", required_argument, 0, 'B' },
- {"smufirmware_2", required_argument, 0, 'S' },
- {"smufnfirmware_2", required_argument, 0, 'L' },
- {"recovery2", required_argument, 0, 'R' },
- {"rtmpubkey2", required_argument, 0, 'K' },
- {"secureos2", required_argument, 0, 'C' },
- {"nvram2", required_argument, 0, 'N' },
- {"securedebug2", required_argument, 0, 'D' },
- {"trustlets2", required_argument, 0, 'T' },
- {"trustletkey2", required_argument, 0, 'U' },
- {"smufirmware2_2", required_argument, 0, 'W' },
- {"smufnfirmware2_2", required_argument, 0, 'E' },
- {"smuscs2", required_argument, 0, 'M' },
-#endif
-
{"output", required_argument, 0, 'o' },
{"flashsize", required_argument, 0, 'f' },
{"location", required_argument, 0, 'l' },
@@ -530,7 +468,7 @@ static struct option long_options[] = {
{NULL, 0, 0, 0 }
};
-static void register_fw_filename(amd_fw_type type, char filename[], int pspflag)
+static void register_fw_filename(amd_fw_type type, char filename[])
{
unsigned int i;
@@ -541,42 +479,19 @@ static void register_fw_filename(amd_fw_type type, char filename[], int pspflag)
}
}
- if (pspflag == 1) {
- for (i = 0; i < sizeof(amd_psp_fw_table) /
- sizeof(amd_fw_entry); i++) {
- if (amd_psp_fw_table[i].type == type) {
- amd_psp_fw_table[i].filename = filename;
- return;
- }
- }
- }
-
-#if PSP2
- if (pspflag == 2) {
- for (i = 0; i < sizeof(amd_psp2_fw_table) /
- sizeof(amd_fw_entry); i++) {
- if (amd_psp2_fw_table[i].type == type) {
- amd_psp2_fw_table[i].filename = filename;
- return;
- }
+ for (i = 0; i < sizeof(amd_psp_fw_table) / sizeof(amd_fw_entry); i++) {
+ if (amd_psp_fw_table[i].type == type) {
+ amd_psp_fw_table[i].filename = filename;
+ return;
}
}
-#endif
}
int main(int argc, char **argv)
{
- int c, pspflag = 0;
+ int c;
int retval = 0;
-#if PSP2
- int psp2flag = 0;
- psp_directory_table *psp2dir;
char *tmp;
-#endif
-#if PSP_COMBO
- int psp2count;
-#endif
-
char *rom = NULL;
uint32_t current;
embedded_firmware *amd_romsig;
@@ -600,141 +515,61 @@ int main(int argc, char **argv)
switch (c) {
case 'x':
- register_fw_filename(AMD_FW_XHCI, optarg, 0);
+ register_fw_filename(AMD_FW_XHCI, optarg);
break;
case 'i':
- register_fw_filename(AMD_FW_IMC, optarg, 0);
+ register_fw_filename(AMD_FW_IMC, optarg);
break;
case 'g':
- register_fw_filename(AMD_FW_GEC, optarg, 0);
+ register_fw_filename(AMD_FW_GEC, optarg);
break;
case 'A':
comboable = 1;
break;
case 'p':
- register_fw_filename(AMD_FW_PSP_PUBKEY, optarg, 1);
- pspflag = 1;
+ register_fw_filename(AMD_FW_PSP_PUBKEY, optarg);
break;
case 'b':
- register_fw_filename(AMD_FW_PSP_BOOTLOADER, optarg, 1);
- pspflag = 1;
+ register_fw_filename(AMD_FW_PSP_BOOTLOADER, optarg);
break;
case 's':
- register_fw_filename(AMD_FW_PSP_SMU_FIRMWARE,
- optarg, 1);
- pspflag = 1;
+ register_fw_filename(AMD_FW_PSP_SMU_FIRMWARE, optarg);
break;
case 'j':
register_fw_filename(AMD_FW_PSP_SMU_FN_FIRMWARE,
- optarg, 1);
- pspflag = 1;
+ optarg);
break;
case 'r':
- register_fw_filename(AMD_FW_PSP_RECOVERY, optarg, 1);
- pspflag = 1;
+ register_fw_filename(AMD_FW_PSP_RECOVERY, optarg);
break;
case 'k':
- register_fw_filename(AMD_FW_PSP_RTM_PUBKEY, optarg, 1);
- pspflag = 1;
+ register_fw_filename(AMD_FW_PSP_RTM_PUBKEY, optarg);
break;
case 'c':
- register_fw_filename(AMD_FW_PSP_SECURED_OS, optarg, 1);
- pspflag = 1;
+ register_fw_filename(AMD_FW_PSP_SECURED_OS, optarg);
break;
case 'n':
- register_fw_filename(AMD_FW_PSP_NVRAM, optarg, 1);
- pspflag = 1;
+ register_fw_filename(AMD_FW_PSP_NVRAM, optarg);
break;
case 'd':
- register_fw_filename(AMD_FW_PSP_SECURED_DEBUG,
- optarg, 1);
- pspflag = 1;
+ register_fw_filename(AMD_FW_PSP_SECURED_DEBUG, optarg);
break;
case 't':
- register_fw_filename(AMD_FW_PSP_TRUSTLETS, optarg, 1);
- pspflag = 1;
+ register_fw_filename(AMD_FW_PSP_TRUSTLETS, optarg);
break;
case 'u':
- register_fw_filename(AMD_FW_PSP_TRUSTLETKEY, optarg, 1);
- pspflag = 1;
+ register_fw_filename(AMD_FW_PSP_TRUSTLETKEY, optarg);
break;
case 'w':
- register_fw_filename(AMD_FW_PSP_SMU_FIRMWARE2,
- optarg, 1);
- pspflag = 1;
+ register_fw_filename(AMD_FW_PSP_SMU_FIRMWARE2, optarg);
break;
case 'e':
register_fw_filename(AMD_FW_PSP_SMU_FN_FIRMWARE2,
- optarg, 1);
- pspflag = 1;
+ optarg);
break;
case 'm':
- register_fw_filename(AMD_FW_PSP_SMUSCS, optarg, 1);
- pspflag = 1;
- break;
-#if PSP2
- case 'P':
- register_fw_filename(AMD_FW_PSP_PUBKEY, optarg, 2);
- psp2flag = 1;
- break;
- case 'B':
- register_fw_filename(AMD_FW_PSP_BOOTLOADER, optarg, 2);
- psp2flag = 1;
- break;
- case 'S':
- register_fw_filename(AMD_FW_PSP_SMU_FIRMWARE,
- optarg, 2);
- psp2flag = 1;
- break;
- case 'L':
- register_fw_filename(AMD_FW_PSP_SMU_FN_FIRMWARE,
- optarg, 2);
- psp2flag = 1;
- break;
- case 'R':
- register_fw_filename(AMD_FW_PSP_RECOVERY, optarg, 2);
- psp2flag = 1;
- break;
- case 'K':
- register_fw_filename(AMD_FW_PSP_RTM_PUBKEY, optarg, 2);
- psp2flag = 1;
- break;
- case 'C':
- register_fw_filename(AMD_FW_PSP_SECURED_OS, optarg, 2);
- psp2flag = 1;
+ register_fw_filename(AMD_FW_PSP_SMUSCS, optarg);
break;
- case 'N':
- register_fw_filename(AMD_FW_PSP_NVRAM, optarg, 2);
- psp2flag = 1;
- break;
- case 'D':
- register_fw_filename(AMD_FW_PSP_SECURED_DEBUG,
- optarg, 2);
- psp2flag = 1;
- break;
- case 'T':
- register_fw_filename(AMD_FW_PSP_TRUSTLETS, optarg, 2);
- psp2flag = 1;
- break;
- case 'U':
- register_fw_filename(AMD_FW_PSP_TRUSTLETKEY, optarg, 2);
- psp2flag = 1;
- break;
- case 'W':
- register_fw_filename(AMD_FW_PSP_SMU_FIRMWARE2,
- optarg, 2);
- psp2flag = 1;
- break;
- case 'E':
- register_fw_filename(AMD_FW_PSP_SMU_FN_FIRMWARE2,
- optarg, 2);
- psp2flag = 1;
- break;
- case 'M':
- register_fw_filename(AMD_FW_PSP_SMUSCS, optarg, 2);
- psp2flag = 1;
- break;
-#endif
case 'o':
output = optarg;
break;
@@ -838,55 +673,44 @@ int main(int argc, char **argv)
amd_fw_table, rom_size);
current = ALIGN(current, 0x10000U);
- if (psp2flag || comboable)
+ if (comboable)
amd_romsig->comboable = current + rom_base_address;
else
amd_romsig->psp_entry = current + rom_base_address;
- if (pspflag == 1) {
- pspdir = (void *)(rom + current);
- current += 0x200; /* Conservative size of pspdir */
- current = integrate_psp_firmwares(rom, current, pspdir,
- amd_psp_fw_table, rom_size);
- }
-
-#if PSP2
- if (psp2flag == 1) {
- psp2dir = (void *)(rom + current);
- current += 0x200; /* Add conservative size of psp2dir. */
-
#if PSP_COMBO
- /* TODO: remove the hardcode. */
- psp_combo_directory *combo_dir = (psp_combo_directory *)psp2dir;
- combo_dir->entries[0].id_sel = 0; /* 0 -Compare PSP ID, 1 -Compare chip family ID */
- combo_dir->entries[0].id = 0x10220B00; /* TODO: PSP ID. Documentation is needed. */
- combo_dir->entries[0].lvl2_addr = current + rom_base_address;
- pspdir = (psp_directory_table *)(rom + current);
-
- current += 0x200; /* Add conservative size of pspdir. Start of PSP entries. */
- current = integrate_psp_firmwares(rom, current, pspdir,
- amd_psp2_fw_table, rom_size);
-
- /* fill the PSP combo head */
- combo_dir->header.cookie = PSP2_COOKIE;
- combo_dir->header.num_entries = 1;
- combo_dir->header.lookup = 1;
- combo_dir->header.reserved[0] = 0;
- combo_dir->header.reserved[1] = 0;
- combo_dir->header.checksum = fletcher32(
- (void *)&combo_dir->header.num_entries,
- 1 * sizeof(psp_directory_entry)
- + sizeof(combo_dir->header.num_entries)
- + sizeof(combo_dir->header.lookup)
- + sizeof(combo_dir->header.reserved[0])
- + sizeof(combo_dir->header.reserved[1]));
-#else
- current = integrate_psp_firmwares(rom, current, psp2dir,
- amd_psp2_fw_table, rom_size);
-#endif
- }
+ /* TODO: remove the hardcode. */
+ psp_combo_directory *combo_dir =
+ (psp_combo_directory *)(rom + current);
+ current = ALIGN(current + sizeof(psp_combo_header)
+ + 1 * sizeof(psp_combo_entry), 0x1000);
+ /* 0 -Compare PSP ID, 1 -Compare chip family ID */
+ combo_dir->entries[0].id_sel = 0;
+ /* TODO: PSP ID. Documentation is needed. */
+ combo_dir->entries[0].id = 0x10220B00;
+ combo_dir->entries[0].lvl2_addr = current + rom_base_address;
+
+ /* fill the PSP combo head */
+ combo_dir->header.cookie = PSP2_COOKIE;
+ combo_dir->header.num_entries = 1;
+ combo_dir->header.lookup = 1;
+ combo_dir->header.reserved[0] = 0;
+ combo_dir->header.reserved[1] = 0;
+ combo_dir->header.checksum = fletcher32(
+ (void *)&combo_dir->header.num_entries,
+ 1 * sizeof(psp_directory_entry)
+ + sizeof(combo_dir->header.num_entries)
+ + sizeof(combo_dir->header.lookup)
+ + sizeof(combo_dir->header.reserved[0])
+ + sizeof(combo_dir->header.reserved[1]));
#endif
+ pspdir = (void *)(rom + current);
+ current += 0x200; /* Conservative size of pspdir */
+ current = integrate_psp_firmwares(rom, current, pspdir,
+ amd_psp_fw_table, rom_size);
+
+
targetfd = open(output, O_RDWR | O_CREAT | O_TRUNC, 0666);
if (targetfd >= 0) {
write(targetfd, amd_romsig, current - romsig_offset);