diff options
-rw-r--r-- | util/amdfwtool/amdfwtool.c | 76 | ||||
-rw-r--r-- | util/amdfwtool/amdfwtool.h | 12 | ||||
-rw-r--r-- | util/amdfwtool/data_parse.c | 51 |
3 files changed, 124 insertions, 15 deletions
diff --git a/util/amdfwtool/amdfwtool.c b/util/amdfwtool/amdfwtool.c index 5ae6d06186..f167e5ed1a 100644 --- a/util/amdfwtool/amdfwtool.c +++ b/util/amdfwtool/amdfwtool.c @@ -239,14 +239,27 @@ amd_fw_entry amd_psp_fw_table[] = { { .type = AMD_FW_PSP_SMUSCS, .level = PSP_BOTH }, { .type = AMD_PSP_FUSE_CHAIN, .level = PSP_LVL2 }, { .type = AMD_DEBUG_UNLOCK, .level = PSP_LVL2 }, + { .type = AMD_HW_IPCFG, .level = PSP_LVL2 }, { .type = AMD_WRAPPED_IKEK, .level = PSP_BOTH }, { .type = AMD_TOKEN_UNLOCK, .level = PSP_BOTH }, + { .type = AMD_SEC_GASKET, .subprog = 0, .level = PSP_BOTH }, { .type = AMD_SEC_GASKET, .subprog = 2, .level = PSP_BOTH }, { .type = AMD_SEC_GASKET, .subprog = 1, .level = PSP_BOTH }, { .type = AMD_MP2_FW, .subprog = 2, .level = PSP_LVL2 }, { .type = AMD_MP2_FW, .subprog = 1, .level = PSP_LVL2 }, + { .type = AMD_MP2_FW, .subprog = 0, .level = PSP_LVL2 }, { .type = AMD_DRIVER_ENTRIES, .level = PSP_LVL2 }, + { .type = AMD_FW_KVM_IMAGE, .level = PSP_LVL2}, { .type = AMD_S0I3_DRIVER, .level = PSP_LVL2 }, + { .type = AMD_VBIOS_BTLOADER, .level = PSP_BOTH }, + { .type = AMD_FW_TOS_SEC_POLICY, .level = PSP_BOTH }, + { .type = AMD_FW_USB_PHY, .level = PSP_LVL2 }, + { .type = AMD_FW_DRTM_TA, .level = PSP_LVL2 }, + { .type = AMD_FW_KEYDB_BL, .level = PSP_BOTH }, + { .type = AMD_FW_KEYDB_TOS, .level = PSP_LVL2 }, + { .type = AMD_FW_DMCU_ERAM, .level = PSP_LVL2 }, + { .type = AMD_FW_DMCU_ISR, .level = PSP_LVL2 }, + { .type = AMD_RPMC_NVRAM, .level = PSP_LVL2 }, { .type = AMD_ABL0, .level = PSP_BOTH }, { .type = AMD_ABL1, .level = PSP_BOTH }, { .type = AMD_ABL2, .level = PSP_BOTH }, @@ -271,6 +284,7 @@ amd_fw_entry amd_fw_table[] = { }; amd_bios_entry amd_bios_table[] = { + { .type = AMD_BIOS_RTM_PUBKEY, .inst = 0, .level = BDT_BOTH }, { .type = AMD_BIOS_APCB, .inst = 0, .level = BDT_BOTH }, { .type = AMD_BIOS_APCB, .inst = 1, .level = BDT_BOTH }, { .type = AMD_BIOS_APCB, .inst = 2, .level = BDT_BOTH }, @@ -366,7 +380,7 @@ typedef struct _psp_directory_header { uint32_t cookie; uint32_t checksum; uint32_t num_entries; - uint32_t reserved; + uint32_t additional_info; } __attribute__((packed, aligned(16))) psp_directory_header; typedef struct _psp_directory_entry { @@ -409,7 +423,7 @@ typedef struct _bios_directory_hdr { uint32_t cookie; uint32_t checksum; uint32_t num_entries; - uint32_t reserved; + uint32_t additional_info; } __attribute__((packed, aligned(16))) bios_directory_hdr; typedef struct _bios_directory_entry { @@ -462,6 +476,7 @@ static void *new_psp_dir(context *ctx, int multi) ctx->current = ALIGN(ctx->current, TABLE_ALIGNMENT); ptr = BUFF_CURRENT(*ctx); + ((psp_directory_header *)ptr)->additional_info = ctx->current; ctx->current += sizeof(psp_directory_header) + MAX_PSP_ENTRIES * sizeof(psp_directory_entry); return ptr; @@ -480,15 +495,20 @@ static void *new_combo_dir(context *ctx) } #endif -static void fill_dir_header(void *directory, uint32_t count, uint32_t cookie) +static void fill_dir_header(void *directory, uint32_t count, uint32_t cookie, context *ctx) { psp_combo_directory *cdir = directory; psp_directory_table *dir = directory; bios_directory_table *bdir = directory; + uint32_t table_size = 0; if (!count) return; + /* The table size needs to be 0x1000 aligned. So align the end of table. */ + if (ctx != NULL) + ctx->current = ALIGN(ctx->current, TABLE_ALIGNMENT); + switch (cookie) { case PSP2_COOKIE: /* caller is responsible for lookup mode */ @@ -505,27 +525,38 @@ static void fill_dir_header(void *directory, uint32_t count, uint32_t cookie) break; case PSP_COOKIE: case PSPL2_COOKIE: + table_size = ctx->current - dir->header.additional_info; + if ((table_size % TABLE_ALIGNMENT) != 0) { + fprintf(stderr, "The PSP table size should be 4K aligned\n"); + exit(1); + } dir->header.cookie = cookie; dir->header.num_entries = count; - dir->header.reserved = 0; + dir->header.additional_info = (table_size / 0x1000) | (1 << 10); /* checksum everything that comes after the Checksum field */ dir->header.checksum = fletcher32(&dir->header.num_entries, count * sizeof(psp_directory_entry) + sizeof(dir->header.num_entries) - + sizeof(dir->header.reserved)); + + sizeof(dir->header.additional_info)); break; case BDT1_COOKIE: case BDT2_COOKIE: + table_size = ctx->current - bdir->header.additional_info; + if ((table_size % TABLE_ALIGNMENT) != 0) { + fprintf(stderr, "The BIOS table size should be 4K aligned\n"); + exit(1); + } bdir->header.cookie = cookie; bdir->header.num_entries = count; - bdir->header.reserved = 0; + bdir->header.additional_info = (table_size / 0x1000) | (1 << 10); /* checksum everything that comes after the Checksum field */ bdir->header.checksum = fletcher32(&bdir->header.num_entries, count * sizeof(bios_directory_entry) + sizeof(bdir->header.num_entries) - + sizeof(bdir->header.reserved)); + + sizeof(bdir->header.additional_info)); break; } + } static ssize_t copy_blob(void *dest, const char *src_file, size_t room) @@ -678,7 +709,7 @@ static void integrate_psp_firmwares(context *ctx, else level = PSP_BOTH; - ctx->current = ALIGN(ctx->current, BLOB_ALIGNMENT); + ctx->current = ALIGN(ctx->current, TABLE_ALIGNMENT); for (i = 0, count = 0; fw_table[i].type != AMD_FW_INVALID; i++) { if (!(fw_table[i].level & level)) @@ -767,7 +798,7 @@ static void integrate_psp_firmwares(context *ctx, exit(1); } - fill_dir_header(pspdir, count, cookie); + fill_dir_header(pspdir, count, cookie, ctx); } static void *new_bios_dir(context *ctx, int multi) @@ -784,6 +815,7 @@ static void *new_bios_dir(context *ctx, int multi) else ctx->current = ALIGN(ctx->current, TABLE_ALIGNMENT); ptr = BUFF_CURRENT(*ctx); + ((bios_directory_hdr *) ptr)->additional_info = ctx->current; ctx->current += sizeof(bios_directory_hdr) + MAX_BIOS_ENTRIES * sizeof(bios_directory_entry); return ptr; @@ -858,7 +890,7 @@ static void integrate_bios_firmwares(context *ctx, else level = BDT_BOTH; - ctx->current = ALIGN(ctx->current, BLOB_ALIGNMENT); + ctx->current = ALIGN(ctx->current, TABLE_ALIGNMENT); for (i = 0, count = 0; fw_table[i].type != AMD_BIOS_INVALID; i++) { if (!(fw_table[i].level & level)) @@ -986,7 +1018,6 @@ static void integrate_bios_firmwares(context *ctx, fw_table[i].type == AMD_BIOS_APCB_BK) ctx->current = ALIGN( ctx->current, ERASE_ALIGNMENT); - bytes = copy_blob(BUFF_CURRENT(*ctx), fw_table[i].filename, BUFF_ROOM(*ctx)); if (bytes <= 0) { @@ -1028,7 +1059,7 @@ static void integrate_bios_firmwares(context *ctx, exit(1); } - fill_dir_header(biosdir, count, cookie); + fill_dir_header(biosdir, count, cookie, ctx); } enum { @@ -1176,6 +1207,7 @@ enum platform { PLATFORM_RAVEN, PLATFORM_PICASSO, PLATFORM_RENOIR, + PLATFORM_CEZANNE, PLATFORM_LUCIENNE, }; @@ -1212,6 +1244,7 @@ static int set_efs_table(uint8_t soc_id, embedded_firmware *amd_romsig, break; case PLATFORM_RENOIR: case PLATFORM_LUCIENNE: + case PLATFORM_CEZANNE: amd_romsig->efs_gen.gen = EFS_SECOND_GEN; amd_romsig->spi_readmode_f17_mod_30_3f = efs_spi_readmode; amd_romsig->spi_fastspeed_f17_mod_30_3f = efs_spi_speed; @@ -1246,6 +1279,8 @@ static int identify_platform(char *soc_name) return PLATFORM_RAVEN; else if (!strcasecmp(soc_name, "Picasso")) return PLATFORM_PICASSO; + else if (!strcasecmp(soc_name, "Cezanne")) + return PLATFORM_CEZANNE; else if (!strcasecmp(soc_name, "Renoir")) return PLATFORM_RENOIR; else if (!strcasecmp(soc_name, "Lucienne")) @@ -1554,7 +1589,6 @@ int main(int argc, char **argv) return 1; } } - ctx.rom = malloc(ctx.rom_size); if (!ctx.rom) { fprintf(stderr, "Error: Failed to allocate memory\n"); @@ -1621,7 +1655,7 @@ int main(int argc, char **argv) combo_dir->entries[0].lvl2_addr = BUFF_TO_RUN(ctx, pspdir); combo_dir->header.lookup = 1; - fill_dir_header(combo_dir, 1, PSP2_COOKIE); + fill_dir_header(combo_dir, 1, PSP2_COOKIE, NULL); #endif if (have_bios_tables(amd_bios_table)) { @@ -1642,7 +1676,19 @@ int main(int argc, char **argv) integrate_bios_firmwares(&ctx, biosdir, 0, amd_bios_table, BDT1_COOKIE); } - amd_romsig->bios1_entry = BUFF_TO_RUN(ctx, biosdir); + switch (soc_id) { + case PLATFORM_RENOIR: + case PLATFORM_LUCIENNE: + case PLATFORM_CEZANNE: + amd_romsig->bios3_entry = BUFF_TO_RUN(ctx, biosdir); + break; + case PLATFORM_STONEYRIDGE: + case PLATFORM_RAVEN: + case PLATFORM_PICASSO: + default: + amd_romsig->bios1_entry = BUFF_TO_RUN(ctx, biosdir); + break; + } } /* Free the filename. */ diff --git a/util/amdfwtool/amdfwtool.h b/util/amdfwtool/amdfwtool.h index 198642c077..6ae4675121 100644 --- a/util/amdfwtool/amdfwtool.h +++ b/util/amdfwtool/amdfwtool.h @@ -26,11 +26,13 @@ typedef enum _amd_fw_type { AMD_PSP_FUSE_CHAIN = 11, AMD_FW_PSP_SMUSCS = 95, AMD_DEBUG_UNLOCK = 0x13, + AMD_HW_IPCFG = 0x20, AMD_WRAPPED_IKEK = 0x21, AMD_TOKEN_UNLOCK = 0x22, AMD_SEC_GASKET = 0x24, AMD_MP2_FW = 0x25, AMD_DRIVER_ENTRIES = 0x28, + AMD_FW_KVM_IMAGE = 0x29, AMD_S0I3_DRIVER = 0x2d, AMD_ABL0 = 0x30, AMD_ABL1 = 0x31, @@ -41,9 +43,18 @@ typedef enum _amd_fw_type { AMD_ABL6 = 0x36, AMD_ABL7 = 0x37, AMD_FW_PSP_WHITELIST = 0x3a, + AMD_VBIOS_BTLOADER = 0x3c, AMD_FW_L2_PTR = 0x40, + AMD_FW_USB_PHY = 0x44, + AMD_FW_TOS_SEC_POLICY = 0x45, + AMD_FW_DRTM_TA = 0x47, + AMD_FW_KEYDB_BL = 0x50, + AMD_FW_KEYDB_TOS = 0x51, AMD_FW_PSP_VERSTAGE = 0x52, AMD_FW_VERSTAGE_SIG = 0x53, + AMD_RPMC_NVRAM = 0x54, + AMD_FW_DMCU_ERAM = 0x58, + AMD_FW_DMCU_ISR = 0x59, AMD_FW_IMC = 0x200, /* Large enough to be larger than the top BHD entry type. */ AMD_FW_GEC, AMD_FW_XHCI, @@ -52,6 +63,7 @@ typedef enum _amd_fw_type { } amd_fw_type; typedef enum _amd_bios_type { + AMD_BIOS_RTM_PUBKEY = 5, AMD_BIOS_APCB = 0x60, AMD_BIOS_APOB = 0x61, AMD_BIOS_BIN = 0x62, diff --git a/util/amdfwtool/data_parse.c b/util/amdfwtool/data_parse.c index 21e7317e22..017c689f13 100644 --- a/util/amdfwtool/data_parse.c +++ b/util/amdfwtool/data_parse.c @@ -90,6 +90,9 @@ static uint8_t find_register_fw_filename_psp_dir(char *fw_name, char *filename, } else if (strcmp(fw_name, "PSP_SMUFW1_SUB0_FILE") == 0) { fw_type = AMD_FW_PSP_SMU_FIRMWARE; subprog = 0; + } else if (strcmp(fw_name, "PSP_HW_IPCFG_FILE") == 0) { + fw_type = AMD_HW_IPCFG; + subprog = 0; } else if (strcmp(fw_name, "PSP_SMUFW1_SUB1_FILE") == 0) { fw_type = AMD_FW_PSP_SMU_FIRMWARE; subprog = 1; @@ -167,12 +170,22 @@ static uint8_t find_register_fw_filename_psp_dir(char *fw_name, char *filename, } else if (strcmp(fw_name, "PSP_IKEK_FILE") == 0) { fw_type = AMD_WRAPPED_IKEK; subprog = 0; + } else if (strcmp(fw_name, "PSP_SECG0_FILE") == 0) { + fw_type = AMD_SEC_GASKET; + subprog = 0; } else if (strcmp(fw_name, "PSP_SECG1_FILE") == 0) { fw_type = AMD_SEC_GASKET; subprog = 1; } else if (strcmp(fw_name, "PSP_SECG2_FILE") == 0) { fw_type = AMD_SEC_GASKET; subprog = 2; + } else if (strcmp(fw_name, "PSP_MP2FW0_FILE") == 0) { + if (cb_config->load_mp2_fw == 1) { + fw_type = AMD_MP2_FW; + subprog = 0; + } else { + fw_type = AMD_FW_SKIP; + } } else if (strcmp(fw_name, "PSP_MP2FW1_FILE") == 0) { if (cb_config->load_mp2_fw == 1) { fw_type = AMD_MP2_FW; @@ -197,10 +210,44 @@ static uint8_t find_register_fw_filename_psp_dir(char *fw_name, char *filename, } else { fw_type = AMD_FW_SKIP; } + } else if (strcmp(fw_name, "AMD_DRIVER_ENTRIES") == 0) { + fw_type = AMD_DRIVER_ENTRIES; + subprog = 0; + } else if (strcmp(fw_name, "VBIOS_BTLOADER_FILE") == 0) { + fw_type = AMD_VBIOS_BTLOADER; + subprog = 0; + } else if (strcmp(fw_name, "SECURE_POLICY_L1_FILE") == 0) { + fw_type = AMD_FW_TOS_SEC_POLICY; + subprog = 0; + } else if (strcmp(fw_name, "UNIFIEDUSB_FILE") == 0) { + fw_type = AMD_FW_USB_PHY; + subprog = 0; + } else if (strcmp(fw_name, "DRTMTA_FILE") == 0) { + fw_type = AMD_FW_DRTM_TA; + subprog = 0; + } else if (strcmp(fw_name, "KEYDBBL_FILE") == 0) { + fw_type = AMD_FW_KEYDB_BL; + subprog = 0; + } else if (strcmp(fw_name, "KEYDB_TOS_FILE") == 0) { + fw_type = AMD_FW_KEYDB_TOS; + subprog = 0; + } else if (strcmp(fw_name, "DMCUERAMDCN21_FILE") == 0) { + fw_type = AMD_FW_DMCU_ERAM; + subprog = 0; + } else if (strcmp(fw_name, "DMCUINTVECTORSDCN21_FILE") == 0) { + fw_type = AMD_FW_DMCU_ISR; + subprog = 0; + } else if (strcmp(fw_name, "PSP_KVM_ENGINE_DUMMY_FILE") == 0) { + fw_type = AMD_FW_KVM_IMAGE; + subprog = 0; + } else if (strcmp(fw_name, "RPMC_FILE") == 0) { + fw_type = AMD_RPMC_NVRAM; + subprog = 0; } else { fw_type = AMD_FW_INVALID; /* TODO: Add more */ } + /* Search and fill the filename */ psp_tableptr = &amd_psp_fw_table[0]; if (fw_type != AMD_FW_SKIP && fw_type != AMD_FW_INVALID) { @@ -261,6 +308,10 @@ static uint8_t find_register_fw_filename_bios_dir(char *fw_name, char *filename, fw_type = AMD_BIOS_PMUD; subprog = 1; instance = 4; + } else if (strcmp(fw_name, "RTM_PUBKEY_FILE") == 0) { + fw_type = AMD_BIOS_RTM_PUBKEY; + subprog = 0; + instance = 0; } else if (strcmp(fw_name, "PSP_MP2CFG_FILE") == 0) { if (cb_config->load_mp2_fw == 1) { fw_type = AMD_BIOS_MP2_CFG; |