blob: 50f844fa674b3a6620364dc24428f224524b6d02 [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 Bao010cc992023-01-25 22:58:49 +080081static enum platform identify_platform(char *soc_name)
82{
83 if (!strcasecmp(soc_name, "Stoneyridge"))
84 return PLATFORM_STONEYRIDGE;
85 else if (!strcasecmp(soc_name, "Carrizo"))
86 return PLATFORM_CARRIZO;
87 else if (!strcasecmp(soc_name, "Raven"))
88 return PLATFORM_RAVEN;
89 else if (!strcasecmp(soc_name, "Picasso"))
90 return PLATFORM_PICASSO;
91 else if (!strcasecmp(soc_name, "Cezanne"))
92 return PLATFORM_CEZANNE;
93 else if (!strcasecmp(soc_name, "Mendocino"))
94 return PLATFORM_MENDOCINO;
95 else if (!strcasecmp(soc_name, "Renoir"))
96 return PLATFORM_RENOIR;
97 else if (!strcasecmp(soc_name, "Lucienne"))
98 return PLATFORM_LUCIENNE;
99 else if (!strcasecmp(soc_name, "Phoenix"))
100 return PLATFORM_PHOENIX;
101 else if (!strcasecmp(soc_name, "Glinda"))
102 return PLATFORM_GLINDA;
103 else
104 return PLATFORM_UNKNOWN;
105}
106
Zheng Bao990d1542021-09-17 13:24:54 +0800107#define SET_LEVEL(tableptr, l, TABLE, ab) \
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800108 do { \
109 switch ((l)) { \
110 case '1': \
Zheng Bao990d1542021-09-17 13:24:54 +0800111 (tableptr)->level = ab ? TABLE##_LVL1_AB : TABLE##_LVL1; \
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800112 break; \
113 case '2': \
Zheng Bao990d1542021-09-17 13:24:54 +0800114 (tableptr)->level = ab ? TABLE##_LVL2_AB : TABLE##_LVL2; \
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800115 break; \
116 case 'b': \
117 case 'B': \
Zheng Bao990d1542021-09-17 13:24:54 +0800118 (tableptr)->level = ab ? TABLE##_BOTH_AB : TABLE##_BOTH; \
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800119 break; \
120 default: \
121 /* use default value */ \
122 break; \
123 } \
124 } while (0)
125
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800126extern amd_fw_entry amd_psp_fw_table[];
127extern amd_bios_entry amd_bios_table[];
128
129static uint8_t find_register_fw_filename_psp_dir(char *fw_name, char *filename,
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800130 char level_to_set, amd_cb_config *cb_config)
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800131{
132 amd_fw_type fw_type = AMD_FW_INVALID;
133 amd_fw_entry *psp_tableptr;
134 uint8_t subprog;
Zheng Bao5ca13432022-10-16 20:18:40 +0800135 uint8_t instance = 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800136
137 if (strcmp(fw_name, "PSPBTLDR_WL_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800138 if (cb_config->have_whitelist) {
Nikolai Vyssotski1965f6502021-05-06 22:15:36 -0500139 fw_type = AMD_FW_PSP_BOOTLOADER_AB;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800140 subprog = 0;
141 } else {
142 fw_type = AMD_FW_SKIP;
143 }
Zheng Bao990d1542021-09-17 13:24:54 +0800144 } else if (strcmp(fw_name, "PSPBTLDR_AB_STAGE1_FILE") == 0) {
145 if (cb_config->recovery_ab) {
146 fw_type = AMD_FW_PSP_BOOTLOADER;
147 subprog = 0;
148 } else {
149 fw_type = AMD_FW_SKIP;
150 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800151 } else if (strcmp(fw_name, "PSPBTLDR_FILE") == 0) {
Zheng Bao990d1542021-09-17 13:24:54 +0800152 if (!cb_config->recovery_ab) {
153 fw_type = AMD_FW_PSP_BOOTLOADER;
154 subprog = 0;
155 } else {
156 fw_type = AMD_FW_SKIP;
157 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800158 } else if (strcmp(fw_name, "AMD_PUBKEY_FILE") == 0) {
159 fw_type = AMD_FW_PSP_PUBKEY;
160 subprog = 0;
161 } else if (strcmp(fw_name, "PSPRCVR_FILE") == 0) {
162 fw_type = AMD_FW_PSP_RECOVERY;
163 subprog = 0;
164 } else if (strcmp(fw_name, "PUBSIGNEDKEY_FILE") == 0) {
165 fw_type = AMD_FW_PSP_RTM_PUBKEY;
166 subprog = 0;
167 } else if (strcmp(fw_name, "PSPNVRAM_FILE") == 0) {
168 fw_type = AMD_FW_PSP_NVRAM;
169 subprog = 0;
170 } else if (strcmp(fw_name, "SMUSCS_FILE") == 0) {
171 fw_type = AMD_FW_PSP_SMUSCS;
172 subprog = 0;
173 } else if (strcmp(fw_name, "PSPTRUSTLETS_FILE") == 0) {
174 fw_type = AMD_FW_PSP_TRUSTLETS;
175 subprog = 0;
176 } else if (strcmp(fw_name, "PSPSECUREDEBUG_FILE") == 0) {
177 fw_type = AMD_FW_PSP_SECURED_DEBUG;
178 subprog = 0;
179 } else if (strcmp(fw_name, "PSP_SMUFW1_SUB0_FILE") == 0) {
180 fw_type = AMD_FW_PSP_SMU_FIRMWARE;
181 subprog = 0;
Zheng Bao9bb62cb2023-03-07 19:48:11 +0800182 } else if (strcmp(fw_name, "PSP_HW_IPCFG_FILE_SUB0") == 0) {
Zheng Baobf29a0d2020-12-03 23:00:48 +0800183 fw_type = AMD_HW_IPCFG;
184 subprog = 0;
Zheng Bao9bb62cb2023-03-07 19:48:11 +0800185 } else if (strcmp(fw_name, "PSP_HW_IPCFG_FILE_SUB1") == 0) {
186 fw_type = AMD_HW_IPCFG;
187 subprog = 1;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800188 } else if (strcmp(fw_name, "PSP_SMUFW1_SUB1_FILE") == 0) {
189 fw_type = AMD_FW_PSP_SMU_FIRMWARE;
190 subprog = 1;
191 } else if (strcmp(fw_name, "PSP_SMUFW1_SUB2_FILE") == 0) {
192 fw_type = AMD_FW_PSP_SMU_FIRMWARE;
193 subprog = 2;
194 } else if (strcmp(fw_name, "PSP_SMUFW2_SUB0_FILE") == 0) {
195 fw_type = AMD_FW_PSP_SMU_FIRMWARE2;
196 subprog = 0;
197 } else if (strcmp(fw_name, "PSP_SMUFW2_SUB1_FILE") == 0) {
198 fw_type = AMD_FW_PSP_SMU_FIRMWARE2;
199 subprog = 1;
200 } else if (strcmp(fw_name, "PSP_SMUFW2_SUB2_FILE") == 0) {
201 fw_type = AMD_FW_PSP_SMU_FIRMWARE2;
202 subprog = 2;
Zheng Bao8eba6622022-10-16 20:29:03 +0800203 } else if (strcmp(fw_name, "PSP_BOOT_DRIVER_FILE") == 0) {
204 fw_type = AMD_BOOT_DRIVER;
205 subprog = 0;
206 } else if (strcmp(fw_name, "PSP_SOC_DRIVER_FILE") == 0) {
207 fw_type = AMD_SOC_DRIVER;
208 subprog = 0;
209 } else if (strcmp(fw_name, "PSP_DEBUG_DRIVER_FILE") == 0) {
210 fw_type = AMD_DEBUG_DRIVER;
211 subprog = 0;
212 } else if (strcmp(fw_name, "PSP_INTERFACE_DRIVER_FILE") == 0) {
213 fw_type = AMD_INTERFACE_DRIVER;
214 subprog = 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800215 } else if (strcmp(fw_name, "PSP_SEC_DBG_KEY_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800216 if (cb_config->unlock_secure) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800217 fw_type = AMD_FW_PSP_SECURED_DEBUG;
218 subprog = 0;
219 } else {
220 fw_type = AMD_FW_SKIP;
221 }
222 } else if (strcmp(fw_name, "PSP_SEC_DEBUG_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800223 if (cb_config->unlock_secure) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800224 fw_type = AMD_DEBUG_UNLOCK;
225 subprog = 0;
226 } else {
227 fw_type = AMD_FW_SKIP;
228 }
229 } else if (strcmp(fw_name, "PSP_ABL0_FILE") == 0) {
230 fw_type = AMD_ABL0;
231 subprog = 0;
232 } else if (strcmp(fw_name, "PSP_ABL1_FILE") == 0) {
233 fw_type = AMD_ABL1;
234 subprog = 0;
235 } else if (strcmp(fw_name, "PSP_ABL2_FILE") == 0) {
236 fw_type = AMD_ABL2;
237 subprog = 0;
238 } else if (strcmp(fw_name, "PSP_ABL3_FILE") == 0) {
239 fw_type = AMD_ABL3;
240 subprog = 0;
241 } else if (strcmp(fw_name, "PSP_ABL4_FILE") == 0) {
242 fw_type = AMD_ABL4;
243 subprog = 0;
244 } else if (strcmp(fw_name, "PSP_ABL5_FILE") == 0) {
245 fw_type = AMD_ABL5;
246 subprog = 0;
247 } else if (strcmp(fw_name, "PSP_ABL6_FILE") == 0) {
248 fw_type = AMD_ABL6;
249 subprog = 0;
250 } else if (strcmp(fw_name, "PSP_ABL7_FILE") == 0) {
251 fw_type = AMD_ABL7;
252 subprog = 0;
253 } else if (strcmp(fw_name, "PSPSECUREOS_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800254 if (cb_config->use_secureos) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800255 fw_type = AMD_FW_PSP_SECURED_OS;
256 subprog = 0;
257 } else {
258 fw_type = AMD_FW_SKIP;
259 }
260 } else if (strcmp(fw_name, "PSPTRUSTLETS_FILE") == 0) {
261 if (cb_config->use_secureos) {
262 fw_type = AMD_FW_PSP_TRUSTLETS;
263 subprog = 0;
264 } else {
265 fw_type = AMD_FW_SKIP;
266 }
267 } else if (strcmp(fw_name, "TRUSTLETKEY_FILE") == 0) {
268 if (cb_config->use_secureos) {
269 fw_type = AMD_FW_PSP_TRUSTLETKEY;
270 subprog = 0;
271 } else {
272 fw_type = AMD_FW_SKIP;
273 }
274 } else if (strcmp(fw_name, "PSP_IKEK_FILE") == 0) {
275 fw_type = AMD_WRAPPED_IKEK;
276 subprog = 0;
Zheng Baobf29a0d2020-12-03 23:00:48 +0800277 } else if (strcmp(fw_name, "PSP_SECG0_FILE") == 0) {
278 fw_type = AMD_SEC_GASKET;
279 subprog = 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800280 } else if (strcmp(fw_name, "PSP_SECG1_FILE") == 0) {
281 fw_type = AMD_SEC_GASKET;
282 subprog = 1;
283 } else if (strcmp(fw_name, "PSP_SECG2_FILE") == 0) {
284 fw_type = AMD_SEC_GASKET;
285 subprog = 2;
Zheng Baobf29a0d2020-12-03 23:00:48 +0800286 } else if (strcmp(fw_name, "PSP_MP2FW0_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800287 if (cb_config->load_mp2_fw) {
Zheng Baobf29a0d2020-12-03 23:00:48 +0800288 fw_type = AMD_MP2_FW;
289 subprog = 0;
290 } else {
291 fw_type = AMD_FW_SKIP;
292 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800293 } else if (strcmp(fw_name, "PSP_MP2FW1_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800294 if (cb_config->load_mp2_fw) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800295 fw_type = AMD_MP2_FW;
296 subprog = 1;
297 } else {
298 fw_type = AMD_FW_SKIP;
299 }
300 } else if (strcmp(fw_name, "PSP_MP2FW2_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800301 if (cb_config->load_mp2_fw) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800302 fw_type = AMD_MP2_FW;
303 subprog = 2;
304 } else {
305 fw_type = AMD_FW_SKIP;
306 }
Zheng Bao8eba6622022-10-16 20:29:03 +0800307 } else if (strcmp(fw_name, "PSP_C20MP_FILE") == 0) {
308 fw_type = AMD_FW_C20_MP;
309 subprog = 0;
Zheng Bao8eba6622022-10-16 20:29:03 +0800310 } else if (strcmp(fw_name, "AMF_SRAM_FILE") == 0) {
311 fw_type = AMD_FW_AMF_SRAM;
312 subprog = 0;
313 } else if (strcmp(fw_name, "AMF_DRAM_FILE_INS0") == 0) {
314 fw_type = AMD_FW_AMF_DRAM;
315 subprog = 0;
316 instance = 0;
317 } else if (strcmp(fw_name, "AMF_DRAM_FILE_INS1") == 0) {
318 fw_type = AMD_FW_AMF_DRAM;
319 subprog = 0;
320 instance = 1;
321 } else if (strcmp(fw_name, "AMF_WLAN_FILE_INS0") == 0) {
322 fw_type = AMD_FW_AMF_WLAN;
323 subprog = 0;
324 instance = 0;
325 } else if (strcmp(fw_name, "AMF_WLAN_FILE_INS1") == 0) {
326 fw_type = AMD_FW_AMF_WLAN;
327 subprog = 0;
328 instance = 1;
329 } else if (strcmp(fw_name, "AMF_MFD_FILE") == 0) {
330 fw_type = AMD_FW_AMF_MFD;
331 subprog = 0;
332 } else if (strcmp(fw_name, "MPCCX_FILE") == 0) {
333 fw_type = AMD_FW_MPCCX;
334 subprog = 0;
335 } else if (strcmp(fw_name, "LSDMA_FILE") == 0) {
336 fw_type = AMD_FW_LSDMA;
337 subprog = 0;
338 } else if (strcmp(fw_name, "MINIMSMU_FILE") == 0) {
339 fw_type = AMD_FW_MINIMSMU;
340 instance = 0;
341 subprog = 0;
342 } else if (strcmp(fw_name, "MINIMSMU_FILE_INS1") == 0) {
343 fw_type = AMD_FW_MINIMSMU;
344 instance = 1;
345 subprog = 0;
346 } else if (strcmp(fw_name, "SRAM_FW_EXT_FILE") == 0) {
347 fw_type = AMD_FW_SRAM_FW_EXT;
348 subprog = 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800349 } else if (strcmp(fw_name, "PSP_DRIVERS_FILE") == 0) {
350 fw_type = AMD_DRIVER_ENTRIES;
351 subprog = 0;
352 } else if (strcmp(fw_name, "PSP_S0I3_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800353 if (cb_config->s0i3) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800354 fw_type = AMD_S0I3_DRIVER;
355 subprog = 0;
356 } else {
357 fw_type = AMD_FW_SKIP;
358 }
Zheng Baobf29a0d2020-12-03 23:00:48 +0800359 } else if (strcmp(fw_name, "AMD_DRIVER_ENTRIES") == 0) {
360 fw_type = AMD_DRIVER_ENTRIES;
361 subprog = 0;
362 } else if (strcmp(fw_name, "VBIOS_BTLOADER_FILE") == 0) {
363 fw_type = AMD_VBIOS_BTLOADER;
364 subprog = 0;
365 } else if (strcmp(fw_name, "SECURE_POLICY_L1_FILE") == 0) {
366 fw_type = AMD_FW_TOS_SEC_POLICY;
367 subprog = 0;
368 } else if (strcmp(fw_name, "UNIFIEDUSB_FILE") == 0) {
369 fw_type = AMD_FW_USB_PHY;
370 subprog = 0;
371 } else if (strcmp(fw_name, "DRTMTA_FILE") == 0) {
372 fw_type = AMD_FW_DRTM_TA;
373 subprog = 0;
374 } else if (strcmp(fw_name, "KEYDBBL_FILE") == 0) {
375 fw_type = AMD_FW_KEYDB_BL;
376 subprog = 0;
377 } else if (strcmp(fw_name, "KEYDB_TOS_FILE") == 0) {
378 fw_type = AMD_FW_KEYDB_TOS;
379 subprog = 0;
Zheng Baoab84fd72022-01-27 22:38:27 +0800380 } else if (strcmp(fw_name, "SPL_TABLE_FILE") == 0) {
Zheng Bao6c5ec8e2022-02-11 11:51:26 +0800381 if (cb_config->have_mb_spl) {
Felix Held11b0d362022-04-02 03:49:07 +0200382 fw_type = AMD_FW_SKIP;
383 } else {
Zheng Bao6c5ec8e2022-02-11 11:51:26 +0800384 fw_type = AMD_FW_SPL;
385 subprog = 0;
Zheng Bao6c5ec8e2022-02-11 11:51:26 +0800386 }
Zheng Baobf29a0d2020-12-03 23:00:48 +0800387 } else if (strcmp(fw_name, "DMCUERAMDCN21_FILE") == 0) {
388 fw_type = AMD_FW_DMCU_ERAM;
389 subprog = 0;
390 } else if (strcmp(fw_name, "DMCUINTVECTORSDCN21_FILE") == 0) {
391 fw_type = AMD_FW_DMCU_ISR;
392 subprog = 0;
Felix Held5f18bb72022-03-24 02:04:51 +0100393 } else if (strcmp(fw_name, "MSMU_FILE") == 0) {
394 fw_type = AMD_FW_MSMU;
395 subprog = 0;
396 } else if (strcmp(fw_name, "DMCUB_FILE") == 0) {
397 fw_type = AMD_FW_DMCUB;
398 subprog = 0;
399 } else if (strcmp(fw_name, "SPIROM_CONFIG_FILE") == 0) {
400 fw_type = AMD_FW_SPIROM_CFG;
401 subprog = 0;
Zheng Bao8eba6622022-10-16 20:29:03 +0800402 } else if (strcmp(fw_name, "MPIO_FILE") == 0) {
403 fw_type = AMD_FW_MPIO;
404 subprog = 0;
405 } else if (strcmp(fw_name, "TPMLITE_FILE") == 0) {
Zheng Bao8eba6622022-10-16 20:29:03 +0800406 fw_type = AMD_FW_TPMLITE;
407 subprog = 0;
Zheng Baobf29a0d2020-12-03 23:00:48 +0800408 } else if (strcmp(fw_name, "PSP_KVM_ENGINE_DUMMY_FILE") == 0) {
409 fw_type = AMD_FW_KVM_IMAGE;
410 subprog = 0;
411 } else if (strcmp(fw_name, "RPMC_FILE") == 0) {
412 fw_type = AMD_RPMC_NVRAM;
413 subprog = 0;
Zheng Baob993cb22021-02-02 18:48:23 +0800414 } else if (strcmp(fw_name, "PSPBTLDR_AB_FILE") == 0) {
Zheng Bao990d1542021-09-17 13:24:54 +0800415 if (!cb_config->have_whitelist || cb_config->recovery_ab) {
Nikolai Vyssotski1965f6502021-05-06 22:15:36 -0500416 fw_type = AMD_FW_PSP_BOOTLOADER_AB;
417 subprog = 0;
418 } else {
419 fw_type = AMD_FW_SKIP;
420 }
Karthikeyan Ramasubramanian0ab04d22022-05-03 18:16:34 -0600421 } else if (strcmp(fw_name, "TA_IKEK_FILE") == 0) {
422 fw_type = AMD_TA_IKEK;
423 subprog = 0;
Fred Reitbergerc4f3a332023-02-07 12:12:40 -0500424 } else if (strcmp(fw_name, "UMSMU_FILE") == 0) {
425 fw_type = AMD_FW_UMSMU;
426 subprog = 0;
Arthur Heymans1f05c802022-10-04 17:50:21 +0200427 } else if (strcmp(fw_name, "PSP_OEM_ABL_KEY_FILE") == 0) {
428 fw_type = AMD_FW_ABL_PUBKEY;
429 subprog = 0;
430 } else if (strcmp(fw_name, "PSP_MP5FW_SUB0_FILE") == 0) {
431 fw_type = AMD_FW_MP5;
432 subprog = 0;
433 } else if (strcmp(fw_name, "PSP_MP5FW_SUB1_FILE") == 0) {
434 fw_type = AMD_FW_MP5;
435 subprog = 1;
436 } else if (strcmp(fw_name, "PSP_MP5FW_SUB2_FILE") == 0) {
437 fw_type = AMD_FW_MP5;
438 subprog = 2;
439 } else if (strcmp(fw_name, "PSP_DXIOFW_FILE") == 0) {
440 fw_type = AMD_FW_DXIO;
441 subprog = 0;
442 } else if (strcmp(fw_name, "PSP_MPIOFW_FILE") == 0) {
443 fw_type = AMD_FW_MPIO;
444 subprog = 0;
Zheng Bao85ee1fd2023-01-30 13:52:30 +0800445 } else if (strcmp(fw_name, "PSP_RIB_FILE_SUB0") == 0) {
Arthur Heymans1f05c802022-10-04 17:50:21 +0200446 fw_type = AMD_RIB;
447 subprog = 0;
Zheng Bao85ee1fd2023-01-30 13:52:30 +0800448 } else if (strcmp(fw_name, "PSP_RIB_FILE_SUB1") == 0) {
449 fw_type = AMD_RIB;
450 subprog = 1;
Zheng Bao8eba6622022-10-16 20:29:03 +0800451 } else if (strcmp(fw_name, "FEATURE_TABLE_FILE") == 0) {
452 fw_type = AMD_FW_FCFG_TABLE;
453 subprog = 0;
Arthur Heymans1f05c802022-10-04 17:50:21 +0200454 } else if (strcmp(fw_name, "PSP_MPDMATFFW_FILE") == 0) {
455 fw_type = AMD_FW_MPDMA_TF;
456 subprog = 0;
457 } else if (strcmp(fw_name, "PSP_GMI3PHYFW_FILE") == 0) {
458 fw_type = AMD_FW_GMI3_PHY;
459 subprog = 0;
460 } else if (strcmp(fw_name, "PSP_MPDMAPMFW_FILE") == 0) {
461 fw_type = AMD_FW_MPDMA_PM;
462 subprog = 0;
463 } else if (strcmp(fw_name, "PSP_TOKEN_UNLOCK_FILE") == 0) {
464 fw_type = AMD_TOKEN_UNLOCK;
465 subprog = 0;
466 } else if (strcmp(fw_name, "SEV_DATA_FILE") == 0) {
467 fw_type = AMD_SEV_DATA;
468 subprog = 0;
469 } else if (strcmp(fw_name, "SEV_CODE_FILE") == 0) {
470 fw_type = AMD_SEV_CODE;
471 subprog = 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800472 } else {
473 fw_type = AMD_FW_INVALID;
474 /* TODO: Add more */
475 }
Zheng Baobf29a0d2020-12-03 23:00:48 +0800476
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800477 /* Search and fill the filename */
478 psp_tableptr = &amd_psp_fw_table[0];
479 if (fw_type != AMD_FW_SKIP && fw_type != AMD_FW_INVALID) {
480 while (psp_tableptr->type != AMD_FW_INVALID) {
481 /* instance are not used in PSP table */
Zheng Bao5ca13432022-10-16 20:18:40 +0800482 if (psp_tableptr->type == fw_type && psp_tableptr->subprog == subprog
483 && psp_tableptr->inst == instance) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800484 psp_tableptr->filename = filename;
Zheng Bao990d1542021-09-17 13:24:54 +0800485 SET_LEVEL(psp_tableptr, level_to_set, PSP,
486 cb_config->recovery_ab);
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800487 break;
488 }
489 psp_tableptr++;
490 }
491 }
492 if (fw_type == AMD_FW_INVALID)
493 return 0;
494 else
495 return 1;
496}
Zheng Bao1a9e5432022-02-17 17:48:27 +0800497#define PMUI_STR_BASE "PSP_PMUI_FILE"
498#define PMUD_STR_BASE "PSP_PMUD_FILE"
499#define PMU_STR_BASE_LEN strlen(PMUI_STR_BASE)
500#define PMU_STR_SUB_INDEX strlen(PMUI_STR_BASE"_SUB")
501#define PMU_STR_INS_INDEX strlen(PMUI_STR_BASE"_SUBx_INS")
Zheng Baofdb02942022-02-22 09:47:59 +0800502#define PMU_STR_ALL_LEN strlen(PMUI_STR_BASE"_SUBx_INSx")
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800503
504static uint8_t find_register_fw_filename_bios_dir(char *fw_name, char *filename,
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800505 char level_to_set, amd_cb_config *cb_config)
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800506{
507 amd_bios_type fw_type = AMD_BIOS_INVALID;
508 amd_bios_entry *bhd_tableptr;
Felix Heldea3417b2020-11-20 20:08:42 +0100509 uint8_t subprog = 0;
510 uint8_t instance = 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800511
512 (void) (cb_config); /* Remove warning and reserved for future. */
513
Zheng Bao1a9e5432022-02-17 17:48:27 +0800514 if (strncmp(fw_name, PMUI_STR_BASE, PMU_STR_BASE_LEN) == 0) {
Zheng Baofdb02942022-02-22 09:47:59 +0800515 assert(strlen(fw_name) == PMU_STR_ALL_LEN);
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800516 fw_type = AMD_BIOS_PMUI;
Felix Held3dfb4852022-09-28 18:00:39 +0200517 subprog = strtol(&fw_name[PMU_STR_SUB_INDEX], NULL, 16);
518 instance = strtol(&fw_name[PMU_STR_INS_INDEX], NULL, 16);
Zheng Bao1a9e5432022-02-17 17:48:27 +0800519 } else if (strncmp(fw_name, PMUD_STR_BASE, PMU_STR_BASE_LEN) == 0) {
Zheng Baofdb02942022-02-22 09:47:59 +0800520 assert(strlen(fw_name) == PMU_STR_ALL_LEN);
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800521 fw_type = AMD_BIOS_PMUD;
Felix Held3dfb4852022-09-28 18:00:39 +0200522 subprog = strtol(&fw_name[PMU_STR_SUB_INDEX], NULL, 16);
523 instance = strtol(&fw_name[PMU_STR_INS_INDEX], NULL, 16);
Zheng Baobf29a0d2020-12-03 23:00:48 +0800524 } else if (strcmp(fw_name, "RTM_PUBKEY_FILE") == 0) {
525 fw_type = AMD_BIOS_RTM_PUBKEY;
526 subprog = 0;
527 instance = 0;
Zheng Bao50143732020-11-14 21:54:06 +0800528 } else if (strcmp(fw_name, "PSP_MP2CFG_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800529 if (cb_config->load_mp2_fw) {
Zheng Bao50143732020-11-14 21:54:06 +0800530 fw_type = AMD_BIOS_MP2_CFG;
531 subprog = 0;
532 } else {
Martin Rotha8e31ca2021-02-13 21:42:46 -0700533 fw_type = AMD_BIOS_SKIP;
Zheng Bao50143732020-11-14 21:54:06 +0800534 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800535 } else {
536 fw_type = AMD_BIOS_INVALID;
537 }
538
539 bhd_tableptr = amd_bios_table;
540
541 if (fw_type != AMD_BIOS_INVALID && fw_type != AMD_BIOS_SKIP) {
542 while (bhd_tableptr->type != AMD_BIOS_INVALID) {
543 if (bhd_tableptr->type == fw_type &&
544 bhd_tableptr->subpr == subprog &&
545 bhd_tableptr->inst == instance) {
546 bhd_tableptr->filename = filename;
Zheng Bao990d1542021-09-17 13:24:54 +0800547 SET_LEVEL(bhd_tableptr, level_to_set, BDT,
548 cb_config->recovery_ab);
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800549 break;
550 }
551 bhd_tableptr++;
552 }
553 }
554 if (fw_type == AMD_BIOS_INVALID)
555 return 0;
556 else
557 return 1;
558}
559
560#define MAX_LINE_SIZE 1024
561
562int get_input_file_line(FILE *f, char line[], int line_buf_size)
563{
564 if (fgets(line, line_buf_size, f) == NULL)
565 return LINE_EOF;
566
567 /* If the file contains a line that is too long, then it's best
568 * to let the user know right away rather than passing back a
569 * truncated result that will lead to problems later on.
570 */
571 line[strlen(line) - 1] = '\0';
572
573 if (strlen(line) == ((size_t) (line_buf_size - 1))) {
Zheng Bao77a2c672020-10-01 17:05:43 +0800574 fprintf(stderr, "The line size in config file should be lower than %d bytes.\n",
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800575 MAX_LINE_SIZE);
576 exit(1);
577 }
578
579 return OK;
580}
581
Zheng Bao4df5af82022-03-01 17:18:00 +0800582#define N_MATCHES 4
583static int is_valid_entry(char *oneline, regmatch_t match[N_MATCHES])
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800584{
Zheng Bao4df5af82022-03-01 17:18:00 +0800585 int retval, index;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800586
Zheng Bao4df5af82022-03-01 17:18:00 +0800587 for (index = 0; index < N_MATCHES; index++) {
588 match[index].rm_so = -1;
589 match[index].rm_eo = -1;
590 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800591 if (regexec(&entries_line_expr, oneline, 3, match, 0) == 0) {
592 oneline[match[1].rm_eo] = '\0';
593 oneline[match[2].rm_eo] = '\0';
594 retval = 1;
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800595 } else if (regexec(&entries_lvl_line_expr, oneline, 4, match, 0) == 0) {
596 /* match[1]: FW type
597 match[2]: FW filename
598 match[3]: Directory level to be dropped
599 */
600 oneline[match[1].rm_eo] = '\0';
601 oneline[match[2].rm_eo] = '\0';
602 oneline[match[3].rm_eo] = '\0';
603 retval = 1;
604 } else {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800605 retval = 0;
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800606 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800607
608 return retval;
609}
610
611static int skip_comment_blank_line(char *oneline)
612{
613 int retval;
614
615 if (regexec(&blank_or_comment_expr, oneline, 0, NULL, 0) == 0) {
616 /* skip comment and blank */
617 retval = 1;
618 } else {
619 /* no match */
620 retval = 0;
621 }
622
623 return retval;
624}
625
Zheng Bao52a18982022-03-01 17:22:52 +0800626char get_level_from_config(char *line, regoff_t level_index, amd_cb_config *cb_config)
627{
628 char lvl = 'x';
629 /* If the optional level field is present,
630 extract the level char. */
631 if (level_index != -1) {
632 if (cb_config->recovery_ab == 0)
633 lvl = line[level_index + 1];
634 else if (strlen(&line[level_index]) >= 3)
635 lvl = line[level_index + 2];
636 }
637
638 assert(lvl == 'x' || lvl == 'X' ||
639 lvl == 'b' || lvl == 'B' ||
640 lvl == '1' || lvl == '2');
641
642 return lvl;
643}
644
Zheng Bao7db76422021-03-27 18:15:35 +0800645static uint8_t process_one_line(char *oneline, regmatch_t *match, char *dir,
Zheng Bao994ff522023-03-09 11:43:55 +0800646 amd_cb_config *cb_config)
Zheng Bao7db76422021-03-27 18:15:35 +0800647{
648 char *path_filename, *fn = &(oneline[match[2].rm_so]);
649 char *fw_type_str = &(oneline[match[1].rm_so]);
650 char ch_lvl = 'x';
651 regoff_t ch_lvl_index = match[3].rm_so;
652
653 /* If the optional level field is present,
654 extract the level char. */
655 ch_lvl = get_level_from_config(oneline, ch_lvl_index, cb_config);
656
657 path_filename = malloc(MAX_LINE_SIZE * 2 + 2);
Martin Roth6bb6ed92023-03-08 14:58:51 -0700658 if (strchr(fn, '/'))
659 snprintf(path_filename, MAX_LINE_SIZE * 2 + 2, "%.*s",
660 MAX_LINE_SIZE, fn);
661 else
662 snprintf(path_filename, MAX_LINE_SIZE * 2 + 2, "%.*s/%.*s",
663 MAX_LINE_SIZE, dir, MAX_LINE_SIZE, fn);
Zheng Bao7db76422021-03-27 18:15:35 +0800664
665 if (find_register_fw_filename_psp_dir(
666 fw_type_str, path_filename, ch_lvl, cb_config) == 0) {
667 if (find_register_fw_filename_bios_dir(
668 fw_type_str, path_filename, ch_lvl, cb_config) == 0) {
669 fprintf(stderr, "Module's name \"%s\" is not valid\n", fw_type_str);
670 return 0; /* Stop parsing. */
Zheng Bao7db76422021-03-27 18:15:35 +0800671 }
Zheng Bao7db76422021-03-27 18:15:35 +0800672 }
673 return 1;
674}
675
Zheng Bao010cc992023-01-25 22:58:49 +0800676static bool needs_ish(enum platform platform_type)
677{
678 if (platform_type == PLATFORM_MENDOCINO || platform_type == PLATFORM_PHOENIX || platform_type == PLATFORM_GLINDA)
679 return true;
680 else
681 return false;
682}
683
684static bool is_second_gen(enum platform platform_type)
685{
686 switch (platform_type) {
687 case PLATFORM_CARRIZO:
688 case PLATFORM_STONEYRIDGE:
689 case PLATFORM_RAVEN:
690 case PLATFORM_PICASSO:
691 return false;
692 case PLATFORM_RENOIR:
693 case PLATFORM_LUCIENNE:
694 case PLATFORM_CEZANNE:
695 case PLATFORM_MENDOCINO:
696 case PLATFORM_PHOENIX:
697 case PLATFORM_GLINDA:
698 return true;
699 case PLATFORM_UNKNOWN:
700 default:
701 fprintf(stderr, "Error: Invalid SOC name.\n\n");
702 return false;
703 }
704}
705
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800706/*
707 return value:
708 0: The config file can not be parsed correctly.
709 1: The config file can be parsed correctly.
710 */
Zheng Bao994ff522023-03-09 11:43:55 +0800711uint8_t process_config(FILE *config, amd_cb_config *cb_config)
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800712{
Zheng Bao7db76422021-03-27 18:15:35 +0800713 char oneline[MAX_LINE_SIZE];
Zheng Bao4df5af82022-03-01 17:18:00 +0800714 regmatch_t match[N_MATCHES];
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800715 char dir[MAX_LINE_SIZE] = {'\0'};
Zheng Baodac44612021-05-27 11:11:34 +0800716 uint32_t dir_len;
Zheng Bao4df5af82022-03-01 17:18:00 +0800717 int index;
718
719 for (index = 0; index < N_MATCHES; index++) {
720 match[index].rm_so = -1;
721 match[index].rm_eo = -1;
722 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800723
724 compile_reg_expr(REG_EXTENDED | REG_NEWLINE,
725 blank_or_comment_regex, &blank_or_comment_expr);
726 compile_reg_expr(REG_EXTENDED | REG_NEWLINE,
727 entries_line_regex, &entries_line_expr);
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800728 compile_reg_expr(REG_EXTENDED | REG_NEWLINE,
729 entries_lvl_line_regex, &entries_lvl_line_expr);
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800730
731 /* Get a line */
Zheng Bao3384e4a2020-10-06 12:03:11 +0800732 /* Get FIRMWARE_LOCATION in the first loop */
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800733 while (get_input_file_line(config, oneline, MAX_LINE_SIZE) == OK) {
734 /* get a line */
735 if (skip_comment_blank_line(oneline))
736 continue;
737 if (is_valid_entry(oneline, match)) {
Zheng Bao3384e4a2020-10-06 12:03:11 +0800738 if (strcmp(&(oneline[match[1].rm_so]), "FIRMWARE_LOCATION") == 0) {
Zheng Baodac44612021-05-27 11:11:34 +0800739 dir_len = match[2].rm_eo - match[2].rm_so;
740 assert(dir_len < MAX_LINE_SIZE);
741 snprintf(dir, MAX_LINE_SIZE, "%.*s", dir_len,
742 &(oneline[match[2].rm_so]));
Zheng Bao010cc992023-01-25 22:58:49 +0800743 } else if (strcmp(&(oneline[match[1].rm_so]), "SOC_NAME") == 0) {
744 cb_config->soc_id =
745 identify_platform(&(oneline[match[2].rm_so]));
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800746 }
747 }
748 }
749
Zheng Bao010cc992023-01-25 22:58:49 +0800750 cb_config->second_gen = is_second_gen(cb_config->soc_id);
751
752 if (needs_ish(cb_config->soc_id))
753 cb_config->need_ish = true;
754
755 if (cb_config->need_ish)
756 cb_config->recovery_ab = true;
757
758 if (cb_config->recovery_ab)
759 cb_config->multi_level = true;
760
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800761 if (dir[0] == '\0') {
762 fprintf(stderr, "No line with FIRMWARE_LOCATION\n");
763 return 0;
764 }
765
766 fseek(config, 0, SEEK_SET);
767 /* Get a line */
768 while (get_input_file_line(config, oneline, MAX_LINE_SIZE) == OK) {
769 /* get a line */
770 if (skip_comment_blank_line(oneline))
771 continue;
772 if (is_valid_entry(oneline, match)) {
Zheng Bao29063fb2023-01-25 22:46:57 +0800773 if (strcmp(&(oneline[match[1].rm_so]), "FIRMWARE_LOCATION") == 0 ||
774 strcmp(&(oneline[match[1].rm_so]), "SOC_NAME") == 0) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800775 continue;
776 } else {
Zheng Bao994ff522023-03-09 11:43:55 +0800777 if (process_one_line(oneline, match, dir,
Zheng Bao7db76422021-03-27 18:15:35 +0800778 cb_config) == 0)
779 return 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800780 }
781 } else {
782 fprintf(stderr, "AMDFWTOOL config file line can't be parsed \"%s\"\n", oneline);
783 return 0;
784 }
785 }
786 return 1;
787}