b1fb8cebf8
The value of level defined in table is the default one. We now give an extra option in config file to change this value so some FWs can be dropped in a more optimized way. For the non A/B recovery mode, The value could be L1, L2, Lb or Lx, which are level 1, leve 2, level both and using default value. If it is empty or Lx, left the level in table unchanged. Give a redundant field [12bxBX] in regular exprssion for A/B recovery which will be done later. Change-Id: I0847bc3793467a2299f14d1d2d2486f3f858d7f3 Signed-off-by: Zheng Bao <fishbaozi@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/57612 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Karthik Ramasubramanian <kramasub@google.com>
554 lines
15 KiB
C
554 lines
15 KiB
C
/* 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 optional whitespace */
|
|
"[[:space:]]*$";
|
|
static regex_t entries_line_expr;
|
|
|
|
static const char entries_lvl_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 one or more whitespace characters */
|
|
"[[:space:]]+"
|
|
/* followed by a 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
|
|
*/
|
|
"([Ll][12bxBX]{1,2})"
|
|
/* followed by optional whitespace */
|
|
"[[:space:]]*$";
|
|
static regex_t entries_lvl_line_expr;
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
#define SET_LEVEL(tableptr, l, TABLE) \
|
|
do { \
|
|
switch ((l)) { \
|
|
case '1': \
|
|
(tableptr)->level = TABLE##_LVL1;\
|
|
break; \
|
|
case '2': \
|
|
(tableptr)->level = TABLE##_LVL2;\
|
|
break; \
|
|
case 'b': \
|
|
case 'B': \
|
|
(tableptr)->level = 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, amd_cb_config *cb_config)
|
|
{
|
|
amd_fw_type fw_type = AMD_FW_INVALID;
|
|
amd_fw_entry *psp_tableptr;
|
|
uint8_t subprog;
|
|
|
|
if (strcmp(fw_name, "PSPBTLDR_WL_FILE") == 0) {
|
|
if (cb_config->have_whitelist == 1) {
|
|
fw_type = AMD_FW_PSP_BOOTLOADER_AB;
|
|
subprog = 0;
|
|
} else {
|
|
fw_type = AMD_FW_SKIP;
|
|
}
|
|
} else if (strcmp(fw_name, "PSPBTLDR_FILE") == 0) {
|
|
fw_type = AMD_FW_PSP_BOOTLOADER;
|
|
subprog = 0;
|
|
} 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") == 0) {
|
|
fw_type = AMD_HW_IPCFG;
|
|
subprog = 0;
|
|
} 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_SEC_DBG_KEY_FILE") == 0) {
|
|
if (cb_config->unlock_secure == 1) {
|
|
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 == 1) {
|
|
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 == 1) {
|
|
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 == 1) {
|
|
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 == 1) {
|
|
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 == 1) {
|
|
fw_type = AMD_MP2_FW;
|
|
subprog = 2;
|
|
} else {
|
|
fw_type = AMD_FW_SKIP;
|
|
}
|
|
} 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 == 1) {
|
|
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, "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, "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 == 0) {
|
|
fw_type = AMD_FW_PSP_BOOTLOADER_AB;
|
|
subprog = 0;
|
|
} else {
|
|
fw_type = AMD_FW_SKIP;
|
|
}
|
|
} 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->filename = filename;
|
|
SET_LEVEL(psp_tableptr, level_to_set, PSP);
|
|
break;
|
|
}
|
|
psp_tableptr++;
|
|
}
|
|
}
|
|
if (fw_type == AMD_FW_INVALID)
|
|
return 0;
|
|
else
|
|
return 1;
|
|
}
|
|
|
|
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 (strcmp(fw_name, "PSP_PMUI_FILE1") == 0) {
|
|
fw_type = AMD_BIOS_PMUI;
|
|
subprog = 0;
|
|
instance = 1;
|
|
} else if (strcmp(fw_name, "PSP_PMUI_FILE2") == 0) {
|
|
fw_type = AMD_BIOS_PMUI;
|
|
subprog = 0;
|
|
instance = 4;
|
|
} else if (strcmp(fw_name, "PSP_PMUI_FILE3") == 0) {
|
|
fw_type = AMD_BIOS_PMUI;
|
|
subprog = 1;
|
|
instance = 1;
|
|
} else if (strcmp(fw_name, "PSP_PMUI_FILE4") == 0) {
|
|
fw_type = AMD_BIOS_PMUI;
|
|
subprog = 1;
|
|
instance = 4;
|
|
} else if (strcmp(fw_name, "PSP_PMUD_FILE1") == 0) {
|
|
fw_type = AMD_BIOS_PMUD;
|
|
subprog = 0;
|
|
instance = 1;
|
|
} else if (strcmp(fw_name, "PSP_PMUD_FILE2") == 0) {
|
|
fw_type = AMD_BIOS_PMUD;
|
|
subprog = 0;
|
|
instance = 4;
|
|
} else if (strcmp(fw_name, "PSP_PMUD_FILE3") == 0) {
|
|
fw_type = AMD_BIOS_PMUD;
|
|
subprog = 1;
|
|
instance = 1;
|
|
} else if (strcmp(fw_name, "PSP_PMUD_FILE4") == 0) {
|
|
fw_type = AMD_BIOS_PMUD;
|
|
subprog = 1;
|
|
instance = 4;
|
|
} 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 == 1) {
|
|
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);
|
|
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)
|
|
{
|
|
int retval;
|
|
|
|
if (regexec(&entries_line_expr, oneline, 3, match, 0) == 0) {
|
|
oneline[match[1].rm_eo] = '\0';
|
|
oneline[match[2].rm_eo] = '\0';
|
|
retval = 1;
|
|
} else if (regexec(&entries_lvl_line_expr, oneline, 4, match, 0) == 0) {
|
|
/* match[1]: FW type
|
|
match[2]: FW filename
|
|
match[3]: Directory level to be dropped
|
|
*/
|
|
oneline[match[1].rm_eo] = '\0';
|
|
oneline[match[2].rm_eo] = '\0';
|
|
oneline[match[3].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;
|
|
}
|
|
|
|
#define N_MATCHES 4
|
|
/*
|
|
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, uint8_t print_deps)
|
|
{
|
|
char oneline[MAX_LINE_SIZE], *path_filename;
|
|
regmatch_t match[N_MATCHES] = {0};
|
|
char dir[MAX_LINE_SIZE] = {'\0'};
|
|
uint32_t dir_len;
|
|
|
|
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);
|
|
compile_reg_expr(REG_EXTENDED | REG_NEWLINE,
|
|
entries_lvl_line_regex, &entries_lvl_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[1].rm_so]), "FIRMWARE_LOCATION") == 0) {
|
|
dir_len = match[2].rm_eo - match[2].rm_so;
|
|
assert(dir_len < MAX_LINE_SIZE);
|
|
snprintf(dir, MAX_LINE_SIZE, "%.*s", dir_len,
|
|
&(oneline[match[2].rm_so]));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
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[1].rm_so]), "FIRMWARE_LOCATION") == 0) {
|
|
continue;
|
|
} else {
|
|
char ch_lvl = 'x';
|
|
path_filename = malloc(MAX_LINE_SIZE * 2 + 2);
|
|
snprintf(path_filename, MAX_LINE_SIZE * 2 + 2, "%.*s/%.*s",
|
|
MAX_LINE_SIZE, dir, MAX_LINE_SIZE,
|
|
&(oneline[match[2].rm_so]));
|
|
|
|
/* If the optional level field is present,
|
|
extract the level char. */
|
|
if (match[3].rm_so != 0) {
|
|
ch_lvl = oneline[match[3].rm_so + 1];
|
|
}
|
|
|
|
if (find_register_fw_filename_psp_dir(
|
|
&(oneline[match[1].rm_so]),
|
|
path_filename, ch_lvl, cb_config) == 0) {
|
|
if (find_register_fw_filename_bios_dir(
|
|
&(oneline[match[1].rm_so]),
|
|
path_filename, ch_lvl, cb_config)
|
|
== 0) {
|
|
fprintf(stderr, "Module's name \"%s\" is not valid\n", oneline);
|
|
return 0; /* Stop parsing. */
|
|
} else {
|
|
if (print_deps)
|
|
printf(" %s ", path_filename);
|
|
}
|
|
} else {
|
|
if (print_deps)
|
|
printf(" %s ", path_filename);
|
|
}
|
|
}
|
|
} else {
|
|
fprintf(stderr, "AMDFWTOOL config file line can't be parsed \"%s\"\n", oneline);
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|