util/: Replace GPLv2 boiler plate with SPDX header
Used commands:
perl -i -p0e 's|\/\*[\s*]*.*is free software[:;][\s*]*you[\s*]*can[\s*]*redistribute[\s*]*it[\s*]*and\/or[\s*]*modify[\s*]*it[\s*]*under[\s*]*the[\s*]*terms[\s*]*of[\s*]*the[\s*]*GNU[\s*]*General[\s*]*Public[\s*]*License[\s*]*as[\s*]*published[\s*]*by[\s*]*the[\s*]*Free[\s*]*Software[\s*]*Foundation[;,][\s*]*version[\s*]*2[\s*]*of[\s*]*the[\s*]*License.[\s*]*This[\s*]*program[\s*]*is[\s*]*distributed[\s*]*in[\s*]*the[\s*]*hope[\s*]*that[\s*]*it[\s*]*will[\s*]*be[\s*]*useful,[\s*]*but[\s*]*WITHOUT[\s*]*ANY[\s*]*WARRANTY;[\s*]*without[\s*]*even[\s*]*the[\s*]*implied[\s*]*warranty[\s*]*of[\s*]*MERCHANTABILITY[\s*]*or[\s*]*FITNESS[\s*]*FOR[\s*]*A[\s*]*PARTICULAR[\s*]*PURPOSE.[\s*]*See[\s*]*the[\s*]*GNU[\s*]*General[\s*]*Public[\s*]*License[\s*]*for[\s*]*more[\s*]*details.[\s*]*\*\/|/* SPDX-License-Identifier: GPL-2.0-only */|' $(cat filelist)
perl -i -p0e 's|This[\s*]*program[\s*]*is[\s*]*free[\s*]*software[:;][\s*]*you[\s*]*can[\s*]*redistribute[\s*]*it[\s*]*and/or[\s*]*modify[\s*]*it[\s*]*under[\s*]*the[\s*]*terms[\s*]*of[\s*]*the[\s*]*GNU[\s*]*General[\s*]*Public[\s*]*License[\s*]*as[\s*]*published[\s*]*by[\s*]*the[\s*]*Free[\s*]*Software[\s*]*Foundation[;,][\s*]*either[\s*]*version[\s*]*2[\s*]*of[\s*]*the[\s*]*License,[\s*]*or[\s*]*.at[\s*]*your[\s*]*option.*[\s*]*any[\s*]*later[\s*]*version.[\s*]*This[\s*]*program[\s*]*is[\s*]*distributed[\s*]*in[\s*]*the[\s*]*hope[\s*]*that[\s*]*it[\s*]*will[\s*]*be[\s*]*useful,[\s*]*but[\s*]*WITHOUT[\s*]*ANY[\s*]*WARRANTY;[\s*]*without[\s*]*even[\s*]*the[\s*]*implied[\s*]*warranty[\s*]*of[\s*]*MERCHANTABILITY[\s*]*or[\s*]*FITNESS[\s*]*FOR[\s*]*A[\s*]*PARTICULAR[\s*]*PURPOSE.[\s*]*See[\s*]*the[\s*]*GNU[\s*]*General[\s*]*Public[\s*]*License[\s*]*for[\s*]*more[\s*]*details.[\s*]*\*\/|/* SPDX-License-Identifier: GPL-2.0-or-later */|' $(cat filelist)
perl -i -p0e 's|\/\*[\s*]*.*This[\s*#]*program[\s*#]*is[\s*#]*free[\s*#]*software[;:,][\s*#]*you[\s*#]*can[\s*#]*redistribute[\s*#]*it[\s*#]*and/or[\s*#]*modify[\s*#]*it[\s*#]*under[\s*#]*the[\s*#]*terms[\s*#]*of[\s*#]*the[\s*#]*GNU[\s*#]*General[\s*#]*Public[\s*#]*License[\s*#]*as[\s*#]*published[\s*#]*by[\s*#]*the[\s*#]*Free[\s*#]*Software[\s*#]*Foundation[;:,][\s*#]*either[\s*#]*version[\s*#]*3[\s*#]*of[\s*#]*the[\s*#]*License[;:,][\s*#]*or[\s*#]*.at[\s*#]*your[\s*#]*option.*[\s*#]*any[\s*#]*later[\s*#]*version.[\s*#]*This[\s*#]*program[\s*#]*is[\s*#]*distributed[\s*#]*in[\s*#]*the[\s*#]*hope[\s*#]*that[\s*#]*it[\s*#]*will[\s*#]*be[\s*#]*useful[;:,][\s*#]*but[\s*#]*WITHOUT[\s*#]*ANY[\s*#]*WARRANTY[;:,][\s*#]*without[\s*#]*even[\s*#]*the[\s*#]*implied[\s*#]*warranty[\s*#]*of[\s*#]*MERCHANTABILITY[\s*#]*or[\s*#]*FITNESS[\s*#]*FOR[\s*#]*A[\s*#]*PARTICULAR[\s*#]*PURPOSE.[\s*#]*See[\s*#]*the[\s*#]*GNU[\s*#]*General[\s*#]*Public[\s*#]*License[\s*#]*for[\s*#]*more[\s*#]*details.[\s*]*\*\/|/* SPDX-License-Identifier: GPL-3.0-or-later */|' $(cat filelist)
perl -i -p0e 's|(\#\#*)[\w]*.*is free software[:;][\#\s]*you[\#\s]*can[\#\s]*redistribute[\#\s]*it[\#\s]*and\/or[\#\s]*modify[\#\s]*it[\s\#]*under[\s \#]*the[\s\#]*terms[\s\#]*of[\s\#]*the[\s\#]*GNU[\s\#]*General[\s\#]*Public[\s\#]*License[\s\#]*as[\s\#]*published[\s\#]*by[\s\#]*the[\s\#]*Free[\s\#]*Software[\s\#]*Foundation[;,][\s\#]*version[\s\#]*2[\s\#]*of[\s\#]*the[\s\#]*License.*[\s\#]*This[\s\#]*program[\s\#]*is[\s\#]*distributed[\s\#]*in[\s\#]*the[\s\#]*hope[\s\#]*that[\s\#]*it[\s\#]*will[\#\s]*be[\#\s]*useful,[\#\s]*but[\#\s]*WITHOUT[\#\s]*ANY[\#\s]*WARRANTY;[\#\s]*without[\#\s]*even[\#\s]*the[\#\s]*implied[\#\s]*warranty[\#\s]*of[\#\s]*MERCHANTABILITY[\#\s]*or[\#\s]*FITNESS[\#\s]*FOR[\#\s]*A[\#\s]*PARTICULAR[\#\s]*PURPOSE.[\#\s]*See[\#\s]*the[\#\s]*GNU[\#\s]*General[\#\s]*Public[\#\s]*License[\#\s]*for[\#\s]*more[\#\s]*details.\s(#* *\n)*|\1 SPDX-License-Identifier: GPL-2.0-only\n\n|' $(cat filelist)
perl -i -p0e 's|(\#\#*)[\w*]*.*is free software[:;][\s*]*you[\s*]*can[\s*]*redistribute[\s*]*it[\s*]*and\/or[\s*]*modify[\s*]*it[\s*]*under[\s*]*the[\s*]*terms[\s*]*of[\s*]*the[\s*]*GNU[\s*]*General[\s*]*Public[\s*]*License[\s*]*as[\s*]*published[\s*]*by[\s*]*the[\s*]*Free[\s*]*Software[\s*]*Foundation[;,][\s*]*version[\s*]*2[\s*]*of[\s*]*the[\s*]*License.[\s*]*This[\s*]*program[\s*]*is[\s*]*distributed[\s*]*in[\s*]*the[\s*]*hope[\s*]*that[\s*]*it[\s*]*will[\s*]*be[\s*]*useful,[\s*]*but[\s*]*WITHOUT[\s*]*ANY[\s*]*WARRANTY;[\s*]*without[\s*]*even[\s*]*the[\s*]*implied[\s*]*warranty[\s*]*of[\s*]*MERCHANTABILITY[\s*]*or[\s*]*FITNESS[\s*]*FOR[\s*]*A[\s*]*PARTICULAR[\s*]*PURPOSE.[\s*]*See[\s*]*the[\s*]*GNU[\s*]*General[\s*]*Public[\s*]*License[\s*]*for[\s*]*more[\s*]*details.\s(#* *\n)*|\1 SPDX-License-Identifier: GPL-2.0-only\n\n|' $(cat filelist)
Change-Id: I1008a63b804f355a916221ac994701d7584f60ff
Signed-off-by: Patrick Georgi <pgeorgi@google.com>
Signed-off-by: Elyes HAOUAS <ehaouas@noos.fr>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/41177
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2020-05-08 20:48:04 +02:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
2015-11-17 15:57:39 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* ROMSIG At ROMBASE + 0x20000:
|
2016-02-19 06:47:31 +01:00
|
|
|
* 0 4 8 C
|
2015-11-17 15:57:39 +01:00
|
|
|
* +------------+---------------+----------------+------------+
|
|
|
|
* | 0x55AA55AA |EC ROM Address |GEC ROM Address |USB3 ROM |
|
|
|
|
* +------------+---------------+----------------+------------+
|
2016-02-19 06:47:31 +01:00
|
|
|
* | PSPDIR ADDR|PSPDIR ADDR |<-- Field 0x14 could be either
|
|
|
|
* +------------+---------------+ 2nd PSP directory or PSP COMBO directory
|
2015-11-17 15:57:39 +01:00
|
|
|
* EC ROM should be 64K aligned.
|
|
|
|
*
|
2015-11-20 05:29:04 +01:00
|
|
|
* PSP directory (Where "PSPDIR ADDR" points)
|
2015-11-17 15:57:39 +01:00
|
|
|
* +------------+---------------+----------------+------------+
|
|
|
|
* | 'PSP$' | Fletcher | Count | Reserved |
|
|
|
|
* +------------+---------------+----------------+------------+
|
|
|
|
* | 0 | size | Base address | Reserved | Pubkey
|
|
|
|
* +------------+---------------+----------------+------------+
|
|
|
|
* | 1 | size | Base address | Reserved | Bootloader
|
|
|
|
* +------------+---------------+----------------+------------+
|
|
|
|
* | 8 | size | Base address | Reserved | Smu Firmware
|
|
|
|
* +------------+---------------+----------------+------------+
|
|
|
|
* | 3 | size | Base address | Reserved | Recovery Firmware
|
|
|
|
* +------------+---------------+----------------+------------+
|
|
|
|
* | |
|
|
|
|
* | |
|
|
|
|
* | Other PSP Firmware |
|
|
|
|
* | |
|
|
|
|
* | |
|
|
|
|
* +------------+---------------+----------------+------------+
|
2015-11-20 05:29:04 +01:00
|
|
|
*
|
2016-02-19 06:47:31 +01:00
|
|
|
* PSP Combo directory
|
2015-11-20 05:29:04 +01:00
|
|
|
* +------------+---------------+----------------+------------+
|
2016-02-19 06:34:59 +01:00
|
|
|
* | 'PSP2' | Fletcher | Count |Look up mode|
|
2015-11-20 05:29:04 +01:00
|
|
|
* +------------+---------------+----------------+------------+
|
2016-03-02 07:47:27 +01:00
|
|
|
* | R e s e r v e d |
|
|
|
|
* +------------+---------------+----------------+------------+
|
2016-02-19 06:34:59 +01:00
|
|
|
* | ID-Sel | PSP ID | PSPDIR ADDR | | 2nd PSP directory
|
2015-11-20 05:29:04 +01:00
|
|
|
* +------------+---------------+----------------+------------+
|
2016-02-19 06:34:59 +01:00
|
|
|
* | ID-Sel | PSP ID | PSPDIR ADDR | | 3rd PSP directory
|
2015-11-20 05:29:04 +01:00
|
|
|
* +------------+---------------+----------------+------------+
|
|
|
|
* | |
|
|
|
|
* | Other PSP |
|
|
|
|
* | |
|
|
|
|
* +------------+---------------+----------------+------------+
|
|
|
|
*
|
2015-11-17 15:57:39 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <errno.h>
|
2020-04-07 22:16:39 +02:00
|
|
|
#include <stdbool.h>
|
2015-11-17 15:57:39 +01:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <getopt.h>
|
2020-10-28 04:38:09 +01:00
|
|
|
#include <libgen.h>
|
2020-12-30 00:01:59 +01:00
|
|
|
#include <stdint.h>
|
2020-10-28 04:38:09 +01:00
|
|
|
|
|
|
|
#include "amdfwtool.h"
|
2015-11-17 15:57:39 +01:00
|
|
|
|
2016-11-08 17:55:01 +01:00
|
|
|
#define AMD_ROMSIG_OFFSET 0x20000
|
|
|
|
#define MIN_ROM_KB 256
|
2015-11-17 15:57:39 +01:00
|
|
|
|
2016-11-08 19:34:02 +01:00
|
|
|
#define ALIGN(val, by) (((val) + (by) - 1) & ~((by) - 1))
|
2019-04-11 17:44:43 +02:00
|
|
|
#define _MAX(A, B) (((A) > (B)) ? (A) : (B))
|
|
|
|
#define ERASE_ALIGNMENT 0x1000U
|
2019-03-05 00:53:15 +01:00
|
|
|
#define TABLE_ALIGNMENT 0x1000U
|
|
|
|
#define BLOB_ALIGNMENT 0x100U
|
2019-04-01 18:48:43 +02:00
|
|
|
#define TABLE_ERASE_ALIGNMENT _MAX(TABLE_ALIGNMENT, ERASE_ALIGNMENT)
|
2019-04-11 17:44:43 +02:00
|
|
|
#define BLOB_ERASE_ALIGNMENT _MAX(BLOB_ALIGNMENT, ERASE_ALIGNMENT)
|
2015-11-17 15:57:39 +01:00
|
|
|
|
2019-04-01 18:16:41 +02:00
|
|
|
#define DEFAULT_SOFT_FUSE_CHAIN "0x1"
|
|
|
|
|
2015-11-17 15:57:39 +01:00
|
|
|
/*
|
2019-03-05 00:50:37 +01:00
|
|
|
* Beginning with Family 15h Models 70h-7F, a.k.a Stoney Ridge, the PSP
|
|
|
|
* can support an optional "combo" implementation. If the PSP sees the
|
|
|
|
* PSP2 cookie, it interprets the table as a roadmap to additional PSP
|
|
|
|
* tables. Using this, support for multiple product generations may be
|
|
|
|
* built into one image. If the PSP$ cookie is found, the table is a
|
|
|
|
* normal directory table.
|
|
|
|
*
|
|
|
|
* Modern generations supporting the combo directories require the
|
|
|
|
* pointer to be at offset 0x14 of the Embedded Firmware Structure,
|
|
|
|
* regardless of the type of directory used. The --combo-capable
|
|
|
|
* argument enforces this placement.
|
|
|
|
*
|
|
|
|
* TODO: Future work may require fully implementing the PSP_COMBO feature.
|
2016-02-19 06:47:31 +01:00
|
|
|
*/
|
2019-03-05 00:50:37 +01:00
|
|
|
#define PSP_COMBO 0
|
2015-11-17 15:57:39 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Creates the OSI Fletcher checksum. See 8473-1, Appendix C, section C.3.
|
|
|
|
* The checksum field of the passed PDU does not need to be reset to zero.
|
|
|
|
*
|
|
|
|
* The "Fletcher Checksum" was proposed in a paper by John G. Fletcher of
|
|
|
|
* Lawrence Livermore Labs. The Fletcher Checksum was proposed as an
|
|
|
|
* alternative to cyclical redundancy checks because it provides error-
|
|
|
|
* detection properties similar to cyclical redundancy checks but at the
|
|
|
|
* cost of a simple summation technique. Its characteristics were first
|
|
|
|
* published in IEEE Transactions on Communications in January 1982. One
|
|
|
|
* version has been adopted by ISO for use in the class-4 transport layer
|
|
|
|
* of the network protocol.
|
|
|
|
*
|
|
|
|
* This program expects:
|
|
|
|
* stdin: The input file to compute a checksum for. The input file
|
|
|
|
* not be longer than 256 bytes.
|
|
|
|
* stdout: Copied from the input file with the Fletcher's Checksum
|
|
|
|
* inserted 8 bytes after the beginning of the file.
|
|
|
|
* stderr: Used to print out error messages.
|
|
|
|
*/
|
2019-02-24 15:18:44 +01:00
|
|
|
static uint32_t fletcher32(const void *data, int length)
|
2015-11-17 15:57:39 +01:00
|
|
|
{
|
|
|
|
uint32_t c0;
|
|
|
|
uint32_t c1;
|
|
|
|
uint32_t checksum;
|
|
|
|
int index;
|
2019-02-24 15:18:44 +01:00
|
|
|
const uint16_t *pptr = data;
|
|
|
|
|
|
|
|
length /= 2;
|
2015-11-17 15:57:39 +01:00
|
|
|
|
|
|
|
c0 = 0xFFFF;
|
|
|
|
c1 = 0xFFFF;
|
|
|
|
|
2019-07-23 15:24:30 +02:00
|
|
|
while (length) {
|
|
|
|
index = length >= 359 ? 359 : length;
|
|
|
|
length -= index;
|
|
|
|
do {
|
2015-11-17 15:57:39 +01:00
|
|
|
c0 += *(pptr++);
|
|
|
|
c1 += c0;
|
2019-07-23 15:24:30 +02:00
|
|
|
} while (--index);
|
|
|
|
c0 = (c0 & 0xFFFF) + (c0 >> 16);
|
|
|
|
c1 = (c1 & 0xFFFF) + (c1 >> 16);
|
2015-11-17 15:57:39 +01:00
|
|
|
}
|
|
|
|
|
2019-02-24 15:18:44 +01:00
|
|
|
/* Sums[0,1] mod 64K + overflow */
|
|
|
|
c0 = (c0 & 0xFFFF) + (c0 >> 16);
|
|
|
|
c1 = (c1 & 0xFFFF) + (c1 >> 16);
|
2015-11-17 15:57:39 +01:00
|
|
|
checksum = (c1 << 16) | c0;
|
|
|
|
|
|
|
|
return checksum;
|
|
|
|
}
|
|
|
|
|
2016-11-08 18:44:18 +01:00
|
|
|
static void usage(void)
|
2015-11-17 15:57:39 +01:00
|
|
|
{
|
2016-11-08 18:37:53 +01:00
|
|
|
printf("amdfwtool: Create AMD Firmware combination\n");
|
2021-04-27 11:21:54 +02:00
|
|
|
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");
|
2016-11-08 18:37:53 +01:00
|
|
|
|
|
|
|
printf("\nPSP options:\n");
|
2021-04-27 11:21:54 +02:00
|
|
|
printf("--combo-capable Place PSP directory pointer at Embedded\n");
|
|
|
|
printf(" Firmware\n");
|
2019-02-28 19:43:40 +01:00
|
|
|
printf(" offset able to support combo directory\n");
|
2021-04-27 11:21:54 +02:00
|
|
|
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("--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");
|
2021-09-17 07:24:54 +02:00
|
|
|
printf("--recovery-ab Use the recovery A/B layout\n");
|
2019-03-19 21:45:31 +01:00
|
|
|
printf("\nBIOS options:\n");
|
2021-04-27 11:21:54 +02:00
|
|
|
printf("--instance <number> Sets instance field for the next BIOS\n");
|
2021-04-27 11:19:43 +02:00
|
|
|
printf(" firmware\n");
|
2021-04-27 11:21:54 +02:00
|
|
|
printf("--apcb <FILE> Add AGESA PSP customization block\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");
|
2017-03-17 23:30:51 +01:00
|
|
|
printf(" size must be larger than %dKB\n",
|
2016-11-08 18:37:53 +01:00
|
|
|
MIN_ROM_KB);
|
2017-03-17 23:30:51 +01:00
|
|
|
printf(" and must a multiple of 1024\n");
|
2021-04-27 11:21:54 +02:00
|
|
|
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");
|
2021-04-27 11:19:43 +02:00
|
|
|
printf(" area\n");
|
2021-04-27 11:21:54 +02:00
|
|
|
printf("--soc-name <socname> Specify SOC name. Supported names are\n");
|
2021-04-27 11:19:43 +02:00
|
|
|
printf(" Stoneyridge, Raven, Picasso, Renoir, Cezanne\n");
|
|
|
|
printf(" or Lucienne\n");
|
2020-06-15 18:18:15 +02:00
|
|
|
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");
|
2021-04-27 11:21:54 +02:00
|
|
|
printf("\nGeneral options:\n");
|
|
|
|
printf("-c|--config <config file> Config file\n");
|
|
|
|
printf("-d|--debug Print debug message\n");
|
|
|
|
printf("-l|--list List out the firmware files\n");
|
|
|
|
printf("-h|--help Show this help\n");
|
2015-11-17 15:57:39 +01:00
|
|
|
}
|
|
|
|
|
2020-10-28 04:38:09 +01:00
|
|
|
amd_fw_entry amd_psp_fw_table[] = {
|
2022-02-24 08:15:50 +01:00
|
|
|
{ .type = AMD_FW_PSP_PUBKEY, .level = PSP_BOTH | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_PSP_BOOTLOADER, .level = PSP_BOTH | PSP_LVL2_AB },
|
2021-09-17 07:24:54 +02:00
|
|
|
{ .type = AMD_FW_PSP_SMU_FIRMWARE, .subprog = 0, .level = PSP_BOTH | PSP_LVL2_AB },
|
2019-04-01 18:48:43 +02:00
|
|
|
{ .type = AMD_FW_PSP_RECOVERY, .level = PSP_LVL1 },
|
|
|
|
{ .type = AMD_FW_PSP_RTM_PUBKEY, .level = PSP_BOTH },
|
2021-09-17 07:24:54 +02:00
|
|
|
{ .type = AMD_FW_PSP_SECURED_OS, .level = PSP_LVL2 | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_PSP_NVRAM, .level = PSP_LVL2 | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_PSP_SMU_FIRMWARE, .subprog = 2, .level = PSP_BOTH | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_PSP_SECURED_DEBUG, .level = PSP_LVL2 | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_PSP_TRUSTLETS, .level = PSP_LVL2 | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_PSP_TRUSTLETKEY, .level = PSP_LVL2 | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_PSP_SMU_FIRMWARE2, .subprog = 2, .level = PSP_BOTH | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_PSP_SMU_FIRMWARE, .subprog = 1, .level = PSP_BOTH | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_PSP_SMU_FIRMWARE2, .subprog = 1, .level = PSP_BOTH | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_PSP_SMU_FIRMWARE2, .level = PSP_BOTH | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_PSP_SMUSCS, .level = PSP_BOTH },
|
|
|
|
{ .type = AMD_PSP_FUSE_CHAIN, .level = PSP_LVL2 | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_DEBUG_UNLOCK, .level = PSP_LVL2 | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_HW_IPCFG, .level = PSP_LVL2 | PSP_LVL2_AB },
|
2022-02-24 08:15:50 +01:00
|
|
|
{ .type = AMD_WRAPPED_IKEK, .level = PSP_BOTH | PSP_LVL2_AB },
|
2021-09-17 07:24:54 +02:00
|
|
|
{ .type = AMD_TOKEN_UNLOCK, .level = PSP_BOTH | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_SEC_GASKET, .subprog = 0, .level = PSP_BOTH | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_SEC_GASKET, .subprog = 2, .level = PSP_BOTH | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_SEC_GASKET, .subprog = 1, .level = PSP_BOTH | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_MP2_FW, .subprog = 2, .level = PSP_LVL2 | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_MP2_FW, .subprog = 1, .level = PSP_LVL2 | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_MP2_FW, .subprog = 0, .level = PSP_LVL2 | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_DRIVER_ENTRIES, .level = PSP_LVL2 | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_KVM_IMAGE, .level = PSP_LVL2 | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_S0I3_DRIVER, .level = PSP_LVL2 | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_VBIOS_BTLOADER, .level = PSP_BOTH | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_TOS_SEC_POLICY, .level = PSP_BOTH | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_USB_PHY, .level = PSP_LVL2 | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_DRTM_TA, .level = PSP_LVL2 | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_KEYDB_BL, .level = PSP_BOTH | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_KEYDB_TOS, .level = PSP_LVL2 | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_SPL, .level = PSP_LVL2 | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_DMCU_ERAM, .level = PSP_LVL2 | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_DMCU_ISR, .level = PSP_LVL2 | PSP_LVL2_AB },
|
2022-03-24 02:04:51 +01:00
|
|
|
{ .type = AMD_FW_MSMU, .level = PSP_LVL2 | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_DMCUB, .level = PSP_LVL2 | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_SPIROM_CFG, .level = PSP_LVL2 | PSP_LVL2_AB },
|
2021-09-17 07:24:54 +02:00
|
|
|
{ .type = AMD_RPMC_NVRAM, .level = PSP_LVL2 | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_PSP_BOOTLOADER_AB, .level = PSP_LVL2 | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_ABL0, .level = PSP_BOTH | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_ABL1, .level = PSP_BOTH | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_ABL2, .level = PSP_BOTH | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_ABL3, .level = PSP_BOTH | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_ABL4, .level = PSP_BOTH | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_ABL5, .level = PSP_BOTH | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_ABL6, .level = PSP_BOTH | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_ABL7, .level = PSP_BOTH | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_PSP_SMU_FIRMWARE, .subprog = 1, .level = PSP_BOTH | PSP_LVL2_AB },
|
|
|
|
{ .type = AMD_FW_PSP_SMU_FIRMWARE2, .subprog = 1, .level = PSP_BOTH | PSP_LVL2_AB },
|
2019-03-19 21:45:31 +01:00
|
|
|
{ .type = AMD_FW_PSP_WHITELIST, .level = PSP_LVL2 },
|
2021-09-17 07:24:54 +02:00
|
|
|
{ .type = AMD_FW_PSP_VERSTAGE, .level = PSP_BOTH | PSP_BOTH_AB },
|
|
|
|
{ .type = AMD_FW_VERSTAGE_SIG, .level = PSP_BOTH | PSP_BOTH_AB },
|
2016-03-02 07:47:27 +01:00
|
|
|
{ .type = AMD_FW_INVALID },
|
2015-11-17 15:57:39 +01:00
|
|
|
};
|
|
|
|
|
2020-10-28 04:38:09 +01:00
|
|
|
amd_fw_entry amd_fw_table[] = {
|
2015-11-17 15:57:39 +01:00
|
|
|
{ .type = AMD_FW_XHCI },
|
|
|
|
{ .type = AMD_FW_IMC },
|
|
|
|
{ .type = AMD_FW_GEC },
|
2016-03-02 07:47:27 +01:00
|
|
|
{ .type = AMD_FW_INVALID },
|
2015-11-17 15:57:39 +01:00
|
|
|
};
|
|
|
|
|
2020-10-28 04:38:09 +01:00
|
|
|
amd_bios_entry amd_bios_table[] = {
|
2020-12-03 16:00:48 +01:00
|
|
|
{ .type = AMD_BIOS_RTM_PUBKEY, .inst = 0, .level = BDT_BOTH },
|
2019-09-25 19:03:53 +02:00
|
|
|
{ .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 },
|
|
|
|
{ .type = AMD_BIOS_APCB, .inst = 3, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB, .inst = 4, .level = BDT_BOTH },
|
2020-03-03 18:35:02 +01:00
|
|
|
{ .type = AMD_BIOS_APCB, .inst = 5, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB, .inst = 6, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB, .inst = 7, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB, .inst = 8, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB, .inst = 9, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB, .inst = 10, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB, .inst = 11, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB, .inst = 12, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB, .inst = 13, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB, .inst = 14, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB, .inst = 15, .level = BDT_BOTH },
|
2020-01-04 01:57:48 +01:00
|
|
|
{ .type = AMD_BIOS_APCB_BK, .inst = 0, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB_BK, .inst = 1, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB_BK, .inst = 2, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB_BK, .inst = 3, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB_BK, .inst = 4, .level = BDT_BOTH },
|
2020-03-03 18:35:02 +01:00
|
|
|
{ .type = AMD_BIOS_APCB_BK, .inst = 5, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB_BK, .inst = 6, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB_BK, .inst = 7, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB_BK, .inst = 8, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB_BK, .inst = 9, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB_BK, .inst = 10, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB_BK, .inst = 11, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB_BK, .inst = 12, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB_BK, .inst = 13, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB_BK, .inst = 14, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APCB_BK, .inst = 15, .level = BDT_BOTH },
|
2019-03-19 21:45:31 +01:00
|
|
|
{ .type = AMD_BIOS_APOB, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_BIN,
|
|
|
|
.reset = 1, .copy = 1, .zlib = 1, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_APOB_NV, .level = BDT_LVL2 },
|
|
|
|
{ .type = AMD_BIOS_PMUI, .inst = 1, .subpr = 0, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_PMUD, .inst = 1, .subpr = 0, .level = BDT_BOTH },
|
2022-02-17 10:22:15 +01:00
|
|
|
{ .type = AMD_BIOS_PMUI, .inst = 2, .subpr = 0, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_PMUD, .inst = 2, .subpr = 0, .level = BDT_BOTH },
|
2019-03-19 21:45:31 +01:00
|
|
|
{ .type = AMD_BIOS_PMUI, .inst = 4, .subpr = 0, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_PMUD, .inst = 4, .subpr = 0, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_PMUI, .inst = 1, .subpr = 1, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_PMUD, .inst = 1, .subpr = 1, .level = BDT_BOTH },
|
2022-02-17 10:22:15 +01:00
|
|
|
{ .type = AMD_BIOS_PMUI, .inst = 2, .subpr = 1, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_PMUD, .inst = 2, .subpr = 1, .level = BDT_BOTH },
|
2019-03-19 21:45:31 +01:00
|
|
|
{ .type = AMD_BIOS_PMUI, .inst = 4, .subpr = 1, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_PMUD, .inst = 4, .subpr = 1, .level = BDT_BOTH },
|
|
|
|
{ .type = AMD_BIOS_UCODE, .inst = 0, .level = BDT_LVL2 },
|
|
|
|
{ .type = AMD_BIOS_UCODE, .inst = 1, .level = BDT_LVL2 },
|
|
|
|
{ .type = AMD_BIOS_UCODE, .inst = 2, .level = BDT_LVL2 },
|
|
|
|
{ .type = AMD_BIOS_MP2_CFG, .level = BDT_LVL2 },
|
2020-04-14 22:59:36 +02:00
|
|
|
{ .type = AMD_BIOS_PSP_SHARED_MEM, .inst = 0, .level = BDT_BOTH },
|
2019-03-19 21:45:31 +01:00
|
|
|
{ .type = AMD_BIOS_INVALID },
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2020-04-14 22:59:36 +02:00
|
|
|
#define MAX_BIOS_ENTRIES 0x2f
|
2019-03-19 21:45:31 +01:00
|
|
|
|
2019-03-05 00:53:15 +01:00
|
|
|
typedef struct _context {
|
|
|
|
char *rom; /* target buffer, size of flash device */
|
|
|
|
uint32_t rom_size; /* size of flash device */
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
uint32_t address_mode; /* 0:abs address; 1:relative to flash; 2: relative to table */
|
2019-03-05 00:53:15 +01:00
|
|
|
uint32_t current; /* pointer within flash & proxy buffer */
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
uint32_t current_table;
|
2019-03-05 00:53:15 +01:00
|
|
|
} context;
|
|
|
|
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
#define ADDRESS_MODE_0_PHY 0
|
|
|
|
#define ADDRESS_MODE_1_REL_BIOS 1
|
|
|
|
#define ADDRESS_MODE_2_REL_TAB 2
|
|
|
|
#define ADDRESS_MODE_3_REL_SLOT 3
|
|
|
|
|
2019-03-05 00:53:15 +01:00
|
|
|
#define RUN_BASE(ctx) (0xFFFFFFFF - (ctx).rom_size + 1)
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
#define RUN_OFFSET_MODE(ctx, offset, mode) \
|
|
|
|
((mode) == ADDRESS_MODE_0_PHY ? RUN_BASE(ctx) + (offset) : \
|
|
|
|
((mode) == ADDRESS_MODE_1_REL_BIOS ? (offset) : \
|
|
|
|
((mode) == ADDRESS_MODE_2_REL_TAB ? (offset) - ctx.current_table : (offset))))
|
|
|
|
#define RUN_OFFSET(ctx, offset) RUN_OFFSET_MODE((ctx), (offset), (ctx).address_mode)
|
|
|
|
#define RUN_TO_OFFSET(ctx, run) ((ctx).address_mode == ADDRESS_MODE_0_PHY ? \
|
|
|
|
(run) - RUN_BASE(ctx) : (run)) /* TODO: */
|
2019-03-05 00:53:15 +01:00
|
|
|
#define RUN_CURRENT(ctx) RUN_OFFSET((ctx), (ctx).current)
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
/* The mode in entry can not be higher than the header's.
|
|
|
|
For example, if table mode is 0, all the entry mode will be 0. */
|
|
|
|
#define RUN_CURRENT_MODE(ctx, mode) RUN_OFFSET_MODE((ctx), (ctx).current, \
|
|
|
|
(ctx).address_mode < (mode) ? (ctx).address_mode : (mode))
|
2019-03-05 00:53:15 +01:00
|
|
|
#define BUFF_OFFSET(ctx, offset) ((void *)((ctx).rom + (offset)))
|
|
|
|
#define BUFF_CURRENT(ctx) BUFF_OFFSET((ctx), (ctx).current)
|
|
|
|
#define BUFF_TO_RUN(ctx, ptr) RUN_OFFSET((ctx), ((char *)(ptr) - (ctx).rom))
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
#define BUFF_TO_RUN_MODE(ctx, ptr, mode) RUN_OFFSET_MODE((ctx), ((char *)(ptr) - (ctx).rom), \
|
|
|
|
(ctx).address_mode < (mode) ? (ctx).address_mode : (mode))
|
2019-03-05 00:53:15 +01:00
|
|
|
#define BUFF_ROOM(ctx) ((ctx).rom_size - (ctx).current)
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
/* Only set the address mode in entry if the table is mode 2. */
|
|
|
|
#define SET_ADDR_MODE(table, mode) \
|
|
|
|
((table)->header.additional_info_fields.address_mode == \
|
|
|
|
ADDRESS_MODE_2_REL_TAB ? (mode) : 0)
|
|
|
|
#define SET_ADDR_MODE_BY_TABLE(table) \
|
|
|
|
SET_ADDR_MODE((table), (table)->header.additional_info_fields.address_mode)
|
2019-03-05 00:53:15 +01:00
|
|
|
|
2021-10-30 06:09:07 +02:00
|
|
|
void assert_fw_entry(uint32_t count, uint32_t max, context *ctx)
|
|
|
|
{
|
|
|
|
if (count >= max) {
|
|
|
|
fprintf(stderr, "Error: BIOS entries (%d) exceeds max allowed items "
|
|
|
|
"(%d)\n", count, max);
|
|
|
|
free(ctx->rom);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-01 18:48:43 +02:00
|
|
|
static void *new_psp_dir(context *ctx, int multi)
|
2019-03-05 00:53:15 +01:00
|
|
|
{
|
|
|
|
void *ptr;
|
|
|
|
|
2019-04-01 18:48:43 +02:00
|
|
|
/*
|
|
|
|
* Force both onto boundary when multi. Primary table is after
|
|
|
|
* updatable table, so alignment ensures primary can stay intact
|
|
|
|
* if secondary is reprogrammed.
|
|
|
|
*/
|
|
|
|
if (multi)
|
|
|
|
ctx->current = ALIGN(ctx->current, TABLE_ERASE_ALIGNMENT);
|
|
|
|
else
|
|
|
|
ctx->current = ALIGN(ctx->current, TABLE_ALIGNMENT);
|
|
|
|
|
2019-03-05 00:53:15 +01:00
|
|
|
ptr = BUFF_CURRENT(*ctx);
|
2021-09-17 07:24:54 +02:00
|
|
|
((psp_directory_header *)ptr)->num_entries = 0;
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
((psp_directory_header *)ptr)->additional_info = 0;
|
|
|
|
((psp_directory_header *)ptr)->additional_info_fields.address_mode = ctx->address_mode;
|
2019-03-05 00:53:15 +01:00
|
|
|
ctx->current += sizeof(psp_directory_header)
|
|
|
|
+ MAX_PSP_ENTRIES * sizeof(psp_directory_entry);
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
2021-09-17 07:30:08 +02:00
|
|
|
static void *new_ish_dir(context *ctx)
|
|
|
|
{
|
|
|
|
void *ptr;
|
|
|
|
ctx->current = ALIGN(ctx->current, TABLE_ALIGNMENT);
|
|
|
|
ptr = BUFF_CURRENT(*ctx);
|
|
|
|
ctx->current += TABLE_ALIGNMENT;
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
2019-07-14 04:03:34 +02:00
|
|
|
#if PSP_COMBO
|
2019-03-05 00:53:15 +01:00
|
|
|
static void *new_combo_dir(context *ctx)
|
|
|
|
{
|
|
|
|
void *ptr;
|
|
|
|
|
|
|
|
ctx->current = ALIGN(ctx->current, TABLE_ALIGNMENT);
|
|
|
|
ptr = BUFF_CURRENT(*ctx);
|
|
|
|
ctx->current += sizeof(psp_combo_header)
|
|
|
|
+ MAX_COMBO_ENTRIES * sizeof(psp_combo_entry);
|
|
|
|
return ptr;
|
|
|
|
}
|
2019-07-14 04:03:34 +02:00
|
|
|
#endif
|
2019-03-05 00:53:15 +01:00
|
|
|
|
2020-12-03 16:00:48 +01:00
|
|
|
static void fill_dir_header(void *directory, uint32_t count, uint32_t cookie, context *ctx)
|
2015-11-17 15:57:39 +01:00
|
|
|
{
|
2019-04-01 18:48:43 +02:00
|
|
|
psp_combo_directory *cdir = directory;
|
|
|
|
psp_directory_table *dir = directory;
|
2019-03-19 21:45:31 +01:00
|
|
|
bios_directory_table *bdir = directory;
|
2020-12-03 16:00:48 +01:00
|
|
|
uint32_t table_size = 0;
|
2019-04-01 18:48:43 +02:00
|
|
|
|
|
|
|
if (!count)
|
|
|
|
return;
|
2021-05-27 05:26:12 +02:00
|
|
|
if (ctx == NULL || directory == NULL) {
|
|
|
|
fprintf(stderr, "Calling %s with NULL pointers\n", __func__);
|
|
|
|
return;
|
|
|
|
}
|
2019-04-01 18:48:43 +02:00
|
|
|
|
2020-12-03 16:00:48 +01:00
|
|
|
/* The table size needs to be 0x1000 aligned. So align the end of table. */
|
2021-05-27 05:26:12 +02:00
|
|
|
ctx->current = ALIGN(ctx->current, TABLE_ALIGNMENT);
|
2020-12-03 16:00:48 +01:00
|
|
|
|
2019-04-01 18:48:43 +02:00
|
|
|
switch (cookie) {
|
|
|
|
case PSP2_COOKIE:
|
2019-03-05 00:52:07 +01:00
|
|
|
/* caller is responsible for lookup mode */
|
|
|
|
cdir->header.cookie = cookie;
|
|
|
|
cdir->header.num_entries = count;
|
|
|
|
cdir->header.reserved[0] = 0;
|
|
|
|
cdir->header.reserved[1] = 0;
|
|
|
|
/* checksum everything that comes after the Checksum field */
|
|
|
|
cdir->header.checksum = fletcher32(&cdir->header.num_entries,
|
|
|
|
count * sizeof(psp_combo_entry)
|
|
|
|
+ sizeof(cdir->header.num_entries)
|
|
|
|
+ sizeof(cdir->header.lookup)
|
|
|
|
+ 2 * sizeof(cdir->header.reserved[0]));
|
2019-04-01 18:48:43 +02:00
|
|
|
break;
|
|
|
|
case PSP_COOKIE:
|
|
|
|
case PSPL2_COOKIE:
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
table_size = ctx->current - ctx->current_table;
|
2020-12-03 16:00:48 +01:00
|
|
|
if ((table_size % TABLE_ALIGNMENT) != 0) {
|
|
|
|
fprintf(stderr, "The PSP table size should be 4K aligned\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2019-03-05 00:52:07 +01:00
|
|
|
dir->header.cookie = cookie;
|
|
|
|
dir->header.num_entries = count;
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
dir->header.additional_info_fields.dir_size = table_size / TABLE_ALIGNMENT;
|
|
|
|
dir->header.additional_info_fields.spi_block_size = 1;
|
|
|
|
dir->header.additional_info_fields.base_addr = 0;
|
2019-03-05 00:52:07 +01:00
|
|
|
/* checksum everything that comes after the Checksum field */
|
|
|
|
dir->header.checksum = fletcher32(&dir->header.num_entries,
|
2019-02-24 15:18:44 +01:00
|
|
|
count * sizeof(psp_directory_entry)
|
2019-03-05 00:52:07 +01:00
|
|
|
+ sizeof(dir->header.num_entries)
|
2020-12-03 16:00:48 +01:00
|
|
|
+ sizeof(dir->header.additional_info));
|
2019-04-01 18:48:43 +02:00
|
|
|
break;
|
2019-03-19 21:45:31 +01:00
|
|
|
case BDT1_COOKIE:
|
|
|
|
case BDT2_COOKIE:
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
table_size = ctx->current - ctx->current_table;
|
2020-12-03 16:00:48 +01:00
|
|
|
if ((table_size % TABLE_ALIGNMENT) != 0) {
|
|
|
|
fprintf(stderr, "The BIOS table size should be 4K aligned\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
2019-03-19 21:45:31 +01:00
|
|
|
bdir->header.cookie = cookie;
|
|
|
|
bdir->header.num_entries = count;
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
bdir->header.additional_info_fields.dir_size = table_size / TABLE_ALIGNMENT;
|
|
|
|
bdir->header.additional_info_fields.spi_block_size = 1;
|
|
|
|
bdir->header.additional_info_fields.base_addr = 0;
|
2019-03-19 21:45:31 +01:00
|
|
|
/* 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)
|
2020-12-03 16:00:48 +01:00
|
|
|
+ sizeof(bdir->header.additional_info));
|
2019-03-19 21:45:31 +01:00
|
|
|
break;
|
2019-03-05 00:52:07 +01:00
|
|
|
}
|
2020-12-03 16:00:48 +01:00
|
|
|
|
2015-11-17 15:57:39 +01:00
|
|
|
}
|
|
|
|
|
2019-02-28 02:40:49 +01:00
|
|
|
static ssize_t copy_blob(void *dest, const char *src_file, size_t room)
|
|
|
|
{
|
|
|
|
int fd;
|
|
|
|
struct stat fd_stat;
|
|
|
|
ssize_t bytes;
|
|
|
|
|
|
|
|
fd = open(src_file, O_RDONLY);
|
|
|
|
if (fd < 0) {
|
2020-10-01 11:05:43 +02:00
|
|
|
fprintf(stderr, "Error opening file: %s: %s\n",
|
2020-03-06 00:04:15 +01:00
|
|
|
src_file, strerror(errno));
|
2019-02-28 02:40:49 +01:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fstat(fd, &fd_stat)) {
|
2020-10-01 11:05:43 +02:00
|
|
|
fprintf(stderr, "fstat error: %s\n", strerror(errno));
|
2019-07-02 18:35:10 +02:00
|
|
|
close(fd);
|
2019-02-28 02:40:49 +01:00
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
|
2020-10-01 10:16:30 +02:00
|
|
|
if ((size_t)fd_stat.st_size > room) {
|
2020-10-01 11:05:43 +02:00
|
|
|
fprintf(stderr, "Error: %s will not fit. Exiting.\n", src_file);
|
2019-07-02 18:35:10 +02:00
|
|
|
close(fd);
|
2019-02-28 02:40:49 +01:00
|
|
|
return -3;
|
|
|
|
}
|
|
|
|
|
|
|
|
bytes = read(fd, dest, (size_t)fd_stat.st_size);
|
|
|
|
close(fd);
|
|
|
|
if (bytes != (ssize_t)fd_stat.st_size) {
|
2020-10-01 11:05:43 +02:00
|
|
|
fprintf(stderr, "Error while reading %s\n", src_file);
|
2019-02-28 02:40:49 +01:00
|
|
|
return -4;
|
|
|
|
}
|
|
|
|
|
|
|
|
return bytes;
|
|
|
|
}
|
|
|
|
|
2021-10-14 09:09:09 +02:00
|
|
|
enum platform {
|
|
|
|
PLATFORM_UNKNOWN,
|
|
|
|
PLATFORM_STONEYRIDGE,
|
|
|
|
PLATFORM_RAVEN,
|
|
|
|
PLATFORM_PICASSO,
|
|
|
|
PLATFORM_RENOIR,
|
|
|
|
PLATFORM_CEZANNE,
|
|
|
|
PLATFORM_MENDOCINO,
|
|
|
|
PLATFORM_LUCIENNE,
|
2022-03-29 02:34:11 +02:00
|
|
|
PLATFORM_SABRINA,
|
2021-10-14 09:09:09 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
static uint32_t get_psp_id(enum platform soc_id)
|
|
|
|
{
|
|
|
|
uint32_t psp_id;
|
|
|
|
switch (soc_id) {
|
|
|
|
case PLATFORM_RAVEN:
|
|
|
|
case PLATFORM_PICASSO:
|
|
|
|
psp_id = 0xBC0A0000;
|
|
|
|
break;
|
|
|
|
case PLATFORM_RENOIR:
|
|
|
|
case PLATFORM_LUCIENNE:
|
|
|
|
psp_id = 0xBC0C0000;
|
|
|
|
break;
|
|
|
|
case PLATFORM_CEZANNE:
|
|
|
|
psp_id = 0xBC0C0140;
|
|
|
|
break;
|
|
|
|
case PLATFORM_MENDOCINO:
|
2022-03-29 02:34:11 +02:00
|
|
|
case PLATFORM_SABRINA:
|
2021-10-14 09:09:09 +02:00
|
|
|
psp_id = 0xBC0D0900;
|
|
|
|
break;
|
|
|
|
case PLATFORM_STONEYRIDGE:
|
|
|
|
psp_id = 0x10220B00;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
psp_id = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return psp_id;
|
|
|
|
}
|
|
|
|
|
2019-03-05 00:53:15 +01:00
|
|
|
static void integrate_firmwares(context *ctx,
|
2019-02-24 00:42:46 +01:00
|
|
|
embedded_firmware *romsig,
|
2019-03-05 00:53:15 +01:00
|
|
|
amd_fw_entry *fw_table)
|
2015-11-17 15:57:39 +01:00
|
|
|
{
|
2018-01-17 18:23:19 +01:00
|
|
|
ssize_t bytes;
|
2020-10-01 10:16:30 +02:00
|
|
|
uint32_t i;
|
2019-03-05 00:53:15 +01:00
|
|
|
|
|
|
|
ctx->current += sizeof(embedded_firmware);
|
|
|
|
ctx->current = ALIGN(ctx->current, BLOB_ALIGNMENT);
|
2015-11-17 15:57:39 +01:00
|
|
|
|
2016-11-08 19:34:02 +01:00
|
|
|
for (i = 0; fw_table[i].type != AMD_FW_INVALID; i++) {
|
2016-03-02 07:47:27 +01:00
|
|
|
if (fw_table[i].filename != NULL) {
|
|
|
|
switch (fw_table[i].type) {
|
|
|
|
case AMD_FW_IMC:
|
2019-03-05 00:53:15 +01:00
|
|
|
ctx->current = ALIGN(ctx->current, 0x10000U);
|
|
|
|
romsig->imc_entry = RUN_CURRENT(*ctx);
|
2016-03-02 07:47:27 +01:00
|
|
|
break;
|
|
|
|
case AMD_FW_GEC:
|
2019-03-05 00:53:15 +01:00
|
|
|
romsig->gec_entry = RUN_CURRENT(*ctx);
|
2016-03-02 07:47:27 +01:00
|
|
|
break;
|
|
|
|
case AMD_FW_XHCI:
|
2019-03-05 00:53:15 +01:00
|
|
|
romsig->xhci_entry = RUN_CURRENT(*ctx);
|
2016-03-02 07:47:27 +01:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* Error */
|
|
|
|
break;
|
|
|
|
}
|
2015-11-17 15:57:39 +01:00
|
|
|
|
2019-03-05 00:53:15 +01:00
|
|
|
bytes = copy_blob(BUFF_CURRENT(*ctx),
|
|
|
|
fw_table[i].filename, BUFF_ROOM(*ctx));
|
2019-03-13 21:43:17 +01:00
|
|
|
if (bytes < 0) {
|
2019-03-05 00:53:15 +01:00
|
|
|
free(ctx->rom);
|
2018-01-17 18:23:19 +01:00
|
|
|
exit(1);
|
|
|
|
}
|
2015-11-17 15:57:39 +01:00
|
|
|
|
2019-03-05 00:53:15 +01:00
|
|
|
ctx->current = ALIGN(ctx->current + bytes,
|
|
|
|
BLOB_ALIGNMENT);
|
2016-03-02 07:47:27 +01:00
|
|
|
}
|
2015-11-17 15:57:39 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-28 04:39:13 +01:00
|
|
|
/* For debugging */
|
|
|
|
static void dump_psp_firmwares(amd_fw_entry *fw_table)
|
|
|
|
{
|
|
|
|
amd_fw_entry *index;
|
|
|
|
|
|
|
|
printf("PSP firmware components:");
|
|
|
|
for (index = fw_table; index->type != AMD_FW_INVALID; index++) {
|
|
|
|
if (index->filename)
|
2021-05-25 10:26:55 +02:00
|
|
|
printf(" %2x: %s\n", index->type, index->filename);
|
2020-10-28 04:39:13 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void dump_bdt_firmwares(amd_bios_entry *fw_table)
|
|
|
|
{
|
|
|
|
amd_bios_entry *index;
|
|
|
|
|
|
|
|
printf("BIOS Directory Table (BDT) components:");
|
|
|
|
for (index = fw_table; index->type != AMD_BIOS_INVALID; index++) {
|
|
|
|
if (index->filename)
|
2021-05-25 10:26:55 +02:00
|
|
|
printf(" %2x: %s\n", index->type, index->filename);
|
2020-10-28 04:39:13 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-28 04:38:09 +01:00
|
|
|
static void free_psp_firmware_filenames(amd_fw_entry *fw_table)
|
|
|
|
{
|
|
|
|
amd_fw_entry *index;
|
|
|
|
|
|
|
|
for (index = fw_table; index->type != AMD_FW_INVALID; index++) {
|
|
|
|
if (index->filename &&
|
|
|
|
index->type != AMD_FW_VERSTAGE_SIG &&
|
|
|
|
index->type != AMD_FW_PSP_VERSTAGE &&
|
2022-02-11 04:51:26 +01:00
|
|
|
index->type != AMD_FW_SPL &&
|
2020-10-28 04:38:09 +01:00
|
|
|
index->type != AMD_FW_PSP_WHITELIST) {
|
|
|
|
free(index->filename);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void free_bdt_firmware_filenames(amd_bios_entry *fw_table)
|
|
|
|
{
|
|
|
|
amd_bios_entry *index;
|
|
|
|
|
|
|
|
for (index = fw_table; index->type != AMD_BIOS_INVALID; index++) {
|
|
|
|
if (index->filename &&
|
|
|
|
index->type != AMD_BIOS_APCB &&
|
|
|
|
index->type != AMD_BIOS_BIN &&
|
|
|
|
index->type != AMD_BIOS_APCB_BK)
|
|
|
|
free(index->filename);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-17 07:24:54 +02:00
|
|
|
static void integrate_psp_ab(context *ctx, psp_directory_table *pspdir,
|
2021-09-17 07:30:08 +02:00
|
|
|
psp_directory_table *pspdir2, ish_directory_table *ish,
|
|
|
|
amd_fw_type ab, enum platform soc_id)
|
2021-09-17 07:24:54 +02:00
|
|
|
{
|
|
|
|
uint32_t count;
|
|
|
|
uint32_t current_table_save;
|
|
|
|
|
|
|
|
current_table_save = ctx->current_table;
|
|
|
|
ctx->current_table = (char *)pspdir - ctx->rom;
|
|
|
|
count = pspdir->header.num_entries;
|
|
|
|
assert_fw_entry(count, MAX_PSP_ENTRIES, ctx);
|
|
|
|
pspdir->entries[count].type = (uint8_t)ab;
|
|
|
|
pspdir->entries[count].subprog = 0;
|
|
|
|
pspdir->entries[count].rsvd = 0;
|
2021-09-17 07:30:08 +02:00
|
|
|
if (ish != NULL) {
|
|
|
|
ish->pl2_location = BUFF_TO_RUN_MODE(*ctx, pspdir2, ADDRESS_MODE_1_REL_BIOS);
|
|
|
|
ish->boot_priority = ab == AMD_FW_RECOVERYAB_A ? 0xFFFFFFFF : 1;
|
|
|
|
ish->update_retry_count = 2;
|
|
|
|
ish->glitch_retry_count = 0;
|
|
|
|
ish->psp_id = get_psp_id(soc_id);
|
|
|
|
ish->checksum = fletcher32(&ish->boot_priority,
|
|
|
|
sizeof(ish_directory_table) - sizeof(uint32_t));
|
|
|
|
pspdir->entries[count].addr =
|
|
|
|
BUFF_TO_RUN_MODE(*ctx, ish, ADDRESS_MODE_1_REL_BIOS);
|
|
|
|
pspdir->entries[count].address_mode =
|
|
|
|
SET_ADDR_MODE(pspdir, ADDRESS_MODE_1_REL_BIOS);
|
|
|
|
pspdir->entries[count].size = TABLE_ALIGNMENT;
|
|
|
|
} else {
|
|
|
|
pspdir->entries[count].addr =
|
|
|
|
BUFF_TO_RUN_MODE(*ctx, pspdir2, ADDRESS_MODE_1_REL_BIOS);
|
|
|
|
pspdir->entries[count].address_mode =
|
|
|
|
SET_ADDR_MODE(pspdir, ADDRESS_MODE_1_REL_BIOS);
|
|
|
|
pspdir->entries[count].size = pspdir2->header.num_entries *
|
2021-09-17 07:24:54 +02:00
|
|
|
sizeof(psp_directory_entry) +
|
|
|
|
sizeof(psp_directory_header);
|
2021-09-17 07:30:08 +02:00
|
|
|
}
|
2021-09-17 07:24:54 +02:00
|
|
|
|
|
|
|
count++;
|
|
|
|
pspdir->header.num_entries = count;
|
|
|
|
ctx->current_table = current_table_save;
|
|
|
|
}
|
|
|
|
|
2019-03-05 00:53:15 +01:00
|
|
|
static void integrate_psp_firmwares(context *ctx,
|
2019-02-24 00:42:46 +01:00
|
|
|
psp_directory_table *pspdir,
|
2019-04-01 18:48:43 +02:00
|
|
|
psp_directory_table *pspdir2,
|
2021-09-17 07:24:54 +02:00
|
|
|
psp_directory_table *pspdir2_b,
|
2019-04-01 18:48:43 +02:00
|
|
|
amd_fw_entry *fw_table,
|
2021-08-20 08:58:22 +02:00
|
|
|
uint32_t cookie,
|
2021-09-17 07:30:08 +02:00
|
|
|
enum platform soc_id,
|
2021-08-20 08:58:22 +02:00
|
|
|
amd_cb_config *cb_config)
|
2015-11-17 15:57:39 +01:00
|
|
|
{
|
2018-01-17 18:23:19 +01:00
|
|
|
ssize_t bytes;
|
2019-02-24 00:41:35 +01:00
|
|
|
unsigned int i, count;
|
2019-04-01 18:48:43 +02:00
|
|
|
int level;
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
uint32_t current_table_save;
|
2021-09-17 07:24:54 +02:00
|
|
|
bool recovery_ab = cb_config->recovery_ab;
|
2021-09-17 07:30:08 +02:00
|
|
|
ish_directory_table *ish_a_dir = NULL, *ish_b_dir = NULL;
|
2019-04-01 18:48:43 +02:00
|
|
|
|
|
|
|
/* This function can create a primary table, a secondary table, or a
|
|
|
|
* flattened table which contains all applicable types. These if-else
|
|
|
|
* statements infer what the caller intended. If a 2nd-level cookie
|
|
|
|
* is passed, clearly a 2nd-level table is intended. However, a
|
|
|
|
* 1st-level cookie may indicate level 1 or flattened. If the caller
|
|
|
|
* passes a pointer to a 2nd-level table, then assume not flat.
|
|
|
|
*/
|
2021-11-04 11:56:47 +01:00
|
|
|
if (!cb_config->multi_level)
|
2021-08-20 08:58:22 +02:00
|
|
|
level = PSP_BOTH;
|
|
|
|
else if (cookie == PSPL2_COOKIE)
|
2019-04-01 18:48:43 +02:00
|
|
|
level = PSP_LVL2;
|
|
|
|
else if (pspdir2)
|
|
|
|
level = PSP_LVL1;
|
|
|
|
else
|
|
|
|
level = PSP_BOTH;
|
2019-03-05 00:53:15 +01:00
|
|
|
|
2021-09-17 07:24:54 +02:00
|
|
|
if (recovery_ab) {
|
|
|
|
if (cookie == PSPL2_COOKIE)
|
|
|
|
level = PSP_LVL2_AB;
|
|
|
|
else if (pspdir2)
|
|
|
|
level = PSP_LVL1_AB;
|
|
|
|
else
|
|
|
|
level = PSP_BOTH_AB;
|
|
|
|
}
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
current_table_save = ctx->current_table;
|
|
|
|
ctx->current_table = (char *)pspdir - ctx->rom;
|
2020-12-03 16:00:48 +01:00
|
|
|
ctx->current = ALIGN(ctx->current, TABLE_ALIGNMENT);
|
2015-11-17 15:57:39 +01:00
|
|
|
|
2019-02-24 00:41:35 +01:00
|
|
|
for (i = 0, count = 0; fw_table[i].type != AMD_FW_INVALID; i++) {
|
2019-04-01 18:48:43 +02:00
|
|
|
if (!(fw_table[i].level & level))
|
|
|
|
continue;
|
|
|
|
|
2021-10-30 06:09:07 +02:00
|
|
|
assert_fw_entry(count, MAX_PSP_ENTRIES, ctx);
|
|
|
|
|
2019-03-19 21:45:31 +01:00
|
|
|
if (fw_table[i].type == AMD_TOKEN_UNLOCK) {
|
|
|
|
if (!fw_table[i].other)
|
|
|
|
continue;
|
|
|
|
ctx->current = ALIGN(ctx->current, ERASE_ALIGNMENT);
|
|
|
|
pspdir->entries[count].type = fw_table[i].type;
|
|
|
|
pspdir->entries[count].size = 4096; /* TODO: doc? */
|
|
|
|
pspdir->entries[count].addr = RUN_CURRENT(*ctx);
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
pspdir->entries[count].address_mode = SET_ADDR_MODE_BY_TABLE(pspdir);
|
2019-03-19 21:45:31 +01:00
|
|
|
pspdir->entries[count].subprog = fw_table[i].subprog;
|
|
|
|
pspdir->entries[count].rsvd = 0;
|
|
|
|
ctx->current = ALIGN(ctx->current + 4096, 0x100U);
|
|
|
|
count++;
|
|
|
|
} else if (fw_table[i].type == AMD_PSP_FUSE_CHAIN) {
|
2019-02-24 00:42:46 +01:00
|
|
|
pspdir->entries[count].type = fw_table[i].type;
|
2019-03-04 18:31:03 +01:00
|
|
|
pspdir->entries[count].subprog = fw_table[i].subprog;
|
|
|
|
pspdir->entries[count].rsvd = 0;
|
2019-02-24 00:42:46 +01:00
|
|
|
pspdir->entries[count].size = 0xFFFFFFFF;
|
2019-04-01 18:16:41 +02:00
|
|
|
pspdir->entries[count].addr = fw_table[i].other;
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
pspdir->entries[count].address_mode = 0;
|
2019-02-24 00:41:35 +01:00
|
|
|
count++;
|
2019-04-11 17:44:43 +02:00
|
|
|
} else if (fw_table[i].type == AMD_FW_PSP_NVRAM) {
|
|
|
|
if (fw_table[i].filename == NULL)
|
|
|
|
continue;
|
|
|
|
/* TODO: Add a way to reserve for NVRAM without
|
|
|
|
* requiring a filename. This isn't a feature used
|
|
|
|
* by coreboot systems, so priority is very low.
|
|
|
|
*/
|
|
|
|
ctx->current = ALIGN(ctx->current, ERASE_ALIGNMENT);
|
|
|
|
bytes = copy_blob(BUFF_CURRENT(*ctx),
|
|
|
|
fw_table[i].filename, BUFF_ROOM(*ctx));
|
|
|
|
if (bytes <= 0) {
|
|
|
|
free(ctx->rom);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
pspdir->entries[count].type = fw_table[i].type;
|
|
|
|
pspdir->entries[count].subprog = fw_table[i].subprog;
|
|
|
|
pspdir->entries[count].rsvd = 0;
|
|
|
|
pspdir->entries[count].size = ALIGN(bytes,
|
|
|
|
ERASE_ALIGNMENT);
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
pspdir->entries[count].addr =
|
|
|
|
RUN_CURRENT_MODE(*ctx, ADDRESS_MODE_1_REL_BIOS);
|
|
|
|
pspdir->entries[count].address_mode =
|
|
|
|
SET_ADDR_MODE(pspdir, ADDRESS_MODE_1_REL_BIOS);
|
2019-04-11 17:44:43 +02:00
|
|
|
|
|
|
|
ctx->current = ALIGN(ctx->current + bytes,
|
|
|
|
BLOB_ERASE_ALIGNMENT);
|
|
|
|
count++;
|
2016-03-02 07:47:27 +01:00
|
|
|
} else if (fw_table[i].filename != NULL) {
|
2019-03-05 00:53:15 +01:00
|
|
|
bytes = copy_blob(BUFF_CURRENT(*ctx),
|
|
|
|
fw_table[i].filename, BUFF_ROOM(*ctx));
|
2019-03-13 21:43:17 +01:00
|
|
|
if (bytes < 0) {
|
2019-03-05 00:53:15 +01:00
|
|
|
free(ctx->rom);
|
2016-11-08 17:55:01 +01:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2019-02-28 02:40:49 +01:00
|
|
|
pspdir->entries[count].type = fw_table[i].type;
|
2019-03-04 18:31:03 +01:00
|
|
|
pspdir->entries[count].subprog = fw_table[i].subprog;
|
|
|
|
pspdir->entries[count].rsvd = 0;
|
2019-02-28 02:40:49 +01:00
|
|
|
pspdir->entries[count].size = (uint32_t)bytes;
|
2019-03-05 00:53:15 +01:00
|
|
|
pspdir->entries[count].addr = RUN_CURRENT(*ctx);
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
pspdir->entries[count].address_mode = SET_ADDR_MODE_BY_TABLE(pspdir);
|
2016-03-02 07:47:27 +01:00
|
|
|
|
2019-03-05 00:53:15 +01:00
|
|
|
ctx->current = ALIGN(ctx->current + bytes,
|
|
|
|
BLOB_ALIGNMENT);
|
2019-02-24 00:41:35 +01:00
|
|
|
count++;
|
2016-03-02 07:47:27 +01:00
|
|
|
} else {
|
|
|
|
/* This APU doesn't have this firmware. */
|
|
|
|
}
|
2015-11-17 15:57:39 +01:00
|
|
|
}
|
2019-03-05 00:53:15 +01:00
|
|
|
|
2021-09-17 07:24:54 +02:00
|
|
|
if (recovery_ab && (pspdir2 != NULL)) {
|
2021-09-17 07:30:08 +02:00
|
|
|
if (cb_config->need_ish) { /* Need ISH */
|
|
|
|
ish_a_dir = new_ish_dir(ctx);
|
|
|
|
if (pspdir2_b != NULL)
|
|
|
|
ish_b_dir = new_ish_dir(ctx);
|
|
|
|
}
|
2021-09-17 07:24:54 +02:00
|
|
|
pspdir->header.num_entries = count;
|
2021-09-17 07:30:08 +02:00
|
|
|
integrate_psp_ab(ctx, pspdir, pspdir2, ish_a_dir,
|
|
|
|
AMD_FW_RECOVERYAB_A, soc_id);
|
2021-09-17 07:24:54 +02:00
|
|
|
if (pspdir2_b != NULL)
|
2021-09-17 07:30:08 +02:00
|
|
|
integrate_psp_ab(ctx, pspdir, pspdir2_b, ish_b_dir,
|
|
|
|
AMD_FW_RECOVERYAB_B, soc_id);
|
2021-09-17 07:24:54 +02:00
|
|
|
count = pspdir->header.num_entries;
|
|
|
|
} else if (pspdir2 != NULL) {
|
2021-10-30 06:09:07 +02:00
|
|
|
assert_fw_entry(count, MAX_PSP_ENTRIES, ctx);
|
2019-04-01 18:48:43 +02:00
|
|
|
pspdir->entries[count].type = AMD_FW_L2_PTR;
|
|
|
|
pspdir->entries[count].subprog = 0;
|
|
|
|
pspdir->entries[count].rsvd = 0;
|
|
|
|
pspdir->entries[count].size = sizeof(pspdir2->header)
|
|
|
|
+ pspdir2->header.num_entries
|
|
|
|
* sizeof(psp_directory_entry);
|
|
|
|
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
pspdir->entries[count].addr =
|
|
|
|
BUFF_TO_RUN_MODE(*ctx, pspdir2, ADDRESS_MODE_1_REL_BIOS);
|
|
|
|
pspdir->entries[count].address_mode =
|
|
|
|
SET_ADDR_MODE(pspdir, ADDRESS_MODE_1_REL_BIOS);
|
2019-04-01 18:48:43 +02:00
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
2020-12-03 16:00:48 +01:00
|
|
|
fill_dir_header(pspdir, count, cookie, ctx);
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
ctx->current_table = current_table_save;
|
2015-11-17 15:57:39 +01:00
|
|
|
}
|
|
|
|
|
2021-09-17 07:24:54 +02:00
|
|
|
static void add_psp_firmware_entry(context *ctx,
|
|
|
|
psp_directory_table *pspdir,
|
|
|
|
void *table, amd_fw_type type, uint32_t size)
|
|
|
|
{
|
|
|
|
uint32_t count = pspdir->header.num_entries;
|
|
|
|
uint32_t index;
|
|
|
|
uint32_t current_table_save;
|
|
|
|
|
|
|
|
current_table_save = ctx->current_table;
|
|
|
|
ctx->current_table = (char *)pspdir - ctx->rom;
|
|
|
|
|
|
|
|
/* If there is an entry of "type", replace it. */
|
|
|
|
for (index = 0; index < count; index++) {
|
|
|
|
if (pspdir->entries[index].type == (uint8_t)type)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_fw_entry(count, MAX_PSP_ENTRIES, ctx);
|
|
|
|
pspdir->entries[index].type = (uint8_t)type;
|
|
|
|
pspdir->entries[index].subprog = 0;
|
|
|
|
pspdir->entries[index].rsvd = 0;
|
|
|
|
pspdir->entries[index].addr = BUFF_TO_RUN(*ctx, table);
|
|
|
|
pspdir->entries[index].address_mode = SET_ADDR_MODE_BY_TABLE(pspdir);
|
|
|
|
pspdir->entries[index].size = size;
|
|
|
|
if (index == count)
|
|
|
|
count++;
|
|
|
|
|
|
|
|
pspdir->header.num_entries = count;
|
|
|
|
pspdir->header.checksum = fletcher32(&pspdir->header.num_entries,
|
|
|
|
count * sizeof(psp_directory_entry)
|
|
|
|
+ sizeof(pspdir->header.num_entries)
|
|
|
|
+ sizeof(pspdir->header.additional_info));
|
|
|
|
|
|
|
|
ctx->current_table = current_table_save;
|
|
|
|
}
|
|
|
|
|
2021-11-04 11:56:47 +01:00
|
|
|
static void *new_bios_dir(context *ctx, bool multi)
|
2019-03-19 21:45:31 +01:00
|
|
|
{
|
|
|
|
void *ptr;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Force both onto boundary when multi. Primary table is after
|
|
|
|
* updatable table, so alignment ensures primary can stay intact
|
|
|
|
* if secondary is reprogrammed.
|
|
|
|
*/
|
|
|
|
if (multi)
|
|
|
|
ctx->current = ALIGN(ctx->current, TABLE_ERASE_ALIGNMENT);
|
|
|
|
else
|
|
|
|
ctx->current = ALIGN(ctx->current, TABLE_ALIGNMENT);
|
|
|
|
ptr = BUFF_CURRENT(*ctx);
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
((bios_directory_hdr *) ptr)->additional_info = 0;
|
|
|
|
((bios_directory_hdr *) ptr)->additional_info_fields.address_mode = ctx->address_mode;
|
|
|
|
ctx->current_table = ctx->current;
|
2019-03-19 21:45:31 +01:00
|
|
|
ctx->current += sizeof(bios_directory_hdr)
|
|
|
|
+ MAX_BIOS_ENTRIES * sizeof(bios_directory_entry);
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int locate_bdt2_bios(bios_directory_table *level2,
|
|
|
|
uint64_t *source, uint32_t *size)
|
|
|
|
{
|
2020-10-01 10:16:30 +02:00
|
|
|
uint32_t i;
|
2019-03-19 21:45:31 +01:00
|
|
|
|
|
|
|
*source = 0;
|
|
|
|
*size = 0;
|
|
|
|
if (!level2)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
for (i = 0 ; i < level2->header.num_entries ; i++) {
|
|
|
|
if (level2->entries[i].type == AMD_BIOS_BIN) {
|
|
|
|
*source = level2->entries[i].source;
|
|
|
|
*size = level2->entries[i].size;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int have_bios_tables(amd_bios_entry *table)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0 ; table[i].type != AMD_BIOS_INVALID; i++) {
|
|
|
|
if (table[i].level & BDT_LVL1 && table[i].filename)
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-01-22 01:17:59 +01:00
|
|
|
static int find_bios_entry(amd_bios_type type)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; amd_bios_table[i].type != AMD_BIOS_INVALID; i++) {
|
|
|
|
if (amd_bios_table[i].type == type)
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2019-03-19 21:45:31 +01:00
|
|
|
static void integrate_bios_firmwares(context *ctx,
|
|
|
|
bios_directory_table *biosdir,
|
|
|
|
bios_directory_table *biosdir2,
|
|
|
|
amd_bios_entry *fw_table,
|
2021-08-20 08:58:22 +02:00
|
|
|
uint32_t cookie,
|
|
|
|
amd_cb_config *cb_config)
|
2019-03-19 21:45:31 +01:00
|
|
|
{
|
|
|
|
ssize_t bytes;
|
2019-07-14 04:03:34 +02:00
|
|
|
unsigned int i, count;
|
2019-03-19 21:45:31 +01:00
|
|
|
int level;
|
2020-01-22 01:17:59 +01:00
|
|
|
int apob_idx;
|
2020-09-01 18:54:11 +02:00
|
|
|
uint32_t size;
|
|
|
|
uint64_t source;
|
2019-03-19 21:45:31 +01:00
|
|
|
|
|
|
|
/* This function can create a primary table, a secondary table, or a
|
|
|
|
* flattened table which contains all applicable types. These if-else
|
|
|
|
* statements infer what the caller intended. If a 2nd-level cookie
|
|
|
|
* is passed, clearly a 2nd-level table is intended. However, a
|
|
|
|
* 1st-level cookie may indicate level 1 or flattened. If the caller
|
|
|
|
* passes a pointer to a 2nd-level table, then assume not flat.
|
|
|
|
*/
|
2021-11-04 11:56:47 +01:00
|
|
|
if (!cb_config->multi_level)
|
2021-08-20 08:58:22 +02:00
|
|
|
level = BDT_BOTH;
|
|
|
|
else if (cookie == BDT2_COOKIE)
|
2019-03-19 21:45:31 +01:00
|
|
|
level = BDT_LVL2;
|
|
|
|
else if (biosdir2)
|
|
|
|
level = BDT_LVL1;
|
|
|
|
else
|
|
|
|
level = BDT_BOTH;
|
|
|
|
|
2020-12-03 16:00:48 +01:00
|
|
|
ctx->current = ALIGN(ctx->current, TABLE_ALIGNMENT);
|
2019-03-19 21:45:31 +01:00
|
|
|
|
|
|
|
for (i = 0, count = 0; fw_table[i].type != AMD_BIOS_INVALID; i++) {
|
|
|
|
if (!(fw_table[i].level & level))
|
|
|
|
continue;
|
|
|
|
if (fw_table[i].filename == NULL && (
|
|
|
|
fw_table[i].type != AMD_BIOS_APOB &&
|
|
|
|
fw_table[i].type != AMD_BIOS_APOB_NV &&
|
|
|
|
fw_table[i].type != AMD_BIOS_L2_PTR &&
|
2020-04-14 22:59:36 +02:00
|
|
|
fw_table[i].type != AMD_BIOS_BIN &&
|
|
|
|
fw_table[i].type != AMD_BIOS_PSP_SHARED_MEM))
|
2019-03-19 21:45:31 +01:00
|
|
|
continue;
|
|
|
|
|
|
|
|
/* BIOS Directory items may have additional requirements */
|
|
|
|
|
2020-07-30 00:32:25 +02:00
|
|
|
/* Check APOB_NV requirements */
|
|
|
|
if (fw_table[i].type == AMD_BIOS_APOB_NV) {
|
|
|
|
if (!fw_table[i].size && !fw_table[i].src)
|
|
|
|
continue; /* APOB_NV not used */
|
|
|
|
if (fw_table[i].src && !fw_table[i].size) {
|
2020-10-01 11:05:43 +02:00
|
|
|
fprintf(stderr, "Error: APOB NV address provided, but no size\n");
|
2019-03-19 21:45:31 +01:00
|
|
|
free(ctx->rom);
|
|
|
|
exit(1);
|
|
|
|
}
|
2020-07-30 00:32:25 +02:00
|
|
|
/* If the APOB isn't used, APOB_NV isn't used either */
|
2020-01-22 01:17:59 +01:00
|
|
|
apob_idx = find_bios_entry(AMD_BIOS_APOB);
|
2020-07-30 00:32:25 +02:00
|
|
|
if (apob_idx < 0 || !fw_table[apob_idx].dest)
|
|
|
|
continue; /* APOV NV not supported */
|
2020-01-22 01:17:59 +01:00
|
|
|
}
|
2019-03-19 21:45:31 +01:00
|
|
|
|
|
|
|
/* APOB_DATA needs destination */
|
|
|
|
if (fw_table[i].type == AMD_BIOS_APOB && !fw_table[i].dest) {
|
2020-10-01 11:05:43 +02:00
|
|
|
fprintf(stderr, "Error: APOB destination not provided\n");
|
2019-03-19 21:45:31 +01:00
|
|
|
free(ctx->rom);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* BIOS binary must have destination and uncompressed size. If
|
|
|
|
* no filename given, then user must provide a source address.
|
|
|
|
*/
|
|
|
|
if (fw_table[i].type == AMD_BIOS_BIN) {
|
|
|
|
if (!fw_table[i].dest || !fw_table[i].size) {
|
2020-10-01 11:05:43 +02:00
|
|
|
fprintf(stderr, "Error: BIOS binary destination and uncompressed size are required\n");
|
2019-03-19 21:45:31 +01:00
|
|
|
free(ctx->rom);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if (!fw_table[i].filename && !fw_table[i].src) {
|
2020-10-01 11:05:43 +02:00
|
|
|
fprintf(stderr, "Error: BIOS binary assumed outside amdfw.rom but no source address given\n");
|
2019-03-19 21:45:31 +01:00
|
|
|
free(ctx->rom);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-14 22:59:36 +02:00
|
|
|
/* PSP_SHARED_MEM needs a destination and size */
|
|
|
|
if (fw_table[i].type == AMD_BIOS_PSP_SHARED_MEM &&
|
|
|
|
(!fw_table[i].dest || !fw_table[i].size))
|
|
|
|
continue;
|
2021-10-30 06:09:07 +02:00
|
|
|
assert_fw_entry(count, MAX_BIOS_ENTRIES, ctx);
|
2020-04-14 22:59:36 +02:00
|
|
|
|
2019-03-19 21:45:31 +01:00
|
|
|
biosdir->entries[count].type = fw_table[i].type;
|
|
|
|
biosdir->entries[count].region_type = fw_table[i].region_type;
|
|
|
|
biosdir->entries[count].dest = fw_table[i].dest ?
|
|
|
|
fw_table[i].dest : (uint64_t)-1;
|
|
|
|
biosdir->entries[count].reset = fw_table[i].reset;
|
|
|
|
biosdir->entries[count].copy = fw_table[i].copy;
|
|
|
|
biosdir->entries[count].ro = fw_table[i].ro;
|
|
|
|
biosdir->entries[count].compressed = fw_table[i].zlib;
|
|
|
|
biosdir->entries[count].inst = fw_table[i].inst;
|
|
|
|
biosdir->entries[count].subprog = fw_table[i].subpr;
|
|
|
|
|
|
|
|
switch (fw_table[i].type) {
|
|
|
|
case AMD_BIOS_APOB:
|
|
|
|
biosdir->entries[count].size = fw_table[i].size;
|
|
|
|
biosdir->entries[count].source = fw_table[i].src;
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
biosdir->entries[count].address_mode = SET_ADDR_MODE_BY_TABLE(biosdir);
|
2019-03-19 21:45:31 +01:00
|
|
|
break;
|
|
|
|
case AMD_BIOS_APOB_NV:
|
|
|
|
if (fw_table[i].src) {
|
|
|
|
/* If source is given, use that and its size */
|
|
|
|
biosdir->entries[count].source = fw_table[i].src;
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
biosdir->entries[count].address_mode =
|
|
|
|
SET_ADDR_MODE(biosdir, ADDRESS_MODE_1_REL_BIOS);
|
2019-03-19 21:45:31 +01:00
|
|
|
biosdir->entries[count].size = fw_table[i].size;
|
|
|
|
} else {
|
|
|
|
/* Else reserve size bytes within amdfw.rom */
|
|
|
|
ctx->current = ALIGN(ctx->current, ERASE_ALIGNMENT);
|
|
|
|
biosdir->entries[count].source = RUN_CURRENT(*ctx);
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
biosdir->entries[count].address_mode =
|
|
|
|
SET_ADDR_MODE(biosdir, ADDRESS_MODE_1_REL_BIOS);
|
2019-03-19 21:45:31 +01:00
|
|
|
biosdir->entries[count].size = ALIGN(
|
|
|
|
fw_table[i].size, ERASE_ALIGNMENT);
|
|
|
|
memset(BUFF_CURRENT(*ctx), 0xff,
|
|
|
|
biosdir->entries[count].size);
|
|
|
|
ctx->current = ctx->current
|
|
|
|
+ biosdir->entries[count].size;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case AMD_BIOS_BIN:
|
|
|
|
/* Don't make a 2nd copy, point to the same one */
|
2020-09-01 18:54:11 +02:00
|
|
|
if (level == BDT_LVL1 && locate_bdt2_bios(biosdir2, &source, &size)) {
|
|
|
|
biosdir->entries[count].source = source;
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
biosdir->entries[count].address_mode =
|
|
|
|
SET_ADDR_MODE(biosdir, ADDRESS_MODE_1_REL_BIOS);
|
2020-09-01 18:54:11 +02:00
|
|
|
biosdir->entries[count].size = size;
|
2019-03-19 21:45:31 +01:00
|
|
|
break;
|
2020-09-01 18:54:11 +02:00
|
|
|
}
|
2019-03-19 21:45:31 +01:00
|
|
|
|
|
|
|
/* level 2, or level 1 and no copy found in level 2 */
|
|
|
|
biosdir->entries[count].source = fw_table[i].src;
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
biosdir->entries[count].address_mode =
|
|
|
|
SET_ADDR_MODE(biosdir, ADDRESS_MODE_1_REL_BIOS);
|
2019-03-19 21:45:31 +01:00
|
|
|
biosdir->entries[count].dest = fw_table[i].dest;
|
|
|
|
biosdir->entries[count].size = fw_table[i].size;
|
|
|
|
|
|
|
|
if (!fw_table[i].filename)
|
|
|
|
break;
|
|
|
|
|
|
|
|
bytes = copy_blob(BUFF_CURRENT(*ctx),
|
|
|
|
fw_table[i].filename, BUFF_ROOM(*ctx));
|
|
|
|
if (bytes <= 0) {
|
|
|
|
free(ctx->rom);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
biosdir->entries[count].source =
|
|
|
|
RUN_CURRENT_MODE(*ctx, ADDRESS_MODE_1_REL_BIOS);
|
|
|
|
biosdir->entries[count].address_mode =
|
|
|
|
SET_ADDR_MODE(biosdir, ADDRESS_MODE_1_REL_BIOS);
|
2019-03-19 21:45:31 +01:00
|
|
|
|
|
|
|
ctx->current = ALIGN(ctx->current + bytes, 0x100U);
|
|
|
|
break;
|
2020-04-14 22:59:36 +02:00
|
|
|
case AMD_BIOS_PSP_SHARED_MEM:
|
|
|
|
biosdir->entries[count].dest = fw_table[i].dest;
|
|
|
|
biosdir->entries[count].size = fw_table[i].size;
|
|
|
|
break;
|
|
|
|
|
2019-03-19 21:45:31 +01:00
|
|
|
default: /* everything else is copied from input */
|
|
|
|
if (fw_table[i].type == AMD_BIOS_APCB ||
|
|
|
|
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) {
|
|
|
|
free(ctx->rom);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
biosdir->entries[count].size = (uint32_t)bytes;
|
|
|
|
biosdir->entries[count].source = RUN_CURRENT(*ctx);
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
biosdir->entries[count].address_mode = SET_ADDR_MODE_BY_TABLE(biosdir);
|
2019-03-19 21:45:31 +01:00
|
|
|
|
|
|
|
ctx->current = ALIGN(ctx->current + bytes, 0x100U);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (biosdir2) {
|
2021-10-30 06:09:07 +02:00
|
|
|
assert_fw_entry(count, MAX_BIOS_ENTRIES, ctx);
|
2019-03-19 21:45:31 +01:00
|
|
|
biosdir->entries[count].type = AMD_BIOS_L2_PTR;
|
2021-05-24 10:11:12 +02:00
|
|
|
biosdir->entries[count].region_type = 0;
|
2019-03-19 21:45:31 +01:00
|
|
|
biosdir->entries[count].size =
|
|
|
|
+ MAX_BIOS_ENTRIES
|
|
|
|
* sizeof(bios_directory_entry);
|
|
|
|
biosdir->entries[count].source =
|
|
|
|
BUFF_TO_RUN(*ctx, biosdir2);
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
biosdir->entries[count].address_mode =
|
|
|
|
SET_ADDR_MODE(biosdir, ADDRESS_MODE_1_REL_BIOS);
|
2019-03-19 21:45:31 +01:00
|
|
|
biosdir->entries[count].subprog = 0;
|
|
|
|
biosdir->entries[count].inst = 0;
|
|
|
|
biosdir->entries[count].copy = 0;
|
|
|
|
biosdir->entries[count].compressed = 0;
|
|
|
|
biosdir->entries[count].dest = -1;
|
|
|
|
biosdir->entries[count].reset = 0;
|
|
|
|
biosdir->entries[count].ro = 0;
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
2020-12-03 16:00:48 +01:00
|
|
|
fill_dir_header(biosdir, count, cookie, ctx);
|
2019-03-19 21:45:31 +01:00
|
|
|
}
|
2020-06-15 18:18:15 +02:00
|
|
|
|
|
|
|
enum {
|
2021-04-27 11:21:54 +02:00
|
|
|
AMDFW_OPT_CONFIG = 'c',
|
|
|
|
AMDFW_OPT_DEBUG = 'd',
|
|
|
|
AMDFW_OPT_HELP = 'h',
|
|
|
|
AMDFW_OPT_LIST_DEPEND = 'l',
|
|
|
|
|
|
|
|
AMDFW_OPT_XHCI = 128,
|
|
|
|
AMDFW_OPT_IMC,
|
|
|
|
AMDFW_OPT_GEC,
|
|
|
|
AMDFW_OPT_COMBO,
|
2021-09-17 07:24:54 +02:00
|
|
|
AMDFW_OPT_RECOVERY_AB,
|
2021-04-27 11:21:54 +02:00
|
|
|
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,
|
2022-02-11 04:51:26 +01:00
|
|
|
AMDFW_OPT_SPL_TABLE,
|
2021-04-27 11:21:54 +02:00
|
|
|
AMDFW_OPT_VERSTAGE,
|
|
|
|
AMDFW_OPT_VERSTAGE_SIG,
|
|
|
|
|
|
|
|
AMDFW_OPT_INSTANCE,
|
|
|
|
AMDFW_OPT_APCB,
|
|
|
|
AMDFW_OPT_APOBBASE,
|
|
|
|
AMDFW_OPT_BIOSBIN,
|
|
|
|
AMDFW_OPT_BIOSBIN_SOURCE,
|
|
|
|
AMDFW_OPT_BIOSBIN_DEST,
|
|
|
|
AMDFW_OPT_BIOS_UNCOMP_SIZE,
|
|
|
|
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_SOC_NAME,
|
2020-06-15 18:18:15 +02:00
|
|
|
/* begin after ASCII characters */
|
|
|
|
LONGOPT_SPI_READ_MODE = 256,
|
|
|
|
LONGOPT_SPI_SPEED = 257,
|
|
|
|
LONGOPT_SPI_MICRON_FLAG = 258,
|
|
|
|
};
|
|
|
|
|
2021-04-27 11:21:54 +02:00
|
|
|
static char const optstring[] = {AMDFW_OPT_CONFIG, ':',
|
|
|
|
AMDFW_OPT_DEBUG, AMDFW_OPT_HELP, AMDFW_OPT_LIST_DEPEND
|
|
|
|
};
|
2016-09-21 05:05:45 +02:00
|
|
|
|
2015-11-17 15:57:39 +01:00
|
|
|
static struct option long_options[] = {
|
2021-04-27 11:21:54 +02:00
|
|
|
{"xhci", required_argument, 0, AMDFW_OPT_XHCI },
|
|
|
|
{"imc", required_argument, 0, AMDFW_OPT_IMC },
|
|
|
|
{"gec", required_argument, 0, AMDFW_OPT_GEC },
|
2019-03-19 21:45:31 +01:00
|
|
|
/* PSP Directory Table items */
|
2021-04-27 11:21:54 +02:00
|
|
|
{"combo-capable", no_argument, 0, AMDFW_OPT_COMBO },
|
2021-09-17 07:24:54 +02:00
|
|
|
{"recovery-ab", no_argument, 0, AMDFW_OPT_RECOVERY_AB },
|
2021-04-27 11:21:54 +02:00
|
|
|
{"multilevel", no_argument, 0, AMDFW_OPT_MULTILEVEL },
|
|
|
|
{"nvram", required_argument, 0, AMDFW_OPT_NVRAM },
|
|
|
|
{"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 },
|
2022-02-11 04:51:26 +01:00
|
|
|
{"spl-table", required_argument, 0, AMDFW_OPT_SPL_TABLE },
|
2021-04-27 11:21:54 +02:00
|
|
|
{"verstage", required_argument, 0, AMDFW_OPT_VERSTAGE },
|
|
|
|
{"verstage_sig", required_argument, 0, AMDFW_OPT_VERSTAGE_SIG },
|
2019-03-19 21:45:31 +01:00
|
|
|
/* BIOS Directory Table items */
|
2021-04-27 11:21:54 +02:00
|
|
|
{"instance", required_argument, 0, AMDFW_OPT_INSTANCE },
|
|
|
|
{"apcb", required_argument, 0, AMDFW_OPT_APCB },
|
|
|
|
{"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 },
|
|
|
|
{"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 },
|
2020-06-15 18:18:15 +02:00
|
|
|
/* 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 },
|
2019-03-19 21:45:31 +01:00
|
|
|
/* other */
|
2021-04-27 11:21:54 +02:00
|
|
|
{"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 },
|
|
|
|
{"soc-name", required_argument, 0, AMDFW_OPT_SOC_NAME },
|
|
|
|
|
|
|
|
{"config", required_argument, 0, AMDFW_OPT_CONFIG },
|
|
|
|
{"debug", no_argument, 0, AMDFW_OPT_DEBUG },
|
|
|
|
{"help", no_argument, 0, AMDFW_OPT_HELP },
|
|
|
|
{"list", no_argument, 0, AMDFW_OPT_LIST_DEPEND },
|
2017-03-17 23:30:51 +01:00
|
|
|
{NULL, 0, 0, 0 }
|
2015-11-17 15:57:39 +01:00
|
|
|
};
|
|
|
|
|
2020-10-28 04:38:09 +01:00
|
|
|
void register_fw_fuse(char *str)
|
2019-04-01 18:16:41 +02:00
|
|
|
{
|
2020-10-01 10:16:30 +02:00
|
|
|
uint32_t i;
|
2019-04-01 18:16:41 +02:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-19 21:45:31 +01:00
|
|
|
static void register_fw_token_unlock(void)
|
|
|
|
{
|
2020-10-01 10:16:30 +02:00
|
|
|
uint32_t i;
|
2019-03-19 21:45:31 +01:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-04 18:31:03 +01:00
|
|
|
static void register_fw_filename(amd_fw_type type, uint8_t sub, char filename[])
|
2015-11-17 15:57:39 +01:00
|
|
|
{
|
2016-11-08 18:44:18 +01:00
|
|
|
unsigned int i;
|
2015-11-17 15:57:39 +01:00
|
|
|
|
2016-11-08 19:34:02 +01:00
|
|
|
for (i = 0; i < sizeof(amd_fw_table) / sizeof(amd_fw_entry); i++) {
|
2015-11-17 15:57:39 +01:00
|
|
|
if (amd_fw_table[i].type == type) {
|
|
|
|
amd_fw_table[i].filename = filename;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-05 00:50:37 +01:00
|
|
|
for (i = 0; i < sizeof(amd_psp_fw_table) / sizeof(amd_fw_entry); i++) {
|
2019-03-04 18:31:03 +01:00
|
|
|
if (amd_psp_fw_table[i].type != type)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (amd_psp_fw_table[i].subprog == sub) {
|
2019-03-05 00:50:37 +01:00
|
|
|
amd_psp_fw_table[i].filename = filename;
|
|
|
|
return;
|
2015-11-17 15:57:39 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-19 21:45:31 +01:00
|
|
|
static void register_bdt_data(amd_bios_type type, int sub, int ins, char name[])
|
|
|
|
{
|
2020-10-01 10:16:30 +02:00
|
|
|
uint32_t i;
|
2019-03-19 21:45:31 +01:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-14 04:03:34 +02:00
|
|
|
static void register_fw_addr(amd_bios_type type, char *src_str,
|
2019-03-19 21:45:31 +01:00
|
|
|
char *dst_str, char *size_str)
|
|
|
|
{
|
2020-10-01 10:16:30 +02:00
|
|
|
uint32_t i;
|
2019-03-19 21:45:31 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-15 18:18:15 +02:00
|
|
|
static int set_efs_table(uint8_t soc_id, embedded_firmware *amd_romsig,
|
|
|
|
uint8_t efs_spi_readmode, uint8_t efs_spi_speed,
|
|
|
|
uint8_t efs_spi_micron_flag)
|
|
|
|
{
|
|
|
|
if ((efs_spi_readmode == 0xFF) || (efs_spi_speed == 0xFF)) {
|
2020-10-01 11:05:43 +02:00
|
|
|
fprintf(stderr, "Error: EFS read mode and SPI speed must be set\n");
|
2020-06-15 18:18:15 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
switch (soc_id) {
|
|
|
|
case PLATFORM_STONEYRIDGE:
|
2022-04-03 06:50:07 +02:00
|
|
|
amd_romsig->efs_gen.gen = EFS_BEFORE_SECOND_GEN;
|
|
|
|
amd_romsig->efs_gen.reserved = ~0;
|
2020-06-15 18:18:15 +02:00
|
|
|
amd_romsig->spi_readmode_f15_mod_60_6f = efs_spi_readmode;
|
|
|
|
amd_romsig->fast_speed_new_f15_mod_60_6f = efs_spi_speed;
|
|
|
|
break;
|
|
|
|
case PLATFORM_RAVEN:
|
|
|
|
case PLATFORM_PICASSO:
|
2020-11-19 22:02:29 +01:00
|
|
|
/* amd_romsig->efs_gen introduced after RAVEN/PICASSO.
|
|
|
|
* Leave as 0xffffffff for first gen */
|
2022-04-03 06:50:07 +02:00
|
|
|
amd_romsig->efs_gen.gen = EFS_BEFORE_SECOND_GEN;
|
|
|
|
amd_romsig->efs_gen.reserved = ~0;
|
2020-06-15 18:18:15 +02:00
|
|
|
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) {
|
|
|
|
case 0:
|
|
|
|
amd_romsig->qpr_dummy_cycle_f17_mod_00_2f = 0xff;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
amd_romsig->qpr_dummy_cycle_f17_mod_00_2f = 0xa;
|
|
|
|
break;
|
|
|
|
default:
|
2020-10-01 11:05:43 +02:00
|
|
|
fprintf(stderr, "Error: EFS Micron flag must be correctly set.\n\n");
|
2020-06-15 18:18:15 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PLATFORM_RENOIR:
|
|
|
|
case PLATFORM_LUCIENNE:
|
2020-12-03 16:00:48 +01:00
|
|
|
case PLATFORM_CEZANNE:
|
2021-08-12 10:30:19 +02:00
|
|
|
case PLATFORM_MENDOCINO:
|
2022-03-29 02:34:11 +02:00
|
|
|
case PLATFORM_SABRINA:
|
2020-11-19 22:02:29 +01:00
|
|
|
amd_romsig->efs_gen.gen = EFS_SECOND_GEN;
|
2022-04-03 06:50:07 +02:00
|
|
|
amd_romsig->efs_gen.reserved = 0;
|
2020-06-15 18:18:15 +02:00
|
|
|
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) {
|
|
|
|
case 0:
|
|
|
|
amd_romsig->micron_detect_f17_mod_30_3f = 0xff;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
amd_romsig->micron_detect_f17_mod_30_3f = 0xaa;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
amd_romsig->micron_detect_f17_mod_30_3f = 0x55;
|
|
|
|
break;
|
|
|
|
default:
|
2020-10-01 11:05:43 +02:00
|
|
|
fprintf(stderr, "Error: EFS Micron flag must be correctly set.\n\n");
|
2020-06-15 18:18:15 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PLATFORM_UNKNOWN:
|
|
|
|
default:
|
2020-10-01 11:05:43 +02:00
|
|
|
fprintf(stderr, "Error: Invalid SOC name.\n\n");
|
2020-06-15 18:18:15 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int identify_platform(char *soc_name)
|
|
|
|
{
|
|
|
|
if (!strcasecmp(soc_name, "Stoneyridge"))
|
|
|
|
return PLATFORM_STONEYRIDGE;
|
|
|
|
else if (!strcasecmp(soc_name, "Raven"))
|
|
|
|
return PLATFORM_RAVEN;
|
|
|
|
else if (!strcasecmp(soc_name, "Picasso"))
|
|
|
|
return PLATFORM_PICASSO;
|
2020-12-03 16:00:48 +01:00
|
|
|
else if (!strcasecmp(soc_name, "Cezanne"))
|
|
|
|
return PLATFORM_CEZANNE;
|
2021-08-12 10:30:19 +02:00
|
|
|
else if (!strcasecmp(soc_name, "Mendocino"))
|
|
|
|
return PLATFORM_MENDOCINO;
|
2020-06-15 18:18:15 +02:00
|
|
|
else if (!strcasecmp(soc_name, "Renoir"))
|
|
|
|
return PLATFORM_RENOIR;
|
|
|
|
else if (!strcasecmp(soc_name, "Lucienne"))
|
|
|
|
return PLATFORM_LUCIENNE;
|
2022-03-29 02:34:11 +02:00
|
|
|
else if (!strcasecmp(soc_name, "Sabrina"))
|
|
|
|
return PLATFORM_SABRINA;
|
2020-06-15 18:18:15 +02:00
|
|
|
else
|
|
|
|
return PLATFORM_UNKNOWN;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-03-29 23:28:49 +02:00
|
|
|
static bool needs_ish(enum platform platform_type)
|
|
|
|
{
|
|
|
|
if (platform_type == PLATFORM_SABRINA)
|
|
|
|
return true;
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-11-17 15:57:39 +01:00
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
2019-03-05 00:50:37 +01:00
|
|
|
int c;
|
2016-11-08 19:22:12 +01:00
|
|
|
int retval = 0;
|
2016-11-08 17:55:01 +01:00
|
|
|
char *tmp;
|
2016-11-08 18:44:18 +01:00
|
|
|
char *rom = NULL;
|
2019-02-24 00:42:46 +01:00
|
|
|
embedded_firmware *amd_romsig;
|
2021-09-17 07:24:54 +02:00
|
|
|
psp_directory_table *pspdir = NULL;
|
|
|
|
psp_directory_table *pspdir2 = NULL;
|
|
|
|
psp_directory_table *pspdir2_b = NULL;
|
2021-11-10 07:09:06 +01:00
|
|
|
bool comboable = false;
|
2019-04-01 18:16:41 +02:00
|
|
|
int fuse_defined = 0;
|
2015-11-17 15:57:39 +01:00
|
|
|
int targetfd;
|
2020-10-28 04:38:09 +01:00
|
|
|
char *output = NULL, *config = NULL;
|
|
|
|
FILE *config_handle;
|
2020-09-28 04:36:29 +02:00
|
|
|
context ctx = { 0 };
|
2019-03-19 21:45:31 +01:00
|
|
|
/* Values cleared after each firmware or parameter, regardless if N/A */
|
|
|
|
uint8_t sub = 0, instance = 0;
|
2017-10-03 22:16:04 +02:00
|
|
|
uint32_t dir_location = 0;
|
2020-04-07 22:16:39 +02:00
|
|
|
bool any_location = 0;
|
2017-10-03 22:16:04 +02:00
|
|
|
uint32_t romsig_offset;
|
2016-11-08 17:55:01 +01:00
|
|
|
uint32_t rom_base_address;
|
2020-06-15 18:18:15 +02:00
|
|
|
uint8_t soc_id = PLATFORM_UNKNOWN;
|
|
|
|
uint8_t efs_spi_readmode = 0xff;
|
|
|
|
uint8_t efs_spi_speed = 0xff;
|
|
|
|
uint8_t efs_spi_micron_flag = 0xff;
|
|
|
|
|
2020-10-28 04:38:09 +01:00
|
|
|
amd_cb_config cb_config;
|
2020-10-28 04:39:13 +01:00
|
|
|
int debug = 0;
|
2020-10-28 04:38:09 +01:00
|
|
|
int list_deps = 0;
|
|
|
|
|
2021-11-04 11:56:47 +01:00
|
|
|
cb_config.have_whitelist = false;
|
|
|
|
cb_config.unlock_secure = false;
|
|
|
|
cb_config.use_secureos = false;
|
|
|
|
cb_config.load_mp2_fw = false;
|
|
|
|
cb_config.s0i3 = false;
|
|
|
|
cb_config.multi_level = false;
|
2021-09-17 07:24:54 +02:00
|
|
|
cb_config.recovery_ab = false;
|
2021-09-17 07:30:08 +02:00
|
|
|
cb_config.need_ish = false;
|
2015-11-17 15:57:39 +01:00
|
|
|
|
|
|
|
while (1) {
|
|
|
|
int optindex = 0;
|
|
|
|
|
|
|
|
c = getopt_long(argc, argv, optstring, long_options, &optindex);
|
|
|
|
|
|
|
|
if (c == -1)
|
|
|
|
break;
|
|
|
|
|
|
|
|
switch (c) {
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_XHCI:
|
2019-03-04 18:31:03 +01:00
|
|
|
register_fw_filename(AMD_FW_XHCI, sub, optarg);
|
2019-03-19 21:45:31 +01:00
|
|
|
sub = instance = 0;
|
2015-11-17 15:57:39 +01:00
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_IMC:
|
2019-03-04 18:31:03 +01:00
|
|
|
register_fw_filename(AMD_FW_IMC, sub, optarg);
|
2019-03-19 21:45:31 +01:00
|
|
|
sub = instance = 0;
|
2015-11-17 15:57:39 +01:00
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_GEC:
|
2019-03-04 18:31:03 +01:00
|
|
|
register_fw_filename(AMD_FW_GEC, sub, optarg);
|
2019-03-19 21:45:31 +01:00
|
|
|
sub = instance = 0;
|
2015-11-17 15:57:39 +01:00
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_COMBO:
|
2021-11-04 11:56:47 +01:00
|
|
|
comboable = true;
|
2019-02-28 19:43:40 +01:00
|
|
|
break;
|
2021-09-17 07:24:54 +02:00
|
|
|
case AMDFW_OPT_RECOVERY_AB:
|
|
|
|
cb_config.recovery_ab = true;
|
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_MULTILEVEL:
|
2021-11-04 11:56:47 +01:00
|
|
|
cb_config.multi_level = true;
|
2019-04-01 18:48:43 +02:00
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_UNLOCK:
|
2019-03-19 21:45:31 +01:00
|
|
|
register_fw_token_unlock();
|
2021-11-04 11:56:47 +01:00
|
|
|
cb_config.unlock_secure = true;
|
2019-03-19 21:45:31 +01:00
|
|
|
sub = instance = 0;
|
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_USE_PSPSECUREOS:
|
2021-11-04 11:56:47 +01:00
|
|
|
cb_config.use_secureos = true;
|
2019-03-04 18:31:03 +01:00
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_INSTANCE:
|
2019-03-19 21:45:31 +01:00
|
|
|
instance = strtoul(optarg, &tmp, 16);
|
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_LOAD_MP2FW:
|
2021-11-04 11:56:47 +01:00
|
|
|
cb_config.load_mp2_fw = true;
|
2015-11-17 15:57:39 +01:00
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_NVRAM:
|
2019-03-04 18:31:03 +01:00
|
|
|
register_fw_filename(AMD_FW_PSP_NVRAM, sub, optarg);
|
2019-03-19 21:45:31 +01:00
|
|
|
sub = instance = 0;
|
2015-11-17 15:57:39 +01:00
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_FUSE:
|
2019-04-01 18:16:41 +02:00
|
|
|
register_fw_fuse(optarg);
|
|
|
|
fuse_defined = 1;
|
|
|
|
sub = 0;
|
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_APCB:
|
2020-12-04 09:39:38 +01:00
|
|
|
if ((instance & 0xF0) == 0)
|
|
|
|
register_bdt_data(AMD_BIOS_APCB, sub, instance & 0xF, optarg);
|
|
|
|
else
|
|
|
|
register_bdt_data(AMD_BIOS_APCB_BK, sub,
|
|
|
|
instance & 0xF, optarg);
|
2019-03-19 21:45:31 +01:00
|
|
|
sub = instance = 0;
|
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_APOBBASE:
|
2019-03-19 21:45:31 +01:00
|
|
|
/* APOB destination */
|
|
|
|
register_fw_addr(AMD_BIOS_APOB, 0, optarg, 0);
|
|
|
|
sub = instance = 0;
|
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_APOB_NVBASE:
|
2019-03-19 21:45:31 +01:00
|
|
|
/* APOB NV source */
|
|
|
|
register_fw_addr(AMD_BIOS_APOB_NV, optarg, 0, 0);
|
|
|
|
sub = instance = 0;
|
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_APOB_NVSIZE:
|
2019-03-19 21:45:31 +01:00
|
|
|
/* APOB NV size */
|
|
|
|
register_fw_addr(AMD_BIOS_APOB_NV, 0, 0, optarg);
|
|
|
|
sub = instance = 0;
|
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_BIOSBIN:
|
2019-03-19 21:45:31 +01:00
|
|
|
register_bdt_data(AMD_BIOS_BIN, sub, instance, optarg);
|
|
|
|
sub = instance = 0;
|
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_BIOSBIN_SOURCE:
|
2019-03-19 21:45:31 +01:00
|
|
|
/* BIOS source */
|
|
|
|
register_fw_addr(AMD_BIOS_BIN, optarg, 0, 0);
|
|
|
|
sub = instance = 0;
|
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_BIOSBIN_DEST:
|
2019-03-19 21:45:31 +01:00
|
|
|
/* BIOS destination */
|
|
|
|
register_fw_addr(AMD_BIOS_BIN, 0, optarg, 0);
|
|
|
|
sub = instance = 0;
|
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_BIOS_UNCOMP_SIZE:
|
2019-03-19 21:45:31 +01:00
|
|
|
/* BIOS destination size */
|
|
|
|
register_fw_addr(AMD_BIOS_BIN, 0, 0, optarg);
|
|
|
|
sub = instance = 0;
|
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_UCODE:
|
2019-03-19 21:45:31 +01:00
|
|
|
register_bdt_data(AMD_BIOS_UCODE, sub,
|
|
|
|
instance, optarg);
|
|
|
|
sub = instance = 0;
|
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_LOAD_S0I3:
|
2021-11-04 11:56:47 +01:00
|
|
|
cb_config.s0i3 = true;
|
2019-03-19 21:45:31 +01:00
|
|
|
break;
|
2022-02-11 04:51:26 +01:00
|
|
|
case AMDFW_OPT_SPL_TABLE:
|
|
|
|
register_fw_filename(AMD_FW_SPL, sub, optarg);
|
|
|
|
sub = instance = 0;
|
|
|
|
cb_config.have_mb_spl = true;
|
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_WHITELIST:
|
2019-03-19 21:45:31 +01:00
|
|
|
register_fw_filename(AMD_FW_PSP_WHITELIST, sub, optarg);
|
|
|
|
sub = instance = 0;
|
2021-11-04 11:56:47 +01:00
|
|
|
cb_config.have_whitelist = true;
|
2019-03-19 21:45:31 +01:00
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_VERSTAGE:
|
2019-07-14 04:13:07 +02:00
|
|
|
register_fw_filename(AMD_FW_PSP_VERSTAGE, sub, optarg);
|
|
|
|
sub = instance = 0;
|
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_VERSTAGE_SIG:
|
2020-09-01 17:36:59 +02:00
|
|
|
register_fw_filename(AMD_FW_VERSTAGE_SIG, sub, optarg);
|
|
|
|
sub = instance = 0;
|
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_SOC_NAME:
|
2020-06-15 18:18:15 +02:00
|
|
|
soc_id = identify_platform(optarg);
|
|
|
|
if (soc_id == PLATFORM_UNKNOWN) {
|
2020-10-01 11:05:43 +02:00
|
|
|
fprintf(stderr, "Error: Invalid SOC name specified\n\n");
|
2020-06-15 18:18:15 +02:00
|
|
|
retval = 1;
|
|
|
|
}
|
|
|
|
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;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_OUTPUT:
|
2015-11-17 15:57:39 +01:00
|
|
|
output = optarg;
|
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_FLASHSIZE:
|
2019-03-05 00:53:15 +01:00
|
|
|
ctx.rom_size = (uint32_t)strtoul(optarg, &tmp, 16);
|
2016-11-08 17:55:01 +01:00
|
|
|
if (*tmp != '\0') {
|
2020-10-01 11:05:43 +02:00
|
|
|
fprintf(stderr, "Error: ROM size specified"
|
2016-11-08 17:55:01 +01:00
|
|
|
" incorrectly (%s)\n\n", optarg);
|
2016-11-08 19:22:12 +01:00
|
|
|
retval = 1;
|
2016-11-08 17:55:01 +01:00
|
|
|
}
|
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_LOCATION:
|
2017-10-03 22:16:04 +02:00
|
|
|
dir_location = (uint32_t)strtoul(optarg, &tmp, 16);
|
|
|
|
if (*tmp != '\0') {
|
2020-10-01 11:05:43 +02:00
|
|
|
fprintf(stderr, "Error: Directory Location specified"
|
2017-10-03 22:16:04 +02:00
|
|
|
" incorrectly (%s)\n\n", optarg);
|
|
|
|
retval = 1;
|
|
|
|
}
|
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_ANYWHERE:
|
2020-04-07 22:16:39 +02:00
|
|
|
any_location = 1;
|
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_SHAREDMEM:
|
2020-04-14 22:59:36 +02:00
|
|
|
/* shared memory destination */
|
|
|
|
register_fw_addr(AMD_BIOS_PSP_SHARED_MEM, 0, optarg, 0);
|
|
|
|
sub = instance = 0;
|
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_SHAREDMEM_SIZE:
|
2020-04-14 22:59:36 +02:00
|
|
|
/* shared memory size */
|
|
|
|
register_fw_addr(AMD_BIOS_PSP_SHARED_MEM, NULL, NULL, optarg);
|
|
|
|
sub = instance = 0;
|
|
|
|
break;
|
2017-10-03 22:16:04 +02:00
|
|
|
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_CONFIG:
|
2020-10-28 04:38:09 +01:00
|
|
|
config = optarg;
|
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_DEBUG:
|
2020-10-28 04:39:13 +01:00
|
|
|
debug = 1;
|
|
|
|
break;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_HELP:
|
2015-11-17 15:57:39 +01:00
|
|
|
usage();
|
2016-11-08 19:22:12 +01:00
|
|
|
return 0;
|
2021-04-27 11:21:54 +02:00
|
|
|
case AMDFW_OPT_LIST_DEPEND:
|
2020-10-28 04:38:09 +01:00
|
|
|
list_deps = 1;
|
|
|
|
break;
|
2015-11-17 15:57:39 +01:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-29 23:28:49 +02:00
|
|
|
if (needs_ish(soc_id))
|
|
|
|
cb_config.need_ish = true;
|
|
|
|
|
2022-03-29 23:28:10 +02:00
|
|
|
if (cb_config.need_ish)
|
|
|
|
cb_config.recovery_ab = true;
|
|
|
|
|
|
|
|
if (cb_config.recovery_ab)
|
|
|
|
cb_config.multi_level = true;
|
|
|
|
|
2020-10-28 04:38:09 +01:00
|
|
|
if (config) {
|
|
|
|
config_handle = fopen(config, "r");
|
|
|
|
if (config_handle == NULL) {
|
|
|
|
fprintf(stderr, "Can not open file %s for reading: %s\n",
|
|
|
|
config, strerror(errno));
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if (process_config(config_handle, &cb_config, list_deps) == 0) {
|
|
|
|
fprintf(stderr, "Configuration file %s parsing error\n", config);
|
|
|
|
fclose(config_handle);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
fclose(config_handle);
|
|
|
|
}
|
2020-10-28 04:39:13 +01:00
|
|
|
/* For debug. */
|
|
|
|
if (debug) {
|
|
|
|
dump_psp_firmwares(amd_psp_fw_table);
|
|
|
|
dump_bdt_firmwares(amd_bios_table);
|
|
|
|
}
|
|
|
|
|
2019-04-01 18:16:41 +02:00
|
|
|
if (!fuse_defined)
|
|
|
|
register_fw_fuse(DEFAULT_SOFT_FUSE_CHAIN);
|
|
|
|
|
2020-10-28 04:38:09 +01:00
|
|
|
if (!output && !list_deps) {
|
|
|
|
fprintf(stderr, "Error: Output value is not specified.\n\n");
|
2016-11-08 19:22:12 +01:00
|
|
|
retval = 1;
|
|
|
|
}
|
|
|
|
|
2020-10-28 04:38:09 +01:00
|
|
|
if ((ctx.rom_size % 1024 != 0) && !list_deps) {
|
|
|
|
fprintf(stderr, "Error: ROM Size (%d bytes) should be a multiple of"
|
2019-03-05 00:53:15 +01:00
|
|
|
" 1024 bytes.\n\n", ctx.rom_size);
|
2016-11-08 19:22:12 +01:00
|
|
|
retval = 1;
|
2016-11-08 17:55:01 +01:00
|
|
|
}
|
|
|
|
|
2020-10-28 04:38:09 +01:00
|
|
|
if ((ctx.rom_size < MIN_ROM_KB * 1024) && !list_deps) {
|
|
|
|
fprintf(stderr, "Error: ROM Size (%dKB) must be at least %dKB.\n\n",
|
2019-03-05 00:53:15 +01:00
|
|
|
ctx.rom_size / 1024, MIN_ROM_KB);
|
2016-11-08 19:22:12 +01:00
|
|
|
retval = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (retval) {
|
|
|
|
usage();
|
|
|
|
return retval;
|
2016-11-08 17:55:01 +01:00
|
|
|
}
|
|
|
|
|
2020-10-28 04:38:09 +01:00
|
|
|
if (list_deps) {
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2019-03-05 00:53:15 +01:00
|
|
|
printf(" AMDFWTOOL Using ROM size of %dKB\n", ctx.rom_size / 1024);
|
2016-11-08 17:55:01 +01:00
|
|
|
|
2019-03-05 00:53:15 +01:00
|
|
|
rom_base_address = 0xFFFFFFFF - ctx.rom_size + 1;
|
2017-10-03 22:16:04 +02:00
|
|
|
if (dir_location && (dir_location < rom_base_address)) {
|
2020-10-01 11:05:43 +02:00
|
|
|
fprintf(stderr, "Error: Directory location outside of ROM.\n\n");
|
2017-10-03 22:16:04 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-04-07 22:16:39 +02:00
|
|
|
if (any_location) {
|
|
|
|
if (dir_location & 0x3f) {
|
2020-10-01 11:05:43 +02:00
|
|
|
fprintf(stderr, "Error: Invalid Directory location.\n");
|
|
|
|
fprintf(stderr, " Valid locations are 64-byte aligned\n");
|
2020-04-07 22:16:39 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
switch (dir_location) {
|
|
|
|
case 0: /* Fall through */
|
|
|
|
case 0xFFFA0000: /* Fall through */
|
|
|
|
case 0xFFF20000: /* Fall through */
|
|
|
|
case 0xFFE20000: /* Fall through */
|
|
|
|
case 0xFFC20000: /* Fall through */
|
|
|
|
case 0xFF820000: /* Fall through */
|
|
|
|
case 0xFF020000: /* Fall through */
|
|
|
|
break;
|
|
|
|
default:
|
2020-10-01 11:05:43 +02:00
|
|
|
fprintf(stderr, "Error: Invalid Directory location.\n");
|
|
|
|
fprintf(stderr, " Valid locations are 0xFFFA0000, 0xFFF20000,\n");
|
|
|
|
fprintf(stderr, " 0xFFE20000, 0xFFC20000, 0xFF820000, 0xFF020000\n");
|
2020-04-07 22:16:39 +02:00
|
|
|
return 1;
|
|
|
|
}
|
2017-10-03 22:16:04 +02:00
|
|
|
}
|
2019-03-05 00:53:15 +01:00
|
|
|
ctx.rom = malloc(ctx.rom_size);
|
|
|
|
if (!ctx.rom) {
|
2020-10-01 11:05:43 +02:00
|
|
|
fprintf(stderr, "Error: Failed to allocate memory\n");
|
2016-11-08 19:22:12 +01:00
|
|
|
return 1;
|
2019-03-05 00:53:15 +01:00
|
|
|
}
|
|
|
|
memset(ctx.rom, 0xFF, ctx.rom_size);
|
2016-11-08 17:55:01 +01:00
|
|
|
|
2017-10-03 22:16:04 +02:00
|
|
|
if (dir_location)
|
2019-03-05 00:53:15 +01:00
|
|
|
romsig_offset = ctx.current = dir_location - rom_base_address;
|
2017-10-03 22:16:04 +02:00
|
|
|
else
|
2019-03-05 00:53:15 +01:00
|
|
|
romsig_offset = ctx.current = AMD_ROMSIG_OFFSET;
|
2017-10-03 22:16:04 +02:00
|
|
|
|
2019-03-05 00:53:15 +01:00
|
|
|
amd_romsig = BUFF_OFFSET(ctx, romsig_offset);
|
2019-02-24 00:42:46 +01:00
|
|
|
amd_romsig->signature = EMBEDDED_FW_SIGNATURE;
|
|
|
|
amd_romsig->imc_entry = 0;
|
|
|
|
amd_romsig->gec_entry = 0;
|
|
|
|
amd_romsig->xhci_entry = 0;
|
2016-11-08 17:55:01 +01:00
|
|
|
|
2020-06-15 18:18:15 +02:00
|
|
|
if (soc_id != PLATFORM_UNKNOWN) {
|
2021-11-03 03:25:03 +01:00
|
|
|
retval = set_efs_table(soc_id, amd_romsig, efs_spi_readmode,
|
|
|
|
efs_spi_speed, efs_spi_micron_flag);
|
|
|
|
if (retval) {
|
|
|
|
fprintf(stderr, "ERROR: Failed to initialize EFS table!\n");
|
|
|
|
return retval;
|
2020-06-15 18:18:15 +02:00
|
|
|
}
|
|
|
|
} else {
|
2020-10-01 11:05:43 +02:00
|
|
|
fprintf(stderr, "WARNING: No SOC name specified.\n");
|
2020-06-15 18:18:15 +02:00
|
|
|
}
|
|
|
|
|
2022-03-29 23:10:45 +02:00
|
|
|
if (cb_config.need_ish)
|
|
|
|
ctx.address_mode = ADDRESS_MODE_2_REL_TAB;
|
|
|
|
else if (amd_romsig->efs_gen.gen == EFS_SECOND_GEN)
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
ctx.address_mode = ADDRESS_MODE_1_REL_BIOS;
|
2021-06-04 13:03:10 +02:00
|
|
|
else
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
ctx.address_mode = ADDRESS_MODE_0_PHY;
|
2021-06-04 13:03:10 +02:00
|
|
|
printf(" AMDFWTOOL Using firmware directory location of %s address: 0x%08x\n",
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
ctx.address_mode == ADDRESS_MODE_0_PHY ? "absolute" : "relative",
|
|
|
|
RUN_CURRENT(ctx));
|
2021-06-04 13:03:10 +02:00
|
|
|
|
2019-03-05 00:53:15 +01:00
|
|
|
integrate_firmwares(&ctx, amd_romsig, amd_fw_table);
|
|
|
|
|
2020-02-17 16:52:40 +01:00
|
|
|
ctx.current = ALIGN(ctx.current, 0x10000U); /* TODO: is it necessary? */
|
amdfwtool: Upgrade "relative address" to four address modes
Address Mode 0: Physical Address, bit 63~56: 0x00
Address Mode 1: Relative Address to entire BIOS image, bit 63~56: 0x40
Address Mode 2: Relative Address to PSP/BIOS directory, bit 63~56: 0x80
Address Mode 3: Relative Address to slot N, bit 63~56: 0xC0
It is the expanding mode for simple relative address mode, for which
address_mode equals 1.
Only mode 2 is added. We need to record current table base address and
calculate the offset. The ctx.current_table is zero outside the
table. When it goes into the function to integrate the table, it
should backup the old value and get current table base. Before it goes
out the function, it should restore the value.
If the table address mode is 2, the address in each entry should be
also add address mode information. If not, the address mode in entry
is meanless.
The old mode 0,1 should be back compatible.
Change-Id: I29a03f4381cd0507e2b2e3b359111e3375a73de1
Signed-off-by: Zheng Bao <fishbaozi@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59308
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
2021-11-15 12:53:21 +01:00
|
|
|
ctx.current_table = 0;
|
2019-03-05 00:53:15 +01:00
|
|
|
|
2021-08-20 08:47:46 +02:00
|
|
|
if (cb_config.multi_level) {
|
2019-04-01 18:48:43 +02:00
|
|
|
/* Do 2nd PSP directory followed by 1st */
|
2021-09-17 07:24:54 +02:00
|
|
|
pspdir2 = new_psp_dir(&ctx, cb_config.multi_level);
|
|
|
|
integrate_psp_firmwares(&ctx, pspdir2, NULL, NULL,
|
2021-09-17 07:30:08 +02:00
|
|
|
amd_psp_fw_table, PSPL2_COOKIE, soc_id, &cb_config);
|
2021-09-17 07:24:54 +02:00
|
|
|
if (cb_config.recovery_ab) {
|
|
|
|
/* B is same as above directories for A */
|
|
|
|
/* Skip creating pspdir2_b here to save flash space. Related
|
|
|
|
* biosdir2_b will be skipped automatically. */
|
|
|
|
pspdir2_b = new_psp_dir(&ctx, cb_config.multi_level);
|
|
|
|
integrate_psp_firmwares(&ctx, pspdir2_b, NULL, NULL,
|
2021-09-17 07:30:08 +02:00
|
|
|
amd_psp_fw_table, PSPL2_COOKIE, soc_id, &cb_config);
|
2021-09-17 07:24:54 +02:00
|
|
|
} else {
|
|
|
|
pspdir2_b = NULL; /* More explicitly */
|
|
|
|
}
|
2021-08-20 08:47:46 +02:00
|
|
|
pspdir = new_psp_dir(&ctx, cb_config.multi_level);
|
2021-09-17 07:24:54 +02:00
|
|
|
integrate_psp_firmwares(&ctx, pspdir, pspdir2, pspdir2_b,
|
2021-09-17 07:30:08 +02:00
|
|
|
amd_psp_fw_table, PSP_COOKIE, soc_id, &cb_config);
|
2019-04-01 18:48:43 +02:00
|
|
|
} else {
|
|
|
|
/* flat: PSP 1 cookie and no pointer to 2nd table */
|
2021-08-20 08:47:46 +02:00
|
|
|
pspdir = new_psp_dir(&ctx, cb_config.multi_level);
|
2021-09-17 07:24:54 +02:00
|
|
|
integrate_psp_firmwares(&ctx, pspdir, NULL, NULL,
|
2021-09-17 07:30:08 +02:00
|
|
|
amd_psp_fw_table, PSP_COOKIE, soc_id, &cb_config);
|
2019-04-01 18:48:43 +02:00
|
|
|
}
|
2015-11-17 15:57:39 +01:00
|
|
|
|
2019-03-05 00:50:37 +01:00
|
|
|
if (comboable)
|
2021-10-23 14:20:21 +02:00
|
|
|
amd_romsig->new_psp_directory = BUFF_TO_RUN(ctx, pspdir);
|
2019-02-28 19:43:40 +01:00
|
|
|
else
|
2021-10-18 14:00:35 +02:00
|
|
|
amd_romsig->psp_directory = BUFF_TO_RUN(ctx, pspdir);
|
2015-11-17 15:57:39 +01:00
|
|
|
|
2016-03-02 07:47:27 +01:00
|
|
|
#if PSP_COMBO
|
2019-03-05 00:53:15 +01:00
|
|
|
psp_combo_directory *combo_dir = new_combo_dir(&ctx);
|
2021-10-18 14:00:35 +02:00
|
|
|
amd_romsig->combo_psp_directory = BUFF_TO_RUN(ctx, combo_dir);
|
2019-03-05 00:50:37 +01:00
|
|
|
/* 0 -Compare PSP ID, 1 -Compare chip family ID */
|
|
|
|
combo_dir->entries[0].id_sel = 0;
|
2021-10-14 09:09:09 +02:00
|
|
|
combo_dir->entries[0].id = get_psp_id(soc_id);
|
2019-03-05 00:53:15 +01:00
|
|
|
combo_dir->entries[0].lvl2_addr = BUFF_TO_RUN(ctx, pspdir);
|
2019-03-05 00:50:37 +01:00
|
|
|
|
|
|
|
combo_dir->header.lookup = 1;
|
2021-06-15 08:41:37 +02:00
|
|
|
fill_dir_header(combo_dir, 1, PSP2_COOKIE, &ctx);
|
2016-03-02 07:47:27 +01:00
|
|
|
#endif
|
2015-11-17 15:57:39 +01:00
|
|
|
|
2019-03-19 21:45:31 +01:00
|
|
|
if (have_bios_tables(amd_bios_table)) {
|
2021-09-17 07:24:54 +02:00
|
|
|
bios_directory_table *biosdir = NULL;
|
2021-08-20 08:47:46 +02:00
|
|
|
if (cb_config.multi_level) {
|
2019-03-19 21:45:31 +01:00
|
|
|
/* Do 2nd level BIOS directory followed by 1st */
|
2021-09-17 07:24:54 +02:00
|
|
|
bios_directory_table *biosdir2 = NULL;
|
|
|
|
bios_directory_table *biosdir2_b = NULL;
|
|
|
|
|
|
|
|
biosdir2 = new_bios_dir(&ctx, cb_config.multi_level);
|
|
|
|
|
2021-11-04 10:47:07 +01:00
|
|
|
integrate_bios_firmwares(&ctx, biosdir2, NULL,
|
2021-08-20 08:58:22 +02:00
|
|
|
amd_bios_table, BDT2_COOKIE, &cb_config);
|
2021-09-17 07:24:54 +02:00
|
|
|
if (cb_config.recovery_ab) {
|
|
|
|
if (pspdir2_b != NULL) {
|
|
|
|
biosdir2_b = new_bios_dir(&ctx, cb_config.multi_level);
|
|
|
|
integrate_bios_firmwares(&ctx, biosdir2_b, NULL,
|
|
|
|
amd_bios_table, BDT2_COOKIE, &cb_config);
|
|
|
|
}
|
|
|
|
add_psp_firmware_entry(&ctx, pspdir2, biosdir2,
|
|
|
|
AMD_FW_BIOS_TABLE, TABLE_ALIGNMENT);
|
|
|
|
if (pspdir2_b != NULL)
|
|
|
|
add_psp_firmware_entry(&ctx, pspdir2_b, biosdir2_b,
|
|
|
|
AMD_FW_BIOS_TABLE, TABLE_ALIGNMENT);
|
|
|
|
} else {
|
|
|
|
biosdir = new_bios_dir(&ctx, cb_config.multi_level);
|
|
|
|
integrate_bios_firmwares(&ctx, biosdir, biosdir2,
|
2021-08-20 08:58:22 +02:00
|
|
|
amd_bios_table, BDT1_COOKIE, &cb_config);
|
2021-09-17 07:24:54 +02:00
|
|
|
}
|
2019-03-19 21:45:31 +01:00
|
|
|
} else {
|
|
|
|
/* flat: BDT1 cookie and no pointer to 2nd table */
|
2021-08-20 08:47:46 +02:00
|
|
|
biosdir = new_bios_dir(&ctx, cb_config.multi_level);
|
2021-11-04 10:47:07 +01:00
|
|
|
integrate_bios_firmwares(&ctx, biosdir, NULL,
|
2021-08-20 08:58:22 +02:00
|
|
|
amd_bios_table, BDT1_COOKIE, &cb_config);
|
2019-03-19 21:45:31 +01:00
|
|
|
}
|
2020-12-03 16:00:48 +01:00
|
|
|
switch (soc_id) {
|
|
|
|
case PLATFORM_RENOIR:
|
|
|
|
case PLATFORM_LUCIENNE:
|
|
|
|
case PLATFORM_CEZANNE:
|
2021-09-17 07:24:54 +02:00
|
|
|
if (!cb_config.recovery_ab)
|
|
|
|
amd_romsig->bios3_entry = BUFF_TO_RUN(ctx, biosdir);
|
2020-12-03 16:00:48 +01:00
|
|
|
break;
|
2021-08-12 10:30:19 +02:00
|
|
|
case PLATFORM_MENDOCINO:
|
2022-03-29 02:34:11 +02:00
|
|
|
case PLATFORM_SABRINA:
|
2021-08-12 10:30:19 +02:00
|
|
|
break;
|
2020-12-03 16:00:48 +01:00
|
|
|
case PLATFORM_STONEYRIDGE:
|
|
|
|
case PLATFORM_RAVEN:
|
|
|
|
case PLATFORM_PICASSO:
|
|
|
|
default:
|
|
|
|
amd_romsig->bios1_entry = BUFF_TO_RUN(ctx, biosdir);
|
|
|
|
break;
|
|
|
|
}
|
2019-03-19 21:45:31 +01:00
|
|
|
}
|
|
|
|
|
2020-10-28 04:38:09 +01:00
|
|
|
/* Free the filename. */
|
|
|
|
free_psp_firmware_filenames(amd_psp_fw_table);
|
|
|
|
free_bdt_firmware_filenames(amd_bios_table);
|
|
|
|
|
2015-11-17 15:57:39 +01:00
|
|
|
targetfd = open(output, O_RDWR | O_CREAT | O_TRUNC, 0666);
|
2016-11-08 19:22:12 +01:00
|
|
|
if (targetfd >= 0) {
|
2020-09-29 11:33:17 +02:00
|
|
|
ssize_t bytes;
|
|
|
|
bytes = write(targetfd, amd_romsig, ctx.current - romsig_offset);
|
|
|
|
if (bytes != ctx.current - romsig_offset) {
|
|
|
|
fprintf(stderr, "Error: Writing to file %s failed\n", output);
|
|
|
|
retval = 1;
|
|
|
|
}
|
2016-11-08 19:22:12 +01:00
|
|
|
close(targetfd);
|
|
|
|
} else {
|
2020-10-01 11:05:43 +02:00
|
|
|
fprintf(stderr, "Error: could not open file: %s\n", output);
|
2016-11-08 19:22:12 +01:00
|
|
|
retval = 1;
|
|
|
|
}
|
2015-11-17 15:57:39 +01:00
|
|
|
|
2016-11-08 19:22:12 +01:00
|
|
|
free(rom);
|
|
|
|
return retval;
|
2015-11-17 15:57:39 +01:00
|
|
|
}
|