opts.c
1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <string.h> 6 #include <getopt.h> 7 8 #include "amdfwtool.h" 9 10 #define MIN_ROM_KB 256 11 #define MAX_MAPPED_WINDOW (16 * MiB) 12 #define MAX_MAPPED_WINDOW_MASK (MAX_MAPPED_WINDOW - 1) 13 14 #define DEFAULT_SOFT_FUSE_CHAIN "0x1" 15 16 enum { 17 AMDFW_OPT_CONFIG = 'c', 18 AMDFW_OPT_DEBUG = 'd', 19 AMDFW_OPT_HELP = 'h', 20 21 AMDFW_OPT_XHCI = 128, 22 AMDFW_OPT_IMC, 23 AMDFW_OPT_GEC, 24 AMDFW_OPT_RECOVERY_AB, 25 AMDFW_OPT_RECOVERY_AB_SINGLE_COPY, 26 AMDFW_OPT_USE_COMBO, 27 AMDFW_OPT_COMBO1_CONFIG, 28 AMDFW_OPT_MULTILEVEL, 29 AMDFW_OPT_NVRAM, 30 31 AMDFW_OPT_FUSE, 32 AMDFW_OPT_UNLOCK, 33 AMDFW_OPT_WHITELIST, 34 AMDFW_OPT_USE_PSPSECUREOS, 35 AMDFW_OPT_LOAD_MP2FW, 36 AMDFW_OPT_LOAD_S0I3, 37 AMDFW_OPT_SPL_TABLE, 38 AMDFW_OPT_VERSTAGE, 39 AMDFW_OPT_VERSTAGE_SIG, 40 AMDFW_OPT_OUTPUT_MANIFEST, 41 42 AMDFW_OPT_INSTANCE, 43 AMDFW_OPT_APCB, 44 AMDFW_OPT_APCB_COMBO1, 45 AMDFW_OPT_APOBBASE, 46 AMDFW_OPT_BIOSBIN, 47 AMDFW_OPT_BIOSBIN_SOURCE, 48 AMDFW_OPT_BIOSBIN_DEST, 49 AMDFW_OPT_BIOS_UNCOMP_SIZE, 50 AMDFW_OPT_BIOSBIN_UNCOMP, 51 AMDFW_OPT_UCODE, 52 AMDFW_OPT_APOB_NVBASE, 53 AMDFW_OPT_APOB_NVSIZE, 54 55 AMDFW_OPT_OUTPUT, 56 AMDFW_OPT_FLASHSIZE, 57 AMDFW_OPT_LOCATION, 58 AMDFW_OPT_ANYWHERE, 59 AMDFW_OPT_SHAREDMEM, 60 AMDFW_OPT_SHAREDMEM_SIZE, 61 AMDFW_OPT_SIGNED_OUTPUT, 62 AMDFW_OPT_SIGNED_ADDR, 63 AMDFW_OPT_BODY_LOCATION, 64 /* begin after ASCII characters */ 65 LONGOPT_SPI_READ_MODE = 256, 66 LONGOPT_SPI_SPEED = 257, 67 LONGOPT_SPI_MICRON_FLAG = 258, 68 LONGOPT_BIOS_SIG = 259, 69 LONGOPT_NVRAM_BASE = 260, 70 LONGOPT_NVRAM_SIZE = 261, 71 LONGOPT_RPMC_NVRAM_BASE = 262, 72 LONGOPT_RPMC_NVRAM_SIZE = 263, 73 }; 74 75 static const char optstring[] = {AMDFW_OPT_CONFIG, ':', 76 AMDFW_OPT_DEBUG, AMDFW_OPT_HELP 77 }; 78 79 static struct option long_options[] = { 80 {"xhci", required_argument, 0, AMDFW_OPT_XHCI }, 81 {"imc", required_argument, 0, AMDFW_OPT_IMC }, 82 {"gec", required_argument, 0, AMDFW_OPT_GEC }, 83 /* PSP Directory Table items */ 84 {"recovery-ab", no_argument, 0, AMDFW_OPT_RECOVERY_AB }, 85 {"recovery-ab-single-copy", no_argument, 0, AMDFW_OPT_RECOVERY_AB_SINGLE_COPY }, 86 {"use-combo", no_argument, 0, AMDFW_OPT_USE_COMBO }, 87 {"combo-config1", required_argument, 0, AMDFW_OPT_COMBO1_CONFIG }, 88 {"multilevel", no_argument, 0, AMDFW_OPT_MULTILEVEL }, 89 {"nvram", required_argument, 0, AMDFW_OPT_NVRAM }, 90 {"nvram-base", required_argument, 0, LONGOPT_NVRAM_BASE }, 91 {"nvram-size", required_argument, 0, LONGOPT_NVRAM_SIZE }, 92 {"rpmc-nvram-base", required_argument, 0, LONGOPT_RPMC_NVRAM_BASE }, 93 {"rpmc-nvram-size", required_argument, 0, LONGOPT_RPMC_NVRAM_SIZE }, 94 {"soft-fuse", required_argument, 0, AMDFW_OPT_FUSE }, 95 {"token-unlock", no_argument, 0, AMDFW_OPT_UNLOCK }, 96 {"whitelist", required_argument, 0, AMDFW_OPT_WHITELIST }, 97 {"use-pspsecureos", no_argument, 0, AMDFW_OPT_USE_PSPSECUREOS }, 98 {"load-mp2-fw", no_argument, 0, AMDFW_OPT_LOAD_MP2FW }, 99 {"load-s0i3", no_argument, 0, AMDFW_OPT_LOAD_S0I3 }, 100 {"spl-table", required_argument, 0, AMDFW_OPT_SPL_TABLE }, 101 {"verstage", required_argument, 0, AMDFW_OPT_VERSTAGE }, 102 {"verstage_sig", required_argument, 0, AMDFW_OPT_VERSTAGE_SIG }, 103 {"output-manifest", required_argument, 0, AMDFW_OPT_OUTPUT_MANIFEST }, 104 /* BIOS Directory Table items */ 105 {"instance", required_argument, 0, AMDFW_OPT_INSTANCE }, 106 {"apcb", required_argument, 0, AMDFW_OPT_APCB }, 107 {"apcb-combo1", required_argument, 0, AMDFW_OPT_APCB_COMBO1 }, 108 {"apob-base", required_argument, 0, AMDFW_OPT_APOBBASE }, 109 {"bios-bin", required_argument, 0, AMDFW_OPT_BIOSBIN }, 110 {"bios-bin-src", required_argument, 0, AMDFW_OPT_BIOSBIN_SOURCE }, 111 {"bios-bin-dest", required_argument, 0, AMDFW_OPT_BIOSBIN_DEST }, 112 {"bios-uncomp-size", required_argument, 0, AMDFW_OPT_BIOS_UNCOMP_SIZE }, 113 {"bios-bin-uncomp", no_argument, 0, AMDFW_OPT_BIOSBIN_UNCOMP }, 114 {"bios-sig-size", required_argument, 0, LONGOPT_BIOS_SIG }, 115 {"ucode", required_argument, 0, AMDFW_OPT_UCODE }, 116 {"apob-nv-base", required_argument, 0, AMDFW_OPT_APOB_NVBASE }, 117 {"apob-nv-size", required_argument, 0, AMDFW_OPT_APOB_NVSIZE }, 118 /* Embedded Firmware Structure items*/ 119 {"spi-read-mode", required_argument, 0, LONGOPT_SPI_READ_MODE }, 120 {"spi-speed", required_argument, 0, LONGOPT_SPI_SPEED }, 121 {"spi-micron-flag", required_argument, 0, LONGOPT_SPI_MICRON_FLAG }, 122 {"body-location", required_argument, 0, AMDFW_OPT_BODY_LOCATION }, 123 /* other */ 124 {"output", required_argument, 0, AMDFW_OPT_OUTPUT }, 125 {"flashsize", required_argument, 0, AMDFW_OPT_FLASHSIZE }, 126 {"location", required_argument, 0, AMDFW_OPT_LOCATION }, 127 {"anywhere", no_argument, 0, AMDFW_OPT_ANYWHERE }, 128 {"sharedmem", required_argument, 0, AMDFW_OPT_SHAREDMEM }, 129 {"sharedmem-size", required_argument, 0, AMDFW_OPT_SHAREDMEM_SIZE }, 130 131 {"signed-output", required_argument, 0, AMDFW_OPT_SIGNED_OUTPUT }, 132 {"signed-addr", required_argument, 0, AMDFW_OPT_SIGNED_ADDR }, 133 134 {"config", required_argument, 0, AMDFW_OPT_CONFIG }, 135 {"debug", no_argument, 0, AMDFW_OPT_DEBUG }, 136 {"help", no_argument, 0, AMDFW_OPT_HELP }, 137 {NULL, 0, 0, 0 } 138 }; 139 140 static void usage(void) 141 { 142 printf("amdfwtool: Create AMD Firmware combination\n"); 143 printf("Usage: amdfwtool [options] --flashsize <size> --output <filename>\n"); 144 printf("--xhci <FILE> Add XHCI blob\n"); 145 printf("--imc <FILE> Add IMC blob\n"); 146 printf("--gec <FILE> Add GEC blob\n"); 147 148 printf("\nPSP options:\n"); 149 printf("--use-combo Use the COMBO layout\n"); 150 printf("--combo-config1 <config file> Config for 1st combo entry\n"); 151 printf("--multilevel Generate primary and secondary tables\n"); 152 printf("--nvram <FILE> Add nvram binary\n"); 153 printf("--soft-fuse Set soft fuse\n"); 154 printf("--token-unlock Set token unlock\n"); 155 printf("--nvram-base <HEX_VAL> Base address of nvram\n"); 156 printf("--nvram-size <HEX_VAL> Size of nvram\n"); 157 printf("--rpmc-nvram-base <HEX_VAL> Base address of RPMC nvram\n"); 158 printf("--rpmc-nvram-size <HEX_VAL> Size of RPMC nvram\n"); 159 printf("--whitelist Set if there is a whitelist\n"); 160 printf("--use-pspsecureos Set if psp secure OS is needed\n"); 161 printf("--load-mp2-fw Set if load MP2 firmware\n"); 162 printf("--load-s0i3 Set if load s0i3 firmware\n"); 163 printf("--verstage <FILE> Add verstage\n"); 164 printf("--verstage_sig Add verstage signature\n"); 165 printf("--recovery-ab Use the recovery A/B layout\n"); 166 printf("\nBIOS options:\n"); 167 printf("--instance <number> Sets instance field for the next BIOS\n"); 168 printf(" firmware\n"); 169 printf("--apcb <FILE> Add AGESA PSP customization block\n"); 170 printf("--apcb-combo1 <FILE> Add APCB for 1st combo\n"); 171 printf("--apob-base <HEX_VAL> Destination for AGESA PSP output block\n"); 172 printf("--apob-nv-base <HEX_VAL> Location of S3 resume data\n"); 173 printf("--apob-nv-size <HEX_VAL> Size of S3 resume data\n"); 174 printf("--ucode <FILE> Add microcode patch\n"); 175 printf("--bios-bin <FILE> Add compressed image; auto source address\n"); 176 printf("--bios-bin-src <HEX_VAL> Address in flash of source if -V not used\n"); 177 printf("--bios-bin-dest <HEX_VAL> Destination for uncompressed BIOS\n"); 178 printf("--bios-uncomp-size <HEX> Uncompressed size of BIOS image\n"); 179 printf("--output <filename> output filename\n"); 180 printf("--flashsize <HEX_VAL> ROM size in bytes\n"); 181 printf(" size must be larger than %dKB\n", 182 MIN_ROM_KB); 183 printf(" and must a multiple of 1024\n"); 184 printf("--location Location of Directory\n"); 185 printf("--anywhere Use any 64-byte aligned addr for Directory\n"); 186 printf("--sharedmem Location of PSP/FW shared memory\n"); 187 printf("--sharedmem-size Maximum size of the PSP/FW shared memory\n"); 188 printf(" area\n"); 189 printf("--output-manifest <FILE> Writes a manifest with the blobs versions\n"); 190 printf("\nEmbedded Firmware Structure options used by the PSP:\n"); 191 printf("--spi-speed <HEX_VAL> SPI fast speed to place in EFS Table\n"); 192 printf(" 0x0 66.66Mhz\n"); 193 printf(" 0x1 33.33MHz\n"); 194 printf(" 0x2 22.22MHz\n"); 195 printf(" 0x3 16.66MHz\n"); 196 printf(" 0x4 100MHz\n"); 197 printf(" 0x5 800KHz\n"); 198 printf("--spi-read-mode <HEX_VAL> SPI read mode to place in EFS Table\n"); 199 printf(" 0x0 Normal Read (up to 33M)\n"); 200 printf(" 0x1 Reserved\n"); 201 printf(" 0x2 Dual IO (1-1-2)\n"); 202 printf(" 0x3 Quad IO (1-1-4)\n"); 203 printf(" 0x4 Dual IO (1-2-2)\n"); 204 printf(" 0x5 Quad IO (1-4-4)\n"); 205 printf(" 0x6 Normal Read (up to 66M)\n"); 206 printf(" 0x7 Fast Read\n"); 207 printf("--spi-micron-flag <HEX_VAL> Micron SPI part support for RV and later SOC\n"); 208 printf(" 0x0 Micron parts are not used\n"); 209 printf(" 0x1 Micron parts are always used\n"); 210 printf(" 0x2 Micron parts optional, this option is only\n"); 211 printf(" supported with RN/LCN SOC\n"); 212 printf("\nGeneral options:\n"); 213 printf("-c|--config <config file> Config file\n"); 214 printf("-d|--debug Print debug message\n"); 215 printf("-h|--help Show this help\n"); 216 } 217 218 extern amd_fw_entry amd_psp_fw_table[]; 219 extern amd_bios_entry amd_bios_table[]; 220 extern amd_fw_entry amd_fw_table[]; 221 222 static void register_amd_psp_fw_addr(amd_fw_type type, int sub, 223 char *dst_str, char *size_str) 224 { 225 unsigned int i; 226 227 for (i = 0; amd_psp_fw_table[i].type != AMD_FW_INVALID; i++) { 228 if (amd_psp_fw_table[i].type != type) 229 continue; 230 231 if (amd_psp_fw_table[i].subprog == sub) { 232 if (dst_str) 233 amd_psp_fw_table[i].dest = strtoull(dst_str, NULL, 16); 234 if (size_str) 235 amd_psp_fw_table[i].size = strtoul(size_str, NULL, 16); 236 return; 237 } 238 } 239 } 240 241 static void register_bios_fw_addr(amd_bios_type type, char *src_str, 242 char *dst_str, char *size_str) 243 { 244 uint32_t i; 245 for (i = 0; amd_bios_table[i].type != AMD_BIOS_INVALID; i++) { 246 if (amd_bios_table[i].type != type) 247 continue; 248 249 if (src_str) 250 amd_bios_table[i].src = strtoull(src_str, NULL, 16); 251 if (dst_str) 252 amd_bios_table[i].dest = strtoull(dst_str, NULL, 16); 253 if (size_str) 254 amd_bios_table[i].size = strtoul(size_str, NULL, 16); 255 256 return; 257 } 258 } 259 260 static void register_fw_token_unlock(void) 261 { 262 uint32_t i; 263 264 for (i = 0; amd_psp_fw_table[i].type != AMD_FW_INVALID; i++) { 265 if (amd_psp_fw_table[i].type != AMD_TOKEN_UNLOCK) 266 continue; 267 268 amd_psp_fw_table[i].other = 1; 269 return; 270 } 271 } 272 273 static void register_fw_filename(amd_fw_type type, uint8_t sub, char filename[]) 274 { 275 unsigned int i; 276 277 for (i = 0; amd_fw_table[i].type != AMD_FW_INVALID; i++) { 278 if (amd_fw_table[i].type == type) { 279 amd_fw_table[i].filename = filename; 280 return; 281 } 282 } 283 284 for (i = 0; amd_psp_fw_table[i].type != AMD_FW_INVALID; i++) { 285 if (amd_psp_fw_table[i].type != type) 286 continue; 287 288 if (amd_psp_fw_table[i].subprog == sub) { 289 amd_psp_fw_table[i].filename = filename; 290 return; 291 } 292 } 293 } 294 295 static void register_bdt_data(amd_bios_type type, int sub, int ins, char name[]) 296 { 297 uint32_t i; 298 299 for (i = 0; amd_bios_table[i].type != AMD_BIOS_INVALID; i++) { 300 if (amd_bios_table[i].type == type 301 && amd_bios_table[i].inst == ins 302 && amd_bios_table[i].subpr == sub) { 303 amd_bios_table[i].filename = name; 304 return; 305 } 306 } 307 } 308 309 static void register_fw_fuse(char *str) 310 { 311 uint32_t i; 312 313 for (i = 0; amd_psp_fw_table[i].type != AMD_FW_INVALID; i++) { 314 if (amd_psp_fw_table[i].type != AMD_PSP_FUSE_CHAIN) 315 continue; 316 317 amd_psp_fw_table[i].other = strtoull(str, NULL, 16); 318 return; 319 } 320 } 321 322 void register_apcb_combo(amd_cb_config *cb_config, int combo_index, context *ctx) 323 { 324 if (ctx->combo_apcb[combo_index].filename != NULL) { 325 register_bdt_data(AMD_BIOS_APCB, 326 ctx->combo_apcb[combo_index].sub, 327 ctx->combo_apcb[combo_index].ins & 0xF, 328 ctx->combo_apcb[combo_index].filename); 329 if (cb_config->have_apcb_bk) 330 register_bdt_data(AMD_BIOS_APCB_BK, 331 ctx->combo_apcb_bk[combo_index].sub, 332 ctx->combo_apcb_bk[combo_index].ins & 0xF, 333 ctx->combo_apcb_bk[combo_index].filename); 334 } else { 335 /* Use main APCB if no Combo APCB is provided */ 336 register_bdt_data(AMD_BIOS_APCB, ctx->combo_apcb[0].sub, 337 ctx->combo_apcb[0].ins & 0xF, ctx->combo_apcb[0].filename); 338 if (cb_config->have_apcb_bk) 339 register_bdt_data(AMD_BIOS_APCB_BK, 340 ctx->combo_apcb_bk[0].sub, 341 ctx->combo_apcb_bk[0].ins & 0xF, 342 ctx->combo_apcb_bk[0].filename); 343 } 344 } 345 346 int amdfwtool_getopt(int argc, char *argv[], amd_cb_config *cb_config, context *ctx) 347 { 348 int c; 349 /* Values cleared after each firmware or parameter, regardless if N/A */ 350 uint8_t sub = 0, instance = 0; 351 char *tmp; 352 int retval = 0; 353 bool any_location = 0; 354 int fuse_defined = 0; 355 356 while (1) { 357 int optindex = 0; 358 int bios_tbl_index = -1; 359 360 c = getopt_long(argc, argv, optstring, long_options, &optindex); 361 362 if (c == -1) 363 break; 364 365 switch (c) { 366 case AMDFW_OPT_XHCI: 367 register_fw_filename(AMD_FW_XHCI, sub, optarg); 368 sub = instance = 0; 369 break; 370 case AMDFW_OPT_IMC: 371 register_fw_filename(AMD_FW_IMC, sub, optarg); 372 sub = instance = 0; 373 break; 374 case AMDFW_OPT_GEC: 375 register_fw_filename(AMD_FW_GEC, sub, optarg); 376 sub = instance = 0; 377 break; 378 case AMDFW_OPT_RECOVERY_AB: 379 cb_config->recovery_ab = true; 380 break; 381 case AMDFW_OPT_RECOVERY_AB_SINGLE_COPY: 382 cb_config->recovery_ab = true; 383 cb_config->recovery_ab_single_copy = true; 384 break; 385 case AMDFW_OPT_USE_COMBO: 386 cb_config->use_combo = true; 387 break; 388 case AMDFW_OPT_COMBO1_CONFIG: 389 cb_config->use_combo = true; 390 /* assert_fw_entry(1, MAX_COMBO_ENTRIES, &ctx); */ 391 cb_config->combo_config[1] = optarg; 392 break; 393 case AMDFW_OPT_MULTILEVEL: 394 cb_config->multi_level = true; 395 break; 396 case AMDFW_OPT_UNLOCK: 397 register_fw_token_unlock(); 398 cb_config->unlock_secure = true; 399 sub = instance = 0; 400 break; 401 case AMDFW_OPT_USE_PSPSECUREOS: 402 cb_config->use_secureos = true; 403 break; 404 case AMDFW_OPT_INSTANCE: 405 instance = strtoul(optarg, &tmp, 16); 406 break; 407 case AMDFW_OPT_LOAD_MP2FW: 408 cb_config->load_mp2_fw = true; 409 break; 410 case AMDFW_OPT_NVRAM: 411 register_fw_filename(AMD_FW_PSP_NVRAM, sub, optarg); 412 sub = instance = 0; 413 break; 414 case AMDFW_OPT_FUSE: 415 register_fw_fuse(optarg); 416 fuse_defined = 1; 417 sub = 0; 418 break; 419 case AMDFW_OPT_APCB: 420 if ((instance & 0xF0) == 0) { 421 register_bdt_data(AMD_BIOS_APCB, sub, instance & 0xF, optarg); 422 ctx->combo_apcb[0].filename = optarg; 423 ctx->combo_apcb[0].ins = instance; 424 ctx->combo_apcb[0].sub = sub; 425 } else { 426 register_bdt_data(AMD_BIOS_APCB_BK, sub, 427 instance & 0xF, optarg); 428 ctx->combo_apcb_bk[0].filename = optarg; 429 ctx->combo_apcb_bk[0].ins = instance; 430 ctx->combo_apcb_bk[0].sub = sub; 431 cb_config->have_apcb_bk = 1; 432 } 433 sub = instance = 0; 434 break; 435 case AMDFW_OPT_APCB_COMBO1: 436 /* assert_fw_entry(1, MAX_COMBO_ENTRIES, &ctx); */ 437 if ((instance & 0xF0) == 0) { 438 ctx->combo_apcb[1].filename = optarg; 439 ctx->combo_apcb[1].ins = instance; 440 ctx->combo_apcb[1].sub = sub; 441 } else { 442 ctx->combo_apcb_bk[1].filename = optarg; 443 ctx->combo_apcb_bk[1].ins = instance; 444 ctx->combo_apcb_bk[1].sub = sub; 445 cb_config->have_apcb_bk = 1; 446 } 447 sub = instance = 0; 448 break; 449 case AMDFW_OPT_APOBBASE: 450 /* APOB destination */ 451 register_bios_fw_addr(AMD_BIOS_APOB, 0, optarg, 0); 452 sub = instance = 0; 453 break; 454 case AMDFW_OPT_APOB_NVBASE: 455 /* APOB NV source */ 456 register_bios_fw_addr(AMD_BIOS_APOB_NV, optarg, 0, 0); 457 sub = instance = 0; 458 break; 459 case AMDFW_OPT_APOB_NVSIZE: 460 /* APOB NV size */ 461 register_bios_fw_addr(AMD_BIOS_APOB_NV, 0, 0, optarg); 462 sub = instance = 0; 463 break; 464 case AMDFW_OPT_BIOSBIN: 465 register_bdt_data(AMD_BIOS_BIN, sub, instance, optarg); 466 sub = instance = 0; 467 break; 468 case AMDFW_OPT_BIOSBIN_SOURCE: 469 /* BIOS source */ 470 register_bios_fw_addr(AMD_BIOS_BIN, optarg, 0, 0); 471 sub = instance = 0; 472 break; 473 case AMDFW_OPT_BIOSBIN_DEST: 474 /* BIOS destination */ 475 register_bios_fw_addr(AMD_BIOS_BIN, 0, optarg, 0); 476 sub = instance = 0; 477 break; 478 case AMDFW_OPT_BIOS_UNCOMP_SIZE: 479 /* BIOS destination size */ 480 register_bios_fw_addr(AMD_BIOS_BIN, 0, 0, optarg); 481 sub = instance = 0; 482 break; 483 case AMDFW_OPT_BIOSBIN_UNCOMP: 484 bios_tbl_index = find_bios_entry(AMD_BIOS_BIN); 485 if (bios_tbl_index != -1) 486 amd_bios_table[bios_tbl_index].zlib = 0; 487 break; 488 case LONGOPT_BIOS_SIG: 489 /* BIOS signature size */ 490 register_bios_fw_addr(AMD_BIOS_SIG, 0, 0, optarg); 491 sub = instance = 0; 492 break; 493 case AMDFW_OPT_UCODE: 494 register_bdt_data(AMD_BIOS_UCODE, sub, 495 instance, optarg); 496 sub = instance = 0; 497 break; 498 case AMDFW_OPT_LOAD_S0I3: 499 cb_config->s0i3 = true; 500 break; 501 case AMDFW_OPT_SPL_TABLE: 502 register_fw_filename(AMD_FW_SPL, sub, optarg); 503 sub = instance = 0; 504 cb_config->have_mb_spl = true; 505 break; 506 case AMDFW_OPT_WHITELIST: 507 register_fw_filename(AMD_FW_PSP_WHITELIST, sub, optarg); 508 sub = instance = 0; 509 cb_config->have_whitelist = true; 510 break; 511 case AMDFW_OPT_VERSTAGE: 512 register_fw_filename(AMD_FW_PSP_VERSTAGE, sub, optarg); 513 sub = instance = 0; 514 break; 515 case AMDFW_OPT_VERSTAGE_SIG: 516 register_fw_filename(AMD_FW_VERSTAGE_SIG, sub, optarg); 517 sub = instance = 0; 518 break; 519 case AMDFW_OPT_OUTPUT_MANIFEST: 520 cb_config->manifest_file = optarg; 521 break; 522 case AMDFW_OPT_SIGNED_OUTPUT: 523 cb_config->signed_output_file = optarg; 524 sub = instance = 0; 525 break; 526 case AMDFW_OPT_SIGNED_ADDR: 527 cb_config->signed_start_addr = strtoull(optarg, NULL, 10); 528 sub = instance = 0; 529 break; 530 case LONGOPT_SPI_READ_MODE: 531 cb_config->efs_spi_readmode = strtoull(optarg, NULL, 16); 532 sub = instance = 0; 533 break; 534 case LONGOPT_SPI_SPEED: 535 cb_config->efs_spi_speed = strtoull(optarg, NULL, 16); 536 sub = instance = 0; 537 break; 538 case LONGOPT_SPI_MICRON_FLAG: 539 cb_config->efs_spi_micron_flag = strtoull(optarg, NULL, 16); 540 sub = instance = 0; 541 break; 542 case AMDFW_OPT_OUTPUT: 543 cb_config->output = optarg; 544 break; 545 case AMDFW_OPT_FLASHSIZE: 546 ctx->rom_size = (uint32_t)strtoul(optarg, &tmp, 16); 547 if (*tmp != '\0') { 548 fprintf(stderr, "Error: ROM size specified" 549 " incorrectly (%s)\n\n", optarg); 550 retval = 1; 551 } 552 break; 553 case AMDFW_OPT_LOCATION: 554 cb_config->efs_location = (uint32_t)strtoul(optarg, &tmp, 16); 555 if (*tmp != '\0') { 556 fprintf(stderr, "Error: Directory Location specified" 557 " incorrectly (%s)\n\n", optarg); 558 retval = 1; 559 } 560 if (cb_config->body_location == 0) 561 cb_config->body_location = cb_config->efs_location; 562 break; 563 case AMDFW_OPT_ANYWHERE: 564 any_location = 1; 565 break; 566 case AMDFW_OPT_SHAREDMEM: 567 /* shared memory destination */ 568 register_bios_fw_addr(AMD_BIOS_PSP_SHARED_MEM, 0, optarg, 0); 569 sub = instance = 0; 570 break; 571 case AMDFW_OPT_SHAREDMEM_SIZE: 572 /* shared memory size */ 573 register_bios_fw_addr(AMD_BIOS_PSP_SHARED_MEM, NULL, NULL, optarg); 574 sub = instance = 0; 575 break; 576 case LONGOPT_NVRAM_BASE: 577 /* PSP NV base */ 578 register_amd_psp_fw_addr(AMD_FW_PSP_NVRAM, sub, optarg, 0); 579 sub = instance = 0; 580 break; 581 case LONGOPT_NVRAM_SIZE: 582 /* PSP NV size */ 583 register_amd_psp_fw_addr(AMD_FW_PSP_NVRAM, sub, 0, optarg); 584 sub = instance = 0; 585 break; 586 case LONGOPT_RPMC_NVRAM_BASE: 587 /* PSP RPMC NV base */ 588 register_amd_psp_fw_addr(AMD_RPMC_NVRAM, sub, optarg, 0); 589 sub = instance = 0; 590 break; 591 case LONGOPT_RPMC_NVRAM_SIZE: 592 /* PSP RPMC NV size */ 593 register_amd_psp_fw_addr(AMD_RPMC_NVRAM, sub, 0, optarg); 594 sub = instance = 0; 595 break; 596 case AMDFW_OPT_CONFIG: 597 cb_config->config = optarg; 598 break; 599 case AMDFW_OPT_DEBUG: 600 cb_config->debug = 1; 601 break; 602 case AMDFW_OPT_HELP: 603 usage(); 604 retval = 1; 605 break; 606 case AMDFW_OPT_BODY_LOCATION: 607 cb_config->body_location = (uint32_t)strtoul(optarg, &tmp, 16); 608 if (*tmp != '\0') { 609 fprintf(stderr, "Error: Body Location specified" 610 " incorrectly (%s)\n\n", optarg); 611 retval = 1; 612 } 613 break; 614 615 default: 616 break; 617 } 618 } 619 620 if (!fuse_defined) 621 register_fw_fuse(DEFAULT_SOFT_FUSE_CHAIN); 622 623 if (!cb_config->output) { 624 fprintf(stderr, "Error: Output value is not specified.\n\n"); 625 retval = 1; 626 } 627 628 if (ctx->rom_size % 1024 != 0) { 629 fprintf(stderr, "Error: ROM Size (%d bytes) should be a multiple of" 630 " 1024 bytes.\n\n", ctx->rom_size); 631 retval = 1; 632 } 633 634 if (ctx->rom_size < MIN_ROM_KB * 1024) { 635 fprintf(stderr, "Error: ROM Size (%dKB) must be at least %dKB.\n\n", 636 ctx->rom_size / 1024, MIN_ROM_KB); 637 retval = 1; 638 } 639 640 printf(" AMDFWTOOL Using ROM size of %dKB\n", ctx->rom_size / 1024); 641 642 if (ctx->rom_size <= MAX_MAPPED_WINDOW) { 643 uint32_t rom_base_address; 644 645 rom_base_address = 0xFFFFFFFF - ctx->rom_size + 1; 646 if (cb_config->efs_location & ~MAX_MAPPED_WINDOW_MASK) 647 cb_config->efs_location = cb_config->efs_location - rom_base_address; 648 if (cb_config->body_location & ~MAX_MAPPED_WINDOW_MASK) 649 cb_config->body_location = cb_config->body_location - rom_base_address; 650 } 651 652 /* If the flash size is larger than 16M, we assume the given 653 addresses are already relative ones. Otherwise we print error.*/ 654 if (cb_config->efs_location && cb_config->efs_location > ctx->rom_size) { 655 fprintf(stderr, "Error: EFS/Directory location outside of ROM.\n\n"); 656 return 1; 657 } 658 if (cb_config->body_location && cb_config->body_location > ctx->rom_size) { 659 fprintf(stderr, "Error: Body location outside of ROM.\n\n"); 660 return 1; 661 } 662 663 if (!cb_config->efs_location && cb_config->body_location) { 664 fprintf(stderr, "Error AMDFW body location specified without EFS location.\n"); 665 return 1; 666 } 667 668 if (cb_config->body_location != cb_config->efs_location && 669 cb_config->body_location < 670 ALIGN(cb_config->efs_location + sizeof(embedded_firmware), 671 BLOB_ALIGNMENT)) { 672 fprintf(stderr, "Error: Insufficient space between EFS and Blobs.\n"); 673 fprintf(stderr, " Require safe spacing of 256 bytes\n"); 674 return 1; 675 } 676 677 if (any_location) { 678 if ((cb_config->body_location & 0x3f) || (cb_config->efs_location & 0x3f)) { 679 fprintf(stderr, "Error: Invalid Directory/EFS location.\n"); 680 fprintf(stderr, " Valid locations are 64-byte aligned\n"); 681 return 1; 682 } 683 } else { 684 /* efs_location is relative address now. */ 685 switch (cb_config->efs_location) { 686 case 0: 687 case 0xFA0000: 688 case 0xF20000: 689 case 0xE20000: 690 case 0xC20000: 691 case 0x820000: 692 case 0x020000: 693 break; 694 case 0x7A0000: 695 case 0x720000: 696 case 0x620000: 697 case 0x420000: 698 /* Special cases for 8M. */ 699 if (ctx->rom_size != 0x800000) { 700 fprintf(stderr, "Error: Invalid Directory location.\n"); 701 fprintf(stderr, "%x is only for 8M image size.", cb_config->efs_location); 702 return 1; 703 } 704 break; 705 case 0x3A0000: 706 case 0x320000: 707 case 0x220000: 708 /* Special cases for 4M. */ 709 if (ctx->rom_size != 0x400000) { 710 fprintf(stderr, "Error: Invalid Directory location.\n"); 711 fprintf(stderr, "%x is only for 4M image size.", cb_config->efs_location); 712 return 1; 713 } 714 break; 715 default: 716 fprintf(stderr, "Error: Invalid Directory location.\n"); 717 fprintf(stderr, " Valid locations are 0xFFFA0000, 0xFFF20000,\n"); 718 fprintf(stderr, " 0xFFE20000, 0xFFC20000, 0xFF820000, 0xFF020000\n"); 719 fprintf(stderr, " 0xFA0000, 0xF20000, 0xE20000, 0xC20000,\n"); 720 fprintf(stderr, " 0x820000, 0x020000\n"); 721 return 1; 722 } 723 } 724 725 printf(" AMDFWTOOL Using firmware directory location of address: 0x%08x", 726 cb_config->efs_location); 727 if (cb_config->body_location != cb_config->efs_location) 728 printf(" with a split body at: 0x%08x\n", cb_config->body_location); 729 else 730 printf("\n"); 731 732 if (retval) { 733 usage(); 734 return retval; 735 } 736 737 return 0; 738 }