aboutsummaryrefslogtreecommitdiff
path: root/util/amdfwtool
diff options
context:
space:
mode:
Diffstat (limited to 'util/amdfwtool')
-rw-r--r--util/amdfwtool/Makefile.mk2
-rw-r--r--util/amdfwtool/amdfwtool.c801
-rw-r--r--util/amdfwtool/amdfwtool.h30
-rw-r--r--util/amdfwtool/opts.c722
4 files changed, 795 insertions, 760 deletions
diff --git a/util/amdfwtool/Makefile.mk b/util/amdfwtool/Makefile.mk
index 8198fe3b6e..0b9cc1b644 100644
--- a/util/amdfwtool/Makefile.mk
+++ b/util/amdfwtool/Makefile.mk
@@ -2,7 +2,7 @@
ifneq ($(BUILD_ALL_TOOLS)$(CONFIG_USE_AMDFWTOOL),)
-amdfwtoolobj = amdfwtool.o data_parse.o signed_psp.o handle_file.o
+amdfwtoolobj = amdfwtool.o data_parse.o signed_psp.o handle_file.o opts.o
amdfwreadobj = amdfwread.o
amdfwheader = amdfwtool.h
diff --git a/util/amdfwtool/amdfwtool.c b/util/amdfwtool/amdfwtool.c
index 61ccefb981..0e18fe322b 100644
--- a/util/amdfwtool/amdfwtool.c
+++ b/util/amdfwtool/amdfwtool.c
@@ -80,21 +80,15 @@
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
-#include <getopt.h>
#include <libgen.h>
#include <stdint.h>
#include "amdfwtool.h"
#define AMD_ROMSIG_OFFSET 0x20000
-#define MIN_ROM_KB 256
-#define MAX_MAPPED_WINDOW (16 * MiB)
-#define MAX_MAPPED_WINDOW_MASK (MAX_MAPPED_WINDOW - 1)
#define _MAX(A, B) (((A) > (B)) ? (A) : (B))
-#define DEFAULT_SOFT_FUSE_CHAIN "0x1"
-
static void output_manifest(int manifest_fd, amd_fw_entry *fw_entry);
/*
@@ -165,82 +159,6 @@ static uint32_t fletcher32(const void *data, int length)
return checksum;
}
-static void usage(void)
-{
- printf("amdfwtool: Create AMD Firmware combination\n");
- printf("Usage: amdfwtool [options] --flashsize <size> --output <filename>\n");
- printf("--xhci <FILE> Add XHCI blob\n");
- printf("--imc <FILE> Add IMC blob\n");
- printf("--gec <FILE> Add GEC blob\n");
-
- printf("\nPSP options:\n");
- printf("--use-combo Use the COMBO layout\n");
- printf("--combo-config1 <config file> Config for 1st combo entry\n");
- printf("--multilevel Generate primary and secondary tables\n");
- printf("--nvram <FILE> Add nvram binary\n");
- printf("--soft-fuse Set soft fuse\n");
- printf("--token-unlock Set token unlock\n");
- printf("--nvram-base <HEX_VAL> Base address of nvram\n");
- printf("--nvram-size <HEX_VAL> Size of nvram\n");
- printf("--whitelist Set if there is a whitelist\n");
- printf("--use-pspsecureos Set if psp secure OS is needed\n");
- printf("--load-mp2-fw Set if load MP2 firmware\n");
- printf("--load-s0i3 Set if load s0i3 firmware\n");
- printf("--verstage <FILE> Add verstage\n");
- printf("--verstage_sig Add verstage signature\n");
- printf("--recovery-ab Use the recovery A/B layout\n");
- printf("\nBIOS options:\n");
- printf("--instance <number> Sets instance field for the next BIOS\n");
- printf(" firmware\n");
- printf("--apcb <FILE> Add AGESA PSP customization block\n");
- printf("--apcb-combo1 <FILE> Add APCB for 1st combo\n");
- printf("--apob-base <HEX_VAL> Destination for AGESA PSP output block\n");
- printf("--apob-nv-base <HEX_VAL> Location of S3 resume data\n");
- printf("--apob-nv-size <HEX_VAL> Size of S3 resume data\n");
- printf("--ucode <FILE> Add microcode patch\n");
- printf("--bios-bin <FILE> Add compressed image; auto source address\n");
- printf("--bios-bin-src <HEX_VAL> Address in flash of source if -V not used\n");
- printf("--bios-bin-dest <HEX_VAL> Destination for uncompressed BIOS\n");
- printf("--bios-uncomp-size <HEX> Uncompressed size of BIOS image\n");
- printf("--output <filename> output filename\n");
- printf("--flashsize <HEX_VAL> ROM size in bytes\n");
- printf(" size must be larger than %dKB\n",
- MIN_ROM_KB);
- printf(" and must a multiple of 1024\n");
- printf("--location Location of Directory\n");
- printf("--anywhere Use any 64-byte aligned addr for Directory\n");
- printf("--sharedmem Location of PSP/FW shared memory\n");
- printf("--sharedmem-size Maximum size of the PSP/FW shared memory\n");
- printf(" area\n");
- printf("--output-manifest <FILE> Writes a manifest with the blobs versions\n");
- printf("\nEmbedded Firmware Structure options used by the PSP:\n");
- printf("--spi-speed <HEX_VAL> SPI fast speed to place in EFS Table\n");
- printf(" 0x0 66.66Mhz\n");
- printf(" 0x1 33.33MHz\n");
- printf(" 0x2 22.22MHz\n");
- printf(" 0x3 16.66MHz\n");
- printf(" 0x4 100MHz\n");
- printf(" 0x5 800KHz\n");
- printf("--spi-read-mode <HEX_VAL> SPI read mode to place in EFS Table\n");
- printf(" 0x0 Normal Read (up to 33M)\n");
- printf(" 0x1 Reserved\n");
- printf(" 0x2 Dual IO (1-1-2)\n");
- printf(" 0x3 Quad IO (1-1-4)\n");
- printf(" 0x4 Dual IO (1-2-2)\n");
- printf(" 0x5 Quad IO (1-4-4)\n");
- printf(" 0x6 Normal Read (up to 66M)\n");
- printf(" 0x7 Fast Read\n");
- printf("--spi-micron-flag <HEX_VAL> Micron SPI part support for RV and later SOC\n");
- printf(" 0x0 Micron parts are not used\n");
- printf(" 0x1 Micron parts are always used\n");
- printf(" 0x2 Micron parts optional, this option is only\n");
- printf(" supported with RN/LCN SOC\n");
- printf("\nGeneral options:\n");
- printf("-c|--config <config file> Config file\n");
- printf("-d|--debug Print debug message\n");
- printf("-h|--help Show this help\n");
-}
-
amd_fw_entry amd_psp_fw_table[] = {
{ .type = AMD_FW_PSP_PUBKEY, .level = PSP_BOTH | PSP_LVL2_AB, .skip_hashing = true },
{ .type = AMD_FW_PSP_BOOTLOADER, .level = PSP_BOTH | PSP_LVL2_AB,
@@ -445,17 +363,6 @@ amd_bios_entry amd_bios_table[] = {
{ .type = AMD_BIOS_INVALID },
};
-typedef struct _context {
- char *rom; /* target buffer, size of flash device */
- uint32_t rom_size; /* size of flash device */
- uint32_t address_mode; /* 0:abs address; 1:relative to flash; 2: relative to table */
- uint32_t current; /* pointer within flash & proxy buffer */
- uint32_t current_pointer_saved;
- uint32_t current_table;
- void *amd_psp_fw_table_clean;
- void *amd_bios_table_clean;
-} context;
-
#define RUN_BASE(ctx) (0xFFFFFFFF - (ctx).rom_size + 1)
#define RUN_OFFSET_MODE(ctx, offset, mode) \
((mode) == AMD_ADDR_PHYSICAL ? RUN_BASE(ctx) + (offset) : \
@@ -1219,7 +1126,7 @@ static int have_bios_tables(amd_bios_entry *table)
return 0;
}
-static int find_bios_entry(amd_bios_type type)
+int find_bios_entry(amd_bios_type type)
{
int i;
@@ -1491,231 +1398,10 @@ static void integrate_bios_firmwares(context *ctx,
fill_dir_header(biosdir, count, cookie, ctx, cb_config);
}
-enum {
- AMDFW_OPT_CONFIG = 'c',
- AMDFW_OPT_DEBUG = 'd',
- AMDFW_OPT_HELP = 'h',
-
- AMDFW_OPT_XHCI = 128,
- AMDFW_OPT_IMC,
- AMDFW_OPT_GEC,
- AMDFW_OPT_RECOVERY_AB,
- AMDFW_OPT_RECOVERY_AB_SINGLE_COPY,
- AMDFW_OPT_USE_COMBO,
- AMDFW_OPT_COMBO1_CONFIG,
- AMDFW_OPT_MULTILEVEL,
- AMDFW_OPT_NVRAM,
-
- AMDFW_OPT_FUSE,
- AMDFW_OPT_UNLOCK,
- AMDFW_OPT_WHITELIST,
- AMDFW_OPT_USE_PSPSECUREOS,
- AMDFW_OPT_LOAD_MP2FW,
- AMDFW_OPT_LOAD_S0I3,
- AMDFW_OPT_SPL_TABLE,
- AMDFW_OPT_VERSTAGE,
- AMDFW_OPT_VERSTAGE_SIG,
- AMDFW_OPT_OUTPUT_MANIFEST,
-
- AMDFW_OPT_INSTANCE,
- AMDFW_OPT_APCB,
- AMDFW_OPT_APCB_COMBO1,
- AMDFW_OPT_APOBBASE,
- AMDFW_OPT_BIOSBIN,
- AMDFW_OPT_BIOSBIN_SOURCE,
- AMDFW_OPT_BIOSBIN_DEST,
- AMDFW_OPT_BIOS_UNCOMP_SIZE,
- AMDFW_OPT_BIOSBIN_UNCOMP,
- AMDFW_OPT_UCODE,
- AMDFW_OPT_APOB_NVBASE,
- AMDFW_OPT_APOB_NVSIZE,
-
- AMDFW_OPT_OUTPUT,
- AMDFW_OPT_FLASHSIZE,
- AMDFW_OPT_LOCATION,
- AMDFW_OPT_ANYWHERE,
- AMDFW_OPT_SHAREDMEM,
- AMDFW_OPT_SHAREDMEM_SIZE,
- AMDFW_OPT_SIGNED_OUTPUT,
- AMDFW_OPT_SIGNED_ADDR,
- AMDFW_OPT_BODY_LOCATION,
- /* begin after ASCII characters */
- LONGOPT_SPI_READ_MODE = 256,
- LONGOPT_SPI_SPEED = 257,
- LONGOPT_SPI_MICRON_FLAG = 258,
- LONGOPT_BIOS_SIG = 259,
- LONGOPT_NVRAM_BASE = 260,
- LONGOPT_NVRAM_SIZE = 261,
-};
-
-static char const optstring[] = {AMDFW_OPT_CONFIG, ':',
- AMDFW_OPT_DEBUG, AMDFW_OPT_HELP
-};
-
-static struct option long_options[] = {
- {"xhci", required_argument, 0, AMDFW_OPT_XHCI },
- {"imc", required_argument, 0, AMDFW_OPT_IMC },
- {"gec", required_argument, 0, AMDFW_OPT_GEC },
- /* PSP Directory Table items */
- {"recovery-ab", no_argument, 0, AMDFW_OPT_RECOVERY_AB },
- {"recovery-ab-single-copy", no_argument, 0, AMDFW_OPT_RECOVERY_AB_SINGLE_COPY },
- {"use-combo", no_argument, 0, AMDFW_OPT_USE_COMBO },
- {"combo-config1", required_argument, 0, AMDFW_OPT_COMBO1_CONFIG },
- {"multilevel", no_argument, 0, AMDFW_OPT_MULTILEVEL },
- {"nvram", required_argument, 0, AMDFW_OPT_NVRAM },
- {"nvram-base", required_argument, 0, LONGOPT_NVRAM_BASE },
- {"nvram-size", required_argument, 0, LONGOPT_NVRAM_SIZE },
- {"soft-fuse", required_argument, 0, AMDFW_OPT_FUSE },
- {"token-unlock", no_argument, 0, AMDFW_OPT_UNLOCK },
- {"whitelist", required_argument, 0, AMDFW_OPT_WHITELIST },
- {"use-pspsecureos", no_argument, 0, AMDFW_OPT_USE_PSPSECUREOS },
- {"load-mp2-fw", no_argument, 0, AMDFW_OPT_LOAD_MP2FW },
- {"load-s0i3", no_argument, 0, AMDFW_OPT_LOAD_S0I3 },
- {"spl-table", required_argument, 0, AMDFW_OPT_SPL_TABLE },
- {"verstage", required_argument, 0, AMDFW_OPT_VERSTAGE },
- {"verstage_sig", required_argument, 0, AMDFW_OPT_VERSTAGE_SIG },
- {"output-manifest", required_argument, 0, AMDFW_OPT_OUTPUT_MANIFEST },
- /* BIOS Directory Table items */
- {"instance", required_argument, 0, AMDFW_OPT_INSTANCE },
- {"apcb", required_argument, 0, AMDFW_OPT_APCB },
- {"apcb-combo1", required_argument, 0, AMDFW_OPT_APCB_COMBO1 },
- {"apob-base", required_argument, 0, AMDFW_OPT_APOBBASE },
- {"bios-bin", required_argument, 0, AMDFW_OPT_BIOSBIN },
- {"bios-bin-src", required_argument, 0, AMDFW_OPT_BIOSBIN_SOURCE },
- {"bios-bin-dest", required_argument, 0, AMDFW_OPT_BIOSBIN_DEST },
- {"bios-uncomp-size", required_argument, 0, AMDFW_OPT_BIOS_UNCOMP_SIZE },
- {"bios-bin-uncomp", no_argument, 0, AMDFW_OPT_BIOSBIN_UNCOMP },
- {"bios-sig-size", required_argument, 0, LONGOPT_BIOS_SIG },
- {"ucode", required_argument, 0, AMDFW_OPT_UCODE },
- {"apob-nv-base", required_argument, 0, AMDFW_OPT_APOB_NVBASE },
- {"apob-nv-size", required_argument, 0, AMDFW_OPT_APOB_NVSIZE },
- /* Embedded Firmware Structure items*/
- {"spi-read-mode", required_argument, 0, LONGOPT_SPI_READ_MODE },
- {"spi-speed", required_argument, 0, LONGOPT_SPI_SPEED },
- {"spi-micron-flag", required_argument, 0, LONGOPT_SPI_MICRON_FLAG },
- {"body-location", required_argument, 0, AMDFW_OPT_BODY_LOCATION },
- /* other */
- {"output", required_argument, 0, AMDFW_OPT_OUTPUT },
- {"flashsize", required_argument, 0, AMDFW_OPT_FLASHSIZE },
- {"location", required_argument, 0, AMDFW_OPT_LOCATION },
- {"anywhere", no_argument, 0, AMDFW_OPT_ANYWHERE },
- {"sharedmem", required_argument, 0, AMDFW_OPT_SHAREDMEM },
- {"sharedmem-size", required_argument, 0, AMDFW_OPT_SHAREDMEM_SIZE },
-
- {"signed-output", required_argument, 0, AMDFW_OPT_SIGNED_OUTPUT },
- {"signed-addr", required_argument, 0, AMDFW_OPT_SIGNED_ADDR },
-
- {"config", required_argument, 0, AMDFW_OPT_CONFIG },
- {"debug", no_argument, 0, AMDFW_OPT_DEBUG },
- {"help", no_argument, 0, AMDFW_OPT_HELP },
- {NULL, 0, 0, 0 }
-};
-
-void register_fw_fuse(char *str)
-{
- uint32_t i;
-
- for (i = 0; i < sizeof(amd_psp_fw_table) / sizeof(amd_fw_entry); i++) {
- if (amd_psp_fw_table[i].type != AMD_PSP_FUSE_CHAIN)
- continue;
-
- amd_psp_fw_table[i].other = strtoull(str, NULL, 16);
- return;
- }
-}
-
-static void register_fw_token_unlock(void)
-{
- uint32_t i;
-
- for (i = 0; i < sizeof(amd_psp_fw_table) / sizeof(amd_fw_entry); i++) {
- if (amd_psp_fw_table[i].type != AMD_TOKEN_UNLOCK)
- continue;
-
- amd_psp_fw_table[i].other = 1;
- return;
- }
-}
-
-static void register_fw_filename(amd_fw_type type, uint8_t sub, char filename[])
-{
- unsigned int i;
-
- for (i = 0; i < sizeof(amd_fw_table) / sizeof(amd_fw_entry); i++) {
- if (amd_fw_table[i].type == type) {
- amd_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)
- continue;
-
- if (amd_psp_fw_table[i].subprog == sub) {
- amd_psp_fw_table[i].filename = filename;
- return;
- }
- }
-}
-
-static void register_bdt_data(amd_bios_type type, int sub, int ins, char name[])
-{
- uint32_t i;
-
- for (i = 0; i < sizeof(amd_bios_table) / sizeof(amd_bios_entry); i++) {
- if (amd_bios_table[i].type == type
- && amd_bios_table[i].inst == ins
- && amd_bios_table[i].subpr == sub) {
- amd_bios_table[i].filename = name;
- return;
- }
- }
-}
-
-static void register_amd_psp_fw_addr(amd_fw_type type, int sub,
- char *dst_str, char *size_str)
-{
- unsigned int i;
-
- for (i = 0; i < sizeof(amd_psp_fw_table) / sizeof(amd_fw_entry); i++) {
- if (amd_psp_fw_table[i].type != type)
- continue;
-
- if (amd_psp_fw_table[i].subprog == sub) {
- if (dst_str)
- amd_psp_fw_table[i].dest = strtoull(dst_str, NULL, 16);
- if (size_str)
- amd_psp_fw_table[i].size = strtoul(size_str, NULL, 16);
- return;
- }
- }
-}
-
-static void register_bios_fw_addr(amd_bios_type type, char *src_str,
- char *dst_str, char *size_str)
-{
- uint32_t i;
- for (i = 0; i < sizeof(amd_bios_table) / sizeof(amd_bios_entry); i++) {
- if (amd_bios_table[i].type != type)
- continue;
-
- if (src_str)
- amd_bios_table[i].src = strtoull(src_str, NULL, 16);
- if (dst_str)
- amd_bios_table[i].dest = strtoull(dst_str, NULL, 16);
- if (size_str)
- amd_bios_table[i].size = strtoul(size_str, NULL, 16);
-
- return;
- }
-}
-
static int set_efs_table(uint8_t soc_id, amd_cb_config *cb_config,
- embedded_firmware *amd_romsig, uint8_t efs_spi_readmode,
- uint8_t efs_spi_speed, uint8_t efs_spi_micron_flag)
+ embedded_firmware *amd_romsig)
{
- if ((efs_spi_readmode == 0xFF) || (efs_spi_speed == 0xFF)) {
+ if ((cb_config->efs_spi_readmode == 0xFF) || (cb_config->efs_spi_speed == 0xFF)) {
fprintf(stderr, "Error: EFS read mode and SPI speed must be set\n");
return 1;
}
@@ -1733,14 +1419,14 @@ static int set_efs_table(uint8_t soc_id, amd_cb_config *cb_config,
switch (soc_id) {
case PLATFORM_CARRIZO:
case PLATFORM_STONEYRIDGE:
- amd_romsig->spi_readmode_f15_mod_60_6f = efs_spi_readmode;
- amd_romsig->fast_speed_new_f15_mod_60_6f = efs_spi_speed;
+ amd_romsig->spi_readmode_f15_mod_60_6f = cb_config->efs_spi_readmode;
+ amd_romsig->fast_speed_new_f15_mod_60_6f = cb_config->efs_spi_speed;
break;
case PLATFORM_RAVEN:
case PLATFORM_PICASSO:
- amd_romsig->spi_readmode_f17_mod_00_2f = efs_spi_readmode;
- amd_romsig->spi_fastspeed_f17_mod_00_2f = efs_spi_speed;
- switch (efs_spi_micron_flag) {
+ amd_romsig->spi_readmode_f17_mod_00_2f = cb_config->efs_spi_readmode;
+ amd_romsig->spi_fastspeed_f17_mod_00_2f = cb_config->efs_spi_speed;
+ switch (cb_config->efs_spi_micron_flag) {
case 0:
amd_romsig->qpr_dummy_cycle_f17_mod_00_2f = 0xff;
break;
@@ -1759,9 +1445,9 @@ static int set_efs_table(uint8_t soc_id, amd_cb_config *cb_config,
case PLATFORM_PHOENIX:
case PLATFORM_GLINDA:
case PLATFORM_GENOA:
- amd_romsig->spi_readmode_f17_mod_30_3f = efs_spi_readmode;
- amd_romsig->spi_fastspeed_f17_mod_30_3f = efs_spi_speed;
- switch (efs_spi_micron_flag) {
+ amd_romsig->spi_readmode_f17_mod_30_3f = cb_config->efs_spi_readmode;
+ amd_romsig->spi_fastspeed_f17_mod_30_3f = cb_config->efs_spi_speed;
+ switch (cb_config->efs_spi_micron_flag) {
case 0:
amd_romsig->micron_detect_f17_mod_30_3f = 0xff;
break;
@@ -1825,294 +1511,26 @@ static bool is_initial_alignment_required(enum platform soc_id)
int main(int argc, char **argv)
{
- int c;
int retval = 0;
- char *tmp;
embedded_firmware *amd_romsig;
psp_directory_table *pspdir = NULL;
psp_directory_table *pspdir2 = NULL;
psp_directory_table *pspdir2_b = NULL;
psp_combo_directory *psp_combo_dir = NULL, *bhd_combo_dir = NULL;
- char *combo_config[MAX_COMBO_ENTRIES] = { 0 };
- struct _combo_apcb {
- char *filename;
- uint8_t ins;
- uint8_t sub;
- } combo_apcb[MAX_COMBO_ENTRIES] = {0}, combo_apcb_bk[MAX_COMBO_ENTRIES] = {0};
int combo_index = 0;
- int fuse_defined = 0;
int targetfd;
- char *output = NULL, *config = NULL;
context ctx = { 0 };
- /* Values cleared after each firmware or parameter, regardless if N/A */
- uint8_t sub = 0, instance = 0;
- uint32_t body_location = 0;
- uint32_t efs_location = 0;
- bool any_location = 0;
uint32_t romsig_offset;
- uint8_t efs_spi_readmode = 0xff;
- uint8_t efs_spi_speed = 0xff;
- uint8_t efs_spi_micron_flag = 0xff;
- const char *signed_output_file = NULL;
- uint64_t signed_start_addr = 0x0;
-
- amd_cb_config cb_config = { 0 };
- int debug = 0;
- char *manifest_file = NULL;
+ amd_cb_config cb_config = {
+ .efs_spi_readmode = 0xff, .efs_spi_speed = 0xff, .efs_spi_micron_flag = 0xff
+ };
ctx.current_pointer_saved = 0xFFFFFFFF;
- while (1) {
- int optindex = 0;
- int bios_tbl_index = -1;
-
- c = getopt_long(argc, argv, optstring, long_options, &optindex);
-
- if (c == -1)
- break;
-
- switch (c) {
- case AMDFW_OPT_XHCI:
- register_fw_filename(AMD_FW_XHCI, sub, optarg);
- sub = instance = 0;
- break;
- case AMDFW_OPT_IMC:
- register_fw_filename(AMD_FW_IMC, sub, optarg);
- sub = instance = 0;
- break;
- case AMDFW_OPT_GEC:
- register_fw_filename(AMD_FW_GEC, sub, optarg);
- sub = instance = 0;
- break;
- case AMDFW_OPT_RECOVERY_AB:
- cb_config.recovery_ab = true;
- break;
- case AMDFW_OPT_RECOVERY_AB_SINGLE_COPY:
- cb_config.recovery_ab = true;
- cb_config.recovery_ab_single_copy = true;
- break;
- case AMDFW_OPT_USE_COMBO:
- cb_config.use_combo = true;
- break;
- case AMDFW_OPT_COMBO1_CONFIG:
- cb_config.use_combo = true;
- assert_fw_entry(1, MAX_COMBO_ENTRIES, &ctx);
- combo_config[1] = optarg;
- break;
- case AMDFW_OPT_MULTILEVEL:
- cb_config.multi_level = true;
- break;
- case AMDFW_OPT_UNLOCK:
- register_fw_token_unlock();
- cb_config.unlock_secure = true;
- sub = instance = 0;
- break;
- case AMDFW_OPT_USE_PSPSECUREOS:
- cb_config.use_secureos = true;
- break;
- case AMDFW_OPT_INSTANCE:
- instance = strtoul(optarg, &tmp, 16);
- break;
- case AMDFW_OPT_LOAD_MP2FW:
- cb_config.load_mp2_fw = true;
- break;
- case AMDFW_OPT_NVRAM:
- register_fw_filename(AMD_FW_PSP_NVRAM, sub, optarg);
- sub = instance = 0;
- break;
- case AMDFW_OPT_FUSE:
- register_fw_fuse(optarg);
- fuse_defined = 1;
- sub = 0;
- break;
- case AMDFW_OPT_APCB:
- if ((instance & 0xF0) == 0) {
- register_bdt_data(AMD_BIOS_APCB, sub, instance & 0xF, optarg);
- combo_apcb[0].filename = optarg;
- combo_apcb[0].ins = instance;
- combo_apcb[0].sub = sub;
- } else {
- register_bdt_data(AMD_BIOS_APCB_BK, sub,
- instance & 0xF, optarg);
- combo_apcb_bk[0].filename = optarg;
- combo_apcb_bk[0].ins = instance;
- combo_apcb_bk[0].sub = sub;
- cb_config.have_apcb_bk = 1;
- }
- sub = instance = 0;
- break;
- case AMDFW_OPT_APCB_COMBO1:
- assert_fw_entry(1, MAX_COMBO_ENTRIES, &ctx);
- if ((instance & 0xF0) == 0) {
- combo_apcb[1].filename = optarg;
- combo_apcb[1].ins = instance;
- combo_apcb[1].sub = sub;
- } else {
- combo_apcb_bk[1].filename = optarg;
- combo_apcb_bk[1].ins = instance;
- combo_apcb_bk[1].sub = sub;
- cb_config.have_apcb_bk = 1;
- }
- sub = instance = 0;
- break;
- case AMDFW_OPT_APOBBASE:
- /* APOB destination */
- register_bios_fw_addr(AMD_BIOS_APOB, 0, optarg, 0);
- sub = instance = 0;
- break;
- case AMDFW_OPT_APOB_NVBASE:
- /* APOB NV source */
- register_bios_fw_addr(AMD_BIOS_APOB_NV, optarg, 0, 0);
- sub = instance = 0;
- break;
- case AMDFW_OPT_APOB_NVSIZE:
- /* APOB NV size */
- register_bios_fw_addr(AMD_BIOS_APOB_NV, 0, 0, optarg);
- sub = instance = 0;
- break;
- case AMDFW_OPT_BIOSBIN:
- register_bdt_data(AMD_BIOS_BIN, sub, instance, optarg);
- sub = instance = 0;
- break;
- case AMDFW_OPT_BIOSBIN_SOURCE:
- /* BIOS source */
- register_bios_fw_addr(AMD_BIOS_BIN, optarg, 0, 0);
- sub = instance = 0;
- break;
- case AMDFW_OPT_BIOSBIN_DEST:
- /* BIOS destination */
- register_bios_fw_addr(AMD_BIOS_BIN, 0, optarg, 0);
- sub = instance = 0;
- break;
- case AMDFW_OPT_BIOS_UNCOMP_SIZE:
- /* BIOS destination size */
- register_bios_fw_addr(AMD_BIOS_BIN, 0, 0, optarg);
- sub = instance = 0;
- break;
- case AMDFW_OPT_BIOSBIN_UNCOMP:
- bios_tbl_index = find_bios_entry(AMD_BIOS_BIN);
- if (bios_tbl_index != -1)
- amd_bios_table[bios_tbl_index].zlib = 0;
- break;
- case LONGOPT_BIOS_SIG:
- /* BIOS signature size */
- register_bios_fw_addr(AMD_BIOS_SIG, 0, 0, optarg);
- sub = instance = 0;
- break;
- case AMDFW_OPT_UCODE:
- register_bdt_data(AMD_BIOS_UCODE, sub,
- instance, optarg);
- sub = instance = 0;
- break;
- case AMDFW_OPT_LOAD_S0I3:
- cb_config.s0i3 = true;
- break;
- case AMDFW_OPT_SPL_TABLE:
- register_fw_filename(AMD_FW_SPL, sub, optarg);
- sub = instance = 0;
- cb_config.have_mb_spl = true;
- break;
- case AMDFW_OPT_WHITELIST:
- register_fw_filename(AMD_FW_PSP_WHITELIST, sub, optarg);
- sub = instance = 0;
- cb_config.have_whitelist = true;
- break;
- case AMDFW_OPT_VERSTAGE:
- register_fw_filename(AMD_FW_PSP_VERSTAGE, sub, optarg);
- sub = instance = 0;
- break;
- case AMDFW_OPT_VERSTAGE_SIG:
- register_fw_filename(AMD_FW_VERSTAGE_SIG, sub, optarg);
- sub = instance = 0;
- break;
- case AMDFW_OPT_OUTPUT_MANIFEST:
- manifest_file = optarg;
- break;
- case AMDFW_OPT_SIGNED_OUTPUT:
- signed_output_file = optarg;
- sub = instance = 0;
- break;
- case AMDFW_OPT_SIGNED_ADDR:
- signed_start_addr = strtoull(optarg, NULL, 10);
- sub = instance = 0;
- break;
- case LONGOPT_SPI_READ_MODE:
- efs_spi_readmode = strtoull(optarg, NULL, 16);
- sub = instance = 0;
- break;
- case LONGOPT_SPI_SPEED:
- efs_spi_speed = strtoull(optarg, NULL, 16);
- sub = instance = 0;
- break;
- case LONGOPT_SPI_MICRON_FLAG:
- efs_spi_micron_flag = strtoull(optarg, NULL, 16);
- sub = instance = 0;
- break;
- case AMDFW_OPT_OUTPUT:
- output = optarg;
- break;
- case AMDFW_OPT_FLASHSIZE:
- ctx.rom_size = (uint32_t)strtoul(optarg, &tmp, 16);
- if (*tmp != '\0') {
- fprintf(stderr, "Error: ROM size specified"
- " incorrectly (%s)\n\n", optarg);
- retval = 1;
- }
- break;
- case AMDFW_OPT_LOCATION:
- efs_location = (uint32_t)strtoul(optarg, &tmp, 16);
- if (*tmp != '\0') {
- fprintf(stderr, "Error: Directory Location specified"
- " incorrectly (%s)\n\n", optarg);
- retval = 1;
- }
- if (body_location == 0)
- body_location = efs_location;
- break;
- case AMDFW_OPT_ANYWHERE:
- any_location = 1;
- break;
- case AMDFW_OPT_SHAREDMEM:
- /* shared memory destination */
- register_bios_fw_addr(AMD_BIOS_PSP_SHARED_MEM, 0, optarg, 0);
- sub = instance = 0;
- break;
- case AMDFW_OPT_SHAREDMEM_SIZE:
- /* shared memory size */
- register_bios_fw_addr(AMD_BIOS_PSP_SHARED_MEM, NULL, NULL, optarg);
- sub = instance = 0;
- break;
- case LONGOPT_NVRAM_BASE:
- /* PSP NV base */
- register_amd_psp_fw_addr(AMD_FW_PSP_NVRAM, sub, optarg, 0);
- sub = instance = 0;
- break;
- case LONGOPT_NVRAM_SIZE:
- /* PSP NV size */
- register_amd_psp_fw_addr(AMD_FW_PSP_NVRAM, sub, 0, optarg);
- sub = instance = 0;
- break;
- case AMDFW_OPT_CONFIG:
- config = optarg;
- break;
- case AMDFW_OPT_DEBUG:
- debug = 1;
- break;
- case AMDFW_OPT_HELP:
- usage();
- return 0;
- case AMDFW_OPT_BODY_LOCATION:
- body_location = (uint32_t)strtoul(optarg, &tmp, 16);
- if (*tmp != '\0') {
- fprintf(stderr, "Error: Body Location specified"
- " incorrectly (%s)\n\n", optarg);
- retval = 1;
- }
- break;
+ retval = amdfwtool_getopt(argc, argv, &cb_config, &ctx);
- default:
- break;
- }
+ if (retval) {
+ return retval;
}
if (cb_config.use_combo) {
@@ -2122,115 +1540,8 @@ int main(int argc, char **argv)
memcpy(ctx.amd_bios_table_clean, amd_bios_table, sizeof(amd_bios_table));
}
- open_process_config(config, &cb_config, debug);
+ open_process_config(cb_config.config, &cb_config, cb_config.debug);
- if (!fuse_defined)
- register_fw_fuse(DEFAULT_SOFT_FUSE_CHAIN);
-
- if (!output) {
- fprintf(stderr, "Error: Output value is not specified.\n\n");
- retval = 1;
- }
-
- if (ctx.rom_size % 1024 != 0) {
- fprintf(stderr, "Error: ROM Size (%d bytes) should be a multiple of"
- " 1024 bytes.\n\n", ctx.rom_size);
- retval = 1;
- }
-
- if (ctx.rom_size < MIN_ROM_KB * 1024) {
- fprintf(stderr, "Error: ROM Size (%dKB) must be at least %dKB.\n\n",
- ctx.rom_size / 1024, MIN_ROM_KB);
- retval = 1;
- }
-
- if (retval) {
- usage();
- return retval;
- }
-
- printf(" AMDFWTOOL Using ROM size of %dKB\n", ctx.rom_size / 1024);
-
- if (ctx.rom_size <= MAX_MAPPED_WINDOW) {
- uint32_t rom_base_address;
-
- rom_base_address = 0xFFFFFFFF - ctx.rom_size + 1;
- if (efs_location & ~MAX_MAPPED_WINDOW_MASK)
- efs_location = efs_location - rom_base_address;
- if (body_location & ~MAX_MAPPED_WINDOW_MASK)
- body_location = body_location - rom_base_address;
- }
-
- /* If the flash size is larger than 16M, we assume the given
- addresses are already relative ones. Otherwise we print error.*/
- if (efs_location && efs_location > ctx.rom_size) {
- fprintf(stderr, "Error: EFS/Directory location outside of ROM.\n\n");
- return 1;
- }
- if (body_location && body_location > ctx.rom_size) {
- fprintf(stderr, "Error: Body location outside of ROM.\n\n");
- return 1;
- }
-
- if (!efs_location && body_location) {
- fprintf(stderr, "Error AMDFW body location specified without EFS location.\n");
- return 1;
- }
-
- if (body_location != efs_location &&
- body_location < ALIGN(efs_location + sizeof(embedded_firmware), BLOB_ALIGNMENT)) {
- fprintf(stderr, "Error: Insufficient space between EFS and Blobs.\n");
- fprintf(stderr, " Require safe spacing of 256 bytes\n");
- return 1;
- }
-
- if (any_location) {
- if ((body_location & 0x3f) || (efs_location & 0x3f)) {
- fprintf(stderr, "Error: Invalid Directory/EFS location.\n");
- fprintf(stderr, " Valid locations are 64-byte aligned\n");
- return 1;
- }
- } else {
- /* efs_location is relative address now. */
- switch (efs_location) {
- case 0:
- case 0xFA0000:
- case 0xF20000:
- case 0xE20000:
- case 0xC20000:
- case 0x820000:
- case 0x020000:
- break;
- case 0x7A0000:
- case 0x720000:
- case 0x620000:
- case 0x420000:
- /* Special cases for 8M. */
- if (ctx.rom_size != 0x800000) {
- fprintf(stderr, "Error: Invalid Directory location.\n");
- fprintf(stderr, "%x is only for 8M image size.", efs_location);
- return 1;
- }
- break;
- case 0x3A0000:
- case 0x320000:
- case 0x220000:
- /* Special cases for 4M. */
- if (ctx.rom_size != 0x400000) {
- fprintf(stderr, "Error: Invalid Directory location.\n");
- fprintf(stderr, "%x is only for 4M image size.", efs_location);
- return 1;
- }
- break;
- default:
- fprintf(stderr, "Error: Invalid Directory location.\n");
- fprintf(stderr, " Valid locations are 0xFFFA0000, 0xFFF20000,\n");
- fprintf(stderr, " 0xFFE20000, 0xFFC20000, 0xFF820000, 0xFF020000\n");
- fprintf(stderr, " 0xFA0000, 0xF20000, 0xE20000, 0xC20000,\n");
- fprintf(stderr, " 0x820000, 0x020000\n");
- return 1;
- }
- }
ctx.rom = malloc(ctx.rom_size);
if (!ctx.rom) {
fprintf(stderr, "Error: Failed to allocate memory\n");
@@ -2238,7 +1549,7 @@ int main(int argc, char **argv)
}
memset(ctx.rom, 0xFF, ctx.rom_size);
- romsig_offset = efs_location ? efs_location : AMD_ROMSIG_OFFSET;
+ romsig_offset = cb_config.efs_location ? cb_config.efs_location : AMD_ROMSIG_OFFSET;
set_current_pointer(&ctx, romsig_offset);
amd_romsig = BUFF_OFFSET(ctx, romsig_offset);
@@ -2248,8 +1559,7 @@ int main(int argc, char **argv)
amd_romsig->xhci_entry = 0;
if (cb_config.soc_id != PLATFORM_UNKNOWN) {
- retval = set_efs_table(cb_config.soc_id, &cb_config, amd_romsig,
- efs_spi_readmode, efs_spi_speed, efs_spi_micron_flag);
+ retval = set_efs_table(cb_config.soc_id, &cb_config, amd_romsig);
if (retval) {
fprintf(stderr, "ERROR: Failed to initialize EFS table!\n");
return retval;
@@ -2264,15 +1574,9 @@ int main(int argc, char **argv)
ctx.address_mode = AMD_ADDR_REL_BIOS;
else
ctx.address_mode = AMD_ADDR_PHYSICAL;
- printf(" AMDFWTOOL Using firmware directory location of address: 0x%08x",
- efs_location);
- if (body_location != efs_location)
- printf(" with a split body at: 0x%08x\n", body_location);
- else
- printf("\n");
- if (efs_location != body_location)
- set_current_pointer(&ctx, body_location);
+ if (cb_config.efs_location != cb_config.body_location)
+ set_current_pointer(&ctx, cb_config.body_location);
else
set_current_pointer(&ctx, romsig_offset + sizeof(embedded_firmware));
@@ -2286,10 +1590,10 @@ int main(int argc, char **argv)
/* If the tool is invoked with command-line options to keep the signed PSP
binaries separate, process the signed binaries first. */
- if (signed_output_file && signed_start_addr)
- process_signed_psp_firmwares(signed_output_file,
+ if (cb_config.signed_output_file && cb_config.signed_start_addr)
+ process_signed_psp_firmwares(cb_config.signed_output_file,
amd_psp_fw_table,
- signed_start_addr,
+ cb_config.signed_start_addr,
cb_config.soc_id);
if (cb_config.use_combo) {
@@ -2301,11 +1605,11 @@ int main(int argc, char **argv)
}
combo_index = 0;
- if (config)
- combo_config[0] = config;
+ if (cb_config.config)
+ cb_config.combo_config[0] = cb_config.config;
do {
- if (cb_config.use_combo && debug)
+ if (cb_config.use_combo && cb_config.debug)
printf("Processing %dth combo entry\n", combo_index);
/* for non-combo image, combo_config[0] == config, and
@@ -2321,8 +1625,8 @@ int main(int argc, char **argv)
memcpy(amd_bios_table, ctx.amd_bios_table_clean,
sizeof(amd_bios_table));
assert_fw_entry(combo_index, MAX_COMBO_ENTRIES, &ctx);
- open_process_config(combo_config[combo_index], &cb_config,
- debug);
+ open_process_config(cb_config.combo_config[combo_index], &cb_config,
+ cb_config.debug);
/* In most cases, the address modes are same. */
if (cb_config.need_ish)
@@ -2332,26 +1636,7 @@ int main(int argc, char **argv)
else
ctx.address_mode = AMD_ADDR_PHYSICAL;
- if (combo_apcb[combo_index].filename != NULL) {
- register_bdt_data(AMD_BIOS_APCB,
- combo_apcb[combo_index].sub,
- combo_apcb[combo_index].ins & 0xF,
- combo_apcb[combo_index].filename);
- if (cb_config.have_apcb_bk)
- register_bdt_data(AMD_BIOS_APCB_BK,
- combo_apcb_bk[combo_index].sub,
- combo_apcb_bk[combo_index].ins & 0xF,
- combo_apcb_bk[combo_index].filename);
- } else {
- /* Use main APCB if no Combo APCB is provided */
- register_bdt_data(AMD_BIOS_APCB, combo_apcb[0].sub,
- combo_apcb[0].ins & 0xF, combo_apcb[0].filename);
- if (cb_config.have_apcb_bk)
- register_bdt_data(AMD_BIOS_APCB_BK,
- combo_apcb_bk[0].sub,
- combo_apcb_bk[0].ins & 0xF,
- combo_apcb_bk[0].filename);
- }
+ register_apcb_combo(&cb_config, combo_index, &ctx);
}
if (cb_config.multi_level) {
@@ -2455,39 +1740,39 @@ int main(int argc, char **argv)
}
}
} while (cb_config.use_combo && ++combo_index < MAX_COMBO_ENTRIES &&
- combo_config[combo_index] != NULL);
+ cb_config.combo_config[combo_index] != NULL);
- targetfd = open(output, O_RDWR | O_CREAT | O_TRUNC, 0666);
+ targetfd = open(cb_config.output, O_RDWR | O_CREAT | O_TRUNC, 0666);
if (targetfd >= 0) {
- uint32_t offset = efs_location;
- uint32_t bytes = efs_location == body_location ?
+ uint32_t offset = cb_config.efs_location;
+ uint32_t bytes = cb_config.efs_location == cb_config.body_location ?
ctx.current - offset : sizeof(*amd_romsig);
uint32_t ret_bytes;
ret_bytes = write_from_buf_to_file(targetfd, BUFF_OFFSET(ctx, offset), bytes);
if (bytes != ret_bytes) {
- fprintf(stderr, "Error: Writing to file %s failed\n", output);
+ fprintf(stderr, "Error: Writing to file %s failed\n", cb_config.output);
retval = 1;
}
close(targetfd);
} else {
- fprintf(stderr, "Error: could not open file: %s\n", output);
+ fprintf(stderr, "Error: could not open file: %s\n", cb_config.output);
retval = 1;
}
- if (efs_location != body_location) {
+ if (cb_config.efs_location != cb_config.body_location) {
ssize_t bytes;
- bytes = write_body(output, BUFF_OFFSET(ctx, body_location),
- ctx.current - body_location);
- if (bytes != ctx.current - body_location) {
+ bytes = write_body(cb_config.output, BUFF_OFFSET(ctx, cb_config.body_location),
+ ctx.current - cb_config.body_location);
+ if (bytes != ctx.current - cb_config.body_location) {
fprintf(stderr, "Error: Writing body\n");
retval = 1;
}
}
- if (manifest_file) {
- dump_blob_version(manifest_file, amd_psp_fw_table);
+ if (cb_config.manifest_file) {
+ dump_blob_version(cb_config.manifest_file, amd_psp_fw_table);
}
amdfwtool_cleanup(&ctx);
diff --git a/util/amdfwtool/amdfwtool.h b/util/amdfwtool/amdfwtool.h
index 91f1473189..fdcd6a84b1 100644
--- a/util/amdfwtool/amdfwtool.h
+++ b/util/amdfwtool/amdfwtool.h
@@ -427,14 +427,39 @@ typedef struct _amd_cb_config {
bool use_combo;
bool have_apcb_bk;
enum platform soc_id;
+
+ uint8_t efs_spi_readmode, efs_spi_speed, efs_spi_micron_flag;
+ uint32_t body_location, efs_location;
+ uint64_t signed_start_addr;
+ char *manifest_file;
+ const char *signed_output_file;
+ char *output, *config;
+ char *combo_config[MAX_COMBO_ENTRIES];
+ int debug;
} amd_cb_config;
-void register_fw_fuse(char *str);
+typedef struct _context {
+ char *rom; /* target buffer, size of flash device */
+ uint32_t rom_size; /* size of flash device */
+ uint32_t address_mode; /* 0:abs address; 1:relative to flash; 2: relative to table */
+ uint32_t current; /* pointer within flash & proxy buffer */
+ uint32_t current_pointer_saved;
+ uint32_t current_table;
+ void *amd_psp_fw_table_clean;
+ void *amd_bios_table_clean;
+ struct _combo_apcb {
+ char *filename;
+ uint8_t ins;
+ uint8_t sub;
+ } combo_apcb[MAX_COMBO_ENTRIES], combo_apcb_bk[MAX_COMBO_ENTRIES];
+} context;
+
uint8_t process_config(FILE *config, amd_cb_config *cb_config);
void process_signed_psp_firmwares(const char *signed_rom,
amd_fw_entry *fw_table,
uint64_t signed_start_addr,
enum platform soc_id);
+int find_bios_entry(amd_bios_type type);
#define EFS_FILE_SUFFIX ".efs"
#define TMP_FILE_SUFFIX ".tmp"
@@ -450,4 +475,7 @@ ssize_t copy_blob(void *dest, const char *src_file, size_t room);
#define LINE_EOF (1)
#define LINE_TOO_LONG (2)
+int amdfwtool_getopt(int argc, char *argv[], amd_cb_config *cb_config, context *ctx);
+void register_apcb_combo(amd_cb_config *cb_config, int combo_index, context *ctx);
+
#endif /* _AMD_FW_TOOL_H_ */
diff --git a/util/amdfwtool/opts.c b/util/amdfwtool/opts.c
new file mode 100644
index 0000000000..511ffd02db
--- /dev/null
+++ b/util/amdfwtool/opts.c
@@ -0,0 +1,722 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+
+#include "amdfwtool.h"
+
+#define MIN_ROM_KB 256
+#define MAX_MAPPED_WINDOW (16 * MiB)
+#define MAX_MAPPED_WINDOW_MASK (MAX_MAPPED_WINDOW - 1)
+
+#define DEFAULT_SOFT_FUSE_CHAIN "0x1"
+
+enum {
+ AMDFW_OPT_CONFIG = 'c',
+ AMDFW_OPT_DEBUG = 'd',
+ AMDFW_OPT_HELP = 'h',
+
+ AMDFW_OPT_XHCI = 128,
+ AMDFW_OPT_IMC,
+ AMDFW_OPT_GEC,
+ AMDFW_OPT_RECOVERY_AB,
+ AMDFW_OPT_RECOVERY_AB_SINGLE_COPY,
+ AMDFW_OPT_USE_COMBO,
+ AMDFW_OPT_COMBO1_CONFIG,
+ AMDFW_OPT_MULTILEVEL,
+ AMDFW_OPT_NVRAM,
+
+ AMDFW_OPT_FUSE,
+ AMDFW_OPT_UNLOCK,
+ AMDFW_OPT_WHITELIST,
+ AMDFW_OPT_USE_PSPSECUREOS,
+ AMDFW_OPT_LOAD_MP2FW,
+ AMDFW_OPT_LOAD_S0I3,
+ AMDFW_OPT_SPL_TABLE,
+ AMDFW_OPT_VERSTAGE,
+ AMDFW_OPT_VERSTAGE_SIG,
+ AMDFW_OPT_OUTPUT_MANIFEST,
+
+ AMDFW_OPT_INSTANCE,
+ AMDFW_OPT_APCB,
+ AMDFW_OPT_APCB_COMBO1,
+ AMDFW_OPT_APOBBASE,
+ AMDFW_OPT_BIOSBIN,
+ AMDFW_OPT_BIOSBIN_SOURCE,
+ AMDFW_OPT_BIOSBIN_DEST,
+ AMDFW_OPT_BIOS_UNCOMP_SIZE,
+ AMDFW_OPT_BIOSBIN_UNCOMP,
+ AMDFW_OPT_UCODE,
+ AMDFW_OPT_APOB_NVBASE,
+ AMDFW_OPT_APOB_NVSIZE,
+
+ AMDFW_OPT_OUTPUT,
+ AMDFW_OPT_FLASHSIZE,
+ AMDFW_OPT_LOCATION,
+ AMDFW_OPT_ANYWHERE,
+ AMDFW_OPT_SHAREDMEM,
+ AMDFW_OPT_SHAREDMEM_SIZE,
+ AMDFW_OPT_SIGNED_OUTPUT,
+ AMDFW_OPT_SIGNED_ADDR,
+ AMDFW_OPT_BODY_LOCATION,
+ /* begin after ASCII characters */
+ LONGOPT_SPI_READ_MODE = 256,
+ LONGOPT_SPI_SPEED = 257,
+ LONGOPT_SPI_MICRON_FLAG = 258,
+ LONGOPT_BIOS_SIG = 259,
+ LONGOPT_NVRAM_BASE = 260,
+ LONGOPT_NVRAM_SIZE = 261,
+};
+
+static const char optstring[] = {AMDFW_OPT_CONFIG, ':',
+ AMDFW_OPT_DEBUG, AMDFW_OPT_HELP
+};
+
+static struct option long_options[] = {
+ {"xhci", required_argument, 0, AMDFW_OPT_XHCI },
+ {"imc", required_argument, 0, AMDFW_OPT_IMC },
+ {"gec", required_argument, 0, AMDFW_OPT_GEC },
+ /* PSP Directory Table items */
+ {"recovery-ab", no_argument, 0, AMDFW_OPT_RECOVERY_AB },
+ {"recovery-ab-single-copy", no_argument, 0, AMDFW_OPT_RECOVERY_AB_SINGLE_COPY },
+ {"use-combo", no_argument, 0, AMDFW_OPT_USE_COMBO },
+ {"combo-config1", required_argument, 0, AMDFW_OPT_COMBO1_CONFIG },
+ {"multilevel", no_argument, 0, AMDFW_OPT_MULTILEVEL },
+ {"nvram", required_argument, 0, AMDFW_OPT_NVRAM },
+ {"nvram-base", required_argument, 0, LONGOPT_NVRAM_BASE },
+ {"nvram-size", required_argument, 0, LONGOPT_NVRAM_SIZE },
+ {"soft-fuse", required_argument, 0, AMDFW_OPT_FUSE },
+ {"token-unlock", no_argument, 0, AMDFW_OPT_UNLOCK },
+ {"whitelist", required_argument, 0, AMDFW_OPT_WHITELIST },
+ {"use-pspsecureos", no_argument, 0, AMDFW_OPT_USE_PSPSECUREOS },
+ {"load-mp2-fw", no_argument, 0, AMDFW_OPT_LOAD_MP2FW },
+ {"load-s0i3", no_argument, 0, AMDFW_OPT_LOAD_S0I3 },
+ {"spl-table", required_argument, 0, AMDFW_OPT_SPL_TABLE },
+ {"verstage", required_argument, 0, AMDFW_OPT_VERSTAGE },
+ {"verstage_sig", required_argument, 0, AMDFW_OPT_VERSTAGE_SIG },
+ {"output-manifest", required_argument, 0, AMDFW_OPT_OUTPUT_MANIFEST },
+ /* BIOS Directory Table items */
+ {"instance", required_argument, 0, AMDFW_OPT_INSTANCE },
+ {"apcb", required_argument, 0, AMDFW_OPT_APCB },
+ {"apcb-combo1", required_argument, 0, AMDFW_OPT_APCB_COMBO1 },
+ {"apob-base", required_argument, 0, AMDFW_OPT_APOBBASE },
+ {"bios-bin", required_argument, 0, AMDFW_OPT_BIOSBIN },
+ {"bios-bin-src", required_argument, 0, AMDFW_OPT_BIOSBIN_SOURCE },
+ {"bios-bin-dest", required_argument, 0, AMDFW_OPT_BIOSBIN_DEST },
+ {"bios-uncomp-size", required_argument, 0, AMDFW_OPT_BIOS_UNCOMP_SIZE },
+ {"bios-bin-uncomp", no_argument, 0, AMDFW_OPT_BIOSBIN_UNCOMP },
+ {"bios-sig-size", required_argument, 0, LONGOPT_BIOS_SIG },
+ {"ucode", required_argument, 0, AMDFW_OPT_UCODE },
+ {"apob-nv-base", required_argument, 0, AMDFW_OPT_APOB_NVBASE },
+ {"apob-nv-size", required_argument, 0, AMDFW_OPT_APOB_NVSIZE },
+ /* Embedded Firmware Structure items*/
+ {"spi-read-mode", required_argument, 0, LONGOPT_SPI_READ_MODE },
+ {"spi-speed", required_argument, 0, LONGOPT_SPI_SPEED },
+ {"spi-micron-flag", required_argument, 0, LONGOPT_SPI_MICRON_FLAG },
+ {"body-location", required_argument, 0, AMDFW_OPT_BODY_LOCATION },
+ /* other */
+ {"output", required_argument, 0, AMDFW_OPT_OUTPUT },
+ {"flashsize", required_argument, 0, AMDFW_OPT_FLASHSIZE },
+ {"location", required_argument, 0, AMDFW_OPT_LOCATION },
+ {"anywhere", no_argument, 0, AMDFW_OPT_ANYWHERE },
+ {"sharedmem", required_argument, 0, AMDFW_OPT_SHAREDMEM },
+ {"sharedmem-size", required_argument, 0, AMDFW_OPT_SHAREDMEM_SIZE },
+
+ {"signed-output", required_argument, 0, AMDFW_OPT_SIGNED_OUTPUT },
+ {"signed-addr", required_argument, 0, AMDFW_OPT_SIGNED_ADDR },
+
+ {"config", required_argument, 0, AMDFW_OPT_CONFIG },
+ {"debug", no_argument, 0, AMDFW_OPT_DEBUG },
+ {"help", no_argument, 0, AMDFW_OPT_HELP },
+ {NULL, 0, 0, 0 }
+};
+
+static void usage(void)
+{
+ printf("amdfwtool: Create AMD Firmware combination\n");
+ printf("Usage: amdfwtool [options] --flashsize <size> --output <filename>\n");
+ printf("--xhci <FILE> Add XHCI blob\n");
+ printf("--imc <FILE> Add IMC blob\n");
+ printf("--gec <FILE> Add GEC blob\n");
+
+ printf("\nPSP options:\n");
+ printf("--use-combo Use the COMBO layout\n");
+ printf("--combo-config1 <config file> Config for 1st combo entry\n");
+ printf("--multilevel Generate primary and secondary tables\n");
+ printf("--nvram <FILE> Add nvram binary\n");
+ printf("--soft-fuse Set soft fuse\n");
+ printf("--token-unlock Set token unlock\n");
+ printf("--nvram-base <HEX_VAL> Base address of nvram\n");
+ printf("--nvram-size <HEX_VAL> Size of nvram\n");
+ printf("--whitelist Set if there is a whitelist\n");
+ printf("--use-pspsecureos Set if psp secure OS is needed\n");
+ printf("--load-mp2-fw Set if load MP2 firmware\n");
+ printf("--load-s0i3 Set if load s0i3 firmware\n");
+ printf("--verstage <FILE> Add verstage\n");
+ printf("--verstage_sig Add verstage signature\n");
+ printf("--recovery-ab Use the recovery A/B layout\n");
+ printf("\nBIOS options:\n");
+ printf("--instance <number> Sets instance field for the next BIOS\n");
+ printf(" firmware\n");
+ printf("--apcb <FILE> Add AGESA PSP customization block\n");
+ printf("--apcb-combo1 <FILE> Add APCB for 1st combo\n");
+ printf("--apob-base <HEX_VAL> Destination for AGESA PSP output block\n");
+ printf("--apob-nv-base <HEX_VAL> Location of S3 resume data\n");
+ printf("--apob-nv-size <HEX_VAL> Size of S3 resume data\n");
+ printf("--ucode <FILE> Add microcode patch\n");
+ printf("--bios-bin <FILE> Add compressed image; auto source address\n");
+ printf("--bios-bin-src <HEX_VAL> Address in flash of source if -V not used\n");
+ printf("--bios-bin-dest <HEX_VAL> Destination for uncompressed BIOS\n");
+ printf("--bios-uncomp-size <HEX> Uncompressed size of BIOS image\n");
+ printf("--output <filename> output filename\n");
+ printf("--flashsize <HEX_VAL> ROM size in bytes\n");
+ printf(" size must be larger than %dKB\n",
+ MIN_ROM_KB);
+ printf(" and must a multiple of 1024\n");
+ printf("--location Location of Directory\n");
+ printf("--anywhere Use any 64-byte aligned addr for Directory\n");
+ printf("--sharedmem Location of PSP/FW shared memory\n");
+ printf("--sharedmem-size Maximum size of the PSP/FW shared memory\n");
+ printf(" area\n");
+ printf("--output-manifest <FILE> Writes a manifest with the blobs versions\n");
+ printf("\nEmbedded Firmware Structure options used by the PSP:\n");
+ printf("--spi-speed <HEX_VAL> SPI fast speed to place in EFS Table\n");
+ printf(" 0x0 66.66Mhz\n");
+ printf(" 0x1 33.33MHz\n");
+ printf(" 0x2 22.22MHz\n");
+ printf(" 0x3 16.66MHz\n");
+ printf(" 0x4 100MHz\n");
+ printf(" 0x5 800KHz\n");
+ printf("--spi-read-mode <HEX_VAL> SPI read mode to place in EFS Table\n");
+ printf(" 0x0 Normal Read (up to 33M)\n");
+ printf(" 0x1 Reserved\n");
+ printf(" 0x2 Dual IO (1-1-2)\n");
+ printf(" 0x3 Quad IO (1-1-4)\n");
+ printf(" 0x4 Dual IO (1-2-2)\n");
+ printf(" 0x5 Quad IO (1-4-4)\n");
+ printf(" 0x6 Normal Read (up to 66M)\n");
+ printf(" 0x7 Fast Read\n");
+ printf("--spi-micron-flag <HEX_VAL> Micron SPI part support for RV and later SOC\n");
+ printf(" 0x0 Micron parts are not used\n");
+ printf(" 0x1 Micron parts are always used\n");
+ printf(" 0x2 Micron parts optional, this option is only\n");
+ printf(" supported with RN/LCN SOC\n");
+ printf("\nGeneral options:\n");
+ printf("-c|--config <config file> Config file\n");
+ printf("-d|--debug Print debug message\n");
+ printf("-h|--help Show this help\n");
+}
+
+extern amd_fw_entry amd_psp_fw_table[];
+extern amd_bios_entry amd_bios_table[];
+extern amd_fw_entry amd_fw_table[];
+
+static void register_amd_psp_fw_addr(amd_fw_type type, int sub,
+ char *dst_str, char *size_str)
+{
+ unsigned int i;
+
+ for (i = 0; amd_psp_fw_table[i].type != AMD_FW_INVALID; i++) {
+ if (amd_psp_fw_table[i].type != type)
+ continue;
+
+ if (amd_psp_fw_table[i].subprog == sub) {
+ if (dst_str)
+ amd_psp_fw_table[i].dest = strtoull(dst_str, NULL, 16);
+ if (size_str)
+ amd_psp_fw_table[i].size = strtoul(size_str, NULL, 16);
+ return;
+ }
+ }
+}
+
+static void register_bios_fw_addr(amd_bios_type type, char *src_str,
+ char *dst_str, char *size_str)
+{
+ uint32_t i;
+ for (i = 0; amd_bios_table[i].type != AMD_BIOS_INVALID; i++) {
+ if (amd_bios_table[i].type != type)
+ continue;
+
+ if (src_str)
+ amd_bios_table[i].src = strtoull(src_str, NULL, 16);
+ if (dst_str)
+ amd_bios_table[i].dest = strtoull(dst_str, NULL, 16);
+ if (size_str)
+ amd_bios_table[i].size = strtoul(size_str, NULL, 16);
+
+ return;
+ }
+}
+
+static void register_fw_token_unlock(void)
+{
+ uint32_t i;
+
+ for (i = 0; amd_psp_fw_table[i].type != AMD_FW_INVALID; i++) {
+ if (amd_psp_fw_table[i].type != AMD_TOKEN_UNLOCK)
+ continue;
+
+ amd_psp_fw_table[i].other = 1;
+ return;
+ }
+}
+
+static void register_fw_filename(amd_fw_type type, uint8_t sub, char filename[])
+{
+ unsigned int i;
+
+ for (i = 0; amd_fw_table[i].type != AMD_FW_INVALID; i++) {
+ if (amd_fw_table[i].type == type) {
+ amd_fw_table[i].filename = filename;
+ return;
+ }
+ }
+
+ for (i = 0; amd_psp_fw_table[i].type != AMD_FW_INVALID; i++) {
+ if (amd_psp_fw_table[i].type != type)
+ continue;
+
+ if (amd_psp_fw_table[i].subprog == sub) {
+ amd_psp_fw_table[i].filename = filename;
+ return;
+ }
+ }
+}
+
+static void register_bdt_data(amd_bios_type type, int sub, int ins, char name[])
+{
+ uint32_t i;
+
+ for (i = 0; amd_bios_table[i].type != AMD_BIOS_INVALID; i++) {
+ if (amd_bios_table[i].type == type
+ && amd_bios_table[i].inst == ins
+ && amd_bios_table[i].subpr == sub) {
+ amd_bios_table[i].filename = name;
+ return;
+ }
+ }
+}
+
+static void register_fw_fuse(char *str)
+{
+ uint32_t i;
+
+ for (i = 0; amd_psp_fw_table[i].type != AMD_FW_INVALID; i++) {
+ if (amd_psp_fw_table[i].type != AMD_PSP_FUSE_CHAIN)
+ continue;
+
+ amd_psp_fw_table[i].other = strtoull(str, NULL, 16);
+ return;
+ }
+}
+
+void register_apcb_combo(amd_cb_config *cb_config, int combo_index, context *ctx)
+{
+ if (ctx->combo_apcb[combo_index].filename != NULL) {
+ register_bdt_data(AMD_BIOS_APCB,
+ ctx->combo_apcb[combo_index].sub,
+ ctx->combo_apcb[combo_index].ins & 0xF,
+ ctx->combo_apcb[combo_index].filename);
+ if (cb_config->have_apcb_bk)
+ register_bdt_data(AMD_BIOS_APCB_BK,
+ ctx->combo_apcb_bk[combo_index].sub,
+ ctx->combo_apcb_bk[combo_index].ins & 0xF,
+ ctx->combo_apcb_bk[combo_index].filename);
+ } else {
+ /* Use main APCB if no Combo APCB is provided */
+ register_bdt_data(AMD_BIOS_APCB, ctx->combo_apcb[0].sub,
+ ctx->combo_apcb[0].ins & 0xF, ctx->combo_apcb[0].filename);
+ if (cb_config->have_apcb_bk)
+ register_bdt_data(AMD_BIOS_APCB_BK,
+ ctx->combo_apcb_bk[0].sub,
+ ctx->combo_apcb_bk[0].ins & 0xF,
+ ctx->combo_apcb_bk[0].filename);
+ }
+}
+
+int amdfwtool_getopt(int argc, char *argv[], amd_cb_config *cb_config, context *ctx)
+{
+ int c;
+ /* Values cleared after each firmware or parameter, regardless if N/A */
+ uint8_t sub = 0, instance = 0;
+ char *tmp;
+ int retval = 0;
+ bool any_location = 0;
+ int fuse_defined = 0;
+
+ while (1) {
+ int optindex = 0;
+ int bios_tbl_index = -1;
+
+ c = getopt_long(argc, argv, optstring, long_options, &optindex);
+
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case AMDFW_OPT_XHCI:
+ register_fw_filename(AMD_FW_XHCI, sub, optarg);
+ sub = instance = 0;
+ break;
+ case AMDFW_OPT_IMC:
+ register_fw_filename(AMD_FW_IMC, sub, optarg);
+ sub = instance = 0;
+ break;
+ case AMDFW_OPT_GEC:
+ register_fw_filename(AMD_FW_GEC, sub, optarg);
+ sub = instance = 0;
+ break;
+ case AMDFW_OPT_RECOVERY_AB:
+ cb_config->recovery_ab = true;
+ break;
+ case AMDFW_OPT_RECOVERY_AB_SINGLE_COPY:
+ cb_config->recovery_ab = true;
+ cb_config->recovery_ab_single_copy = true;
+ break;
+ case AMDFW_OPT_USE_COMBO:
+ cb_config->use_combo = true;
+ break;
+ case AMDFW_OPT_COMBO1_CONFIG:
+ cb_config->use_combo = true;
+ /* assert_fw_entry(1, MAX_COMBO_ENTRIES, &ctx); */
+ cb_config->combo_config[1] = optarg;
+ break;
+ case AMDFW_OPT_MULTILEVEL:
+ cb_config->multi_level = true;
+ break;
+ case AMDFW_OPT_UNLOCK:
+ register_fw_token_unlock();
+ cb_config->unlock_secure = true;
+ sub = instance = 0;
+ break;
+ case AMDFW_OPT_USE_PSPSECUREOS:
+ cb_config->use_secureos = true;
+ break;
+ case AMDFW_OPT_INSTANCE:
+ instance = strtoul(optarg, &tmp, 16);
+ break;
+ case AMDFW_OPT_LOAD_MP2FW:
+ cb_config->load_mp2_fw = true;
+ break;
+ case AMDFW_OPT_NVRAM:
+ register_fw_filename(AMD_FW_PSP_NVRAM, sub, optarg);
+ sub = instance = 0;
+ break;
+ case AMDFW_OPT_FUSE:
+ register_fw_fuse(optarg);
+ fuse_defined = 1;
+ sub = 0;
+ break;
+ case AMDFW_OPT_APCB:
+ if ((instance & 0xF0) == 0) {
+ register_bdt_data(AMD_BIOS_APCB, sub, instance & 0xF, optarg);
+ ctx->combo_apcb[0].filename = optarg;
+ ctx->combo_apcb[0].ins = instance;
+ ctx->combo_apcb[0].sub = sub;
+ } else {
+ register_bdt_data(AMD_BIOS_APCB_BK, sub,
+ instance & 0xF, optarg);
+ ctx->combo_apcb_bk[0].filename = optarg;
+ ctx->combo_apcb_bk[0].ins = instance;
+ ctx->combo_apcb_bk[0].sub = sub;
+ cb_config->have_apcb_bk = 1;
+ }
+ sub = instance = 0;
+ break;
+ case AMDFW_OPT_APCB_COMBO1:
+ /* assert_fw_entry(1, MAX_COMBO_ENTRIES, &ctx); */
+ if ((instance & 0xF0) == 0) {
+ ctx->combo_apcb[1].filename = optarg;
+ ctx->combo_apcb[1].ins = instance;
+ ctx->combo_apcb[1].sub = sub;
+ } else {
+ ctx->combo_apcb_bk[1].filename = optarg;
+ ctx->combo_apcb_bk[1].ins = instance;
+ ctx->combo_apcb_bk[1].sub = sub;
+ cb_config->have_apcb_bk = 1;
+ }
+ sub = instance = 0;
+ break;
+ case AMDFW_OPT_APOBBASE:
+ /* APOB destination */
+ register_bios_fw_addr(AMD_BIOS_APOB, 0, optarg, 0);
+ sub = instance = 0;
+ break;
+ case AMDFW_OPT_APOB_NVBASE:
+ /* APOB NV source */
+ register_bios_fw_addr(AMD_BIOS_APOB_NV, optarg, 0, 0);
+ sub = instance = 0;
+ break;
+ case AMDFW_OPT_APOB_NVSIZE:
+ /* APOB NV size */
+ register_bios_fw_addr(AMD_BIOS_APOB_NV, 0, 0, optarg);
+ sub = instance = 0;
+ break;
+ case AMDFW_OPT_BIOSBIN:
+ register_bdt_data(AMD_BIOS_BIN, sub, instance, optarg);
+ sub = instance = 0;
+ break;
+ case AMDFW_OPT_BIOSBIN_SOURCE:
+ /* BIOS source */
+ register_bios_fw_addr(AMD_BIOS_BIN, optarg, 0, 0);
+ sub = instance = 0;
+ break;
+ case AMDFW_OPT_BIOSBIN_DEST:
+ /* BIOS destination */
+ register_bios_fw_addr(AMD_BIOS_BIN, 0, optarg, 0);
+ sub = instance = 0;
+ break;
+ case AMDFW_OPT_BIOS_UNCOMP_SIZE:
+ /* BIOS destination size */
+ register_bios_fw_addr(AMD_BIOS_BIN, 0, 0, optarg);
+ sub = instance = 0;
+ break;
+ case AMDFW_OPT_BIOSBIN_UNCOMP:
+ bios_tbl_index = find_bios_entry(AMD_BIOS_BIN);
+ if (bios_tbl_index != -1)
+ amd_bios_table[bios_tbl_index].zlib = 0;
+ break;
+ case LONGOPT_BIOS_SIG:
+ /* BIOS signature size */
+ register_bios_fw_addr(AMD_BIOS_SIG, 0, 0, optarg);
+ sub = instance = 0;
+ break;
+ case AMDFW_OPT_UCODE:
+ register_bdt_data(AMD_BIOS_UCODE, sub,
+ instance, optarg);
+ sub = instance = 0;
+ break;
+ case AMDFW_OPT_LOAD_S0I3:
+ cb_config->s0i3 = true;
+ break;
+ case AMDFW_OPT_SPL_TABLE:
+ register_fw_filename(AMD_FW_SPL, sub, optarg);
+ sub = instance = 0;
+ cb_config->have_mb_spl = true;
+ break;
+ case AMDFW_OPT_WHITELIST:
+ register_fw_filename(AMD_FW_PSP_WHITELIST, sub, optarg);
+ sub = instance = 0;
+ cb_config->have_whitelist = true;
+ break;
+ case AMDFW_OPT_VERSTAGE:
+ register_fw_filename(AMD_FW_PSP_VERSTAGE, sub, optarg);
+ sub = instance = 0;
+ break;
+ case AMDFW_OPT_VERSTAGE_SIG:
+ register_fw_filename(AMD_FW_VERSTAGE_SIG, sub, optarg);
+ sub = instance = 0;
+ break;
+ case AMDFW_OPT_OUTPUT_MANIFEST:
+ cb_config->manifest_file = optarg;
+ break;
+ case AMDFW_OPT_SIGNED_OUTPUT:
+ cb_config->signed_output_file = optarg;
+ sub = instance = 0;
+ break;
+ case AMDFW_OPT_SIGNED_ADDR:
+ cb_config->signed_start_addr = strtoull(optarg, NULL, 10);
+ sub = instance = 0;
+ break;
+ case LONGOPT_SPI_READ_MODE:
+ cb_config->efs_spi_readmode = strtoull(optarg, NULL, 16);
+ sub = instance = 0;
+ break;
+ case LONGOPT_SPI_SPEED:
+ cb_config->efs_spi_speed = strtoull(optarg, NULL, 16);
+ sub = instance = 0;
+ break;
+ case LONGOPT_SPI_MICRON_FLAG:
+ cb_config->efs_spi_micron_flag = strtoull(optarg, NULL, 16);
+ sub = instance = 0;
+ break;
+ case AMDFW_OPT_OUTPUT:
+ cb_config->output = optarg;
+ break;
+ case AMDFW_OPT_FLASHSIZE:
+ ctx->rom_size = (uint32_t)strtoul(optarg, &tmp, 16);
+ if (*tmp != '\0') {
+ fprintf(stderr, "Error: ROM size specified"
+ " incorrectly (%s)\n\n", optarg);
+ retval = 1;
+ }
+ break;
+ case AMDFW_OPT_LOCATION:
+ cb_config->efs_location = (uint32_t)strtoul(optarg, &tmp, 16);
+ if (*tmp != '\0') {
+ fprintf(stderr, "Error: Directory Location specified"
+ " incorrectly (%s)\n\n", optarg);
+ retval = 1;
+ }
+ if (cb_config->body_location == 0)
+ cb_config->body_location = cb_config->efs_location;
+ break;
+ case AMDFW_OPT_ANYWHERE:
+ any_location = 1;
+ break;
+ case AMDFW_OPT_SHAREDMEM:
+ /* shared memory destination */
+ register_bios_fw_addr(AMD_BIOS_PSP_SHARED_MEM, 0, optarg, 0);
+ sub = instance = 0;
+ break;
+ case AMDFW_OPT_SHAREDMEM_SIZE:
+ /* shared memory size */
+ register_bios_fw_addr(AMD_BIOS_PSP_SHARED_MEM, NULL, NULL, optarg);
+ sub = instance = 0;
+ break;
+ case LONGOPT_NVRAM_BASE:
+ /* PSP NV base */
+ register_amd_psp_fw_addr(AMD_FW_PSP_NVRAM, sub, optarg, 0);
+ sub = instance = 0;
+ break;
+ case LONGOPT_NVRAM_SIZE:
+ /* PSP NV size */
+ register_amd_psp_fw_addr(AMD_FW_PSP_NVRAM, sub, 0, optarg);
+ sub = instance = 0;
+ break;
+ case AMDFW_OPT_CONFIG:
+ cb_config->config = optarg;
+ break;
+ case AMDFW_OPT_DEBUG:
+ cb_config->debug = 1;
+ break;
+ case AMDFW_OPT_HELP:
+ usage();
+ retval = 1;
+ break;
+ case AMDFW_OPT_BODY_LOCATION:
+ cb_config->body_location = (uint32_t)strtoul(optarg, &tmp, 16);
+ if (*tmp != '\0') {
+ fprintf(stderr, "Error: Body Location specified"
+ " incorrectly (%s)\n\n", optarg);
+ retval = 1;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (!fuse_defined)
+ register_fw_fuse(DEFAULT_SOFT_FUSE_CHAIN);
+
+ if (!cb_config->output) {
+ fprintf(stderr, "Error: Output value is not specified.\n\n");
+ retval = 1;
+ }
+
+ if (ctx->rom_size % 1024 != 0) {
+ fprintf(stderr, "Error: ROM Size (%d bytes) should be a multiple of"
+ " 1024 bytes.\n\n", ctx->rom_size);
+ retval = 1;
+ }
+
+ if (ctx->rom_size < MIN_ROM_KB * 1024) {
+ fprintf(stderr, "Error: ROM Size (%dKB) must be at least %dKB.\n\n",
+ ctx->rom_size / 1024, MIN_ROM_KB);
+ retval = 1;
+ }
+
+ printf(" AMDFWTOOL Using ROM size of %dKB\n", ctx->rom_size / 1024);
+
+ if (ctx->rom_size <= MAX_MAPPED_WINDOW) {
+ uint32_t rom_base_address;
+
+ rom_base_address = 0xFFFFFFFF - ctx->rom_size + 1;
+ if (cb_config->efs_location & ~MAX_MAPPED_WINDOW_MASK)
+ cb_config->efs_location = cb_config->efs_location - rom_base_address;
+ if (cb_config->body_location & ~MAX_MAPPED_WINDOW_MASK)
+ cb_config->body_location = cb_config->body_location - rom_base_address;
+ }
+
+ /* If the flash size is larger than 16M, we assume the given
+ addresses are already relative ones. Otherwise we print error.*/
+ if (cb_config->efs_location && cb_config->efs_location > ctx->rom_size) {
+ fprintf(stderr, "Error: EFS/Directory location outside of ROM.\n\n");
+ return 1;
+ }
+ if (cb_config->body_location && cb_config->body_location > ctx->rom_size) {
+ fprintf(stderr, "Error: Body location outside of ROM.\n\n");
+ return 1;
+ }
+
+ if (!cb_config->efs_location && cb_config->body_location) {
+ fprintf(stderr, "Error AMDFW body location specified without EFS location.\n");
+ return 1;
+ }
+
+ if (cb_config->body_location != cb_config->efs_location &&
+ cb_config->body_location <
+ ALIGN(cb_config->efs_location + sizeof(embedded_firmware),
+ BLOB_ALIGNMENT)) {
+ fprintf(stderr, "Error: Insufficient space between EFS and Blobs.\n");
+ fprintf(stderr, " Require safe spacing of 256 bytes\n");
+ return 1;
+ }
+
+ if (any_location) {
+ if ((cb_config->body_location & 0x3f) || (cb_config->efs_location & 0x3f)) {
+ fprintf(stderr, "Error: Invalid Directory/EFS location.\n");
+ fprintf(stderr, " Valid locations are 64-byte aligned\n");
+ return 1;
+ }
+ } else {
+ /* efs_location is relative address now. */
+ switch (cb_config->efs_location) {
+ case 0:
+ case 0xFA0000:
+ case 0xF20000:
+ case 0xE20000:
+ case 0xC20000:
+ case 0x820000:
+ case 0x020000:
+ break;
+ case 0x7A0000:
+ case 0x720000:
+ case 0x620000:
+ case 0x420000:
+ /* Special cases for 8M. */
+ if (ctx->rom_size != 0x800000) {
+ fprintf(stderr, "Error: Invalid Directory location.\n");
+ fprintf(stderr, "%x is only for 8M image size.", cb_config->efs_location);
+ return 1;
+ }
+ break;
+ case 0x3A0000:
+ case 0x320000:
+ case 0x220000:
+ /* Special cases for 4M. */
+ if (ctx->rom_size != 0x400000) {
+ fprintf(stderr, "Error: Invalid Directory location.\n");
+ fprintf(stderr, "%x is only for 4M image size.", cb_config->efs_location);
+ return 1;
+ }
+ break;
+ default:
+ fprintf(stderr, "Error: Invalid Directory location.\n");
+ fprintf(stderr, " Valid locations are 0xFFFA0000, 0xFFF20000,\n");
+ fprintf(stderr, " 0xFFE20000, 0xFFC20000, 0xFF820000, 0xFF020000\n");
+ fprintf(stderr, " 0xFA0000, 0xF20000, 0xE20000, 0xC20000,\n");
+ fprintf(stderr, " 0x820000, 0x020000\n");
+ return 1;
+ }
+ }
+
+ printf(" AMDFWTOOL Using firmware directory location of address: 0x%08x",
+ cb_config->efs_location);
+ if (cb_config->body_location != cb_config->efs_location)
+ printf(" with a split body at: 0x%08x\n", cb_config->body_location);
+ else
+ printf("\n");
+
+ if (retval) {
+ usage();
+ return retval;
+ }
+
+ return 0;
+}