util/amdfwtool: Handle address mode properly for Turin
Trying to read a firmware binary for Turin platform results in "Invalid address(41400) or mode(0)" error. The utility does not respect the address mode set by the directory header. The address mode of th entries is valid only if the address mode of the directory is equal to 2 or 3. Check the address mode of the directory and use it for entries only when its value is less than 2. TEST=Successfuly parse vendor BIOS for Gigabyte MZ33-AR1. Change-Id: I479bc846bfb334231fdc707274a8ac44b6c384d4 Signed-off-by: Michał Żygowski <michal.zygowski@3mdeb.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/89039 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Benjamin Doron <benjamin.doron00@gmail.com>
This commit is contained in:
parent
97cf4a1919
commit
46b03e682c
2 changed files with 38 additions and 4 deletions
|
|
@ -263,18 +263,27 @@ static int amdfw_bios_dir_walk(FILE *fw, uint32_t bios_offset, uint32_t cookie,
|
|||
size_t num_current_entries = 0;
|
||||
bios_directory_hdr header;
|
||||
uint32_t l2_dir_offset = 0;
|
||||
uint64_t dir_mode = 0;
|
||||
char indent[MAX_INDENTATION_LEN] = {0};
|
||||
|
||||
if (read_bios_directory(fw, bios_offset, cookie, &header,
|
||||
¤t_entries, &num_current_entries) != 0)
|
||||
return 1;
|
||||
|
||||
if (header.additional_info_fields.version == 1)
|
||||
dir_mode = header.additional_info_fields_v1.address_mode;
|
||||
else
|
||||
dir_mode = header.additional_info_fields.address_mode;
|
||||
|
||||
do_indentation_string(indent, level);
|
||||
for (size_t i = 0; i < num_current_entries; i++) {
|
||||
uint32_t type = current_entries[i].type;
|
||||
uint64_t mode = current_entries[i].address_mode;
|
||||
uint64_t addr = current_entries[i].source;
|
||||
|
||||
if (dir_mode < 2)
|
||||
mode = dir_mode;
|
||||
|
||||
if (type == AMD_BIOS_APOB || type == AMD_BIOS_PSP_SHARED_MEM)
|
||||
printf("%sBIOS%s: 0x%02x 0x%lx(DRAM-Address)\n",
|
||||
indent, cookie == BHD_COOKIE ? "L1" : "L2",
|
||||
|
|
@ -313,22 +322,31 @@ static int amdfw_psp_dir_walk(FILE *fw, uint32_t psp_offset, uint32_t cookie, ui
|
|||
uint32_t bios_dir_offset = 0;
|
||||
uint32_t ish_dir_offset = 0;
|
||||
ish_directory_table ish_dir;
|
||||
uint64_t dir_mode = 0;
|
||||
char indent[MAX_INDENTATION_LEN] = {0};
|
||||
|
||||
if (read_psp_directory(fw, psp_offset, cookie, &header,
|
||||
¤t_entries, &num_current_entries) != 0)
|
||||
return 1;
|
||||
|
||||
if (header.additional_info_fields.version == 1)
|
||||
dir_mode = header.additional_info_fields_v1.address_mode;
|
||||
else
|
||||
dir_mode = header.additional_info_fields.address_mode;
|
||||
|
||||
do_indentation_string(indent, level);
|
||||
for (size_t i = 0; i < num_current_entries; i++) {
|
||||
uint32_t type = current_entries[i].type;
|
||||
uint64_t mode = current_entries[i].address_mode;
|
||||
uint64_t addr = current_entries[i].addr;
|
||||
|
||||
if (dir_mode < 2)
|
||||
mode = dir_mode;
|
||||
|
||||
if (type == AMD_PSP_FUSE_CHAIN)
|
||||
printf("%sPSP%s: 0x%02x 0x%lx(Soft-fuse)\n",
|
||||
indent, cookie == PSP_COOKIE ? "L1" : "L2",
|
||||
type, mode << 62 | addr);
|
||||
type, (uint64_t)current_entries[i].address_mode << 62 | addr);
|
||||
else
|
||||
printf("%sPSP%s: 0x%02x 0x%08lx 0x%08x\n",
|
||||
indent, cookie == PSP_COOKIE ? "L1" : "L2",
|
||||
|
|
|
|||
|
|
@ -210,8 +210,16 @@ typedef struct _psp_directory_header {
|
|||
uint32_t spi_block_size:4;
|
||||
uint32_t base_addr:15;
|
||||
uint32_t address_mode:2;
|
||||
uint32_t not_used:1;
|
||||
uint32_t version:1;
|
||||
} __attribute__((packed)) additional_info_fields;
|
||||
struct {
|
||||
uint32_t dir_size:16;
|
||||
uint32_t spi_block_size:4;
|
||||
uint32_t dir_header_size:4;
|
||||
uint32_t address_mode:2;
|
||||
uint32_t reserved:5;
|
||||
uint32_t version:1;
|
||||
} __attribute__((packed)) additional_info_fields_v1;
|
||||
};
|
||||
} __attribute__((packed, aligned(16))) psp_directory_header;
|
||||
|
||||
|
|
@ -272,8 +280,16 @@ typedef struct _bios_directory_hdr {
|
|||
uint32_t spi_block_size:4;
|
||||
uint32_t base_addr:15;
|
||||
uint32_t address_mode:2;
|
||||
uint32_t not_used:1;
|
||||
uint32_t version:1;
|
||||
} __attribute__((packed)) additional_info_fields;
|
||||
struct {
|
||||
uint32_t dir_size:16;
|
||||
uint32_t spi_block_size:4;
|
||||
uint32_t dir_header_size:4;
|
||||
uint32_t address_mode:2;
|
||||
uint32_t reserved:5;
|
||||
uint32_t version:1;
|
||||
} __attribute__((packed)) additional_info_fields_v1;
|
||||
};
|
||||
} __attribute__((packed, aligned(16))) bios_directory_hdr;
|
||||
|
||||
|
|
@ -459,7 +475,7 @@ typedef struct _amd_cb_config {
|
|||
typedef struct _context {
|
||||
char *rom; /* target buffer, size of flash device */
|
||||
uint32_t rom_size; /* size of flash device */
|
||||
uint32_t address_mode; /* 0:abs address; 1:relative to flash; 2: relative to table */
|
||||
uint32_t address_mode; /* 0:abs address; 1:relative to flash; 2: relative to table 3: relative to partition */
|
||||
uint32_t current; /* pointer within flash & proxy buffer */
|
||||
uint32_t current_pointer_saved;
|
||||
uint32_t current_table;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue