coreboot-kgpe-d16/util/amdfwtool/data_parse.c

829 lines
24 KiB
C
Raw Normal View History

/* SPDX-License-Identifier: GPL-2.0-only */
#include <stdio.h>
#include <regex.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#include "amdfwtool.h"
/* TODO: a empty line does not matched. */
static const char blank_or_comment_regex[] =
/* a blank line */
"(^[[:space:]]*$)"
"|" /* or ... */
/* a line consisting of: optional whitespace followed by */
"(^[[:space:]]*"
/* a '#' character and optionally, additional characters */
"#.*$)";
static regex_t blank_or_comment_expr;
static const char entries_line_regex[] =
/* optional whitespace */
"^[[:space:]]*"
/* followed by a chunk of nonwhitespace for macro field */
"([^[:space:]]+)"
/* followed by one or more whitespace characters */
"[[:space:]]+"
/* followed by a chunk of nonwhitespace for filename field */
"([^[:space:]]+)"
/* followed by an optional whitespace + chunk of nonwhitespace for level field
1st char L: Indicator of field "level"
2nd char:
Directory level to be dropped in.
1: Level 1
2: Level 2
b: Level both 1&2
x: use default value hardcoded in table
3rd char:
For A/B recovery. Defined same as 2nd char.
Examples:
L2: Level 2 for normal mode
L12: Level 1 for normal mode, level 2 for A/B mode
Lx1: Use default value for normal mode, level 1 for A/B mode
*/
"([[:space:]]+([Ll][12bxBX]{1,2}))?"
util/amdfwtool: Add ability to split hash table Hash table containing hashes of all signed PSP binaries is compiled at build time and installed into the concerned CBFS. During boot, PSP verstage reads the hash table binary and passes it to PSP bootloader. PSP bootloader in turn uses the hash table to verify the signed PSP binaries. Currently the hashes for all the signed PSP binaries are compiled into one hash table. On upcoming platforms with more number of signed PSP binaries, PSP bootloader does not have resources to handle one monolithic hash table. Instead PSP bootloader recommends splitting them into smaller hash tables (currently limited to 3 hash tables). Update amdfwtool tool to support splitting hash tables. This is done by adding an optional hash table id to the entries in the amdfw.cfg file. By default, one hash table binary is always compiled and it's name is of the format ${signed_rom}.hash. If an entry has a hash table id defined, then this utility will compile a separate hash table binary whose name is of the format ${signed_rom}.${N}.hash where N is the hash table id. BUG=b:277292697 TEST=Build Skyrim BIOS image and boot to OS. Ensure that the hash table is identical with and without this change. Perform suspend/resume cycles, warm/cold reset cycles for 50 iterations each. TEST=Artificially inject hash table id against some entries in amdfw.cfg and ensure that the concerned hash table binaries are getting compiled. Change-Id: I7ef338d67695a34c33b5c166924832939f381191 Signed-off-by: Karthikeyan Ramasubramanian <kramasub@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/75188 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Raul Rangel <rrangel@chromium.org>
2023-05-03 21:34:41 +02:00
/* followed by an optional whitespace + chunk of nonwhitespace for hash table field
1st char H: Indicator of field "Hash Table ID"
2nd char:
Table ID to be dropped in.
0: Table 0 / Default Unified Table
1: Table 1
...
9: Table 9
Examples:
H2: Put the hash for the concerned entry in Hash Table 2
*/
"([[:space:]]+([Hh][0-9]+))?"
/* followed by an optional whitespace + "UUID" to indicate the binary is using 16 bytes
UUID as firmware identity. In the absence of this field, the binary is using 2 bytes
FWID as firmware identity.
*/
"([[:space:]]+(UUID))?"
/* followed by optional whitespace */
"[[:space:]]*$";
static regex_t entries_line_expr;
enum match_id {
FW_TYPE = 1,
FW_FILE,
OPT_SPACE1,
OPT_LEVEL,
util/amdfwtool: Add ability to split hash table Hash table containing hashes of all signed PSP binaries is compiled at build time and installed into the concerned CBFS. During boot, PSP verstage reads the hash table binary and passes it to PSP bootloader. PSP bootloader in turn uses the hash table to verify the signed PSP binaries. Currently the hashes for all the signed PSP binaries are compiled into one hash table. On upcoming platforms with more number of signed PSP binaries, PSP bootloader does not have resources to handle one monolithic hash table. Instead PSP bootloader recommends splitting them into smaller hash tables (currently limited to 3 hash tables). Update amdfwtool tool to support splitting hash tables. This is done by adding an optional hash table id to the entries in the amdfw.cfg file. By default, one hash table binary is always compiled and it's name is of the format ${signed_rom}.hash. If an entry has a hash table id defined, then this utility will compile a separate hash table binary whose name is of the format ${signed_rom}.${N}.hash where N is the hash table id. BUG=b:277292697 TEST=Build Skyrim BIOS image and boot to OS. Ensure that the hash table is identical with and without this change. Perform suspend/resume cycles, warm/cold reset cycles for 50 iterations each. TEST=Artificially inject hash table id against some entries in amdfw.cfg and ensure that the concerned hash table binaries are getting compiled. Change-Id: I7ef338d67695a34c33b5c166924832939f381191 Signed-off-by: Karthikeyan Ramasubramanian <kramasub@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/75188 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Raul Rangel <rrangel@chromium.org>
2023-05-03 21:34:41 +02:00
OPT_SPACE2,
OPT_HASH_TABLE_ID,
OPT_SPACE3,
OPT_FWID_TYPE,
N_MATCHES,
};
void compile_reg_expr(int cflags, const char *expr, regex_t *reg)
{
static const size_t ERROR_BUF_SIZE = 256;
char error_msg[ERROR_BUF_SIZE];
int result;
result = regcomp(reg, expr, cflags);
if (result != 0) {
regerror(result, reg, error_msg, ERROR_BUF_SIZE);
fprintf(stderr, "%s\n", error_msg);
}
}
static enum platform identify_platform(char *soc_name)
{
if (!strcasecmp(soc_name, "Stoneyridge"))
return PLATFORM_STONEYRIDGE;
else if (!strcasecmp(soc_name, "Carrizo"))
return PLATFORM_CARRIZO;
else if (!strcasecmp(soc_name, "Raven"))
return PLATFORM_RAVEN;
else if (!strcasecmp(soc_name, "Picasso"))
return PLATFORM_PICASSO;
else if (!strcasecmp(soc_name, "Cezanne"))
return PLATFORM_CEZANNE;
else if (!strcasecmp(soc_name, "Mendocino"))
return PLATFORM_MENDOCINO;
else if (!strcasecmp(soc_name, "Renoir"))
return PLATFORM_RENOIR;
else if (!strcasecmp(soc_name, "Lucienne"))
return PLATFORM_LUCIENNE;
else if (!strcasecmp(soc_name, "Phoenix"))
return PLATFORM_PHOENIX;
else if (!strcasecmp(soc_name, "Glinda"))
return PLATFORM_GLINDA;
else if (!strcasecmp(soc_name, "Genoa"))
return PLATFORM_GENOA;
else
return PLATFORM_UNKNOWN;
}
#define SET_LEVEL(tableptr, l, TABLE, ab) \
do { \
switch ((l)) { \
case '1': \
(tableptr)->level = ab ? TABLE##_LVL1_AB : TABLE##_LVL1; \
break; \
case '2': \
(tableptr)->level = ab ? TABLE##_LVL2_AB : TABLE##_LVL2; \
break; \
case 'b': \
case 'B': \
(tableptr)->level = ab ? TABLE##_BOTH_AB : TABLE##_BOTH; \
break; \
default: \
/* use default value */ \
break; \
} \
} while (0)
extern amd_fw_entry amd_psp_fw_table[];
extern amd_bios_entry amd_bios_table[];
static uint8_t find_register_fw_filename_psp_dir(char *fw_name, char *filename,
char level_to_set, uint8_t hash_tbl_id, fwid_type_t fwid_type,
amd_cb_config *cb_config)
{
amd_fw_type fw_type = AMD_FW_INVALID;
amd_fw_entry *psp_tableptr;
uint8_t subprog;
uint8_t instance = 0;
if (strcmp(fw_name, "PSPBTLDR_WL_FILE") == 0) {
if (cb_config->have_whitelist) {
fw_type = AMD_FW_PSP_BOOTLOADER_AB;
subprog = 0;
} else {
fw_type = AMD_FW_SKIP;
}
} else if (strcmp(fw_name, "PSPBTLDR_AB_STAGE1_FILE") == 0) {
if (cb_config->recovery_ab) {
fw_type = AMD_FW_PSP_BOOTLOADER;
subprog = 0;
} else {
fw_type = AMD_FW_SKIP;
}
} else if (strcmp(fw_name, "PSPBTLDR_FILE") == 0) {
if (!cb_config->recovery_ab) {
fw_type = AMD_FW_PSP_BOOTLOADER;
subprog = 0;
} else {
fw_type = AMD_FW_SKIP;
}
} else if (strcmp(fw_name, "AMD_PUBKEY_FILE") == 0) {
fw_type = AMD_FW_PSP_PUBKEY;
subprog = 0;
} else if (strcmp(fw_name, "PSPRCVR_FILE") == 0) {
fw_type = AMD_FW_PSP_RECOVERY;
subprog = 0;
} else if (strcmp(fw_name, "PUBSIGNEDKEY_FILE") == 0) {
fw_type = AMD_FW_PSP_RTM_PUBKEY;
subprog = 0;
} else if (strcmp(fw_name, "PSPNVRAM_FILE") == 0) {
fw_type = AMD_FW_PSP_NVRAM;
subprog = 0;
} else if (strcmp(fw_name, "SMUSCS_FILE") == 0) {
fw_type = AMD_FW_PSP_SMUSCS;
subprog = 0;
} else if (strcmp(fw_name, "PSPTRUSTLETS_FILE") == 0) {
fw_type = AMD_FW_PSP_TRUSTLETS;
subprog = 0;
} else if (strcmp(fw_name, "PSPSECUREDEBUG_FILE") == 0) {
fw_type = AMD_FW_PSP_SECURED_DEBUG;
subprog = 0;
} else if (strcmp(fw_name, "PSP_SMUFW1_SUB0_FILE") == 0) {
fw_type = AMD_FW_PSP_SMU_FIRMWARE;
subprog = 0;
} else if (strcmp(fw_name, "PSP_HW_IPCFG_FILE_SUB0") == 0) {
fw_type = AMD_HW_IPCFG;
subprog = 0;
} else if (strcmp(fw_name, "PSP_HW_IPCFG_FILE_SUB1") == 0) {
fw_type = AMD_HW_IPCFG;
subprog = 1;
} else if (strcmp(fw_name, "PSP_SMUFW1_SUB1_FILE") == 0) {
fw_type = AMD_FW_PSP_SMU_FIRMWARE;
subprog = 1;
} else if (strcmp(fw_name, "PSP_SMUFW1_SUB2_FILE") == 0) {
fw_type = AMD_FW_PSP_SMU_FIRMWARE;
subprog = 2;
} else if (strcmp(fw_name, "PSP_SMUFW2_SUB0_FILE") == 0) {
fw_type = AMD_FW_PSP_SMU_FIRMWARE2;
subprog = 0;
} else if (strcmp(fw_name, "PSP_SMUFW2_SUB1_FILE") == 0) {
fw_type = AMD_FW_PSP_SMU_FIRMWARE2;
subprog = 1;
} else if (strcmp(fw_name, "PSP_SMUFW2_SUB2_FILE") == 0) {
fw_type = AMD_FW_PSP_SMU_FIRMWARE2;
subprog = 2;
} else if (strcmp(fw_name, "PSP_BOOT_DRIVER_FILE") == 0) {
fw_type = AMD_BOOT_DRIVER;
subprog = 0;
} else if (strcmp(fw_name, "PSP_SOC_DRIVER_FILE") == 0) {
fw_type = AMD_SOC_DRIVER;
subprog = 0;
} else if (strcmp(fw_name, "PSP_DEBUG_DRIVER_FILE") == 0) {
fw_type = AMD_DEBUG_DRIVER;
subprog = 0;
} else if (strcmp(fw_name, "PSP_INTERFACE_DRIVER_FILE") == 0) {
fw_type = AMD_INTERFACE_DRIVER;
subprog = 0;
} else if (strcmp(fw_name, "PSP_SEC_DBG_KEY_FILE") == 0) {
if (cb_config->unlock_secure) {
fw_type = AMD_FW_PSP_SECURED_DEBUG;
subprog = 0;
} else {
fw_type = AMD_FW_SKIP;
}
} else if (strcmp(fw_name, "PSP_SEC_DEBUG_FILE") == 0) {
if (cb_config->unlock_secure) {
fw_type = AMD_DEBUG_UNLOCK;
subprog = 0;
} else {
fw_type = AMD_FW_SKIP;
}
} else if (strcmp(fw_name, "PSP_ABL0_FILE") == 0) {
fw_type = AMD_ABL0;
subprog = 0;
} else if (strcmp(fw_name, "PSP_ABL1_FILE") == 0) {
fw_type = AMD_ABL1;
subprog = 0;
} else if (strcmp(fw_name, "PSP_ABL2_FILE") == 0) {
fw_type = AMD_ABL2;
subprog = 0;
} else if (strcmp(fw_name, "PSP_ABL3_FILE") == 0) {
fw_type = AMD_ABL3;
subprog = 0;
} else if (strcmp(fw_name, "PSP_ABL4_FILE") == 0) {
fw_type = AMD_ABL4;
subprog = 0;
} else if (strcmp(fw_name, "PSP_ABL5_FILE") == 0) {
fw_type = AMD_ABL5;
subprog = 0;
} else if (strcmp(fw_name, "PSP_ABL6_FILE") == 0) {
fw_type = AMD_ABL6;
subprog = 0;
} else if (strcmp(fw_name, "PSP_ABL7_FILE") == 0) {
fw_type = AMD_ABL7;
subprog = 0;
} else if (strcmp(fw_name, "PSPSECUREOS_FILE") == 0) {
if (cb_config->use_secureos) {
fw_type = AMD_FW_PSP_SECURED_OS;
subprog = 0;
} else {
fw_type = AMD_FW_SKIP;
}
} else if (strcmp(fw_name, "PSPTRUSTLETS_FILE") == 0) {
if (cb_config->use_secureos) {
fw_type = AMD_FW_PSP_TRUSTLETS;
subprog = 0;
} else {
fw_type = AMD_FW_SKIP;
}
} else if (strcmp(fw_name, "TRUSTLETKEY_FILE") == 0) {
if (cb_config->use_secureos) {
fw_type = AMD_FW_PSP_TRUSTLETKEY;
subprog = 0;
} else {
fw_type = AMD_FW_SKIP;
}
} else if (strcmp(fw_name, "PSP_IKEK_FILE") == 0) {
fw_type = AMD_WRAPPED_IKEK;
subprog = 0;
} else if (strcmp(fw_name, "PSP_SECG0_FILE") == 0) {
fw_type = AMD_SEC_GASKET;
subprog = 0;
} else if (strcmp(fw_name, "PSP_SECG1_FILE") == 0) {
fw_type = AMD_SEC_GASKET;
subprog = 1;
} else if (strcmp(fw_name, "PSP_SECG2_FILE") == 0) {
fw_type = AMD_SEC_GASKET;
subprog = 2;
} else if (strcmp(fw_name, "PSP_MP2FW0_FILE") == 0) {
if (cb_config->load_mp2_fw) {
fw_type = AMD_MP2_FW;
subprog = 0;
} else {
fw_type = AMD_FW_SKIP;
}
} else if (strcmp(fw_name, "PSP_MP2FW1_FILE") == 0) {
if (cb_config->load_mp2_fw) {
fw_type = AMD_MP2_FW;
subprog = 1;
} else {
fw_type = AMD_FW_SKIP;
}
} else if (strcmp(fw_name, "PSP_MP2FW2_FILE") == 0) {
if (cb_config->load_mp2_fw) {
fw_type = AMD_MP2_FW;
subprog = 2;
} else {
fw_type = AMD_FW_SKIP;
}
} else if (strcmp(fw_name, "PSP_C20MP_FILE") == 0) {
fw_type = AMD_FW_C20_MP;
subprog = 0;
} else if (strcmp(fw_name, "AMF_SRAM_FILE") == 0) {
fw_type = AMD_FW_AMF_SRAM;
subprog = 0;
} else if (strcmp(fw_name, "AMF_DRAM_FILE_INS0") == 0) {
fw_type = AMD_FW_AMF_DRAM;
subprog = 0;
instance = 0;
} else if (strcmp(fw_name, "AMF_DRAM_FILE_INS1") == 0) {
fw_type = AMD_FW_AMF_DRAM;
subprog = 0;
instance = 1;
} else if (strcmp(fw_name, "AMF_WLAN_FILE_INS0") == 0) {
fw_type = AMD_FW_AMF_WLAN;
subprog = 0;
instance = 0;
} else if (strcmp(fw_name, "AMF_WLAN_FILE_INS1") == 0) {
fw_type = AMD_FW_AMF_WLAN;
subprog = 0;
instance = 1;
} else if (strcmp(fw_name, "AMF_MFD_FILE") == 0) {
fw_type = AMD_FW_AMF_MFD;
subprog = 0;
} else if (strcmp(fw_name, "MPCCX_FILE") == 0) {
fw_type = AMD_FW_MPCCX;
subprog = 0;
} else if (strcmp(fw_name, "LSDMA_FILE") == 0) {
fw_type = AMD_FW_LSDMA;
subprog = 0;
} else if (strcmp(fw_name, "MINIMSMU_FILE") == 0) {
fw_type = AMD_FW_MINIMSMU;
instance = 0;
subprog = 0;
} else if (strcmp(fw_name, "MINIMSMU_FILE_INS1") == 0) {
fw_type = AMD_FW_MINIMSMU;
instance = 1;
subprog = 0;
} else if (strcmp(fw_name, "SRAM_FW_EXT_FILE") == 0) {
fw_type = AMD_FW_SRAM_FW_EXT;
subprog = 0;
} else if (strcmp(fw_name, "PSP_DRIVERS_FILE") == 0) {
fw_type = AMD_DRIVER_ENTRIES;
subprog = 0;
} else if (strcmp(fw_name, "PSP_S0I3_FILE") == 0) {
if (cb_config->s0i3) {
fw_type = AMD_S0I3_DRIVER;
subprog = 0;
} else {
fw_type = AMD_FW_SKIP;
}
} else if (strcmp(fw_name, "AMD_DRIVER_ENTRIES") == 0) {
fw_type = AMD_DRIVER_ENTRIES;
subprog = 0;
} else if (strcmp(fw_name, "VBIOS_BTLOADER_FILE") == 0) {
fw_type = AMD_VBIOS_BTLOADER;
subprog = 0;
} else if (strcmp(fw_name, "SECURE_POLICY_L1_FILE") == 0) {
fw_type = AMD_FW_TOS_SEC_POLICY;
subprog = 0;
} else if (strcmp(fw_name, "UNIFIEDUSB_FILE") == 0) {
fw_type = AMD_FW_USB_PHY;
subprog = 0;
} else if (strcmp(fw_name, "DRTMTA_FILE") == 0) {
fw_type = AMD_FW_DRTM_TA;
subprog = 0;
} else if (strcmp(fw_name, "KEYDBBL_FILE") == 0) {
fw_type = AMD_FW_KEYDB_BL;
subprog = 0;
} else if (strcmp(fw_name, "KEYDB_TOS_FILE") == 0) {
fw_type = AMD_FW_KEYDB_TOS;
subprog = 0;
} else if (strcmp(fw_name, "SPL_TABLE_FILE") == 0) {
if (cb_config->have_mb_spl) {
fw_type = AMD_FW_SKIP;
} else {
fw_type = AMD_FW_SPL;
subprog = 0;
}
} else if (strcmp(fw_name, "DMCUERAMDCN21_FILE") == 0) {
fw_type = AMD_FW_DMCU_ERAM;
subprog = 0;
} else if (strcmp(fw_name, "DMCUINTVECTORSDCN21_FILE") == 0) {
fw_type = AMD_FW_DMCU_ISR;
subprog = 0;
} else if (strcmp(fw_name, "MSMU_FILE") == 0) {
fw_type = AMD_FW_MSMU;
subprog = 0;
} else if (strcmp(fw_name, "DMCUB_FILE") == 0) {
fw_type = AMD_FW_DMCUB;
subprog = 0;
} else if (strcmp(fw_name, "SPIROM_CONFIG_FILE") == 0) {
fw_type = AMD_FW_SPIROM_CFG;
subprog = 0;
} else if (strcmp(fw_name, "MPIO_FILE") == 0) {
fw_type = AMD_FW_MPIO;
subprog = 0;
} else if (strcmp(fw_name, "TPMLITE_FILE") == 0) {
fw_type = AMD_FW_TPMLITE;
subprog = 0;
} else if (strcmp(fw_name, "PSP_KVM_ENGINE_DUMMY_FILE") == 0) {
fw_type = AMD_FW_KVM_IMAGE;
subprog = 0;
} else if (strcmp(fw_name, "RPMC_FILE") == 0) {
fw_type = AMD_RPMC_NVRAM;
subprog = 0;
} else if (strcmp(fw_name, "PSPBTLDR_AB_FILE") == 0) {
if (!cb_config->have_whitelist || cb_config->recovery_ab) {
fw_type = AMD_FW_PSP_BOOTLOADER_AB;
subprog = 0;
} else {
fw_type = AMD_FW_SKIP;
}
} else if (strcmp(fw_name, "TA_IKEK_FILE") == 0) {
fw_type = AMD_TA_IKEK;
subprog = 0;
} else if (strcmp(fw_name, "UMSMU_FILE") == 0) {
fw_type = AMD_FW_UMSMU;
subprog = 0;
} else if (strcmp(fw_name, "PSP_OEM_ABL_KEY_FILE") == 0) {
fw_type = AMD_FW_ABL_PUBKEY;
subprog = 0;
} else if (strcmp(fw_name, "PSP_MP5FW_SUB0_FILE") == 0) {
fw_type = AMD_FW_MP5;
subprog = 0;
} else if (strcmp(fw_name, "PSP_MP5FW_SUB1_FILE") == 0) {
fw_type = AMD_FW_MP5;
subprog = 1;
} else if (strcmp(fw_name, "PSP_MP5FW_SUB2_FILE") == 0) {
fw_type = AMD_FW_MP5;
subprog = 2;
} else if (strcmp(fw_name, "PSP_DXIOFW_FILE") == 0) {
fw_type = AMD_FW_DXIO;
subprog = 0;
} else if (strcmp(fw_name, "PSP_MPIOFW_FILE") == 0) {
fw_type = AMD_FW_MPIO;
subprog = 0;
} else if (strcmp(fw_name, "PSP_RIB_FILE_SUB0") == 0) {
fw_type = AMD_RIB;
subprog = 0;
} else if (strcmp(fw_name, "PSP_RIB_FILE_SUB1") == 0) {
fw_type = AMD_RIB;
subprog = 1;
} else if (strcmp(fw_name, "FEATURE_TABLE_FILE") == 0) {
fw_type = AMD_FW_FCFG_TABLE;
subprog = 0;
} else if (strcmp(fw_name, "PSP_MPDMATFFW_FILE") == 0) {
fw_type = AMD_FW_MPDMA_TF;
subprog = 0;
} else if (strcmp(fw_name, "PSP_GMI3PHYFW_FILE") == 0) {
fw_type = AMD_FW_GMI3_PHY;
subprog = 0;
} else if (strcmp(fw_name, "PSP_MPDMAPMFW_FILE") == 0) {
fw_type = AMD_FW_MPDMA_PM;
subprog = 0;
} else if (strcmp(fw_name, "PSP_TOKEN_UNLOCK_FILE") == 0) {
fw_type = AMD_TOKEN_UNLOCK;
subprog = 0;
} else if (strcmp(fw_name, "SEV_DATA_FILE") == 0) {
fw_type = AMD_SEV_DATA;
subprog = 0;
} else if (strcmp(fw_name, "SEV_CODE_FILE") == 0) {
fw_type = AMD_SEV_CODE;
subprog = 0;
} else {
fw_type = AMD_FW_INVALID;
/* TODO: Add more */
}
/* Search and fill the filename */
psp_tableptr = &amd_psp_fw_table[0];
if (fw_type != AMD_FW_SKIP && fw_type != AMD_FW_INVALID) {
while (psp_tableptr->type != AMD_FW_INVALID) {
/* instance are not used in PSP table */
if (psp_tableptr->type == fw_type && psp_tableptr->subprog == subprog
&& psp_tableptr->inst == instance) {
psp_tableptr->filename = filename;
SET_LEVEL(psp_tableptr, level_to_set, PSP,
cb_config->recovery_ab);
util/amdfwtool: Add ability to split hash table Hash table containing hashes of all signed PSP binaries is compiled at build time and installed into the concerned CBFS. During boot, PSP verstage reads the hash table binary and passes it to PSP bootloader. PSP bootloader in turn uses the hash table to verify the signed PSP binaries. Currently the hashes for all the signed PSP binaries are compiled into one hash table. On upcoming platforms with more number of signed PSP binaries, PSP bootloader does not have resources to handle one monolithic hash table. Instead PSP bootloader recommends splitting them into smaller hash tables (currently limited to 3 hash tables). Update amdfwtool tool to support splitting hash tables. This is done by adding an optional hash table id to the entries in the amdfw.cfg file. By default, one hash table binary is always compiled and it's name is of the format ${signed_rom}.hash. If an entry has a hash table id defined, then this utility will compile a separate hash table binary whose name is of the format ${signed_rom}.${N}.hash where N is the hash table id. BUG=b:277292697 TEST=Build Skyrim BIOS image and boot to OS. Ensure that the hash table is identical with and without this change. Perform suspend/resume cycles, warm/cold reset cycles for 50 iterations each. TEST=Artificially inject hash table id against some entries in amdfw.cfg and ensure that the concerned hash table binaries are getting compiled. Change-Id: I7ef338d67695a34c33b5c166924832939f381191 Signed-off-by: Karthikeyan Ramasubramanian <kramasub@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/75188 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Raul Rangel <rrangel@chromium.org>
2023-05-03 21:34:41 +02:00
psp_tableptr->hash_tbl_id = hash_tbl_id;
psp_tableptr->fwid_type = fwid_type;
break;
}
psp_tableptr++;
}
}
if (fw_type == AMD_FW_INVALID)
return 0;
else
return 1;
}
#define PMUI_STR_BASE "PSP_PMUI_FILE"
#define PMUD_STR_BASE "PSP_PMUD_FILE"
#define PMU_STR_BASE_LEN strlen(PMUI_STR_BASE)
#define PMU_STR_SUB_INDEX strlen(PMUI_STR_BASE"_SUB")
#define PMU_STR_INS_INDEX strlen(PMUI_STR_BASE"_SUBx_INS")
#define PMU_STR_ALL_LEN strlen(PMUI_STR_BASE"_SUBx_INSx")
static uint8_t find_register_fw_filename_bios_dir(char *fw_name, char *filename,
char level_to_set, amd_cb_config *cb_config)
{
amd_bios_type fw_type = AMD_BIOS_INVALID;
amd_bios_entry *bhd_tableptr;
uint8_t subprog = 0;
uint8_t instance = 0;
(void) (cb_config); /* Remove warning and reserved for future. */
if (strncmp(fw_name, PMUI_STR_BASE, PMU_STR_BASE_LEN) == 0) {
assert(strlen(fw_name) == PMU_STR_ALL_LEN);
fw_type = AMD_BIOS_PMUI;
subprog = strtol(&fw_name[PMU_STR_SUB_INDEX], NULL, 16);
instance = strtol(&fw_name[PMU_STR_INS_INDEX], NULL, 16);
} else if (strncmp(fw_name, PMUD_STR_BASE, PMU_STR_BASE_LEN) == 0) {
assert(strlen(fw_name) == PMU_STR_ALL_LEN);
fw_type = AMD_BIOS_PMUD;
subprog = strtol(&fw_name[PMU_STR_SUB_INDEX], NULL, 16);
instance = strtol(&fw_name[PMU_STR_INS_INDEX], NULL, 16);
} else if (strcmp(fw_name, "RTM_PUBKEY_FILE") == 0) {
fw_type = AMD_BIOS_RTM_PUBKEY;
subprog = 0;
instance = 0;
} else if (strcmp(fw_name, "PSP_MP2CFG_FILE") == 0) {
if (cb_config->load_mp2_fw) {
fw_type = AMD_BIOS_MP2_CFG;
subprog = 0;
} else {
fw_type = AMD_BIOS_SKIP;
}
} else {
fw_type = AMD_BIOS_INVALID;
}
bhd_tableptr = amd_bios_table;
if (fw_type != AMD_BIOS_INVALID && fw_type != AMD_BIOS_SKIP) {
while (bhd_tableptr->type != AMD_BIOS_INVALID) {
if (bhd_tableptr->type == fw_type &&
bhd_tableptr->subpr == subprog &&
bhd_tableptr->inst == instance) {
bhd_tableptr->filename = filename;
SET_LEVEL(bhd_tableptr, level_to_set, BDT,
cb_config->recovery_ab);
break;
}
bhd_tableptr++;
}
}
if (fw_type == AMD_BIOS_INVALID)
return 0;
else
return 1;
}
#define MAX_LINE_SIZE 1024
int get_input_file_line(FILE *f, char line[], int line_buf_size)
{
if (fgets(line, line_buf_size, f) == NULL)
return LINE_EOF;
/* If the file contains a line that is too long, then it's best
* to let the user know right away rather than passing back a
* truncated result that will lead to problems later on.
*/
line[strlen(line) - 1] = '\0';
if (strlen(line) == ((size_t) (line_buf_size - 1))) {
fprintf(stderr, "The line size in config file should be lower than %d bytes.\n",
MAX_LINE_SIZE);
exit(1);
}
return OK;
}
static int is_valid_entry(char *oneline, regmatch_t match[N_MATCHES])
{
int retval, index;
for (index = 0; index < N_MATCHES; index++) {
match[index].rm_so = -1;
match[index].rm_eo = -1;
}
if (regexec(&entries_line_expr, oneline, N_MATCHES, match, 0) == 0) {
/* match[1]: FW type
match[2]: FW filename
match[4]: Optional directory level to be dropped
util/amdfwtool: Add ability to split hash table Hash table containing hashes of all signed PSP binaries is compiled at build time and installed into the concerned CBFS. During boot, PSP verstage reads the hash table binary and passes it to PSP bootloader. PSP bootloader in turn uses the hash table to verify the signed PSP binaries. Currently the hashes for all the signed PSP binaries are compiled into one hash table. On upcoming platforms with more number of signed PSP binaries, PSP bootloader does not have resources to handle one monolithic hash table. Instead PSP bootloader recommends splitting them into smaller hash tables (currently limited to 3 hash tables). Update amdfwtool tool to support splitting hash tables. This is done by adding an optional hash table id to the entries in the amdfw.cfg file. By default, one hash table binary is always compiled and it's name is of the format ${signed_rom}.hash. If an entry has a hash table id defined, then this utility will compile a separate hash table binary whose name is of the format ${signed_rom}.${N}.hash where N is the hash table id. BUG=b:277292697 TEST=Build Skyrim BIOS image and boot to OS. Ensure that the hash table is identical with and without this change. Perform suspend/resume cycles, warm/cold reset cycles for 50 iterations each. TEST=Artificially inject hash table id against some entries in amdfw.cfg and ensure that the concerned hash table binaries are getting compiled. Change-Id: I7ef338d67695a34c33b5c166924832939f381191 Signed-off-by: Karthikeyan Ramasubramanian <kramasub@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/75188 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Raul Rangel <rrangel@chromium.org>
2023-05-03 21:34:41 +02:00
match[6]: Optional hash table ID to put the hash for the entry
*/
oneline[match[FW_TYPE].rm_eo] = '\0';
oneline[match[FW_FILE].rm_eo] = '\0';
oneline[match[OPT_LEVEL].rm_eo] = '\0';
util/amdfwtool: Add ability to split hash table Hash table containing hashes of all signed PSP binaries is compiled at build time and installed into the concerned CBFS. During boot, PSP verstage reads the hash table binary and passes it to PSP bootloader. PSP bootloader in turn uses the hash table to verify the signed PSP binaries. Currently the hashes for all the signed PSP binaries are compiled into one hash table. On upcoming platforms with more number of signed PSP binaries, PSP bootloader does not have resources to handle one monolithic hash table. Instead PSP bootloader recommends splitting them into smaller hash tables (currently limited to 3 hash tables). Update amdfwtool tool to support splitting hash tables. This is done by adding an optional hash table id to the entries in the amdfw.cfg file. By default, one hash table binary is always compiled and it's name is of the format ${signed_rom}.hash. If an entry has a hash table id defined, then this utility will compile a separate hash table binary whose name is of the format ${signed_rom}.${N}.hash where N is the hash table id. BUG=b:277292697 TEST=Build Skyrim BIOS image and boot to OS. Ensure that the hash table is identical with and without this change. Perform suspend/resume cycles, warm/cold reset cycles for 50 iterations each. TEST=Artificially inject hash table id against some entries in amdfw.cfg and ensure that the concerned hash table binaries are getting compiled. Change-Id: I7ef338d67695a34c33b5c166924832939f381191 Signed-off-by: Karthikeyan Ramasubramanian <kramasub@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/75188 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Raul Rangel <rrangel@chromium.org>
2023-05-03 21:34:41 +02:00
oneline[match[OPT_HASH_TABLE_ID].rm_eo] = '\0';
oneline[match[OPT_FWID_TYPE].rm_eo] = '\0';
retval = 1;
} else {
retval = 0;
}
return retval;
}
static int skip_comment_blank_line(char *oneline)
{
int retval;
if (regexec(&blank_or_comment_expr, oneline, 0, NULL, 0) == 0) {
/* skip comment and blank */
retval = 1;
} else {
/* no match */
retval = 0;
}
return retval;
}
util/amdfwtool: Add ability to split hash table Hash table containing hashes of all signed PSP binaries is compiled at build time and installed into the concerned CBFS. During boot, PSP verstage reads the hash table binary and passes it to PSP bootloader. PSP bootloader in turn uses the hash table to verify the signed PSP binaries. Currently the hashes for all the signed PSP binaries are compiled into one hash table. On upcoming platforms with more number of signed PSP binaries, PSP bootloader does not have resources to handle one monolithic hash table. Instead PSP bootloader recommends splitting them into smaller hash tables (currently limited to 3 hash tables). Update amdfwtool tool to support splitting hash tables. This is done by adding an optional hash table id to the entries in the amdfw.cfg file. By default, one hash table binary is always compiled and it's name is of the format ${signed_rom}.hash. If an entry has a hash table id defined, then this utility will compile a separate hash table binary whose name is of the format ${signed_rom}.${N}.hash where N is the hash table id. BUG=b:277292697 TEST=Build Skyrim BIOS image and boot to OS. Ensure that the hash table is identical with and without this change. Perform suspend/resume cycles, warm/cold reset cycles for 50 iterations each. TEST=Artificially inject hash table id against some entries in amdfw.cfg and ensure that the concerned hash table binaries are getting compiled. Change-Id: I7ef338d67695a34c33b5c166924832939f381191 Signed-off-by: Karthikeyan Ramasubramanian <kramasub@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/75188 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Raul Rangel <rrangel@chromium.org>
2023-05-03 21:34:41 +02:00
static char get_level_from_config(char *line, regoff_t level_index, amd_cb_config *cb_config)
{
char lvl = 'x';
util/amdfwtool: Add ability to split hash table Hash table containing hashes of all signed PSP binaries is compiled at build time and installed into the concerned CBFS. During boot, PSP verstage reads the hash table binary and passes it to PSP bootloader. PSP bootloader in turn uses the hash table to verify the signed PSP binaries. Currently the hashes for all the signed PSP binaries are compiled into one hash table. On upcoming platforms with more number of signed PSP binaries, PSP bootloader does not have resources to handle one monolithic hash table. Instead PSP bootloader recommends splitting them into smaller hash tables (currently limited to 3 hash tables). Update amdfwtool tool to support splitting hash tables. This is done by adding an optional hash table id to the entries in the amdfw.cfg file. By default, one hash table binary is always compiled and it's name is of the format ${signed_rom}.hash. If an entry has a hash table id defined, then this utility will compile a separate hash table binary whose name is of the format ${signed_rom}.${N}.hash where N is the hash table id. BUG=b:277292697 TEST=Build Skyrim BIOS image and boot to OS. Ensure that the hash table is identical with and without this change. Perform suspend/resume cycles, warm/cold reset cycles for 50 iterations each. TEST=Artificially inject hash table id against some entries in amdfw.cfg and ensure that the concerned hash table binaries are getting compiled. Change-Id: I7ef338d67695a34c33b5c166924832939f381191 Signed-off-by: Karthikeyan Ramasubramanian <kramasub@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/75188 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Raul Rangel <rrangel@chromium.org>
2023-05-03 21:34:41 +02:00
/* If the optional level field is present, extract the level char. */
if (level_index != -1) {
if (cb_config->recovery_ab == 0)
lvl = line[level_index + 1];
else if (strlen(&line[level_index]) >= 3)
lvl = line[level_index + 2];
}
assert(lvl == 'x' || lvl == 'X' ||
lvl == 'b' || lvl == 'B' ||
lvl == '1' || lvl == '2');
return lvl;
}
util/amdfwtool: Add ability to split hash table Hash table containing hashes of all signed PSP binaries is compiled at build time and installed into the concerned CBFS. During boot, PSP verstage reads the hash table binary and passes it to PSP bootloader. PSP bootloader in turn uses the hash table to verify the signed PSP binaries. Currently the hashes for all the signed PSP binaries are compiled into one hash table. On upcoming platforms with more number of signed PSP binaries, PSP bootloader does not have resources to handle one monolithic hash table. Instead PSP bootloader recommends splitting them into smaller hash tables (currently limited to 3 hash tables). Update amdfwtool tool to support splitting hash tables. This is done by adding an optional hash table id to the entries in the amdfw.cfg file. By default, one hash table binary is always compiled and it's name is of the format ${signed_rom}.hash. If an entry has a hash table id defined, then this utility will compile a separate hash table binary whose name is of the format ${signed_rom}.${N}.hash where N is the hash table id. BUG=b:277292697 TEST=Build Skyrim BIOS image and boot to OS. Ensure that the hash table is identical with and without this change. Perform suspend/resume cycles, warm/cold reset cycles for 50 iterations each. TEST=Artificially inject hash table id against some entries in amdfw.cfg and ensure that the concerned hash table binaries are getting compiled. Change-Id: I7ef338d67695a34c33b5c166924832939f381191 Signed-off-by: Karthikeyan Ramasubramanian <kramasub@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/75188 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Raul Rangel <rrangel@chromium.org>
2023-05-03 21:34:41 +02:00
static uint8_t get_hash_tbl_id(char *line, regoff_t hash_tbl_index)
{
uint8_t tbl = 0;
/* If the optional hash table field is present, extract the table id char. */
if (hash_tbl_index != -1)
tbl = (uint8_t)atoi(&line[hash_tbl_index + 1]);
assert(tbl < MAX_NUM_HASH_TABLES);
return tbl;
}
static fwid_type_t get_fwid_type(char *line, regoff_t fwid_type_index)
{
if (fwid_type_index != -1 && !strncmp(&line[fwid_type_index], "UUID", strlen("UUID")))
return FWID_TYPE_UUID;
return FWID_TYPE_FWID;
}
static uint8_t process_one_line(char *oneline, regmatch_t *match, char *dir,
amd_cb_config *cb_config)
{
char *path_filename, *fn = &(oneline[match[FW_FILE].rm_so]);
char *fw_type_str = &(oneline[match[FW_TYPE].rm_so]);
regoff_t ch_lvl_index = match[OPT_LEVEL].rm_so == match[OPT_LEVEL].rm_eo ?
-1 : match[OPT_LEVEL].rm_so;
util/amdfwtool: Add ability to split hash table Hash table containing hashes of all signed PSP binaries is compiled at build time and installed into the concerned CBFS. During boot, PSP verstage reads the hash table binary and passes it to PSP bootloader. PSP bootloader in turn uses the hash table to verify the signed PSP binaries. Currently the hashes for all the signed PSP binaries are compiled into one hash table. On upcoming platforms with more number of signed PSP binaries, PSP bootloader does not have resources to handle one monolithic hash table. Instead PSP bootloader recommends splitting them into smaller hash tables (currently limited to 3 hash tables). Update amdfwtool tool to support splitting hash tables. This is done by adding an optional hash table id to the entries in the amdfw.cfg file. By default, one hash table binary is always compiled and it's name is of the format ${signed_rom}.hash. If an entry has a hash table id defined, then this utility will compile a separate hash table binary whose name is of the format ${signed_rom}.${N}.hash where N is the hash table id. BUG=b:277292697 TEST=Build Skyrim BIOS image and boot to OS. Ensure that the hash table is identical with and without this change. Perform suspend/resume cycles, warm/cold reset cycles for 50 iterations each. TEST=Artificially inject hash table id against some entries in amdfw.cfg and ensure that the concerned hash table binaries are getting compiled. Change-Id: I7ef338d67695a34c33b5c166924832939f381191 Signed-off-by: Karthikeyan Ramasubramanian <kramasub@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/75188 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Raul Rangel <rrangel@chromium.org>
2023-05-03 21:34:41 +02:00
regoff_t ch_hash_tbl_index =
match[OPT_HASH_TABLE_ID].rm_so == match[OPT_HASH_TABLE_ID].rm_eo ?
-1 : match[OPT_HASH_TABLE_ID].rm_so;
regoff_t ch_fwid_type_index = match[OPT_FWID_TYPE].rm_so == match[OPT_FWID_TYPE].rm_eo ?
-1 : match[OPT_FWID_TYPE].rm_so;
util/amdfwtool: Add ability to split hash table Hash table containing hashes of all signed PSP binaries is compiled at build time and installed into the concerned CBFS. During boot, PSP verstage reads the hash table binary and passes it to PSP bootloader. PSP bootloader in turn uses the hash table to verify the signed PSP binaries. Currently the hashes for all the signed PSP binaries are compiled into one hash table. On upcoming platforms with more number of signed PSP binaries, PSP bootloader does not have resources to handle one monolithic hash table. Instead PSP bootloader recommends splitting them into smaller hash tables (currently limited to 3 hash tables). Update amdfwtool tool to support splitting hash tables. This is done by adding an optional hash table id to the entries in the amdfw.cfg file. By default, one hash table binary is always compiled and it's name is of the format ${signed_rom}.hash. If an entry has a hash table id defined, then this utility will compile a separate hash table binary whose name is of the format ${signed_rom}.${N}.hash where N is the hash table id. BUG=b:277292697 TEST=Build Skyrim BIOS image and boot to OS. Ensure that the hash table is identical with and without this change. Perform suspend/resume cycles, warm/cold reset cycles for 50 iterations each. TEST=Artificially inject hash table id against some entries in amdfw.cfg and ensure that the concerned hash table binaries are getting compiled. Change-Id: I7ef338d67695a34c33b5c166924832939f381191 Signed-off-by: Karthikeyan Ramasubramanian <kramasub@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/75188 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Raul Rangel <rrangel@chromium.org>
2023-05-03 21:34:41 +02:00
char ch_lvl = get_level_from_config(oneline, ch_lvl_index, cb_config);
uint8_t ch_hash_tbl = get_hash_tbl_id(oneline, ch_hash_tbl_index);
fwid_type_t ch_fwid_type = get_fwid_type(oneline, ch_fwid_type_index);
path_filename = malloc(MAX_LINE_SIZE * 2 + 2);
if (strchr(fn, '/'))
snprintf(path_filename, MAX_LINE_SIZE * 2 + 2, "%.*s",
MAX_LINE_SIZE, fn);
else
snprintf(path_filename, MAX_LINE_SIZE * 2 + 2, "%.*s/%.*s",
MAX_LINE_SIZE, dir, MAX_LINE_SIZE, fn);
if (find_register_fw_filename_psp_dir(fw_type_str, path_filename,
ch_lvl, ch_hash_tbl, ch_fwid_type, cb_config) == 0) {
if (find_register_fw_filename_bios_dir(fw_type_str, path_filename,
ch_lvl, cb_config) == 0) {
fprintf(stderr, "Module's name \"%s\" is not valid\n", fw_type_str);
return 0; /* Stop parsing. */
}
}
return 1;
}
static bool needs_ish(enum platform platform_type)
{
if (platform_type == PLATFORM_MENDOCINO || platform_type == PLATFORM_PHOENIX || platform_type == PLATFORM_GLINDA)
return true;
else
return false;
}
static bool is_second_gen(enum platform platform_type)
{
switch (platform_type) {
case PLATFORM_CARRIZO:
case PLATFORM_STONEYRIDGE:
case PLATFORM_RAVEN:
case PLATFORM_PICASSO:
return false;
case PLATFORM_RENOIR:
case PLATFORM_LUCIENNE:
case PLATFORM_CEZANNE:
case PLATFORM_MENDOCINO:
case PLATFORM_PHOENIX:
case PLATFORM_GLINDA:
case PLATFORM_GENOA:
return true;
case PLATFORM_UNKNOWN:
default:
fprintf(stderr, "Error: Invalid SOC name.\n\n");
return false;
}
}
#define FW_LOCATION "FIRMWARE_LOCATION"
#define SOC_NAME "SOC_NAME"
/*
return value:
0: The config file can not be parsed correctly.
1: The config file can be parsed correctly.
*/
uint8_t process_config(FILE *config, amd_cb_config *cb_config)
{
char oneline[MAX_LINE_SIZE];
regmatch_t match[N_MATCHES];
char dir[MAX_LINE_SIZE] = {'\0'};
uint32_t dir_len;
int index;
for (index = 0; index < N_MATCHES; index++) {
match[index].rm_so = -1;
match[index].rm_eo = -1;
}
compile_reg_expr(REG_EXTENDED | REG_NEWLINE,
blank_or_comment_regex, &blank_or_comment_expr);
compile_reg_expr(REG_EXTENDED | REG_NEWLINE,
entries_line_regex, &entries_line_expr);
/* Get a line */
/* Get FIRMWARE_LOCATION in the first loop */
while (get_input_file_line(config, oneline, MAX_LINE_SIZE) == OK) {
/* get a line */
if (skip_comment_blank_line(oneline))
continue;
if (is_valid_entry(oneline, match)) {
if (strcmp(&(oneline[match[FW_TYPE].rm_so]), FW_LOCATION) == 0) {
dir_len = match[FW_FILE].rm_eo - match[FW_FILE].rm_so;
assert(dir_len < MAX_LINE_SIZE);
snprintf(dir, MAX_LINE_SIZE, "%.*s", dir_len,
&(oneline[match[FW_FILE].rm_so]));
} else if (strcmp(&(oneline[match[FW_TYPE].rm_so]), SOC_NAME) == 0) {
cb_config->soc_id = identify_platform(
&(oneline[match[FW_FILE].rm_so]));
}
}
}
cb_config->second_gen = is_second_gen(cb_config->soc_id);
if (needs_ish(cb_config->soc_id))
cb_config->need_ish = true;
if (cb_config->need_ish)
cb_config->recovery_ab = true;
if (cb_config->recovery_ab)
cb_config->multi_level = true;
if (dir[0] == '\0') {
fprintf(stderr, "No line with FIRMWARE_LOCATION\n");
return 0;
}
fseek(config, 0, SEEK_SET);
/* Get a line */
while (get_input_file_line(config, oneline, MAX_LINE_SIZE) == OK) {
/* get a line */
if (skip_comment_blank_line(oneline))
continue;
if (is_valid_entry(oneline, match)) {
if (strcmp(&(oneline[match[FW_TYPE].rm_so]), FW_LOCATION) == 0 ||
strcmp(&(oneline[match[FW_TYPE].rm_so]), SOC_NAME) == 0) {
continue;
} else {
if (process_one_line(oneline, match, dir,
cb_config) == 0)
return 0;
}
} else {
fprintf(stderr, "AMDFWTOOL config file line can't be parsed \"%s\"\n", oneline);
return 0;
}
}
return 1;
}