blob: a6b73ee1ec31f47c81bd1d3e22bf9dbde91c49d1 [file] [log] [blame]
Zheng Baoaddf3402021-06-03 15:46:53 +08001/* SPDX-License-Identifier: GPL-2.0-only */
2
Zheng Baoc5e28ab2020-10-28 11:38:09 +08003#include <stdio.h>
4#include <regex.h>
5#include <string.h>
6#include <stdlib.h>
Idwer Vollering93df1d92020-12-30 00:01:59 +01007#include <stdint.h>
Zheng Baodac44612021-05-27 11:11:34 +08008#include <assert.h>
Zheng Baoc5e28ab2020-10-28 11:38:09 +08009
10#include "amdfwtool.h"
11
12/* TODO: a empty line does not matched. */
13static 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 "#.*$)";
21static regex_t blank_or_comment_expr;
22
23static 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:]]*$";
34static regex_t entries_line_expr;
35
Zheng Baob1fb8ce2021-09-13 18:00:09 +080036static 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.
57
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
62 */
63 "([Ll][12bxBX]{1,2})"
64 /* followed by optional whitespace */
65 "[[:space:]]*$";
66static regex_t entries_lvl_line_expr;
67
Zheng Baoc5e28ab2020-10-28 11:38:09 +080068void compile_reg_expr(int cflags, const char *expr, regex_t *reg)
69{
70 static const size_t ERROR_BUF_SIZE = 256;
71 char error_msg[ERROR_BUF_SIZE];
72 int result;
73
74 result = regcomp(reg, expr, cflags);
75 if (result != 0) {
76 regerror(result, reg, error_msg, ERROR_BUF_SIZE);
Zheng Bao77a2c672020-10-01 17:05:43 +080077 fprintf(stderr, "%s\n", error_msg);
Zheng Baoc5e28ab2020-10-28 11:38:09 +080078 }
79}
80
Zheng Bao990d1542021-09-17 13:24:54 +080081#define SET_LEVEL(tableptr, l, TABLE, ab) \
Zheng Baob1fb8ce2021-09-13 18:00:09 +080082 do { \
83 switch ((l)) { \
84 case '1': \
Zheng Bao990d1542021-09-17 13:24:54 +080085 (tableptr)->level = ab ? TABLE##_LVL1_AB : TABLE##_LVL1; \
Zheng Baob1fb8ce2021-09-13 18:00:09 +080086 break; \
87 case '2': \
Zheng Bao990d1542021-09-17 13:24:54 +080088 (tableptr)->level = ab ? TABLE##_LVL2_AB : TABLE##_LVL2; \
Zheng Baob1fb8ce2021-09-13 18:00:09 +080089 break; \
90 case 'b': \
91 case 'B': \
Zheng Bao990d1542021-09-17 13:24:54 +080092 (tableptr)->level = ab ? TABLE##_BOTH_AB : TABLE##_BOTH; \
Zheng Baob1fb8ce2021-09-13 18:00:09 +080093 break; \
94 default: \
95 /* use default value */ \
96 break; \
97 } \
98 } while (0)
99
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800100extern amd_fw_entry amd_psp_fw_table[];
101extern amd_bios_entry amd_bios_table[];
102
103static uint8_t find_register_fw_filename_psp_dir(char *fw_name, char *filename,
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800104 char level_to_set, amd_cb_config *cb_config)
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800105{
106 amd_fw_type fw_type = AMD_FW_INVALID;
107 amd_fw_entry *psp_tableptr;
108 uint8_t subprog;
109
110 if (strcmp(fw_name, "PSPBTLDR_WL_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800111 if (cb_config->have_whitelist) {
Nikolai Vyssotski1965f6502021-05-06 22:15:36 -0500112 fw_type = AMD_FW_PSP_BOOTLOADER_AB;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800113 subprog = 0;
114 } else {
115 fw_type = AMD_FW_SKIP;
116 }
Zheng Bao990d1542021-09-17 13:24:54 +0800117 } else if (strcmp(fw_name, "PSPBTLDR_AB_STAGE1_FILE") == 0) {
118 if (cb_config->recovery_ab) {
119 fw_type = AMD_FW_PSP_BOOTLOADER;
120 subprog = 0;
121 } else {
122 fw_type = AMD_FW_SKIP;
123 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800124 } else if (strcmp(fw_name, "PSPBTLDR_FILE") == 0) {
Zheng Bao990d1542021-09-17 13:24:54 +0800125 if (!cb_config->recovery_ab) {
126 fw_type = AMD_FW_PSP_BOOTLOADER;
127 subprog = 0;
128 } else {
129 fw_type = AMD_FW_SKIP;
130 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800131 } else if (strcmp(fw_name, "AMD_PUBKEY_FILE") == 0) {
132 fw_type = AMD_FW_PSP_PUBKEY;
133 subprog = 0;
134 } else if (strcmp(fw_name, "PSPRCVR_FILE") == 0) {
135 fw_type = AMD_FW_PSP_RECOVERY;
136 subprog = 0;
137 } else if (strcmp(fw_name, "PUBSIGNEDKEY_FILE") == 0) {
138 fw_type = AMD_FW_PSP_RTM_PUBKEY;
139 subprog = 0;
140 } else if (strcmp(fw_name, "PSPNVRAM_FILE") == 0) {
141 fw_type = AMD_FW_PSP_NVRAM;
142 subprog = 0;
143 } else if (strcmp(fw_name, "SMUSCS_FILE") == 0) {
144 fw_type = AMD_FW_PSP_SMUSCS;
145 subprog = 0;
146 } else if (strcmp(fw_name, "PSPTRUSTLETS_FILE") == 0) {
147 fw_type = AMD_FW_PSP_TRUSTLETS;
148 subprog = 0;
149 } else if (strcmp(fw_name, "PSPSECUREDEBUG_FILE") == 0) {
150 fw_type = AMD_FW_PSP_SECURED_DEBUG;
151 subprog = 0;
152 } else if (strcmp(fw_name, "PSP_SMUFW1_SUB0_FILE") == 0) {
153 fw_type = AMD_FW_PSP_SMU_FIRMWARE;
154 subprog = 0;
Zheng Baobf29a0d2020-12-03 23:00:48 +0800155 } else if (strcmp(fw_name, "PSP_HW_IPCFG_FILE") == 0) {
156 fw_type = AMD_HW_IPCFG;
157 subprog = 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800158 } else if (strcmp(fw_name, "PSP_SMUFW1_SUB1_FILE") == 0) {
159 fw_type = AMD_FW_PSP_SMU_FIRMWARE;
160 subprog = 1;
161 } else if (strcmp(fw_name, "PSP_SMUFW1_SUB2_FILE") == 0) {
162 fw_type = AMD_FW_PSP_SMU_FIRMWARE;
163 subprog = 2;
164 } else if (strcmp(fw_name, "PSP_SMUFW2_SUB0_FILE") == 0) {
165 fw_type = AMD_FW_PSP_SMU_FIRMWARE2;
166 subprog = 0;
167 } else if (strcmp(fw_name, "PSP_SMUFW2_SUB1_FILE") == 0) {
168 fw_type = AMD_FW_PSP_SMU_FIRMWARE2;
169 subprog = 1;
170 } else if (strcmp(fw_name, "PSP_SMUFW2_SUB2_FILE") == 0) {
171 fw_type = AMD_FW_PSP_SMU_FIRMWARE2;
172 subprog = 2;
173 } else if (strcmp(fw_name, "PSP_SEC_DBG_KEY_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800174 if (cb_config->unlock_secure) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800175 fw_type = AMD_FW_PSP_SECURED_DEBUG;
176 subprog = 0;
177 } else {
178 fw_type = AMD_FW_SKIP;
179 }
180 } else if (strcmp(fw_name, "PSP_SEC_DEBUG_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800181 if (cb_config->unlock_secure) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800182 fw_type = AMD_DEBUG_UNLOCK;
183 subprog = 0;
184 } else {
185 fw_type = AMD_FW_SKIP;
186 }
187 } else if (strcmp(fw_name, "PSP_ABL0_FILE") == 0) {
188 fw_type = AMD_ABL0;
189 subprog = 0;
190 } else if (strcmp(fw_name, "PSP_ABL1_FILE") == 0) {
191 fw_type = AMD_ABL1;
192 subprog = 0;
193 } else if (strcmp(fw_name, "PSP_ABL2_FILE") == 0) {
194 fw_type = AMD_ABL2;
195 subprog = 0;
196 } else if (strcmp(fw_name, "PSP_ABL3_FILE") == 0) {
197 fw_type = AMD_ABL3;
198 subprog = 0;
199 } else if (strcmp(fw_name, "PSP_ABL4_FILE") == 0) {
200 fw_type = AMD_ABL4;
201 subprog = 0;
202 } else if (strcmp(fw_name, "PSP_ABL5_FILE") == 0) {
203 fw_type = AMD_ABL5;
204 subprog = 0;
205 } else if (strcmp(fw_name, "PSP_ABL6_FILE") == 0) {
206 fw_type = AMD_ABL6;
207 subprog = 0;
208 } else if (strcmp(fw_name, "PSP_ABL7_FILE") == 0) {
209 fw_type = AMD_ABL7;
210 subprog = 0;
211 } else if (strcmp(fw_name, "PSPSECUREOS_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800212 if (cb_config->use_secureos) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800213 fw_type = AMD_FW_PSP_SECURED_OS;
214 subprog = 0;
215 } else {
216 fw_type = AMD_FW_SKIP;
217 }
218 } else if (strcmp(fw_name, "PSPTRUSTLETS_FILE") == 0) {
219 if (cb_config->use_secureos) {
220 fw_type = AMD_FW_PSP_TRUSTLETS;
221 subprog = 0;
222 } else {
223 fw_type = AMD_FW_SKIP;
224 }
225 } else if (strcmp(fw_name, "TRUSTLETKEY_FILE") == 0) {
226 if (cb_config->use_secureos) {
227 fw_type = AMD_FW_PSP_TRUSTLETKEY;
228 subprog = 0;
229 } else {
230 fw_type = AMD_FW_SKIP;
231 }
232 } else if (strcmp(fw_name, "PSP_IKEK_FILE") == 0) {
233 fw_type = AMD_WRAPPED_IKEK;
234 subprog = 0;
Zheng Baobf29a0d2020-12-03 23:00:48 +0800235 } else if (strcmp(fw_name, "PSP_SECG0_FILE") == 0) {
236 fw_type = AMD_SEC_GASKET;
237 subprog = 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800238 } else if (strcmp(fw_name, "PSP_SECG1_FILE") == 0) {
239 fw_type = AMD_SEC_GASKET;
240 subprog = 1;
241 } else if (strcmp(fw_name, "PSP_SECG2_FILE") == 0) {
242 fw_type = AMD_SEC_GASKET;
243 subprog = 2;
Zheng Baobf29a0d2020-12-03 23:00:48 +0800244 } else if (strcmp(fw_name, "PSP_MP2FW0_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800245 if (cb_config->load_mp2_fw) {
Zheng Baobf29a0d2020-12-03 23:00:48 +0800246 fw_type = AMD_MP2_FW;
247 subprog = 0;
248 } else {
249 fw_type = AMD_FW_SKIP;
250 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800251 } else if (strcmp(fw_name, "PSP_MP2FW1_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800252 if (cb_config->load_mp2_fw) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800253 fw_type = AMD_MP2_FW;
254 subprog = 1;
255 } else {
256 fw_type = AMD_FW_SKIP;
257 }
258 } else if (strcmp(fw_name, "PSP_MP2FW2_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800259 if (cb_config->load_mp2_fw) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800260 fw_type = AMD_MP2_FW;
261 subprog = 2;
262 } else {
263 fw_type = AMD_FW_SKIP;
264 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800265 } else if (strcmp(fw_name, "PSP_DRIVERS_FILE") == 0) {
266 fw_type = AMD_DRIVER_ENTRIES;
267 subprog = 0;
268 } else if (strcmp(fw_name, "PSP_S0I3_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800269 if (cb_config->s0i3) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800270 fw_type = AMD_S0I3_DRIVER;
271 subprog = 0;
272 } else {
273 fw_type = AMD_FW_SKIP;
274 }
Zheng Baobf29a0d2020-12-03 23:00:48 +0800275 } else if (strcmp(fw_name, "AMD_DRIVER_ENTRIES") == 0) {
276 fw_type = AMD_DRIVER_ENTRIES;
277 subprog = 0;
278 } else if (strcmp(fw_name, "VBIOS_BTLOADER_FILE") == 0) {
279 fw_type = AMD_VBIOS_BTLOADER;
280 subprog = 0;
281 } else if (strcmp(fw_name, "SECURE_POLICY_L1_FILE") == 0) {
282 fw_type = AMD_FW_TOS_SEC_POLICY;
283 subprog = 0;
284 } else if (strcmp(fw_name, "UNIFIEDUSB_FILE") == 0) {
285 fw_type = AMD_FW_USB_PHY;
286 subprog = 0;
287 } else if (strcmp(fw_name, "DRTMTA_FILE") == 0) {
288 fw_type = AMD_FW_DRTM_TA;
289 subprog = 0;
290 } else if (strcmp(fw_name, "KEYDBBL_FILE") == 0) {
291 fw_type = AMD_FW_KEYDB_BL;
292 subprog = 0;
293 } else if (strcmp(fw_name, "KEYDB_TOS_FILE") == 0) {
294 fw_type = AMD_FW_KEYDB_TOS;
295 subprog = 0;
Zheng Baoab84fd72022-01-27 22:38:27 +0800296 } else if (strcmp(fw_name, "SPL_TABLE_FILE") == 0) {
Zheng Bao6c5ec8e2022-02-11 11:51:26 +0800297 if (cb_config->have_mb_spl) {
298 fw_type = AMD_FW_SPL;
299 subprog = 0;
300 } else {
301 fw_type = AMD_FW_SKIP;
302 }
Zheng Baobf29a0d2020-12-03 23:00:48 +0800303 } else if (strcmp(fw_name, "DMCUERAMDCN21_FILE") == 0) {
304 fw_type = AMD_FW_DMCU_ERAM;
305 subprog = 0;
306 } else if (strcmp(fw_name, "DMCUINTVECTORSDCN21_FILE") == 0) {
307 fw_type = AMD_FW_DMCU_ISR;
308 subprog = 0;
309 } else if (strcmp(fw_name, "PSP_KVM_ENGINE_DUMMY_FILE") == 0) {
310 fw_type = AMD_FW_KVM_IMAGE;
311 subprog = 0;
312 } else if (strcmp(fw_name, "RPMC_FILE") == 0) {
313 fw_type = AMD_RPMC_NVRAM;
314 subprog = 0;
Zheng Baob993cb22021-02-02 18:48:23 +0800315 } else if (strcmp(fw_name, "PSPBTLDR_AB_FILE") == 0) {
Zheng Bao990d1542021-09-17 13:24:54 +0800316 if (!cb_config->have_whitelist || cb_config->recovery_ab) {
Nikolai Vyssotski1965f6502021-05-06 22:15:36 -0500317 fw_type = AMD_FW_PSP_BOOTLOADER_AB;
318 subprog = 0;
319 } else {
320 fw_type = AMD_FW_SKIP;
321 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800322 } else {
323 fw_type = AMD_FW_INVALID;
324 /* TODO: Add more */
325 }
Zheng Baobf29a0d2020-12-03 23:00:48 +0800326
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800327 /* Search and fill the filename */
328 psp_tableptr = &amd_psp_fw_table[0];
329 if (fw_type != AMD_FW_SKIP && fw_type != AMD_FW_INVALID) {
330 while (psp_tableptr->type != AMD_FW_INVALID) {
331 /* instance are not used in PSP table */
332 if (psp_tableptr->type == fw_type && psp_tableptr->subprog == subprog) {
333 psp_tableptr->filename = filename;
Zheng Bao990d1542021-09-17 13:24:54 +0800334 SET_LEVEL(psp_tableptr, level_to_set, PSP,
335 cb_config->recovery_ab);
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800336 break;
337 }
338 psp_tableptr++;
339 }
340 }
341 if (fw_type == AMD_FW_INVALID)
342 return 0;
343 else
344 return 1;
345}
Zheng Bao1a9e5432022-02-17 17:48:27 +0800346#define PMUI_STR_BASE "PSP_PMUI_FILE"
347#define PMUD_STR_BASE "PSP_PMUD_FILE"
348#define PMU_STR_BASE_LEN strlen(PMUI_STR_BASE)
349#define PMU_STR_SUB_INDEX strlen(PMUI_STR_BASE"_SUB")
350#define PMU_STR_INS_INDEX strlen(PMUI_STR_BASE"_SUBx_INS")
Zheng Baofdb02942022-02-22 09:47:59 +0800351#define PMU_STR_ALL_LEN strlen(PMUI_STR_BASE"_SUBx_INSx")
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800352
353static uint8_t find_register_fw_filename_bios_dir(char *fw_name, char *filename,
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800354 char level_to_set, amd_cb_config *cb_config)
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800355{
356 amd_bios_type fw_type = AMD_BIOS_INVALID;
357 amd_bios_entry *bhd_tableptr;
Felix Heldea3417b2020-11-20 20:08:42 +0100358 uint8_t subprog = 0;
359 uint8_t instance = 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800360
361 (void) (cb_config); /* Remove warning and reserved for future. */
362
Zheng Bao1a9e5432022-02-17 17:48:27 +0800363 if (strncmp(fw_name, PMUI_STR_BASE, PMU_STR_BASE_LEN) == 0) {
Zheng Baofdb02942022-02-22 09:47:59 +0800364 assert(strlen(fw_name) == PMU_STR_ALL_LEN);
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800365 fw_type = AMD_BIOS_PMUI;
Zheng Bao1a9e5432022-02-17 17:48:27 +0800366 subprog = fw_name[PMU_STR_SUB_INDEX] - '0';
367 instance = fw_name[PMU_STR_INS_INDEX] - '0';
368 } else if (strncmp(fw_name, PMUD_STR_BASE, PMU_STR_BASE_LEN) == 0) {
Zheng Baofdb02942022-02-22 09:47:59 +0800369 assert(strlen(fw_name) == PMU_STR_ALL_LEN);
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800370 fw_type = AMD_BIOS_PMUD;
Zheng Bao1a9e5432022-02-17 17:48:27 +0800371 subprog = fw_name[PMU_STR_SUB_INDEX] - '0';
372 instance = fw_name[PMU_STR_INS_INDEX] - '0';
Zheng Baobf29a0d2020-12-03 23:00:48 +0800373 } else if (strcmp(fw_name, "RTM_PUBKEY_FILE") == 0) {
374 fw_type = AMD_BIOS_RTM_PUBKEY;
375 subprog = 0;
376 instance = 0;
Zheng Bao50143732020-11-14 21:54:06 +0800377 } else if (strcmp(fw_name, "PSP_MP2CFG_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800378 if (cb_config->load_mp2_fw) {
Zheng Bao50143732020-11-14 21:54:06 +0800379 fw_type = AMD_BIOS_MP2_CFG;
380 subprog = 0;
381 } else {
Martin Rotha8e31ca2021-02-13 21:42:46 -0700382 fw_type = AMD_BIOS_SKIP;
Zheng Bao50143732020-11-14 21:54:06 +0800383 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800384 } else {
385 fw_type = AMD_BIOS_INVALID;
386 }
387
388 bhd_tableptr = amd_bios_table;
389
390 if (fw_type != AMD_BIOS_INVALID && fw_type != AMD_BIOS_SKIP) {
391 while (bhd_tableptr->type != AMD_BIOS_INVALID) {
392 if (bhd_tableptr->type == fw_type &&
393 bhd_tableptr->subpr == subprog &&
394 bhd_tableptr->inst == instance) {
395 bhd_tableptr->filename = filename;
Zheng Bao990d1542021-09-17 13:24:54 +0800396 SET_LEVEL(bhd_tableptr, level_to_set, BDT,
397 cb_config->recovery_ab);
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800398 break;
399 }
400 bhd_tableptr++;
401 }
402 }
403 if (fw_type == AMD_BIOS_INVALID)
404 return 0;
405 else
406 return 1;
407}
408
409#define MAX_LINE_SIZE 1024
410
411int get_input_file_line(FILE *f, char line[], int line_buf_size)
412{
413 if (fgets(line, line_buf_size, f) == NULL)
414 return LINE_EOF;
415
416 /* If the file contains a line that is too long, then it's best
417 * to let the user know right away rather than passing back a
418 * truncated result that will lead to problems later on.
419 */
420 line[strlen(line) - 1] = '\0';
421
422 if (strlen(line) == ((size_t) (line_buf_size - 1))) {
Zheng Bao77a2c672020-10-01 17:05:43 +0800423 fprintf(stderr, "The line size in config file should be lower than %d bytes.\n",
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800424 MAX_LINE_SIZE);
425 exit(1);
426 }
427
428 return OK;
429}
430
431static int is_valid_entry(char *oneline, regmatch_t *match)
432{
433 int retval;
434
435 if (regexec(&entries_line_expr, oneline, 3, match, 0) == 0) {
436 oneline[match[1].rm_eo] = '\0';
437 oneline[match[2].rm_eo] = '\0';
438 retval = 1;
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800439 } else if (regexec(&entries_lvl_line_expr, oneline, 4, match, 0) == 0) {
440 /* match[1]: FW type
441 match[2]: FW filename
442 match[3]: Directory level to be dropped
443 */
444 oneline[match[1].rm_eo] = '\0';
445 oneline[match[2].rm_eo] = '\0';
446 oneline[match[3].rm_eo] = '\0';
447 retval = 1;
448 } else {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800449 retval = 0;
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800450 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800451
452 return retval;
453}
454
455static int skip_comment_blank_line(char *oneline)
456{
457 int retval;
458
459 if (regexec(&blank_or_comment_expr, oneline, 0, NULL, 0) == 0) {
460 /* skip comment and blank */
461 retval = 1;
462 } else {
463 /* no match */
464 retval = 0;
465 }
466
467 return retval;
468}
469
470#define N_MATCHES 4
471/*
472 return value:
473 0: The config file can not be parsed correctly.
474 1: The config file can be parsed correctly.
475 */
476uint8_t process_config(FILE *config, amd_cb_config *cb_config, uint8_t print_deps)
477{
478 char oneline[MAX_LINE_SIZE], *path_filename;
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800479 regmatch_t match[N_MATCHES] = {0};
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800480 char dir[MAX_LINE_SIZE] = {'\0'};
Zheng Baodac44612021-05-27 11:11:34 +0800481 uint32_t dir_len;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800482
483 compile_reg_expr(REG_EXTENDED | REG_NEWLINE,
484 blank_or_comment_regex, &blank_or_comment_expr);
485 compile_reg_expr(REG_EXTENDED | REG_NEWLINE,
486 entries_line_regex, &entries_line_expr);
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800487 compile_reg_expr(REG_EXTENDED | REG_NEWLINE,
488 entries_lvl_line_regex, &entries_lvl_line_expr);
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800489
490 /* Get a line */
Zheng Bao3384e4a2020-10-06 12:03:11 +0800491 /* Get FIRMWARE_LOCATION in the first loop */
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800492 while (get_input_file_line(config, oneline, MAX_LINE_SIZE) == OK) {
493 /* get a line */
494 if (skip_comment_blank_line(oneline))
495 continue;
496 if (is_valid_entry(oneline, match)) {
Zheng Bao3384e4a2020-10-06 12:03:11 +0800497 if (strcmp(&(oneline[match[1].rm_so]), "FIRMWARE_LOCATION") == 0) {
Zheng Baodac44612021-05-27 11:11:34 +0800498 dir_len = match[2].rm_eo - match[2].rm_so;
499 assert(dir_len < MAX_LINE_SIZE);
500 snprintf(dir, MAX_LINE_SIZE, "%.*s", dir_len,
501 &(oneline[match[2].rm_so]));
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800502 break;
503 }
504 }
505 }
506
507 if (dir[0] == '\0') {
508 fprintf(stderr, "No line with FIRMWARE_LOCATION\n");
509 return 0;
510 }
511
512 fseek(config, 0, SEEK_SET);
513 /* Get a line */
514 while (get_input_file_line(config, oneline, MAX_LINE_SIZE) == OK) {
515 /* get a line */
516 if (skip_comment_blank_line(oneline))
517 continue;
518 if (is_valid_entry(oneline, match)) {
Zheng Bao3384e4a2020-10-06 12:03:11 +0800519 if (strcmp(&(oneline[match[1].rm_so]), "FIRMWARE_LOCATION") == 0) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800520 continue;
521 } else {
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800522 char ch_lvl = 'x';
Zheng Baodac44612021-05-27 11:11:34 +0800523 path_filename = malloc(MAX_LINE_SIZE * 2 + 2);
524 snprintf(path_filename, MAX_LINE_SIZE * 2 + 2, "%.*s/%.*s",
525 MAX_LINE_SIZE, dir, MAX_LINE_SIZE,
526 &(oneline[match[2].rm_so]));
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800527
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800528 /* If the optional level field is present,
529 extract the level char. */
530 if (match[3].rm_so != 0) {
Zheng Bao990d1542021-09-17 13:24:54 +0800531 if (cb_config->recovery_ab == 0)
532 ch_lvl = oneline[match[3].rm_so + 1];
533 else
534 ch_lvl = oneline[match[3].rm_so + 2];
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800535 }
536
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800537 if (find_register_fw_filename_psp_dir(
538 &(oneline[match[1].rm_so]),
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800539 path_filename, ch_lvl, cb_config) == 0) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800540 if (find_register_fw_filename_bios_dir(
541 &(oneline[match[1].rm_so]),
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800542 path_filename, ch_lvl, cb_config)
543 == 0) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800544 fprintf(stderr, "Module's name \"%s\" is not valid\n", oneline);
545 return 0; /* Stop parsing. */
546 } else {
547 if (print_deps)
548 printf(" %s ", path_filename);
549 }
550 } else {
551 if (print_deps)
552 printf(" %s ", path_filename);
553 }
554 }
555 } else {
556 fprintf(stderr, "AMDFWTOOL config file line can't be parsed \"%s\"\n", oneline);
557 return 0;
558 }
559 }
560 return 1;
561}