blob: a28a7eb168338b4c989fb346e583fd16b7ff7313 [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;
Zheng Bao5ca13432022-10-16 20:18:40 +0800109 uint8_t instance = 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800110
111 if (strcmp(fw_name, "PSPBTLDR_WL_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800112 if (cb_config->have_whitelist) {
Nikolai Vyssotski1965f6502021-05-06 22:15:36 -0500113 fw_type = AMD_FW_PSP_BOOTLOADER_AB;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800114 subprog = 0;
115 } else {
116 fw_type = AMD_FW_SKIP;
117 }
Zheng Bao990d1542021-09-17 13:24:54 +0800118 } 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;
124 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800125 } else if (strcmp(fw_name, "PSPBTLDR_FILE") == 0) {
Zheng Bao990d1542021-09-17 13:24:54 +0800126 if (!cb_config->recovery_ab) {
127 fw_type = AMD_FW_PSP_BOOTLOADER;
128 subprog = 0;
129 } else {
130 fw_type = AMD_FW_SKIP;
131 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800132 } 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;
Zheng Baobf29a0d2020-12-03 23:00:48 +0800156 } else if (strcmp(fw_name, "PSP_HW_IPCFG_FILE") == 0) {
157 fw_type = AMD_HW_IPCFG;
158 subprog = 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800159 } 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_SEC_DBG_KEY_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800175 if (cb_config->unlock_secure) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800176 fw_type = AMD_FW_PSP_SECURED_DEBUG;
177 subprog = 0;
178 } else {
179 fw_type = AMD_FW_SKIP;
180 }
181 } else if (strcmp(fw_name, "PSP_SEC_DEBUG_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800182 if (cb_config->unlock_secure) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800183 fw_type = AMD_DEBUG_UNLOCK;
184 subprog = 0;
185 } else {
186 fw_type = AMD_FW_SKIP;
187 }
188 } else if (strcmp(fw_name, "PSP_ABL0_FILE") == 0) {
189 fw_type = AMD_ABL0;
190 subprog = 0;
191 } else if (strcmp(fw_name, "PSP_ABL1_FILE") == 0) {
192 fw_type = AMD_ABL1;
193 subprog = 0;
194 } else if (strcmp(fw_name, "PSP_ABL2_FILE") == 0) {
195 fw_type = AMD_ABL2;
196 subprog = 0;
197 } else if (strcmp(fw_name, "PSP_ABL3_FILE") == 0) {
198 fw_type = AMD_ABL3;
199 subprog = 0;
200 } else if (strcmp(fw_name, "PSP_ABL4_FILE") == 0) {
201 fw_type = AMD_ABL4;
202 subprog = 0;
203 } else if (strcmp(fw_name, "PSP_ABL5_FILE") == 0) {
204 fw_type = AMD_ABL5;
205 subprog = 0;
206 } else if (strcmp(fw_name, "PSP_ABL6_FILE") == 0) {
207 fw_type = AMD_ABL6;
208 subprog = 0;
209 } else if (strcmp(fw_name, "PSP_ABL7_FILE") == 0) {
210 fw_type = AMD_ABL7;
211 subprog = 0;
212 } else if (strcmp(fw_name, "PSPSECUREOS_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800213 if (cb_config->use_secureos) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800214 fw_type = AMD_FW_PSP_SECURED_OS;
215 subprog = 0;
216 } else {
217 fw_type = AMD_FW_SKIP;
218 }
219 } else if (strcmp(fw_name, "PSPTRUSTLETS_FILE") == 0) {
220 if (cb_config->use_secureos) {
221 fw_type = AMD_FW_PSP_TRUSTLETS;
222 subprog = 0;
223 } else {
224 fw_type = AMD_FW_SKIP;
225 }
226 } else if (strcmp(fw_name, "TRUSTLETKEY_FILE") == 0) {
227 if (cb_config->use_secureos) {
228 fw_type = AMD_FW_PSP_TRUSTLETKEY;
229 subprog = 0;
230 } else {
231 fw_type = AMD_FW_SKIP;
232 }
233 } else if (strcmp(fw_name, "PSP_IKEK_FILE") == 0) {
234 fw_type = AMD_WRAPPED_IKEK;
235 subprog = 0;
Zheng Baobf29a0d2020-12-03 23:00:48 +0800236 } else if (strcmp(fw_name, "PSP_SECG0_FILE") == 0) {
237 fw_type = AMD_SEC_GASKET;
238 subprog = 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800239 } else if (strcmp(fw_name, "PSP_SECG1_FILE") == 0) {
240 fw_type = AMD_SEC_GASKET;
241 subprog = 1;
242 } else if (strcmp(fw_name, "PSP_SECG2_FILE") == 0) {
243 fw_type = AMD_SEC_GASKET;
244 subprog = 2;
Zheng Baobf29a0d2020-12-03 23:00:48 +0800245 } else if (strcmp(fw_name, "PSP_MP2FW0_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800246 if (cb_config->load_mp2_fw) {
Zheng Baobf29a0d2020-12-03 23:00:48 +0800247 fw_type = AMD_MP2_FW;
248 subprog = 0;
249 } else {
250 fw_type = AMD_FW_SKIP;
251 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800252 } else if (strcmp(fw_name, "PSP_MP2FW1_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800253 if (cb_config->load_mp2_fw) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800254 fw_type = AMD_MP2_FW;
255 subprog = 1;
256 } else {
257 fw_type = AMD_FW_SKIP;
258 }
259 } else if (strcmp(fw_name, "PSP_MP2FW2_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800260 if (cb_config->load_mp2_fw) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800261 fw_type = AMD_MP2_FW;
262 subprog = 2;
263 } else {
264 fw_type = AMD_FW_SKIP;
265 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800266 } else if (strcmp(fw_name, "PSP_DRIVERS_FILE") == 0) {
267 fw_type = AMD_DRIVER_ENTRIES;
268 subprog = 0;
269 } else if (strcmp(fw_name, "PSP_S0I3_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800270 if (cb_config->s0i3) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800271 fw_type = AMD_S0I3_DRIVER;
272 subprog = 0;
273 } else {
274 fw_type = AMD_FW_SKIP;
275 }
Zheng Baobf29a0d2020-12-03 23:00:48 +0800276 } else if (strcmp(fw_name, "AMD_DRIVER_ENTRIES") == 0) {
277 fw_type = AMD_DRIVER_ENTRIES;
278 subprog = 0;
279 } else if (strcmp(fw_name, "VBIOS_BTLOADER_FILE") == 0) {
280 fw_type = AMD_VBIOS_BTLOADER;
281 subprog = 0;
282 } else if (strcmp(fw_name, "SECURE_POLICY_L1_FILE") == 0) {
283 fw_type = AMD_FW_TOS_SEC_POLICY;
284 subprog = 0;
285 } else if (strcmp(fw_name, "UNIFIEDUSB_FILE") == 0) {
286 fw_type = AMD_FW_USB_PHY;
287 subprog = 0;
288 } else if (strcmp(fw_name, "DRTMTA_FILE") == 0) {
289 fw_type = AMD_FW_DRTM_TA;
290 subprog = 0;
291 } else if (strcmp(fw_name, "KEYDBBL_FILE") == 0) {
292 fw_type = AMD_FW_KEYDB_BL;
293 subprog = 0;
294 } else if (strcmp(fw_name, "KEYDB_TOS_FILE") == 0) {
295 fw_type = AMD_FW_KEYDB_TOS;
296 subprog = 0;
Zheng Baoab84fd72022-01-27 22:38:27 +0800297 } else if (strcmp(fw_name, "SPL_TABLE_FILE") == 0) {
Zheng Bao6c5ec8e2022-02-11 11:51:26 +0800298 if (cb_config->have_mb_spl) {
Felix Held11b0d362022-04-02 03:49:07 +0200299 fw_type = AMD_FW_SKIP;
300 } else {
Zheng Bao6c5ec8e2022-02-11 11:51:26 +0800301 fw_type = AMD_FW_SPL;
302 subprog = 0;
Zheng Bao6c5ec8e2022-02-11 11:51:26 +0800303 }
Zheng Baobf29a0d2020-12-03 23:00:48 +0800304 } else if (strcmp(fw_name, "DMCUERAMDCN21_FILE") == 0) {
305 fw_type = AMD_FW_DMCU_ERAM;
306 subprog = 0;
307 } else if (strcmp(fw_name, "DMCUINTVECTORSDCN21_FILE") == 0) {
308 fw_type = AMD_FW_DMCU_ISR;
309 subprog = 0;
Felix Held5f18bb72022-03-24 02:04:51 +0100310 } else if (strcmp(fw_name, "MSMU_FILE") == 0) {
311 fw_type = AMD_FW_MSMU;
312 subprog = 0;
313 } else if (strcmp(fw_name, "DMCUB_FILE") == 0) {
314 fw_type = AMD_FW_DMCUB;
315 subprog = 0;
316 } else if (strcmp(fw_name, "SPIROM_CONFIG_FILE") == 0) {
317 fw_type = AMD_FW_SPIROM_CFG;
318 subprog = 0;
Zheng Baobf29a0d2020-12-03 23:00:48 +0800319 } else if (strcmp(fw_name, "PSP_KVM_ENGINE_DUMMY_FILE") == 0) {
320 fw_type = AMD_FW_KVM_IMAGE;
321 subprog = 0;
322 } else if (strcmp(fw_name, "RPMC_FILE") == 0) {
323 fw_type = AMD_RPMC_NVRAM;
324 subprog = 0;
Zheng Baob993cb22021-02-02 18:48:23 +0800325 } else if (strcmp(fw_name, "PSPBTLDR_AB_FILE") == 0) {
Zheng Bao990d1542021-09-17 13:24:54 +0800326 if (!cb_config->have_whitelist || cb_config->recovery_ab) {
Nikolai Vyssotski1965f6502021-05-06 22:15:36 -0500327 fw_type = AMD_FW_PSP_BOOTLOADER_AB;
328 subprog = 0;
329 } else {
330 fw_type = AMD_FW_SKIP;
331 }
Karthikeyan Ramasubramanian0ab04d22022-05-03 18:16:34 -0600332 } else if (strcmp(fw_name, "TA_IKEK_FILE") == 0) {
333 fw_type = AMD_TA_IKEK;
334 subprog = 0;
Arthur Heymans1f05c802022-10-04 17:50:21 +0200335 } else if (strcmp(fw_name, "PSP_OEM_ABL_KEY_FILE") == 0) {
336 fw_type = AMD_FW_ABL_PUBKEY;
337 subprog = 0;
338 } else if (strcmp(fw_name, "PSP_MP5FW_SUB0_FILE") == 0) {
339 fw_type = AMD_FW_MP5;
340 subprog = 0;
341 } else if (strcmp(fw_name, "PSP_MP5FW_SUB1_FILE") == 0) {
342 fw_type = AMD_FW_MP5;
343 subprog = 1;
344 } else if (strcmp(fw_name, "PSP_MP5FW_SUB2_FILE") == 0) {
345 fw_type = AMD_FW_MP5;
346 subprog = 2;
347 } else if (strcmp(fw_name, "PSP_DXIOFW_FILE") == 0) {
348 fw_type = AMD_FW_DXIO;
349 subprog = 0;
350 } else if (strcmp(fw_name, "PSP_MPIOFW_FILE") == 0) {
351 fw_type = AMD_FW_MPIO;
352 subprog = 0;
353 } else if (strcmp(fw_name, "PSP_RIB_FILE") == 0) {
354 fw_type = AMD_RIB;
355 subprog = 0;
356 } else if (strcmp(fw_name, "PSP_MPDMATFFW_FILE") == 0) {
357 fw_type = AMD_FW_MPDMA_TF;
358 subprog = 0;
359 } else if (strcmp(fw_name, "PSP_GMI3PHYFW_FILE") == 0) {
360 fw_type = AMD_FW_GMI3_PHY;
361 subprog = 0;
362 } else if (strcmp(fw_name, "PSP_MPDMAPMFW_FILE") == 0) {
363 fw_type = AMD_FW_MPDMA_PM;
364 subprog = 0;
365 } else if (strcmp(fw_name, "PSP_TOKEN_UNLOCK_FILE") == 0) {
366 fw_type = AMD_TOKEN_UNLOCK;
367 subprog = 0;
368 } else if (strcmp(fw_name, "SEV_DATA_FILE") == 0) {
369 fw_type = AMD_SEV_DATA;
370 subprog = 0;
371 } else if (strcmp(fw_name, "SEV_CODE_FILE") == 0) {
372 fw_type = AMD_SEV_CODE;
373 subprog = 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800374 } else {
375 fw_type = AMD_FW_INVALID;
376 /* TODO: Add more */
377 }
Zheng Baobf29a0d2020-12-03 23:00:48 +0800378
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800379 /* Search and fill the filename */
380 psp_tableptr = &amd_psp_fw_table[0];
381 if (fw_type != AMD_FW_SKIP && fw_type != AMD_FW_INVALID) {
382 while (psp_tableptr->type != AMD_FW_INVALID) {
383 /* instance are not used in PSP table */
Zheng Bao5ca13432022-10-16 20:18:40 +0800384 if (psp_tableptr->type == fw_type && psp_tableptr->subprog == subprog
385 && psp_tableptr->inst == instance) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800386 psp_tableptr->filename = filename;
Zheng Bao990d1542021-09-17 13:24:54 +0800387 SET_LEVEL(psp_tableptr, level_to_set, PSP,
388 cb_config->recovery_ab);
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800389 break;
390 }
391 psp_tableptr++;
392 }
393 }
394 if (fw_type == AMD_FW_INVALID)
395 return 0;
396 else
397 return 1;
398}
Zheng Bao1a9e5432022-02-17 17:48:27 +0800399#define PMUI_STR_BASE "PSP_PMUI_FILE"
400#define PMUD_STR_BASE "PSP_PMUD_FILE"
401#define PMU_STR_BASE_LEN strlen(PMUI_STR_BASE)
402#define PMU_STR_SUB_INDEX strlen(PMUI_STR_BASE"_SUB")
403#define PMU_STR_INS_INDEX strlen(PMUI_STR_BASE"_SUBx_INS")
Zheng Baofdb02942022-02-22 09:47:59 +0800404#define PMU_STR_ALL_LEN strlen(PMUI_STR_BASE"_SUBx_INSx")
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800405
406static uint8_t find_register_fw_filename_bios_dir(char *fw_name, char *filename,
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800407 char level_to_set, amd_cb_config *cb_config)
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800408{
409 amd_bios_type fw_type = AMD_BIOS_INVALID;
410 amd_bios_entry *bhd_tableptr;
Felix Heldea3417b2020-11-20 20:08:42 +0100411 uint8_t subprog = 0;
412 uint8_t instance = 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800413
414 (void) (cb_config); /* Remove warning and reserved for future. */
415
Zheng Bao1a9e5432022-02-17 17:48:27 +0800416 if (strncmp(fw_name, PMUI_STR_BASE, PMU_STR_BASE_LEN) == 0) {
Zheng Baofdb02942022-02-22 09:47:59 +0800417 assert(strlen(fw_name) == PMU_STR_ALL_LEN);
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800418 fw_type = AMD_BIOS_PMUI;
Felix Held3dfb4852022-09-28 18:00:39 +0200419 subprog = strtol(&fw_name[PMU_STR_SUB_INDEX], NULL, 16);
420 instance = strtol(&fw_name[PMU_STR_INS_INDEX], NULL, 16);
Zheng Bao1a9e5432022-02-17 17:48:27 +0800421 } else if (strncmp(fw_name, PMUD_STR_BASE, PMU_STR_BASE_LEN) == 0) {
Zheng Baofdb02942022-02-22 09:47:59 +0800422 assert(strlen(fw_name) == PMU_STR_ALL_LEN);
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800423 fw_type = AMD_BIOS_PMUD;
Felix Held3dfb4852022-09-28 18:00:39 +0200424 subprog = strtol(&fw_name[PMU_STR_SUB_INDEX], NULL, 16);
425 instance = strtol(&fw_name[PMU_STR_INS_INDEX], NULL, 16);
Zheng Baobf29a0d2020-12-03 23:00:48 +0800426 } else if (strcmp(fw_name, "RTM_PUBKEY_FILE") == 0) {
427 fw_type = AMD_BIOS_RTM_PUBKEY;
428 subprog = 0;
429 instance = 0;
Zheng Bao50143732020-11-14 21:54:06 +0800430 } else if (strcmp(fw_name, "PSP_MP2CFG_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800431 if (cb_config->load_mp2_fw) {
Zheng Bao50143732020-11-14 21:54:06 +0800432 fw_type = AMD_BIOS_MP2_CFG;
433 subprog = 0;
434 } else {
Martin Rotha8e31ca2021-02-13 21:42:46 -0700435 fw_type = AMD_BIOS_SKIP;
Zheng Bao50143732020-11-14 21:54:06 +0800436 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800437 } else {
438 fw_type = AMD_BIOS_INVALID;
439 }
440
441 bhd_tableptr = amd_bios_table;
442
443 if (fw_type != AMD_BIOS_INVALID && fw_type != AMD_BIOS_SKIP) {
444 while (bhd_tableptr->type != AMD_BIOS_INVALID) {
445 if (bhd_tableptr->type == fw_type &&
446 bhd_tableptr->subpr == subprog &&
447 bhd_tableptr->inst == instance) {
448 bhd_tableptr->filename = filename;
Zheng Bao990d1542021-09-17 13:24:54 +0800449 SET_LEVEL(bhd_tableptr, level_to_set, BDT,
450 cb_config->recovery_ab);
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800451 break;
452 }
453 bhd_tableptr++;
454 }
455 }
456 if (fw_type == AMD_BIOS_INVALID)
457 return 0;
458 else
459 return 1;
460}
461
462#define MAX_LINE_SIZE 1024
463
464int get_input_file_line(FILE *f, char line[], int line_buf_size)
465{
466 if (fgets(line, line_buf_size, f) == NULL)
467 return LINE_EOF;
468
469 /* If the file contains a line that is too long, then it's best
470 * to let the user know right away rather than passing back a
471 * truncated result that will lead to problems later on.
472 */
473 line[strlen(line) - 1] = '\0';
474
475 if (strlen(line) == ((size_t) (line_buf_size - 1))) {
Zheng Bao77a2c672020-10-01 17:05:43 +0800476 fprintf(stderr, "The line size in config file should be lower than %d bytes.\n",
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800477 MAX_LINE_SIZE);
478 exit(1);
479 }
480
481 return OK;
482}
483
Zheng Bao4df5af82022-03-01 17:18:00 +0800484#define N_MATCHES 4
485static int is_valid_entry(char *oneline, regmatch_t match[N_MATCHES])
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800486{
Zheng Bao4df5af82022-03-01 17:18:00 +0800487 int retval, index;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800488
Zheng Bao4df5af82022-03-01 17:18:00 +0800489 for (index = 0; index < N_MATCHES; index++) {
490 match[index].rm_so = -1;
491 match[index].rm_eo = -1;
492 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800493 if (regexec(&entries_line_expr, oneline, 3, match, 0) == 0) {
494 oneline[match[1].rm_eo] = '\0';
495 oneline[match[2].rm_eo] = '\0';
496 retval = 1;
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800497 } else if (regexec(&entries_lvl_line_expr, oneline, 4, match, 0) == 0) {
498 /* match[1]: FW type
499 match[2]: FW filename
500 match[3]: Directory level to be dropped
501 */
502 oneline[match[1].rm_eo] = '\0';
503 oneline[match[2].rm_eo] = '\0';
504 oneline[match[3].rm_eo] = '\0';
505 retval = 1;
506 } else {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800507 retval = 0;
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800508 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800509
510 return retval;
511}
512
513static int skip_comment_blank_line(char *oneline)
514{
515 int retval;
516
517 if (regexec(&blank_or_comment_expr, oneline, 0, NULL, 0) == 0) {
518 /* skip comment and blank */
519 retval = 1;
520 } else {
521 /* no match */
522 retval = 0;
523 }
524
525 return retval;
526}
527
Zheng Bao52a18982022-03-01 17:22:52 +0800528char get_level_from_config(char *line, regoff_t level_index, amd_cb_config *cb_config)
529{
530 char lvl = 'x';
531 /* If the optional level field is present,
532 extract the level char. */
533 if (level_index != -1) {
534 if (cb_config->recovery_ab == 0)
535 lvl = line[level_index + 1];
536 else if (strlen(&line[level_index]) >= 3)
537 lvl = line[level_index + 2];
538 }
539
540 assert(lvl == 'x' || lvl == 'X' ||
541 lvl == 'b' || lvl == 'B' ||
542 lvl == '1' || lvl == '2');
543
544 return lvl;
545}
546
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800547/*
548 return value:
549 0: The config file can not be parsed correctly.
550 1: The config file can be parsed correctly.
551 */
552uint8_t process_config(FILE *config, amd_cb_config *cb_config, uint8_t print_deps)
553{
554 char oneline[MAX_LINE_SIZE], *path_filename;
Zheng Bao4df5af82022-03-01 17:18:00 +0800555 regmatch_t match[N_MATCHES];
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800556 char dir[MAX_LINE_SIZE] = {'\0'};
Zheng Baodac44612021-05-27 11:11:34 +0800557 uint32_t dir_len;
Zheng Bao4df5af82022-03-01 17:18:00 +0800558 int index;
559
560 for (index = 0; index < N_MATCHES; index++) {
561 match[index].rm_so = -1;
562 match[index].rm_eo = -1;
563 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800564
565 compile_reg_expr(REG_EXTENDED | REG_NEWLINE,
566 blank_or_comment_regex, &blank_or_comment_expr);
567 compile_reg_expr(REG_EXTENDED | REG_NEWLINE,
568 entries_line_regex, &entries_line_expr);
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800569 compile_reg_expr(REG_EXTENDED | REG_NEWLINE,
570 entries_lvl_line_regex, &entries_lvl_line_expr);
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800571
572 /* Get a line */
Zheng Bao3384e4a2020-10-06 12:03:11 +0800573 /* Get FIRMWARE_LOCATION in the first loop */
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800574 while (get_input_file_line(config, oneline, MAX_LINE_SIZE) == OK) {
575 /* get a line */
576 if (skip_comment_blank_line(oneline))
577 continue;
578 if (is_valid_entry(oneline, match)) {
Zheng Bao3384e4a2020-10-06 12:03:11 +0800579 if (strcmp(&(oneline[match[1].rm_so]), "FIRMWARE_LOCATION") == 0) {
Zheng Baodac44612021-05-27 11:11:34 +0800580 dir_len = match[2].rm_eo - match[2].rm_so;
581 assert(dir_len < MAX_LINE_SIZE);
582 snprintf(dir, MAX_LINE_SIZE, "%.*s", dir_len,
583 &(oneline[match[2].rm_so]));
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800584 break;
585 }
586 }
587 }
588
589 if (dir[0] == '\0') {
590 fprintf(stderr, "No line with FIRMWARE_LOCATION\n");
591 return 0;
592 }
593
594 fseek(config, 0, SEEK_SET);
595 /* Get a line */
596 while (get_input_file_line(config, oneline, MAX_LINE_SIZE) == OK) {
597 /* get a line */
598 if (skip_comment_blank_line(oneline))
599 continue;
600 if (is_valid_entry(oneline, match)) {
Zheng Bao3384e4a2020-10-06 12:03:11 +0800601 if (strcmp(&(oneline[match[1].rm_so]), "FIRMWARE_LOCATION") == 0) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800602 continue;
603 } else {
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800604 char ch_lvl = 'x';
Zheng Baodac44612021-05-27 11:11:34 +0800605 path_filename = malloc(MAX_LINE_SIZE * 2 + 2);
606 snprintf(path_filename, MAX_LINE_SIZE * 2 + 2, "%.*s/%.*s",
607 MAX_LINE_SIZE, dir, MAX_LINE_SIZE,
608 &(oneline[match[2].rm_so]));
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800609
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800610 /* If the optional level field is present,
611 extract the level char. */
Zheng Bao52a18982022-03-01 17:22:52 +0800612 ch_lvl = get_level_from_config(oneline,
613 match[3].rm_so, cb_config);
Zheng Bao4df5af82022-03-01 17:18:00 +0800614
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800615 if (find_register_fw_filename_psp_dir(
616 &(oneline[match[1].rm_so]),
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800617 path_filename, ch_lvl, cb_config) == 0) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800618 if (find_register_fw_filename_bios_dir(
619 &(oneline[match[1].rm_so]),
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800620 path_filename, ch_lvl, cb_config)
621 == 0) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800622 fprintf(stderr, "Module's name \"%s\" is not valid\n", oneline);
623 return 0; /* Stop parsing. */
624 } else {
625 if (print_deps)
626 printf(" %s ", path_filename);
627 }
628 } else {
629 if (print_deps)
630 printf(" %s ", path_filename);
631 }
632 }
633 } else {
634 fprintf(stderr, "AMDFWTOOL config file line can't be parsed \"%s\"\n", oneline);
635 return 0;
636 }
637 }
638 return 1;
639}