1 /* SPDX-License-Identifier: GPL-2.0-only */
10 #include "amdfwtool.h"
12 /* TODO: a empty line does not matched. */
13 static const char blank_or_comment_regex
[] =
17 /* a line consisting of: optional whitespace followed by */
19 /* a '#' character and optionally, additional characters */
21 static regex_t blank_or_comment_expr
;
23 static const char entries_line_regex
[] =
24 /* optional whitespace */
26 /* followed by a chunk of nonwhitespace for macro field */
28 /* followed by one or more whitespace characters */
30 /* followed by a chunk of nonwhitespace for filename field */
32 /* followed by an optional whitespace + chunk of nonwhitespace for level field
33 1st char L: Indicator of field "level"
35 Directory level to be dropped in.
39 x: use default value hardcoded in table
41 For A/B recovery. Defined same as 2nd char.
44 L2: Level 2 for normal mode
45 L12: Level 1 for normal mode, level 2 for A/B mode
46 Lx1: Use default value for normal mode, level 1 for A/B mode
48 "([[:space:]]+([Ll][12bxBX]{1,2}))?"
49 /* followed by an optional whitespace + chunk of nonwhitespace for hash table field
50 1st char H: Indicator of field "Hash Table ID"
52 Table ID to be dropped in.
53 0: Table 0 / Default Unified Table
59 H2: Put the hash for the concerned entry in Hash Table 2
61 "([[:space:]]+([Hh][0-9]+))?"
62 /* followed by an optional whitespace + "UUID" to indicate the binary is using 16 bytes
63 UUID as firmware identity. In the absence of this field, the binary is using 2 bytes
64 FWID as firmware identity.
66 "([[:space:]]+(UUID))?"
67 /* followed by optional whitespace */
69 static regex_t entries_line_expr
;
83 void compile_reg_expr(int cflags
, const char *expr
, regex_t
*reg
)
85 static const size_t ERROR_BUF_SIZE
= 256;
86 char error_msg
[ERROR_BUF_SIZE
];
89 result
= regcomp(reg
, expr
, cflags
);
91 regerror(result
, reg
, error_msg
, ERROR_BUF_SIZE
);
92 fprintf(stderr
, "%s\n", error_msg
);
96 static enum platform
identify_platform(char *soc_name
)
98 if (!strcasecmp(soc_name
, "Stoneyridge"))
99 return PLATFORM_STONEYRIDGE
;
100 else if (!strcasecmp(soc_name
, "Carrizo"))
101 return PLATFORM_CARRIZO
;
102 else if (!strcasecmp(soc_name
, "Raven"))
103 return PLATFORM_RAVEN
;
104 else if (!strcasecmp(soc_name
, "Picasso"))
105 return PLATFORM_PICASSO
;
106 else if (!strcasecmp(soc_name
, "Cezanne"))
107 return PLATFORM_CEZANNE
;
108 else if (!strcasecmp(soc_name
, "Mendocino"))
109 return PLATFORM_MENDOCINO
;
110 else if (!strcasecmp(soc_name
, "Renoir"))
111 return PLATFORM_RENOIR
;
112 else if (!strcasecmp(soc_name
, "Lucienne"))
113 return PLATFORM_LUCIENNE
;
114 else if (!strcasecmp(soc_name
, "Phoenix"))
115 return PLATFORM_PHOENIX
;
116 else if (!strcasecmp(soc_name
, "Glinda"))
117 return PLATFORM_GLINDA
;
118 else if (!strcasecmp(soc_name
, "Genoa"))
119 return PLATFORM_GENOA
;
121 return PLATFORM_UNKNOWN
;
124 #define SET_LEVEL(tableptr, l, TABLE, ab) \
128 (tableptr)->level = ab ? TABLE##_LVL1_AB : TABLE##_LVL1; \
131 (tableptr)->level = ab ? TABLE##_LVL2_AB : TABLE##_LVL2; \
135 (tableptr)->level = ab ? TABLE##_BOTH_AB : TABLE##_BOTH; \
138 /* use default value */ \
143 extern amd_fw_entry amd_psp_fw_table
[];
144 extern amd_bios_entry amd_bios_table
[];
146 static uint8_t find_register_fw_filename_psp_dir(char *fw_name
, char *filename
,
147 char level_to_set
, uint8_t hash_tbl_id
, fwid_type_t fwid_type
,
148 amd_cb_config
*cb_config
)
150 amd_fw_type fw_type
= AMD_FW_INVALID
;
151 amd_fw_entry
*psp_tableptr
;
153 uint8_t instance
= 0;
155 if (strcmp(fw_name
, "PSPBTLDR_WL_FILE") == 0) {
156 if (cb_config
->have_whitelist
) {
157 fw_type
= AMD_FW_PSP_BOOTLOADER_AB
;
160 fw_type
= AMD_FW_SKIP
;
162 } else if (strcmp(fw_name
, "PSPBTLDR_AB_STAGE1_FILE") == 0) {
163 if (cb_config
->recovery_ab
) {
164 fw_type
= AMD_FW_PSP_BOOTLOADER
;
167 fw_type
= AMD_FW_SKIP
;
169 } else if (strcmp(fw_name
, "PSPBTLDR_FILE") == 0) {
170 if (!cb_config
->recovery_ab
) {
171 fw_type
= AMD_FW_PSP_BOOTLOADER
;
174 fw_type
= AMD_FW_SKIP
;
176 } else if (strcmp(fw_name
, "AMD_PUBKEY_FILE") == 0) {
177 fw_type
= AMD_FW_PSP_PUBKEY
;
179 } else if (strcmp(fw_name
, "AMD_FUSE_CHAIN") == 0) {
180 fw_type
= AMD_PSP_FUSE_CHAIN
;
182 } else if (strcmp(fw_name
, "PSPRCVR_FILE") == 0) {
183 fw_type
= AMD_FW_PSP_RECOVERY
;
185 } else if (strcmp(fw_name
, "PUBSIGNEDKEY_FILE") == 0) {
186 fw_type
= AMD_FW_PSP_RTM_PUBKEY
;
188 } else if (strcmp(fw_name
, "PSPNVRAM_FILE") == 0) {
189 fw_type
= AMD_FW_PSP_NVRAM
;
191 } else if (strcmp(fw_name
, "SMUSCS_FILE") == 0) {
192 fw_type
= AMD_FW_PSP_SMUSCS
;
194 } else if (strcmp(fw_name
, "PSPTRUSTLETS_FILE") == 0) {
195 fw_type
= AMD_FW_PSP_TRUSTLETS
;
197 } else if (strcmp(fw_name
, "PSPSECUREDEBUG_FILE") == 0) {
198 fw_type
= AMD_FW_PSP_SECURED_DEBUG
;
200 } else if (strcmp(fw_name
, "PSP_SMUFW1_SUB0_FILE") == 0) {
201 fw_type
= AMD_FW_PSP_SMU_FIRMWARE
;
203 } else if (strcmp(fw_name
, "PSP_HW_IPCFG_FILE_SUB0") == 0) {
204 fw_type
= AMD_HW_IPCFG
;
206 } else if (strcmp(fw_name
, "PSP_HW_IPCFG_FILE_SUB1") == 0) {
207 fw_type
= AMD_HW_IPCFG
;
209 } else if (strcmp(fw_name
, "PSP_SMUFW1_SUB1_FILE") == 0) {
210 fw_type
= AMD_FW_PSP_SMU_FIRMWARE
;
212 } else if (strcmp(fw_name
, "PSP_SMUFW1_SUB2_FILE") == 0) {
213 fw_type
= AMD_FW_PSP_SMU_FIRMWARE
;
215 } else if (strcmp(fw_name
, "PSP_SMUFW2_SUB0_FILE") == 0) {
216 fw_type
= AMD_FW_PSP_SMU_FIRMWARE2
;
218 } else if (strcmp(fw_name
, "PSP_SMUFW2_SUB1_FILE") == 0) {
219 fw_type
= AMD_FW_PSP_SMU_FIRMWARE2
;
221 } else if (strcmp(fw_name
, "PSP_SMUFW2_SUB2_FILE") == 0) {
222 fw_type
= AMD_FW_PSP_SMU_FIRMWARE2
;
224 } else if (strcmp(fw_name
, "PSP_BOOT_DRIVER_FILE") == 0) {
225 fw_type
= AMD_BOOT_DRIVER
;
227 } else if (strcmp(fw_name
, "PSP_SOC_DRIVER_FILE") == 0) {
228 fw_type
= AMD_SOC_DRIVER
;
230 } else if (strcmp(fw_name
, "PSP_DEBUG_DRIVER_FILE") == 0) {
231 fw_type
= AMD_DEBUG_DRIVER
;
233 } else if (strcmp(fw_name
, "PSP_INTERFACE_DRIVER_FILE") == 0) {
234 fw_type
= AMD_INTERFACE_DRIVER
;
236 } else if (strcmp(fw_name
, "PSP_SEC_DBG_KEY_FILE") == 0) {
237 if (cb_config
->unlock_secure
) {
238 fw_type
= AMD_FW_PSP_SECURED_DEBUG
;
241 fw_type
= AMD_FW_SKIP
;
243 } else if (strcmp(fw_name
, "PSP_SEC_DEBUG_FILE") == 0) {
244 if (cb_config
->unlock_secure
) {
245 fw_type
= AMD_DEBUG_UNLOCK
;
248 fw_type
= AMD_FW_SKIP
;
250 } else if (strcmp(fw_name
, "PSP_ABL0_FILE") == 0) {
253 } else if (strcmp(fw_name
, "PSP_ABL1_FILE") == 0) {
256 } else if (strcmp(fw_name
, "PSP_ABL2_FILE") == 0) {
259 } else if (strcmp(fw_name
, "PSP_ABL3_FILE") == 0) {
262 } else if (strcmp(fw_name
, "PSP_ABL4_FILE") == 0) {
265 } else if (strcmp(fw_name
, "PSP_ABL5_FILE") == 0) {
268 } else if (strcmp(fw_name
, "PSP_ABL6_FILE") == 0) {
271 } else if (strcmp(fw_name
, "PSP_ABL7_FILE") == 0) {
274 } else if (strcmp(fw_name
, "PSPSECUREOS_FILE") == 0) {
275 if (cb_config
->use_secureos
) {
276 fw_type
= AMD_FW_PSP_SECURED_OS
;
279 fw_type
= AMD_FW_SKIP
;
281 } else if (strcmp(fw_name
, "PSPTRUSTLETS_FILE") == 0) {
282 if (cb_config
->use_secureos
) {
283 fw_type
= AMD_FW_PSP_TRUSTLETS
;
286 fw_type
= AMD_FW_SKIP
;
288 } else if (strcmp(fw_name
, "TRUSTLETKEY_FILE") == 0) {
289 if (cb_config
->use_secureos
) {
290 fw_type
= AMD_FW_PSP_TRUSTLETKEY
;
293 fw_type
= AMD_FW_SKIP
;
295 } else if (strcmp(fw_name
, "PSP_IKEK_FILE") == 0) {
296 fw_type
= AMD_WRAPPED_IKEK
;
298 } else if (strcmp(fw_name
, "PSP_SECG0_FILE") == 0) {
299 fw_type
= AMD_SEC_GASKET
;
301 } else if (strcmp(fw_name
, "PSP_SECG1_FILE") == 0) {
302 fw_type
= AMD_SEC_GASKET
;
304 } else if (strcmp(fw_name
, "PSP_SECG2_FILE") == 0) {
305 fw_type
= AMD_SEC_GASKET
;
307 } else if (strcmp(fw_name
, "PSP_MP2FW0_FILE") == 0) {
308 if (cb_config
->load_mp2_fw
) {
309 fw_type
= AMD_MP2_FW
;
312 fw_type
= AMD_FW_SKIP
;
314 } else if (strcmp(fw_name
, "PSP_MP2FW1_FILE") == 0) {
315 if (cb_config
->load_mp2_fw
) {
316 fw_type
= AMD_MP2_FW
;
319 fw_type
= AMD_FW_SKIP
;
321 } else if (strcmp(fw_name
, "PSP_MP2FW2_FILE") == 0) {
322 if (cb_config
->load_mp2_fw
) {
323 fw_type
= AMD_MP2_FW
;
326 fw_type
= AMD_FW_SKIP
;
328 } else if (strcmp(fw_name
, "PSP_C20MP_FILE") == 0) {
329 fw_type
= AMD_FW_C20_MP
;
331 } else if (strcmp(fw_name
, "AMF_SRAM_FILE") == 0) {
332 fw_type
= AMD_FW_AMF_SRAM
;
334 } else if (strcmp(fw_name
, "AMF_DRAM_FILE_INS0") == 0) {
335 fw_type
= AMD_FW_AMF_DRAM
;
338 } else if (strcmp(fw_name
, "AMF_DRAM_FILE_INS1") == 0) {
339 fw_type
= AMD_FW_AMF_DRAM
;
342 } else if (strcmp(fw_name
, "AMF_WLAN_FILE_INS0") == 0) {
343 fw_type
= AMD_FW_AMF_WLAN
;
346 } else if (strcmp(fw_name
, "AMF_WLAN_FILE_INS1") == 0) {
347 fw_type
= AMD_FW_AMF_WLAN
;
350 } else if (strcmp(fw_name
, "AMF_MFD_FILE") == 0) {
351 fw_type
= AMD_FW_AMF_MFD
;
353 } else if (strcmp(fw_name
, "MPCCX_FILE") == 0) {
354 fw_type
= AMD_FW_MPCCX
;
356 } else if (strcmp(fw_name
, "LSDMA_FILE") == 0) {
357 fw_type
= AMD_FW_LSDMA
;
359 } else if (strcmp(fw_name
, "MINIMSMU_FILE") == 0) {
360 fw_type
= AMD_FW_MINIMSMU
;
363 } else if (strcmp(fw_name
, "MINIMSMU_FILE_INS1") == 0) {
364 fw_type
= AMD_FW_MINIMSMU
;
367 } else if (strcmp(fw_name
, "SRAM_FW_EXT_FILE") == 0) {
368 fw_type
= AMD_FW_SRAM_FW_EXT
;
370 } else if (strcmp(fw_name
, "PSP_DRIVERS_FILE") == 0) {
371 fw_type
= AMD_DRIVER_ENTRIES
;
373 } else if (strcmp(fw_name
, "PSP_S0I3_FILE") == 0) {
374 if (cb_config
->s0i3
) {
375 fw_type
= AMD_S0I3_DRIVER
;
378 fw_type
= AMD_FW_SKIP
;
380 } else if (strcmp(fw_name
, "AMD_DRIVER_ENTRIES") == 0) {
381 fw_type
= AMD_DRIVER_ENTRIES
;
383 } else if (strcmp(fw_name
, "VBIOS_BTLOADER_FILE") == 0) {
384 fw_type
= AMD_VBIOS_BTLOADER
;
386 } else if (strcmp(fw_name
, "SECURE_POLICY_L1_FILE") == 0) {
387 fw_type
= AMD_FW_TOS_SEC_POLICY
;
389 } else if (strcmp(fw_name
, "UNIFIEDUSB_FILE") == 0) {
390 fw_type
= AMD_FW_USB_PHY
;
392 } else if (strcmp(fw_name
, "DRTMTA_FILE") == 0) {
393 fw_type
= AMD_FW_DRTM_TA
;
395 } else if (strcmp(fw_name
, "KEYDBBL_FILE") == 0) {
396 fw_type
= AMD_FW_KEYDB_BL
;
398 } else if (strcmp(fw_name
, "KEYDB_TOS_FILE") == 0) {
399 fw_type
= AMD_FW_KEYDB_TOS
;
401 } else if (strcmp(fw_name
, "SPL_TABLE_FILE") == 0) {
402 if (cb_config
->have_mb_spl
) {
403 fw_type
= AMD_FW_SKIP
;
405 fw_type
= AMD_FW_SPL
;
408 } else if (strcmp(fw_name
, "DMCUERAMDCN21_FILE") == 0) {
409 fw_type
= AMD_FW_DMCU_ERAM
;
411 } else if (strcmp(fw_name
, "DMCUINTVECTORSDCN21_FILE") == 0) {
412 fw_type
= AMD_FW_DMCU_ISR
;
414 } else if (strcmp(fw_name
, "MSMU_FILE") == 0) {
415 fw_type
= AMD_FW_MSMU
;
417 } else if (strcmp(fw_name
, "DMCUB_FILE") == 0) {
418 fw_type
= AMD_FW_DMCUB
;
420 } else if (strcmp(fw_name
, "SPIROM_CONFIG_FILE") == 0) {
421 fw_type
= AMD_FW_SPIROM_CFG
;
423 } else if (strcmp(fw_name
, "MPIO_FILE") == 0) {
424 fw_type
= AMD_FW_MPIO
;
426 } else if (strcmp(fw_name
, "TPMLITE_FILE") == 0) {
427 fw_type
= AMD_FW_TPMLITE
;
429 } else if (strcmp(fw_name
, "PSP_KVM_ENGINE_DUMMY_FILE") == 0) {
430 fw_type
= AMD_FW_KVM_IMAGE
;
432 } else if (strcmp(fw_name
, "RPMC_FILE") == 0) {
433 fw_type
= AMD_RPMC_NVRAM
;
435 } else if (strcmp(fw_name
, "PSPBTLDR_AB_FILE") == 0) {
436 if (!cb_config
->have_whitelist
|| cb_config
->recovery_ab
) {
437 fw_type
= AMD_FW_PSP_BOOTLOADER_AB
;
440 fw_type
= AMD_FW_SKIP
;
442 } else if (strcmp(fw_name
, "TA_IKEK_FILE") == 0) {
443 fw_type
= AMD_TA_IKEK
;
445 } else if (strcmp(fw_name
, "UMSMU_FILE") == 0) {
446 fw_type
= AMD_FW_UMSMU
;
448 } else if (strcmp(fw_name
, "PSP_OEM_ABL_KEY_FILE") == 0) {
449 fw_type
= AMD_FW_ABL_PUBKEY
;
451 } else if (strcmp(fw_name
, "PSP_MP5FW_SUB0_FILE") == 0) {
452 fw_type
= AMD_FW_MP5
;
454 } else if (strcmp(fw_name
, "PSP_MP5FW_SUB1_FILE") == 0) {
455 fw_type
= AMD_FW_MP5
;
457 } else if (strcmp(fw_name
, "PSP_MP5FW_SUB2_FILE") == 0) {
458 fw_type
= AMD_FW_MP5
;
460 } else if (strcmp(fw_name
, "PSP_DXIOFW_FILE") == 0) {
461 fw_type
= AMD_FW_DXIO
;
463 } else if (strcmp(fw_name
, "PSP_MPIOFW_FILE") == 0) {
464 fw_type
= AMD_FW_MPIO
;
466 } else if (strcmp(fw_name
, "PSP_RIB_FILE_SUB0") == 0) {
469 } else if (strcmp(fw_name
, "PSP_RIB_FILE_SUB1") == 0) {
472 } else if (strcmp(fw_name
, "FEATURE_TABLE_FILE") == 0) {
473 fw_type
= AMD_FW_FCFG_TABLE
;
475 } else if (strcmp(fw_name
, "PSP_MPDMATFFW_FILE") == 0) {
476 fw_type
= AMD_FW_MPDMA_TF
;
478 } else if (strcmp(fw_name
, "PSP_GMI3PHYFW_FILE") == 0) {
479 fw_type
= AMD_FW_GMI3_PHY
;
481 } else if (strcmp(fw_name
, "PSP_MPDMAPMFW_FILE") == 0) {
482 fw_type
= AMD_FW_MPDMA_PM
;
484 } else if (strcmp(fw_name
, "PSP_TOKEN_UNLOCK_FILE") == 0) {
485 fw_type
= AMD_TOKEN_UNLOCK
;
487 } else if (strcmp(fw_name
, "SEV_DATA_FILE") == 0) {
488 fw_type
= AMD_SEV_DATA
;
490 } else if (strcmp(fw_name
, "SEV_CODE_FILE") == 0) {
491 fw_type
= AMD_SEV_CODE
;
494 fw_type
= AMD_FW_INVALID
;
498 /* Search and fill the filename */
499 psp_tableptr
= &amd_psp_fw_table
[0];
500 if (fw_type
!= AMD_FW_SKIP
&& fw_type
!= AMD_FW_INVALID
) {
501 while (psp_tableptr
->type
!= AMD_FW_INVALID
) {
502 /* instance are not used in PSP table */
503 if (psp_tableptr
->type
== fw_type
&& psp_tableptr
->subprog
== subprog
504 && psp_tableptr
->inst
== instance
) {
505 if (psp_tableptr
->type
!= AMD_PSP_FUSE_CHAIN
) {
506 psp_tableptr
->filename
= filename
;
507 psp_tableptr
->hash_tbl_id
= hash_tbl_id
;
508 psp_tableptr
->fwid_type
= fwid_type
;
510 SET_LEVEL(psp_tableptr
, level_to_set
, PSP
,
511 cb_config
->recovery_ab
);
517 if (fw_type
== AMD_FW_INVALID
)
522 #define PMUI_STR_BASE "PSP_PMUI_FILE"
523 #define PMUD_STR_BASE "PSP_PMUD_FILE"
524 #define PMU_STR_BASE_LEN strlen(PMUI_STR_BASE)
525 #define PMU_STR_SUB_INDEX strlen(PMUI_STR_BASE"_SUB")
526 #define PMU_STR_INS_INDEX strlen(PMUI_STR_BASE"_SUBx_INS")
527 #define PMU_STR_ALL_LEN strlen(PMUI_STR_BASE"_SUBx_INSx")
529 static uint8_t find_register_fw_filename_bios_dir(char *fw_name
, char *filename
,
530 char level_to_set
, amd_cb_config
*cb_config
)
532 amd_bios_type fw_type
= AMD_BIOS_INVALID
;
533 amd_bios_entry
*bhd_tableptr
;
535 uint8_t instance
= 0;
537 (void) (cb_config
); /* Remove warning and reserved for future. */
539 if (strncmp(fw_name
, PMUI_STR_BASE
, PMU_STR_BASE_LEN
) == 0) {
540 assert(strlen(fw_name
) == PMU_STR_ALL_LEN
);
541 fw_type
= AMD_BIOS_PMUI
;
542 subprog
= strtol(&fw_name
[PMU_STR_SUB_INDEX
], NULL
, 16);
543 instance
= strtol(&fw_name
[PMU_STR_INS_INDEX
], NULL
, 16);
544 } else if (strncmp(fw_name
, PMUD_STR_BASE
, PMU_STR_BASE_LEN
) == 0) {
545 assert(strlen(fw_name
) == PMU_STR_ALL_LEN
);
546 fw_type
= AMD_BIOS_PMUD
;
547 subprog
= strtol(&fw_name
[PMU_STR_SUB_INDEX
], NULL
, 16);
548 instance
= strtol(&fw_name
[PMU_STR_INS_INDEX
], NULL
, 16);
549 } else if (strcmp(fw_name
, "RTM_PUBKEY_FILE") == 0) {
550 fw_type
= AMD_BIOS_RTM_PUBKEY
;
553 } else if (strcmp(fw_name
, "PSP_MP2CFG_FILE") == 0) {
554 if (cb_config
->load_mp2_fw
) {
555 fw_type
= AMD_BIOS_MP2_CFG
;
558 fw_type
= AMD_BIOS_SKIP
;
561 fw_type
= AMD_BIOS_INVALID
;
564 bhd_tableptr
= amd_bios_table
;
566 if (fw_type
!= AMD_BIOS_INVALID
&& fw_type
!= AMD_BIOS_SKIP
) {
567 while (bhd_tableptr
->type
!= AMD_BIOS_INVALID
) {
568 if (bhd_tableptr
->type
== fw_type
&&
569 bhd_tableptr
->subpr
== subprog
&&
570 bhd_tableptr
->inst
== instance
) {
571 bhd_tableptr
->filename
= filename
;
572 SET_LEVEL(bhd_tableptr
, level_to_set
, BDT
,
573 cb_config
->recovery_ab
);
579 if (fw_type
== AMD_BIOS_INVALID
)
585 #define MAX_LINE_SIZE 1024
587 int get_input_file_line(FILE *f
, char line
[], int line_buf_size
)
589 if (fgets(line
, line_buf_size
, f
) == NULL
)
592 /* If the file contains a line that is too long, then it's best
593 * to let the user know right away rather than passing back a
594 * truncated result that will lead to problems later on.
596 line
[strlen(line
) - 1] = '\0';
598 if (strlen(line
) == ((size_t) (line_buf_size
- 1))) {
599 fprintf(stderr
, "The line size in config file should be lower than %d bytes.\n",
607 static int is_valid_entry(char *oneline
, regmatch_t match
[N_MATCHES
])
611 for (index
= 0; index
< N_MATCHES
; index
++) {
612 match
[index
].rm_so
= -1;
613 match
[index
].rm_eo
= -1;
615 if (regexec(&entries_line_expr
, oneline
, N_MATCHES
, match
, 0) == 0) {
617 match[2]: FW filename
618 match[4]: Optional directory level to be dropped
619 match[6]: Optional hash table ID to put the hash for the entry
621 if (match
[FW_TYPE
].rm_eo
!= -1)
622 oneline
[match
[FW_TYPE
].rm_eo
] = '\0';
623 if (match
[FW_FILE
].rm_eo
!= -1)
624 oneline
[match
[FW_FILE
].rm_eo
] = '\0';
625 if (match
[OPT_LEVEL
].rm_eo
!= -1)
626 oneline
[match
[OPT_LEVEL
].rm_eo
] = '\0';
627 if (match
[OPT_HASH_TABLE_ID
].rm_eo
!= -1)
628 oneline
[match
[OPT_HASH_TABLE_ID
].rm_eo
] = '\0';
629 if (match
[OPT_FWID_TYPE
].rm_eo
!= -1)
630 oneline
[match
[OPT_FWID_TYPE
].rm_eo
] = '\0';
639 static int skip_comment_blank_line(char *oneline
)
643 if (regexec(&blank_or_comment_expr
, oneline
, 0, NULL
, 0) == 0) {
644 /* skip comment and blank */
654 static char get_level_from_config(char *line
, regoff_t level_index
, amd_cb_config
*cb_config
)
657 /* If the optional level field is present, extract the level char. */
658 if (level_index
!= -1) {
659 if (cb_config
->recovery_ab
== 0)
660 lvl
= line
[level_index
+ 1];
661 else if (strlen(&line
[level_index
]) >= 3)
662 lvl
= line
[level_index
+ 2];
665 assert(lvl
== 'x' || lvl
== 'X' ||
666 lvl
== 'b' || lvl
== 'B' ||
667 lvl
== '1' || lvl
== '2');
672 static uint8_t get_hash_tbl_id(char *line
, regoff_t hash_tbl_index
)
675 /* If the optional hash table field is present, extract the table id char. */
676 if (hash_tbl_index
!= -1)
677 tbl
= (uint8_t)atoi(&line
[hash_tbl_index
+ 1]);
679 assert(tbl
< MAX_NUM_HASH_TABLES
);
683 static fwid_type_t
get_fwid_type(char *line
, regoff_t fwid_type_index
)
685 if (fwid_type_index
!= -1 && !strncmp(&line
[fwid_type_index
], "UUID", strlen("UUID")))
686 return FWID_TYPE_UUID
;
688 return FWID_TYPE_FWID
;
691 static uint8_t process_one_line(char *oneline
, regmatch_t
*match
, char *dir
,
692 amd_cb_config
*cb_config
)
694 char *path_filename
, *fn
= &(oneline
[match
[FW_FILE
].rm_so
]);
695 char *fw_type_str
= &(oneline
[match
[FW_TYPE
].rm_so
]);
696 regoff_t ch_lvl_index
= match
[OPT_LEVEL
].rm_so
== match
[OPT_LEVEL
].rm_eo
?
697 -1 : match
[OPT_LEVEL
].rm_so
;
698 regoff_t ch_hash_tbl_index
=
699 match
[OPT_HASH_TABLE_ID
].rm_so
== match
[OPT_HASH_TABLE_ID
].rm_eo
?
700 -1 : match
[OPT_HASH_TABLE_ID
].rm_so
;
701 regoff_t ch_fwid_type_index
= match
[OPT_FWID_TYPE
].rm_so
== match
[OPT_FWID_TYPE
].rm_eo
?
702 -1 : match
[OPT_FWID_TYPE
].rm_so
;
703 char ch_lvl
= get_level_from_config(oneline
, ch_lvl_index
, cb_config
);
704 uint8_t ch_hash_tbl
= get_hash_tbl_id(oneline
, ch_hash_tbl_index
);
705 fwid_type_t ch_fwid_type
= get_fwid_type(oneline
, ch_fwid_type_index
);
707 path_filename
= malloc(MAX_LINE_SIZE
* 2 + 2);
709 snprintf(path_filename
, MAX_LINE_SIZE
* 2 + 2, "%.*s",
712 snprintf(path_filename
, MAX_LINE_SIZE
* 2 + 2, "%.*s/%.*s",
713 MAX_LINE_SIZE
, dir
, MAX_LINE_SIZE
, fn
);
715 if (find_register_fw_filename_psp_dir(fw_type_str
, path_filename
,
716 ch_lvl
, ch_hash_tbl
, ch_fwid_type
, cb_config
) == 0) {
717 if (find_register_fw_filename_bios_dir(fw_type_str
, path_filename
,
718 ch_lvl
, cb_config
) == 0) {
719 fprintf(stderr
, "Module's name \"%s\" is not valid\n", fw_type_str
);
720 return 0; /* Stop parsing. */
726 bool needs_ish(enum platform platform_type
)
728 if (platform_type
== PLATFORM_MENDOCINO
|| platform_type
== PLATFORM_PHOENIX
|| platform_type
== PLATFORM_GLINDA
)
734 static bool is_second_gen(enum platform platform_type
)
736 switch (platform_type
) {
737 case PLATFORM_CARRIZO
:
738 case PLATFORM_STONEYRIDGE
:
740 case PLATFORM_PICASSO
:
742 case PLATFORM_RENOIR
:
743 case PLATFORM_LUCIENNE
:
744 case PLATFORM_CEZANNE
:
745 case PLATFORM_MENDOCINO
:
746 case PLATFORM_PHOENIX
:
747 case PLATFORM_GLINDA
:
750 case PLATFORM_UNKNOWN
:
752 fprintf(stderr
, "Error: Invalid SOC name.\n\n");
757 #define FW_LOCATION "FIRMWARE_LOCATION"
758 #define SOC_NAME "SOC_NAME"
761 0: The config file can not be parsed correctly.
762 1: The config file can be parsed correctly.
764 uint8_t process_config(FILE *config
, amd_cb_config
*cb_config
)
766 char oneline
[MAX_LINE_SIZE
];
767 regmatch_t match
[N_MATCHES
];
768 char dir
[MAX_LINE_SIZE
] = {'\0'};
772 for (index
= 0; index
< N_MATCHES
; index
++) {
773 match
[index
].rm_so
= -1;
774 match
[index
].rm_eo
= -1;
777 compile_reg_expr(REG_EXTENDED
| REG_NEWLINE
,
778 blank_or_comment_regex
, &blank_or_comment_expr
);
779 compile_reg_expr(REG_EXTENDED
| REG_NEWLINE
,
780 entries_line_regex
, &entries_line_expr
);
783 /* Get FIRMWARE_LOCATION in the first loop */
784 while (get_input_file_line(config
, oneline
, MAX_LINE_SIZE
) == OK
) {
786 if (skip_comment_blank_line(oneline
))
788 if (is_valid_entry(oneline
, match
)) {
789 if (strcmp(&(oneline
[match
[FW_TYPE
].rm_so
]), FW_LOCATION
) == 0) {
790 dir_len
= match
[FW_FILE
].rm_eo
- match
[FW_FILE
].rm_so
;
791 assert(dir_len
< MAX_LINE_SIZE
);
792 snprintf(dir
, MAX_LINE_SIZE
, "%.*s", dir_len
,
793 &(oneline
[match
[FW_FILE
].rm_so
]));
794 } else if (strcmp(&(oneline
[match
[FW_TYPE
].rm_so
]), SOC_NAME
) == 0) {
795 cb_config
->soc_id
= identify_platform(
796 &(oneline
[match
[FW_FILE
].rm_so
]));
801 cb_config
->second_gen
= is_second_gen(cb_config
->soc_id
);
803 if (needs_ish(cb_config
->soc_id
))
804 cb_config
->need_ish
= true;
806 if (cb_config
->need_ish
)
807 cb_config
->recovery_ab
= true;
809 if (cb_config
->recovery_ab
)
810 cb_config
->multi_level
= true;
812 if (dir
[0] == '\0') {
813 fprintf(stderr
, "No line with FIRMWARE_LOCATION\n");
817 fseek(config
, 0, SEEK_SET
);
819 while (get_input_file_line(config
, oneline
, MAX_LINE_SIZE
) == OK
) {
821 if (skip_comment_blank_line(oneline
))
823 if (is_valid_entry(oneline
, match
)) {
824 if (strcmp(&(oneline
[match
[FW_TYPE
].rm_so
]), FW_LOCATION
) == 0 ||
825 strcmp(&(oneline
[match
[FW_TYPE
].rm_so
]), SOC_NAME
) == 0) {
828 if (process_one_line(oneline
, match
, dir
,
833 fprintf(stderr
, "AMDFWTOOL config file line can't be parsed \"%s\"\n", oneline
);