amdfwtool: Remove the duplicated entry RIB
[coreboot.git] / util / amdfwtool / data_parse.c
blob8a336d90c6ba6201801743017b097b7b2ac65190
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <stdio.h>
4 #include <regex.h>
5 #include <string.h>
6 #include <stdlib.h>
7 #include <stdint.h>
8 #include <assert.h>
10 #include "amdfwtool.h"
12 /* TODO: a empty line does not matched. */
13 static const char blank_or_comment_regex[] =
14 /* a blank line */
15 "(^[[:space:]]*$)"
16 "|" /* or ... */
17 /* a line consisting of: optional whitespace followed by */
18 "(^[[:space:]]*"
19 /* a '#' character and optionally, additional characters */
20 "#.*$)";
21 static regex_t blank_or_comment_expr;
23 static const char entries_line_regex[] =
24 /* optional whitespace */
25 "^[[:space:]]*"
26 /* followed by a chunk of nonwhitespace for macro field */
27 "([^[:space:]]+)"
28 /* followed by one or more whitespace characters */
29 "[[:space:]]+"
30 /* followed by a chunk of nonwhitespace for filename field */
31 "([^[:space:]]+)"
32 /* followed by optional whitespace */
33 "[[:space:]]*$";
34 static regex_t entries_line_expr;
36 static const char entries_lvl_line_regex[] =
37 /* optional whitespace */
38 "^[[:space:]]*"
39 /* followed by a chunk of nonwhitespace for macro field */
40 "([^[:space:]]+)"
41 /* followed by one or more whitespace characters */
42 "[[:space:]]+"
43 /* followed by a chunk of nonwhitespace for filename field */
44 "([^[:space:]]+)"
45 /* followed by one or more whitespace characters */
46 "[[:space:]]+"
47 /* followed by a chunk of nonwhitespace for level field
48 1st char L: Indicator of field "level"
49 2nd char:
50 Directory level to be dropped in.
51 1: Level 1
52 2: Level 2
53 b: Level both 1&2
54 x: use default value hardcoded in table
55 3rd char:
56 For A/B recovery. Defined same as 2nd char.
58 Examples:
59 L2: Level 2 for normal mode
60 L12: Level 1 for normal mode, level 2 for A/B mode
61 Lx1: Use default value for normal mode, level 1 for A/B mode
63 "([Ll][12bxBX]{1,2})"
64 /* followed by optional whitespace */
65 "[[:space:]]*$";
66 static regex_t entries_lvl_line_expr;
68 void compile_reg_expr(int cflags, const char *expr, regex_t *reg)
70 static const size_t ERROR_BUF_SIZE = 256;
71 char error_msg[ERROR_BUF_SIZE];
72 int result;
74 result = regcomp(reg, expr, cflags);
75 if (result != 0) {
76 regerror(result, reg, error_msg, ERROR_BUF_SIZE);
77 fprintf(stderr, "%s\n", error_msg);
81 #define SET_LEVEL(tableptr, l, TABLE, ab) \
82 do { \
83 switch ((l)) { \
84 case '1': \
85 (tableptr)->level = ab ? TABLE##_LVL1_AB : TABLE##_LVL1; \
86 break; \
87 case '2': \
88 (tableptr)->level = ab ? TABLE##_LVL2_AB : TABLE##_LVL2; \
89 break; \
90 case 'b': \
91 case 'B': \
92 (tableptr)->level = ab ? TABLE##_BOTH_AB : TABLE##_BOTH; \
93 break; \
94 default: \
95 /* use default value */ \
96 break; \
97 } \
98 } while (0)
100 extern amd_fw_entry amd_psp_fw_table[];
101 extern amd_bios_entry amd_bios_table[];
103 static uint8_t find_register_fw_filename_psp_dir(char *fw_name, char *filename,
104 char level_to_set, amd_cb_config *cb_config)
106 amd_fw_type fw_type = AMD_FW_INVALID;
107 amd_fw_entry *psp_tableptr;
108 uint8_t subprog;
109 uint8_t instance = 0;
111 if (strcmp(fw_name, "PSPBTLDR_WL_FILE") == 0) {
112 if (cb_config->have_whitelist) {
113 fw_type = AMD_FW_PSP_BOOTLOADER_AB;
114 subprog = 0;
115 } else {
116 fw_type = AMD_FW_SKIP;
118 } else if (strcmp(fw_name, "PSPBTLDR_AB_STAGE1_FILE") == 0) {
119 if (cb_config->recovery_ab) {
120 fw_type = AMD_FW_PSP_BOOTLOADER;
121 subprog = 0;
122 } else {
123 fw_type = AMD_FW_SKIP;
125 } else if (strcmp(fw_name, "PSPBTLDR_FILE") == 0) {
126 if (!cb_config->recovery_ab) {
127 fw_type = AMD_FW_PSP_BOOTLOADER;
128 subprog = 0;
129 } else {
130 fw_type = AMD_FW_SKIP;
132 } else if (strcmp(fw_name, "AMD_PUBKEY_FILE") == 0) {
133 fw_type = AMD_FW_PSP_PUBKEY;
134 subprog = 0;
135 } else if (strcmp(fw_name, "PSPRCVR_FILE") == 0) {
136 fw_type = AMD_FW_PSP_RECOVERY;
137 subprog = 0;
138 } else if (strcmp(fw_name, "PUBSIGNEDKEY_FILE") == 0) {
139 fw_type = AMD_FW_PSP_RTM_PUBKEY;
140 subprog = 0;
141 } else if (strcmp(fw_name, "PSPNVRAM_FILE") == 0) {
142 fw_type = AMD_FW_PSP_NVRAM;
143 subprog = 0;
144 } else if (strcmp(fw_name, "SMUSCS_FILE") == 0) {
145 fw_type = AMD_FW_PSP_SMUSCS;
146 subprog = 0;
147 } else if (strcmp(fw_name, "PSPTRUSTLETS_FILE") == 0) {
148 fw_type = AMD_FW_PSP_TRUSTLETS;
149 subprog = 0;
150 } else if (strcmp(fw_name, "PSPSECUREDEBUG_FILE") == 0) {
151 fw_type = AMD_FW_PSP_SECURED_DEBUG;
152 subprog = 0;
153 } else if (strcmp(fw_name, "PSP_SMUFW1_SUB0_FILE") == 0) {
154 fw_type = AMD_FW_PSP_SMU_FIRMWARE;
155 subprog = 0;
156 } else if (strcmp(fw_name, "PSP_HW_IPCFG_FILE") == 0) {
157 fw_type = AMD_HW_IPCFG;
158 subprog = 0;
159 } else if (strcmp(fw_name, "PSP_SMUFW1_SUB1_FILE") == 0) {
160 fw_type = AMD_FW_PSP_SMU_FIRMWARE;
161 subprog = 1;
162 } else if (strcmp(fw_name, "PSP_SMUFW1_SUB2_FILE") == 0) {
163 fw_type = AMD_FW_PSP_SMU_FIRMWARE;
164 subprog = 2;
165 } else if (strcmp(fw_name, "PSP_SMUFW2_SUB0_FILE") == 0) {
166 fw_type = AMD_FW_PSP_SMU_FIRMWARE2;
167 subprog = 0;
168 } else if (strcmp(fw_name, "PSP_SMUFW2_SUB1_FILE") == 0) {
169 fw_type = AMD_FW_PSP_SMU_FIRMWARE2;
170 subprog = 1;
171 } else if (strcmp(fw_name, "PSP_SMUFW2_SUB2_FILE") == 0) {
172 fw_type = AMD_FW_PSP_SMU_FIRMWARE2;
173 subprog = 2;
174 } else if (strcmp(fw_name, "PSP_BOOT_DRIVER_FILE") == 0) {
175 fw_type = AMD_BOOT_DRIVER;
176 subprog = 0;
177 } else if (strcmp(fw_name, "PSP_SOC_DRIVER_FILE") == 0) {
178 fw_type = AMD_SOC_DRIVER;
179 subprog = 0;
180 } else if (strcmp(fw_name, "PSP_DEBUG_DRIVER_FILE") == 0) {
181 fw_type = AMD_DEBUG_DRIVER;
182 subprog = 0;
183 } else if (strcmp(fw_name, "PSP_INTERFACE_DRIVER_FILE") == 0) {
184 fw_type = AMD_INTERFACE_DRIVER;
185 subprog = 0;
186 } else if (strcmp(fw_name, "PSP_SEC_DBG_KEY_FILE") == 0) {
187 if (cb_config->unlock_secure) {
188 fw_type = AMD_FW_PSP_SECURED_DEBUG;
189 subprog = 0;
190 } else {
191 fw_type = AMD_FW_SKIP;
193 } else if (strcmp(fw_name, "PSP_SEC_DEBUG_FILE") == 0) {
194 if (cb_config->unlock_secure) {
195 fw_type = AMD_DEBUG_UNLOCK;
196 subprog = 0;
197 } else {
198 fw_type = AMD_FW_SKIP;
200 } else if (strcmp(fw_name, "PSP_ABL0_FILE") == 0) {
201 fw_type = AMD_ABL0;
202 subprog = 0;
203 } else if (strcmp(fw_name, "PSP_ABL1_FILE") == 0) {
204 fw_type = AMD_ABL1;
205 subprog = 0;
206 } else if (strcmp(fw_name, "PSP_ABL2_FILE") == 0) {
207 fw_type = AMD_ABL2;
208 subprog = 0;
209 } else if (strcmp(fw_name, "PSP_ABL3_FILE") == 0) {
210 fw_type = AMD_ABL3;
211 subprog = 0;
212 } else if (strcmp(fw_name, "PSP_ABL4_FILE") == 0) {
213 fw_type = AMD_ABL4;
214 subprog = 0;
215 } else if (strcmp(fw_name, "PSP_ABL5_FILE") == 0) {
216 fw_type = AMD_ABL5;
217 subprog = 0;
218 } else if (strcmp(fw_name, "PSP_ABL6_FILE") == 0) {
219 fw_type = AMD_ABL6;
220 subprog = 0;
221 } else if (strcmp(fw_name, "PSP_ABL7_FILE") == 0) {
222 fw_type = AMD_ABL7;
223 subprog = 0;
224 } else if (strcmp(fw_name, "PSPSECUREOS_FILE") == 0) {
225 if (cb_config->use_secureos) {
226 fw_type = AMD_FW_PSP_SECURED_OS;
227 subprog = 0;
228 } else {
229 fw_type = AMD_FW_SKIP;
231 } else if (strcmp(fw_name, "PSPTRUSTLETS_FILE") == 0) {
232 if (cb_config->use_secureos) {
233 fw_type = AMD_FW_PSP_TRUSTLETS;
234 subprog = 0;
235 } else {
236 fw_type = AMD_FW_SKIP;
238 } else if (strcmp(fw_name, "TRUSTLETKEY_FILE") == 0) {
239 if (cb_config->use_secureos) {
240 fw_type = AMD_FW_PSP_TRUSTLETKEY;
241 subprog = 0;
242 } else {
243 fw_type = AMD_FW_SKIP;
245 } else if (strcmp(fw_name, "PSP_IKEK_FILE") == 0) {
246 fw_type = AMD_WRAPPED_IKEK;
247 subprog = 0;
248 } else if (strcmp(fw_name, "PSP_SECG0_FILE") == 0) {
249 fw_type = AMD_SEC_GASKET;
250 subprog = 0;
251 } else if (strcmp(fw_name, "PSP_SECG1_FILE") == 0) {
252 fw_type = AMD_SEC_GASKET;
253 subprog = 1;
254 } else if (strcmp(fw_name, "PSP_SECG2_FILE") == 0) {
255 fw_type = AMD_SEC_GASKET;
256 subprog = 2;
257 } else if (strcmp(fw_name, "PSP_MP2FW0_FILE") == 0) {
258 if (cb_config->load_mp2_fw) {
259 fw_type = AMD_MP2_FW;
260 subprog = 0;
261 } else {
262 fw_type = AMD_FW_SKIP;
264 } else if (strcmp(fw_name, "PSP_MP2FW1_FILE") == 0) {
265 if (cb_config->load_mp2_fw) {
266 fw_type = AMD_MP2_FW;
267 subprog = 1;
268 } else {
269 fw_type = AMD_FW_SKIP;
271 } else if (strcmp(fw_name, "PSP_MP2FW2_FILE") == 0) {
272 if (cb_config->load_mp2_fw) {
273 fw_type = AMD_MP2_FW;
274 subprog = 2;
275 } else {
276 fw_type = AMD_FW_SKIP;
278 } else if (strcmp(fw_name, "PSP_C20MP_FILE") == 0) {
279 fw_type = AMD_FW_C20_MP;
280 subprog = 0;
281 } else if (strcmp(fw_name, "AMF_SRAM_FILE") == 0) {
282 fw_type = AMD_FW_AMF_SRAM;
283 subprog = 0;
284 } else if (strcmp(fw_name, "AMF_DRAM_FILE_INS0") == 0) {
285 fw_type = AMD_FW_AMF_DRAM;
286 subprog = 0;
287 instance = 0;
288 } else if (strcmp(fw_name, "AMF_DRAM_FILE_INS1") == 0) {
289 fw_type = AMD_FW_AMF_DRAM;
290 subprog = 0;
291 instance = 1;
292 } else if (strcmp(fw_name, "AMF_WLAN_FILE_INS0") == 0) {
293 fw_type = AMD_FW_AMF_WLAN;
294 subprog = 0;
295 instance = 0;
296 } else if (strcmp(fw_name, "AMF_WLAN_FILE_INS1") == 0) {
297 fw_type = AMD_FW_AMF_WLAN;
298 subprog = 0;
299 instance = 1;
300 } else if (strcmp(fw_name, "AMF_MFD_FILE") == 0) {
301 fw_type = AMD_FW_AMF_MFD;
302 subprog = 0;
303 } else if (strcmp(fw_name, "MPCCX_FILE") == 0) {
304 fw_type = AMD_FW_MPCCX;
305 subprog = 0;
306 } else if (strcmp(fw_name, "LSDMA_FILE") == 0) {
307 fw_type = AMD_FW_LSDMA;
308 subprog = 0;
309 } else if (strcmp(fw_name, "MINIMSMU_FILE") == 0) {
310 fw_type = AMD_FW_MINIMSMU;
311 instance = 0;
312 subprog = 0;
313 } else if (strcmp(fw_name, "MINIMSMU_FILE_INS1") == 0) {
314 fw_type = AMD_FW_MINIMSMU;
315 instance = 1;
316 subprog = 0;
317 } else if (strcmp(fw_name, "SRAM_FW_EXT_FILE") == 0) {
318 fw_type = AMD_FW_SRAM_FW_EXT;
319 subprog = 0;
320 } else if (strcmp(fw_name, "PSP_DRIVERS_FILE") == 0) {
321 fw_type = AMD_DRIVER_ENTRIES;
322 subprog = 0;
323 } else if (strcmp(fw_name, "PSP_S0I3_FILE") == 0) {
324 if (cb_config->s0i3) {
325 fw_type = AMD_S0I3_DRIVER;
326 subprog = 0;
327 } else {
328 fw_type = AMD_FW_SKIP;
330 } else if (strcmp(fw_name, "AMD_DRIVER_ENTRIES") == 0) {
331 fw_type = AMD_DRIVER_ENTRIES;
332 subprog = 0;
333 } else if (strcmp(fw_name, "VBIOS_BTLOADER_FILE") == 0) {
334 fw_type = AMD_VBIOS_BTLOADER;
335 subprog = 0;
336 } else if (strcmp(fw_name, "SECURE_POLICY_L1_FILE") == 0) {
337 fw_type = AMD_FW_TOS_SEC_POLICY;
338 subprog = 0;
339 } else if (strcmp(fw_name, "UNIFIEDUSB_FILE") == 0) {
340 fw_type = AMD_FW_USB_PHY;
341 subprog = 0;
342 } else if (strcmp(fw_name, "DRTMTA_FILE") == 0) {
343 fw_type = AMD_FW_DRTM_TA;
344 subprog = 0;
345 } else if (strcmp(fw_name, "KEYDBBL_FILE") == 0) {
346 fw_type = AMD_FW_KEYDB_BL;
347 subprog = 0;
348 } else if (strcmp(fw_name, "KEYDB_TOS_FILE") == 0) {
349 fw_type = AMD_FW_KEYDB_TOS;
350 subprog = 0;
351 } else if (strcmp(fw_name, "SPL_TABLE_FILE") == 0) {
352 if (cb_config->have_mb_spl) {
353 fw_type = AMD_FW_SKIP;
354 } else {
355 fw_type = AMD_FW_SPL;
356 subprog = 0;
358 } else if (strcmp(fw_name, "DMCUERAMDCN21_FILE") == 0) {
359 fw_type = AMD_FW_DMCU_ERAM;
360 subprog = 0;
361 } else if (strcmp(fw_name, "DMCUINTVECTORSDCN21_FILE") == 0) {
362 fw_type = AMD_FW_DMCU_ISR;
363 subprog = 0;
364 } else if (strcmp(fw_name, "MSMU_FILE") == 0) {
365 fw_type = AMD_FW_MSMU;
366 subprog = 0;
367 } else if (strcmp(fw_name, "DMCUB_FILE") == 0) {
368 fw_type = AMD_FW_DMCUB;
369 subprog = 0;
370 } else if (strcmp(fw_name, "SPIROM_CONFIG_FILE") == 0) {
371 fw_type = AMD_FW_SPIROM_CFG;
372 subprog = 0;
373 } else if (strcmp(fw_name, "MPIO_FILE") == 0) {
374 fw_type = AMD_FW_MPIO;
375 subprog = 0;
376 } else if (strcmp(fw_name, "TPMLITE_FILE") == 0) {
377 printf("TPMLITE\n");
378 fw_type = AMD_FW_TPMLITE;
379 subprog = 0;
380 } else if (strcmp(fw_name, "PSP_KVM_ENGINE_DUMMY_FILE") == 0) {
381 fw_type = AMD_FW_KVM_IMAGE;
382 subprog = 0;
383 } else if (strcmp(fw_name, "RPMC_FILE") == 0) {
384 fw_type = AMD_RPMC_NVRAM;
385 subprog = 0;
386 } else if (strcmp(fw_name, "PSPBTLDR_AB_FILE") == 0) {
387 if (!cb_config->have_whitelist || cb_config->recovery_ab) {
388 fw_type = AMD_FW_PSP_BOOTLOADER_AB;
389 subprog = 0;
390 } else {
391 fw_type = AMD_FW_SKIP;
393 } else if (strcmp(fw_name, "TA_IKEK_FILE") == 0) {
394 fw_type = AMD_TA_IKEK;
395 subprog = 0;
396 } else if (strcmp(fw_name, "PSP_OEM_ABL_KEY_FILE") == 0) {
397 fw_type = AMD_FW_ABL_PUBKEY;
398 subprog = 0;
399 } else if (strcmp(fw_name, "PSP_MP5FW_SUB0_FILE") == 0) {
400 fw_type = AMD_FW_MP5;
401 subprog = 0;
402 } else if (strcmp(fw_name, "PSP_MP5FW_SUB1_FILE") == 0) {
403 fw_type = AMD_FW_MP5;
404 subprog = 1;
405 } else if (strcmp(fw_name, "PSP_MP5FW_SUB2_FILE") == 0) {
406 fw_type = AMD_FW_MP5;
407 subprog = 2;
408 } else if (strcmp(fw_name, "PSP_DXIOFW_FILE") == 0) {
409 fw_type = AMD_FW_DXIO;
410 subprog = 0;
411 } else if (strcmp(fw_name, "PSP_MPIOFW_FILE") == 0) {
412 fw_type = AMD_FW_MPIO;
413 subprog = 0;
414 } else if (strcmp(fw_name, "PSP_RIB_FILE") == 0) {
415 fw_type = AMD_RIB;
416 subprog = 0;
417 } else if (strcmp(fw_name, "FEATURE_TABLE_FILE") == 0) {
418 fw_type = AMD_FW_FCFG_TABLE;
419 subprog = 0;
420 } else if (strcmp(fw_name, "PSP_MPDMATFFW_FILE") == 0) {
421 fw_type = AMD_FW_MPDMA_TF;
422 subprog = 0;
423 } else if (strcmp(fw_name, "PSP_GMI3PHYFW_FILE") == 0) {
424 fw_type = AMD_FW_GMI3_PHY;
425 subprog = 0;
426 } else if (strcmp(fw_name, "PSP_MPDMAPMFW_FILE") == 0) {
427 fw_type = AMD_FW_MPDMA_PM;
428 subprog = 0;
429 } else if (strcmp(fw_name, "PSP_TOKEN_UNLOCK_FILE") == 0) {
430 fw_type = AMD_TOKEN_UNLOCK;
431 subprog = 0;
432 } else if (strcmp(fw_name, "SEV_DATA_FILE") == 0) {
433 fw_type = AMD_SEV_DATA;
434 subprog = 0;
435 } else if (strcmp(fw_name, "SEV_CODE_FILE") == 0) {
436 fw_type = AMD_SEV_CODE;
437 subprog = 0;
438 } else {
439 fw_type = AMD_FW_INVALID;
440 /* TODO: Add more */
443 /* Search and fill the filename */
444 psp_tableptr = &amd_psp_fw_table[0];
445 if (fw_type != AMD_FW_SKIP && fw_type != AMD_FW_INVALID) {
446 while (psp_tableptr->type != AMD_FW_INVALID) {
447 /* instance are not used in PSP table */
448 if (psp_tableptr->type == fw_type && psp_tableptr->subprog == subprog
449 && psp_tableptr->inst == instance) {
450 psp_tableptr->filename = filename;
451 SET_LEVEL(psp_tableptr, level_to_set, PSP,
452 cb_config->recovery_ab);
453 break;
455 psp_tableptr++;
458 if (fw_type == AMD_FW_INVALID)
459 return 0;
460 else
461 return 1;
463 #define PMUI_STR_BASE "PSP_PMUI_FILE"
464 #define PMUD_STR_BASE "PSP_PMUD_FILE"
465 #define PMU_STR_BASE_LEN strlen(PMUI_STR_BASE)
466 #define PMU_STR_SUB_INDEX strlen(PMUI_STR_BASE"_SUB")
467 #define PMU_STR_INS_INDEX strlen(PMUI_STR_BASE"_SUBx_INS")
468 #define PMU_STR_ALL_LEN strlen(PMUI_STR_BASE"_SUBx_INSx")
470 static uint8_t find_register_fw_filename_bios_dir(char *fw_name, char *filename,
471 char level_to_set, amd_cb_config *cb_config)
473 amd_bios_type fw_type = AMD_BIOS_INVALID;
474 amd_bios_entry *bhd_tableptr;
475 uint8_t subprog = 0;
476 uint8_t instance = 0;
478 (void) (cb_config); /* Remove warning and reserved for future. */
480 if (strncmp(fw_name, PMUI_STR_BASE, PMU_STR_BASE_LEN) == 0) {
481 assert(strlen(fw_name) == PMU_STR_ALL_LEN);
482 fw_type = AMD_BIOS_PMUI;
483 subprog = strtol(&fw_name[PMU_STR_SUB_INDEX], NULL, 16);
484 instance = strtol(&fw_name[PMU_STR_INS_INDEX], NULL, 16);
485 } else if (strncmp(fw_name, PMUD_STR_BASE, PMU_STR_BASE_LEN) == 0) {
486 assert(strlen(fw_name) == PMU_STR_ALL_LEN);
487 fw_type = AMD_BIOS_PMUD;
488 subprog = strtol(&fw_name[PMU_STR_SUB_INDEX], NULL, 16);
489 instance = strtol(&fw_name[PMU_STR_INS_INDEX], NULL, 16);
490 } else if (strcmp(fw_name, "RTM_PUBKEY_FILE") == 0) {
491 fw_type = AMD_BIOS_RTM_PUBKEY;
492 subprog = 0;
493 instance = 0;
494 } else if (strcmp(fw_name, "PSP_MP2CFG_FILE") == 0) {
495 if (cb_config->load_mp2_fw) {
496 fw_type = AMD_BIOS_MP2_CFG;
497 subprog = 0;
498 } else {
499 fw_type = AMD_BIOS_SKIP;
501 } else {
502 fw_type = AMD_BIOS_INVALID;
505 bhd_tableptr = amd_bios_table;
507 if (fw_type != AMD_BIOS_INVALID && fw_type != AMD_BIOS_SKIP) {
508 while (bhd_tableptr->type != AMD_BIOS_INVALID) {
509 if (bhd_tableptr->type == fw_type &&
510 bhd_tableptr->subpr == subprog &&
511 bhd_tableptr->inst == instance) {
512 bhd_tableptr->filename = filename;
513 SET_LEVEL(bhd_tableptr, level_to_set, BDT,
514 cb_config->recovery_ab);
515 break;
517 bhd_tableptr++;
520 if (fw_type == AMD_BIOS_INVALID)
521 return 0;
522 else
523 return 1;
526 #define MAX_LINE_SIZE 1024
528 int get_input_file_line(FILE *f, char line[], int line_buf_size)
530 if (fgets(line, line_buf_size, f) == NULL)
531 return LINE_EOF;
533 /* If the file contains a line that is too long, then it's best
534 * to let the user know right away rather than passing back a
535 * truncated result that will lead to problems later on.
537 line[strlen(line) - 1] = '\0';
539 if (strlen(line) == ((size_t) (line_buf_size - 1))) {
540 fprintf(stderr, "The line size in config file should be lower than %d bytes.\n",
541 MAX_LINE_SIZE);
542 exit(1);
545 return OK;
548 #define N_MATCHES 4
549 static int is_valid_entry(char *oneline, regmatch_t match[N_MATCHES])
551 int retval, index;
553 for (index = 0; index < N_MATCHES; index++) {
554 match[index].rm_so = -1;
555 match[index].rm_eo = -1;
557 if (regexec(&entries_line_expr, oneline, 3, match, 0) == 0) {
558 oneline[match[1].rm_eo] = '\0';
559 oneline[match[2].rm_eo] = '\0';
560 retval = 1;
561 } else if (regexec(&entries_lvl_line_expr, oneline, 4, match, 0) == 0) {
562 /* match[1]: FW type
563 match[2]: FW filename
564 match[3]: Directory level to be dropped
566 oneline[match[1].rm_eo] = '\0';
567 oneline[match[2].rm_eo] = '\0';
568 oneline[match[3].rm_eo] = '\0';
569 retval = 1;
570 } else {
571 retval = 0;
574 return retval;
577 static int skip_comment_blank_line(char *oneline)
579 int retval;
581 if (regexec(&blank_or_comment_expr, oneline, 0, NULL, 0) == 0) {
582 /* skip comment and blank */
583 retval = 1;
584 } else {
585 /* no match */
586 retval = 0;
589 return retval;
592 char get_level_from_config(char *line, regoff_t level_index, amd_cb_config *cb_config)
594 char lvl = 'x';
595 /* If the optional level field is present,
596 extract the level char. */
597 if (level_index != -1) {
598 if (cb_config->recovery_ab == 0)
599 lvl = line[level_index + 1];
600 else if (strlen(&line[level_index]) >= 3)
601 lvl = line[level_index + 2];
604 assert(lvl == 'x' || lvl == 'X' ||
605 lvl == 'b' || lvl == 'B' ||
606 lvl == '1' || lvl == '2');
608 return lvl;
612 return value:
613 0: The config file can not be parsed correctly.
614 1: The config file can be parsed correctly.
616 uint8_t process_config(FILE *config, amd_cb_config *cb_config, uint8_t print_deps)
618 char oneline[MAX_LINE_SIZE], *path_filename;
619 regmatch_t match[N_MATCHES];
620 char dir[MAX_LINE_SIZE] = {'\0'};
621 uint32_t dir_len;
622 int index;
624 for (index = 0; index < N_MATCHES; index++) {
625 match[index].rm_so = -1;
626 match[index].rm_eo = -1;
629 compile_reg_expr(REG_EXTENDED | REG_NEWLINE,
630 blank_or_comment_regex, &blank_or_comment_expr);
631 compile_reg_expr(REG_EXTENDED | REG_NEWLINE,
632 entries_line_regex, &entries_line_expr);
633 compile_reg_expr(REG_EXTENDED | REG_NEWLINE,
634 entries_lvl_line_regex, &entries_lvl_line_expr);
636 /* Get a line */
637 /* Get FIRMWARE_LOCATION in the first loop */
638 while (get_input_file_line(config, oneline, MAX_LINE_SIZE) == OK) {
639 /* get a line */
640 if (skip_comment_blank_line(oneline))
641 continue;
642 if (is_valid_entry(oneline, match)) {
643 if (strcmp(&(oneline[match[1].rm_so]), "FIRMWARE_LOCATION") == 0) {
644 dir_len = match[2].rm_eo - match[2].rm_so;
645 assert(dir_len < MAX_LINE_SIZE);
646 snprintf(dir, MAX_LINE_SIZE, "%.*s", dir_len,
647 &(oneline[match[2].rm_so]));
648 break;
653 if (dir[0] == '\0') {
654 fprintf(stderr, "No line with FIRMWARE_LOCATION\n");
655 return 0;
658 fseek(config, 0, SEEK_SET);
659 /* Get a line */
660 while (get_input_file_line(config, oneline, MAX_LINE_SIZE) == OK) {
661 /* get a line */
662 if (skip_comment_blank_line(oneline))
663 continue;
664 if (is_valid_entry(oneline, match)) {
665 if (strcmp(&(oneline[match[1].rm_so]), "FIRMWARE_LOCATION") == 0) {
666 continue;
667 } else {
668 char ch_lvl = 'x';
669 path_filename = malloc(MAX_LINE_SIZE * 2 + 2);
670 snprintf(path_filename, MAX_LINE_SIZE * 2 + 2, "%.*s/%.*s",
671 MAX_LINE_SIZE, dir, MAX_LINE_SIZE,
672 &(oneline[match[2].rm_so]));
674 /* If the optional level field is present,
675 extract the level char. */
676 ch_lvl = get_level_from_config(oneline,
677 match[3].rm_so, cb_config);
679 if (find_register_fw_filename_psp_dir(
680 &(oneline[match[1].rm_so]),
681 path_filename, ch_lvl, cb_config) == 0) {
682 if (find_register_fw_filename_bios_dir(
683 &(oneline[match[1].rm_so]),
684 path_filename, ch_lvl, cb_config)
685 == 0) {
686 fprintf(stderr, "Module's name \"%s\" is not valid\n", oneline);
687 return 0; /* Stop parsing. */
688 } else {
689 if (print_deps)
690 printf(" %s ", path_filename);
692 } else {
693 if (print_deps)
694 printf(" %s ", path_filename);
697 } else {
698 fprintf(stderr, "AMDFWTOOL config file line can't be parsed \"%s\"\n", oneline);
699 return 0;
702 return 1;