blob: c2dc3e22c51f3586aa6f8182323779731c700a12 [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:]]+)"
Karthikeyan Ramasubramaniandc498932023-05-02 22:10:57 -060032 /* followed by an optional whitespace + chunk of nonwhitespace for level field
Zheng Baob1fb8ce2021-09-13 18:00:09 +080033 1st char L: Indicator of field "level"
34 2nd char:
35 Directory level to be dropped in.
36 1: Level 1
37 2: Level 2
38 b: Level both 1&2
39 x: use default value hardcoded in table
40 3rd char:
41 For A/B recovery. Defined same as 2nd char.
42
43 Examples:
44 L2: Level 2 for normal mode
45 L12: Level 1 for normal mode, level 2 for A/B mode
46 Lx1: Use default value for normal mode, level 1 for A/B mode
47 */
Karthikeyan Ramasubramaniandc498932023-05-02 22:10:57 -060048 "([[:space:]]+([Ll][12bxBX]{1,2}))?"
Karthikeyan Ramasubramaniand7a5d9e2023-05-03 13:34:41 -060049 /* followed by an optional whitespace + chunk of nonwhitespace for hash table field
50 1st char H: Indicator of field "Hash Table ID"
51 2nd char:
52 Table ID to be dropped in.
53 0: Table 0 / Default Unified Table
54 1: Table 1
55 ...
56 9: Table 9
57
58 Examples:
59 H2: Put the hash for the concerned entry in Hash Table 2
60 */
61 "([[:space:]]+([Hh][0-9]+))?"
Zheng Baob1fb8ce2021-09-13 18:00:09 +080062 /* followed by optional whitespace */
63 "[[:space:]]*$";
Karthikeyan Ramasubramaniandc498932023-05-02 22:10:57 -060064static regex_t entries_line_expr;
65
66enum match_id {
67 FW_TYPE = 1,
68 FW_FILE,
69 OPT_SPACE1,
70 OPT_LEVEL,
Karthikeyan Ramasubramaniand7a5d9e2023-05-03 13:34:41 -060071 OPT_SPACE2,
72 OPT_HASH_TABLE_ID,
Karthikeyan Ramasubramaniandc498932023-05-02 22:10:57 -060073 N_MATCHES,
74};
Zheng Baob1fb8ce2021-09-13 18:00:09 +080075
Zheng Baoc5e28ab2020-10-28 11:38:09 +080076void compile_reg_expr(int cflags, const char *expr, regex_t *reg)
77{
78 static const size_t ERROR_BUF_SIZE = 256;
79 char error_msg[ERROR_BUF_SIZE];
80 int result;
81
82 result = regcomp(reg, expr, cflags);
83 if (result != 0) {
84 regerror(result, reg, error_msg, ERROR_BUF_SIZE);
Zheng Bao77a2c672020-10-01 17:05:43 +080085 fprintf(stderr, "%s\n", error_msg);
Zheng Baoc5e28ab2020-10-28 11:38:09 +080086 }
87}
88
Zheng Bao010cc992023-01-25 22:58:49 +080089static enum platform identify_platform(char *soc_name)
90{
91 if (!strcasecmp(soc_name, "Stoneyridge"))
92 return PLATFORM_STONEYRIDGE;
93 else if (!strcasecmp(soc_name, "Carrizo"))
94 return PLATFORM_CARRIZO;
95 else if (!strcasecmp(soc_name, "Raven"))
96 return PLATFORM_RAVEN;
97 else if (!strcasecmp(soc_name, "Picasso"))
98 return PLATFORM_PICASSO;
99 else if (!strcasecmp(soc_name, "Cezanne"))
100 return PLATFORM_CEZANNE;
101 else if (!strcasecmp(soc_name, "Mendocino"))
102 return PLATFORM_MENDOCINO;
103 else if (!strcasecmp(soc_name, "Renoir"))
104 return PLATFORM_RENOIR;
105 else if (!strcasecmp(soc_name, "Lucienne"))
106 return PLATFORM_LUCIENNE;
107 else if (!strcasecmp(soc_name, "Phoenix"))
108 return PLATFORM_PHOENIX;
109 else if (!strcasecmp(soc_name, "Glinda"))
110 return PLATFORM_GLINDA;
111 else
112 return PLATFORM_UNKNOWN;
113}
114
Zheng Bao990d1542021-09-17 13:24:54 +0800115#define SET_LEVEL(tableptr, l, TABLE, ab) \
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800116 do { \
117 switch ((l)) { \
118 case '1': \
Zheng Bao990d1542021-09-17 13:24:54 +0800119 (tableptr)->level = ab ? TABLE##_LVL1_AB : TABLE##_LVL1; \
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800120 break; \
121 case '2': \
Zheng Bao990d1542021-09-17 13:24:54 +0800122 (tableptr)->level = ab ? TABLE##_LVL2_AB : TABLE##_LVL2; \
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800123 break; \
124 case 'b': \
125 case 'B': \
Zheng Bao990d1542021-09-17 13:24:54 +0800126 (tableptr)->level = ab ? TABLE##_BOTH_AB : TABLE##_BOTH; \
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800127 break; \
128 default: \
129 /* use default value */ \
130 break; \
131 } \
132 } while (0)
133
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800134extern amd_fw_entry amd_psp_fw_table[];
135extern amd_bios_entry amd_bios_table[];
136
137static uint8_t find_register_fw_filename_psp_dir(char *fw_name, char *filename,
Karthikeyan Ramasubramaniand7a5d9e2023-05-03 13:34:41 -0600138 char level_to_set, uint8_t hash_tbl_id, amd_cb_config *cb_config)
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800139{
140 amd_fw_type fw_type = AMD_FW_INVALID;
141 amd_fw_entry *psp_tableptr;
142 uint8_t subprog;
Zheng Bao5ca13432022-10-16 20:18:40 +0800143 uint8_t instance = 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800144
145 if (strcmp(fw_name, "PSPBTLDR_WL_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800146 if (cb_config->have_whitelist) {
Nikolai Vyssotski1965f6502021-05-06 22:15:36 -0500147 fw_type = AMD_FW_PSP_BOOTLOADER_AB;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800148 subprog = 0;
149 } else {
150 fw_type = AMD_FW_SKIP;
151 }
Zheng Bao990d1542021-09-17 13:24:54 +0800152 } else if (strcmp(fw_name, "PSPBTLDR_AB_STAGE1_FILE") == 0) {
153 if (cb_config->recovery_ab) {
154 fw_type = AMD_FW_PSP_BOOTLOADER;
155 subprog = 0;
156 } else {
157 fw_type = AMD_FW_SKIP;
158 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800159 } else if (strcmp(fw_name, "PSPBTLDR_FILE") == 0) {
Zheng Bao990d1542021-09-17 13:24:54 +0800160 if (!cb_config->recovery_ab) {
161 fw_type = AMD_FW_PSP_BOOTLOADER;
162 subprog = 0;
163 } else {
164 fw_type = AMD_FW_SKIP;
165 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800166 } else if (strcmp(fw_name, "AMD_PUBKEY_FILE") == 0) {
167 fw_type = AMD_FW_PSP_PUBKEY;
168 subprog = 0;
169 } else if (strcmp(fw_name, "PSPRCVR_FILE") == 0) {
170 fw_type = AMD_FW_PSP_RECOVERY;
171 subprog = 0;
172 } else if (strcmp(fw_name, "PUBSIGNEDKEY_FILE") == 0) {
173 fw_type = AMD_FW_PSP_RTM_PUBKEY;
174 subprog = 0;
175 } else if (strcmp(fw_name, "PSPNVRAM_FILE") == 0) {
176 fw_type = AMD_FW_PSP_NVRAM;
177 subprog = 0;
178 } else if (strcmp(fw_name, "SMUSCS_FILE") == 0) {
179 fw_type = AMD_FW_PSP_SMUSCS;
180 subprog = 0;
181 } else if (strcmp(fw_name, "PSPTRUSTLETS_FILE") == 0) {
182 fw_type = AMD_FW_PSP_TRUSTLETS;
183 subprog = 0;
184 } else if (strcmp(fw_name, "PSPSECUREDEBUG_FILE") == 0) {
185 fw_type = AMD_FW_PSP_SECURED_DEBUG;
186 subprog = 0;
187 } else if (strcmp(fw_name, "PSP_SMUFW1_SUB0_FILE") == 0) {
188 fw_type = AMD_FW_PSP_SMU_FIRMWARE;
189 subprog = 0;
Zheng Bao9bb62cb2023-03-07 19:48:11 +0800190 } else if (strcmp(fw_name, "PSP_HW_IPCFG_FILE_SUB0") == 0) {
Zheng Baobf29a0d2020-12-03 23:00:48 +0800191 fw_type = AMD_HW_IPCFG;
192 subprog = 0;
Zheng Bao9bb62cb2023-03-07 19:48:11 +0800193 } else if (strcmp(fw_name, "PSP_HW_IPCFG_FILE_SUB1") == 0) {
194 fw_type = AMD_HW_IPCFG;
195 subprog = 1;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800196 } else if (strcmp(fw_name, "PSP_SMUFW1_SUB1_FILE") == 0) {
197 fw_type = AMD_FW_PSP_SMU_FIRMWARE;
198 subprog = 1;
199 } else if (strcmp(fw_name, "PSP_SMUFW1_SUB2_FILE") == 0) {
200 fw_type = AMD_FW_PSP_SMU_FIRMWARE;
201 subprog = 2;
202 } else if (strcmp(fw_name, "PSP_SMUFW2_SUB0_FILE") == 0) {
203 fw_type = AMD_FW_PSP_SMU_FIRMWARE2;
204 subprog = 0;
205 } else if (strcmp(fw_name, "PSP_SMUFW2_SUB1_FILE") == 0) {
206 fw_type = AMD_FW_PSP_SMU_FIRMWARE2;
207 subprog = 1;
208 } else if (strcmp(fw_name, "PSP_SMUFW2_SUB2_FILE") == 0) {
209 fw_type = AMD_FW_PSP_SMU_FIRMWARE2;
210 subprog = 2;
Zheng Bao8eba6622022-10-16 20:29:03 +0800211 } else if (strcmp(fw_name, "PSP_BOOT_DRIVER_FILE") == 0) {
212 fw_type = AMD_BOOT_DRIVER;
213 subprog = 0;
214 } else if (strcmp(fw_name, "PSP_SOC_DRIVER_FILE") == 0) {
215 fw_type = AMD_SOC_DRIVER;
216 subprog = 0;
217 } else if (strcmp(fw_name, "PSP_DEBUG_DRIVER_FILE") == 0) {
218 fw_type = AMD_DEBUG_DRIVER;
219 subprog = 0;
220 } else if (strcmp(fw_name, "PSP_INTERFACE_DRIVER_FILE") == 0) {
221 fw_type = AMD_INTERFACE_DRIVER;
222 subprog = 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800223 } else if (strcmp(fw_name, "PSP_SEC_DBG_KEY_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800224 if (cb_config->unlock_secure) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800225 fw_type = AMD_FW_PSP_SECURED_DEBUG;
226 subprog = 0;
227 } else {
228 fw_type = AMD_FW_SKIP;
229 }
230 } else if (strcmp(fw_name, "PSP_SEC_DEBUG_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800231 if (cb_config->unlock_secure) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800232 fw_type = AMD_DEBUG_UNLOCK;
233 subprog = 0;
234 } else {
235 fw_type = AMD_FW_SKIP;
236 }
237 } else if (strcmp(fw_name, "PSP_ABL0_FILE") == 0) {
238 fw_type = AMD_ABL0;
239 subprog = 0;
240 } else if (strcmp(fw_name, "PSP_ABL1_FILE") == 0) {
241 fw_type = AMD_ABL1;
242 subprog = 0;
243 } else if (strcmp(fw_name, "PSP_ABL2_FILE") == 0) {
244 fw_type = AMD_ABL2;
245 subprog = 0;
246 } else if (strcmp(fw_name, "PSP_ABL3_FILE") == 0) {
247 fw_type = AMD_ABL3;
248 subprog = 0;
249 } else if (strcmp(fw_name, "PSP_ABL4_FILE") == 0) {
250 fw_type = AMD_ABL4;
251 subprog = 0;
252 } else if (strcmp(fw_name, "PSP_ABL5_FILE") == 0) {
253 fw_type = AMD_ABL5;
254 subprog = 0;
255 } else if (strcmp(fw_name, "PSP_ABL6_FILE") == 0) {
256 fw_type = AMD_ABL6;
257 subprog = 0;
258 } else if (strcmp(fw_name, "PSP_ABL7_FILE") == 0) {
259 fw_type = AMD_ABL7;
260 subprog = 0;
261 } else if (strcmp(fw_name, "PSPSECUREOS_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800262 if (cb_config->use_secureos) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800263 fw_type = AMD_FW_PSP_SECURED_OS;
264 subprog = 0;
265 } else {
266 fw_type = AMD_FW_SKIP;
267 }
268 } else if (strcmp(fw_name, "PSPTRUSTLETS_FILE") == 0) {
269 if (cb_config->use_secureos) {
270 fw_type = AMD_FW_PSP_TRUSTLETS;
271 subprog = 0;
272 } else {
273 fw_type = AMD_FW_SKIP;
274 }
275 } else if (strcmp(fw_name, "TRUSTLETKEY_FILE") == 0) {
276 if (cb_config->use_secureos) {
277 fw_type = AMD_FW_PSP_TRUSTLETKEY;
278 subprog = 0;
279 } else {
280 fw_type = AMD_FW_SKIP;
281 }
282 } else if (strcmp(fw_name, "PSP_IKEK_FILE") == 0) {
283 fw_type = AMD_WRAPPED_IKEK;
284 subprog = 0;
Zheng Baobf29a0d2020-12-03 23:00:48 +0800285 } else if (strcmp(fw_name, "PSP_SECG0_FILE") == 0) {
286 fw_type = AMD_SEC_GASKET;
287 subprog = 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800288 } else if (strcmp(fw_name, "PSP_SECG1_FILE") == 0) {
289 fw_type = AMD_SEC_GASKET;
290 subprog = 1;
291 } else if (strcmp(fw_name, "PSP_SECG2_FILE") == 0) {
292 fw_type = AMD_SEC_GASKET;
293 subprog = 2;
Zheng Baobf29a0d2020-12-03 23:00:48 +0800294 } else if (strcmp(fw_name, "PSP_MP2FW0_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800295 if (cb_config->load_mp2_fw) {
Zheng Baobf29a0d2020-12-03 23:00:48 +0800296 fw_type = AMD_MP2_FW;
297 subprog = 0;
298 } else {
299 fw_type = AMD_FW_SKIP;
300 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800301 } else if (strcmp(fw_name, "PSP_MP2FW1_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800302 if (cb_config->load_mp2_fw) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800303 fw_type = AMD_MP2_FW;
304 subprog = 1;
305 } else {
306 fw_type = AMD_FW_SKIP;
307 }
308 } else if (strcmp(fw_name, "PSP_MP2FW2_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800309 if (cb_config->load_mp2_fw) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800310 fw_type = AMD_MP2_FW;
311 subprog = 2;
312 } else {
313 fw_type = AMD_FW_SKIP;
314 }
Zheng Bao8eba6622022-10-16 20:29:03 +0800315 } else if (strcmp(fw_name, "PSP_C20MP_FILE") == 0) {
316 fw_type = AMD_FW_C20_MP;
317 subprog = 0;
Zheng Bao8eba6622022-10-16 20:29:03 +0800318 } else if (strcmp(fw_name, "AMF_SRAM_FILE") == 0) {
319 fw_type = AMD_FW_AMF_SRAM;
320 subprog = 0;
321 } else if (strcmp(fw_name, "AMF_DRAM_FILE_INS0") == 0) {
322 fw_type = AMD_FW_AMF_DRAM;
323 subprog = 0;
324 instance = 0;
325 } else if (strcmp(fw_name, "AMF_DRAM_FILE_INS1") == 0) {
326 fw_type = AMD_FW_AMF_DRAM;
327 subprog = 0;
328 instance = 1;
329 } else if (strcmp(fw_name, "AMF_WLAN_FILE_INS0") == 0) {
330 fw_type = AMD_FW_AMF_WLAN;
331 subprog = 0;
332 instance = 0;
333 } else if (strcmp(fw_name, "AMF_WLAN_FILE_INS1") == 0) {
334 fw_type = AMD_FW_AMF_WLAN;
335 subprog = 0;
336 instance = 1;
337 } else if (strcmp(fw_name, "AMF_MFD_FILE") == 0) {
338 fw_type = AMD_FW_AMF_MFD;
339 subprog = 0;
340 } else if (strcmp(fw_name, "MPCCX_FILE") == 0) {
341 fw_type = AMD_FW_MPCCX;
342 subprog = 0;
343 } else if (strcmp(fw_name, "LSDMA_FILE") == 0) {
344 fw_type = AMD_FW_LSDMA;
345 subprog = 0;
346 } else if (strcmp(fw_name, "MINIMSMU_FILE") == 0) {
347 fw_type = AMD_FW_MINIMSMU;
348 instance = 0;
349 subprog = 0;
350 } else if (strcmp(fw_name, "MINIMSMU_FILE_INS1") == 0) {
351 fw_type = AMD_FW_MINIMSMU;
352 instance = 1;
353 subprog = 0;
354 } else if (strcmp(fw_name, "SRAM_FW_EXT_FILE") == 0) {
355 fw_type = AMD_FW_SRAM_FW_EXT;
356 subprog = 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800357 } else if (strcmp(fw_name, "PSP_DRIVERS_FILE") == 0) {
358 fw_type = AMD_DRIVER_ENTRIES;
359 subprog = 0;
360 } else if (strcmp(fw_name, "PSP_S0I3_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800361 if (cb_config->s0i3) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800362 fw_type = AMD_S0I3_DRIVER;
363 subprog = 0;
364 } else {
365 fw_type = AMD_FW_SKIP;
366 }
Zheng Baobf29a0d2020-12-03 23:00:48 +0800367 } else if (strcmp(fw_name, "AMD_DRIVER_ENTRIES") == 0) {
368 fw_type = AMD_DRIVER_ENTRIES;
369 subprog = 0;
370 } else if (strcmp(fw_name, "VBIOS_BTLOADER_FILE") == 0) {
371 fw_type = AMD_VBIOS_BTLOADER;
372 subprog = 0;
373 } else if (strcmp(fw_name, "SECURE_POLICY_L1_FILE") == 0) {
374 fw_type = AMD_FW_TOS_SEC_POLICY;
375 subprog = 0;
376 } else if (strcmp(fw_name, "UNIFIEDUSB_FILE") == 0) {
377 fw_type = AMD_FW_USB_PHY;
378 subprog = 0;
379 } else if (strcmp(fw_name, "DRTMTA_FILE") == 0) {
380 fw_type = AMD_FW_DRTM_TA;
381 subprog = 0;
382 } else if (strcmp(fw_name, "KEYDBBL_FILE") == 0) {
383 fw_type = AMD_FW_KEYDB_BL;
384 subprog = 0;
385 } else if (strcmp(fw_name, "KEYDB_TOS_FILE") == 0) {
386 fw_type = AMD_FW_KEYDB_TOS;
387 subprog = 0;
Zheng Baoab84fd72022-01-27 22:38:27 +0800388 } else if (strcmp(fw_name, "SPL_TABLE_FILE") == 0) {
Zheng Bao6c5ec8e2022-02-11 11:51:26 +0800389 if (cb_config->have_mb_spl) {
Felix Held11b0d362022-04-02 03:49:07 +0200390 fw_type = AMD_FW_SKIP;
391 } else {
Zheng Bao6c5ec8e2022-02-11 11:51:26 +0800392 fw_type = AMD_FW_SPL;
393 subprog = 0;
Zheng Bao6c5ec8e2022-02-11 11:51:26 +0800394 }
Zheng Baobf29a0d2020-12-03 23:00:48 +0800395 } else if (strcmp(fw_name, "DMCUERAMDCN21_FILE") == 0) {
396 fw_type = AMD_FW_DMCU_ERAM;
397 subprog = 0;
398 } else if (strcmp(fw_name, "DMCUINTVECTORSDCN21_FILE") == 0) {
399 fw_type = AMD_FW_DMCU_ISR;
400 subprog = 0;
Felix Held5f18bb72022-03-24 02:04:51 +0100401 } else if (strcmp(fw_name, "MSMU_FILE") == 0) {
402 fw_type = AMD_FW_MSMU;
403 subprog = 0;
404 } else if (strcmp(fw_name, "DMCUB_FILE") == 0) {
405 fw_type = AMD_FW_DMCUB;
406 subprog = 0;
407 } else if (strcmp(fw_name, "SPIROM_CONFIG_FILE") == 0) {
408 fw_type = AMD_FW_SPIROM_CFG;
409 subprog = 0;
Zheng Bao8eba6622022-10-16 20:29:03 +0800410 } else if (strcmp(fw_name, "MPIO_FILE") == 0) {
411 fw_type = AMD_FW_MPIO;
412 subprog = 0;
413 } else if (strcmp(fw_name, "TPMLITE_FILE") == 0) {
Zheng Bao8eba6622022-10-16 20:29:03 +0800414 fw_type = AMD_FW_TPMLITE;
415 subprog = 0;
Zheng Baobf29a0d2020-12-03 23:00:48 +0800416 } else if (strcmp(fw_name, "PSP_KVM_ENGINE_DUMMY_FILE") == 0) {
417 fw_type = AMD_FW_KVM_IMAGE;
418 subprog = 0;
419 } else if (strcmp(fw_name, "RPMC_FILE") == 0) {
420 fw_type = AMD_RPMC_NVRAM;
421 subprog = 0;
Zheng Baob993cb22021-02-02 18:48:23 +0800422 } else if (strcmp(fw_name, "PSPBTLDR_AB_FILE") == 0) {
Zheng Bao990d1542021-09-17 13:24:54 +0800423 if (!cb_config->have_whitelist || cb_config->recovery_ab) {
Nikolai Vyssotski1965f6502021-05-06 22:15:36 -0500424 fw_type = AMD_FW_PSP_BOOTLOADER_AB;
425 subprog = 0;
426 } else {
427 fw_type = AMD_FW_SKIP;
428 }
Karthikeyan Ramasubramanian0ab04d22022-05-03 18:16:34 -0600429 } else if (strcmp(fw_name, "TA_IKEK_FILE") == 0) {
430 fw_type = AMD_TA_IKEK;
431 subprog = 0;
Fred Reitbergerc4f3a332023-02-07 12:12:40 -0500432 } else if (strcmp(fw_name, "UMSMU_FILE") == 0) {
433 fw_type = AMD_FW_UMSMU;
434 subprog = 0;
Arthur Heymans1f05c802022-10-04 17:50:21 +0200435 } else if (strcmp(fw_name, "PSP_OEM_ABL_KEY_FILE") == 0) {
436 fw_type = AMD_FW_ABL_PUBKEY;
437 subprog = 0;
438 } else if (strcmp(fw_name, "PSP_MP5FW_SUB0_FILE") == 0) {
439 fw_type = AMD_FW_MP5;
440 subprog = 0;
441 } else if (strcmp(fw_name, "PSP_MP5FW_SUB1_FILE") == 0) {
442 fw_type = AMD_FW_MP5;
443 subprog = 1;
444 } else if (strcmp(fw_name, "PSP_MP5FW_SUB2_FILE") == 0) {
445 fw_type = AMD_FW_MP5;
446 subprog = 2;
447 } else if (strcmp(fw_name, "PSP_DXIOFW_FILE") == 0) {
448 fw_type = AMD_FW_DXIO;
449 subprog = 0;
450 } else if (strcmp(fw_name, "PSP_MPIOFW_FILE") == 0) {
451 fw_type = AMD_FW_MPIO;
452 subprog = 0;
Zheng Bao85ee1fd2023-01-30 13:52:30 +0800453 } else if (strcmp(fw_name, "PSP_RIB_FILE_SUB0") == 0) {
Arthur Heymans1f05c802022-10-04 17:50:21 +0200454 fw_type = AMD_RIB;
455 subprog = 0;
Zheng Bao85ee1fd2023-01-30 13:52:30 +0800456 } else if (strcmp(fw_name, "PSP_RIB_FILE_SUB1") == 0) {
457 fw_type = AMD_RIB;
458 subprog = 1;
Zheng Bao8eba6622022-10-16 20:29:03 +0800459 } else if (strcmp(fw_name, "FEATURE_TABLE_FILE") == 0) {
460 fw_type = AMD_FW_FCFG_TABLE;
461 subprog = 0;
Arthur Heymans1f05c802022-10-04 17:50:21 +0200462 } else if (strcmp(fw_name, "PSP_MPDMATFFW_FILE") == 0) {
463 fw_type = AMD_FW_MPDMA_TF;
464 subprog = 0;
465 } else if (strcmp(fw_name, "PSP_GMI3PHYFW_FILE") == 0) {
466 fw_type = AMD_FW_GMI3_PHY;
467 subprog = 0;
468 } else if (strcmp(fw_name, "PSP_MPDMAPMFW_FILE") == 0) {
469 fw_type = AMD_FW_MPDMA_PM;
470 subprog = 0;
471 } else if (strcmp(fw_name, "PSP_TOKEN_UNLOCK_FILE") == 0) {
472 fw_type = AMD_TOKEN_UNLOCK;
473 subprog = 0;
474 } else if (strcmp(fw_name, "SEV_DATA_FILE") == 0) {
475 fw_type = AMD_SEV_DATA;
476 subprog = 0;
477 } else if (strcmp(fw_name, "SEV_CODE_FILE") == 0) {
478 fw_type = AMD_SEV_CODE;
479 subprog = 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800480 } else {
481 fw_type = AMD_FW_INVALID;
482 /* TODO: Add more */
483 }
Zheng Baobf29a0d2020-12-03 23:00:48 +0800484
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800485 /* Search and fill the filename */
486 psp_tableptr = &amd_psp_fw_table[0];
487 if (fw_type != AMD_FW_SKIP && fw_type != AMD_FW_INVALID) {
488 while (psp_tableptr->type != AMD_FW_INVALID) {
489 /* instance are not used in PSP table */
Zheng Bao5ca13432022-10-16 20:18:40 +0800490 if (psp_tableptr->type == fw_type && psp_tableptr->subprog == subprog
491 && psp_tableptr->inst == instance) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800492 psp_tableptr->filename = filename;
Zheng Bao990d1542021-09-17 13:24:54 +0800493 SET_LEVEL(psp_tableptr, level_to_set, PSP,
494 cb_config->recovery_ab);
Karthikeyan Ramasubramaniand7a5d9e2023-05-03 13:34:41 -0600495 psp_tableptr->hash_tbl_id = hash_tbl_id;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800496 break;
497 }
498 psp_tableptr++;
499 }
500 }
501 if (fw_type == AMD_FW_INVALID)
502 return 0;
503 else
504 return 1;
505}
Zheng Bao1a9e5432022-02-17 17:48:27 +0800506#define PMUI_STR_BASE "PSP_PMUI_FILE"
507#define PMUD_STR_BASE "PSP_PMUD_FILE"
508#define PMU_STR_BASE_LEN strlen(PMUI_STR_BASE)
509#define PMU_STR_SUB_INDEX strlen(PMUI_STR_BASE"_SUB")
510#define PMU_STR_INS_INDEX strlen(PMUI_STR_BASE"_SUBx_INS")
Zheng Baofdb02942022-02-22 09:47:59 +0800511#define PMU_STR_ALL_LEN strlen(PMUI_STR_BASE"_SUBx_INSx")
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800512
513static uint8_t find_register_fw_filename_bios_dir(char *fw_name, char *filename,
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800514 char level_to_set, amd_cb_config *cb_config)
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800515{
516 amd_bios_type fw_type = AMD_BIOS_INVALID;
517 amd_bios_entry *bhd_tableptr;
Felix Heldea3417b2020-11-20 20:08:42 +0100518 uint8_t subprog = 0;
519 uint8_t instance = 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800520
521 (void) (cb_config); /* Remove warning and reserved for future. */
522
Zheng Bao1a9e5432022-02-17 17:48:27 +0800523 if (strncmp(fw_name, PMUI_STR_BASE, PMU_STR_BASE_LEN) == 0) {
Zheng Baofdb02942022-02-22 09:47:59 +0800524 assert(strlen(fw_name) == PMU_STR_ALL_LEN);
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800525 fw_type = AMD_BIOS_PMUI;
Felix Held3dfb4852022-09-28 18:00:39 +0200526 subprog = strtol(&fw_name[PMU_STR_SUB_INDEX], NULL, 16);
527 instance = strtol(&fw_name[PMU_STR_INS_INDEX], NULL, 16);
Zheng Bao1a9e5432022-02-17 17:48:27 +0800528 } else if (strncmp(fw_name, PMUD_STR_BASE, PMU_STR_BASE_LEN) == 0) {
Zheng Baofdb02942022-02-22 09:47:59 +0800529 assert(strlen(fw_name) == PMU_STR_ALL_LEN);
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800530 fw_type = AMD_BIOS_PMUD;
Felix Held3dfb4852022-09-28 18:00:39 +0200531 subprog = strtol(&fw_name[PMU_STR_SUB_INDEX], NULL, 16);
532 instance = strtol(&fw_name[PMU_STR_INS_INDEX], NULL, 16);
Zheng Baobf29a0d2020-12-03 23:00:48 +0800533 } else if (strcmp(fw_name, "RTM_PUBKEY_FILE") == 0) {
534 fw_type = AMD_BIOS_RTM_PUBKEY;
535 subprog = 0;
536 instance = 0;
Zheng Bao50143732020-11-14 21:54:06 +0800537 } else if (strcmp(fw_name, "PSP_MP2CFG_FILE") == 0) {
Zheng Baoba3af5e2021-11-04 18:56:47 +0800538 if (cb_config->load_mp2_fw) {
Zheng Bao50143732020-11-14 21:54:06 +0800539 fw_type = AMD_BIOS_MP2_CFG;
540 subprog = 0;
541 } else {
Martin Rotha8e31ca2021-02-13 21:42:46 -0700542 fw_type = AMD_BIOS_SKIP;
Zheng Bao50143732020-11-14 21:54:06 +0800543 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800544 } else {
545 fw_type = AMD_BIOS_INVALID;
546 }
547
548 bhd_tableptr = amd_bios_table;
549
550 if (fw_type != AMD_BIOS_INVALID && fw_type != AMD_BIOS_SKIP) {
551 while (bhd_tableptr->type != AMD_BIOS_INVALID) {
552 if (bhd_tableptr->type == fw_type &&
553 bhd_tableptr->subpr == subprog &&
554 bhd_tableptr->inst == instance) {
555 bhd_tableptr->filename = filename;
Zheng Bao990d1542021-09-17 13:24:54 +0800556 SET_LEVEL(bhd_tableptr, level_to_set, BDT,
557 cb_config->recovery_ab);
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800558 break;
559 }
560 bhd_tableptr++;
561 }
562 }
563 if (fw_type == AMD_BIOS_INVALID)
564 return 0;
565 else
566 return 1;
567}
568
569#define MAX_LINE_SIZE 1024
570
571int get_input_file_line(FILE *f, char line[], int line_buf_size)
572{
573 if (fgets(line, line_buf_size, f) == NULL)
574 return LINE_EOF;
575
576 /* If the file contains a line that is too long, then it's best
577 * to let the user know right away rather than passing back a
578 * truncated result that will lead to problems later on.
579 */
580 line[strlen(line) - 1] = '\0';
581
582 if (strlen(line) == ((size_t) (line_buf_size - 1))) {
Zheng Bao77a2c672020-10-01 17:05:43 +0800583 fprintf(stderr, "The line size in config file should be lower than %d bytes.\n",
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800584 MAX_LINE_SIZE);
585 exit(1);
586 }
587
588 return OK;
589}
590
Zheng Bao4df5af82022-03-01 17:18:00 +0800591static int is_valid_entry(char *oneline, regmatch_t match[N_MATCHES])
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800592{
Zheng Bao4df5af82022-03-01 17:18:00 +0800593 int retval, index;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800594
Zheng Bao4df5af82022-03-01 17:18:00 +0800595 for (index = 0; index < N_MATCHES; index++) {
596 match[index].rm_so = -1;
597 match[index].rm_eo = -1;
598 }
Karthikeyan Ramasubramaniandc498932023-05-02 22:10:57 -0600599 if (regexec(&entries_line_expr, oneline, N_MATCHES, match, 0) == 0) {
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800600 /* match[1]: FW type
601 match[2]: FW filename
Karthikeyan Ramasubramaniandc498932023-05-02 22:10:57 -0600602 match[4]: Optional directory level to be dropped
Karthikeyan Ramasubramaniand7a5d9e2023-05-03 13:34:41 -0600603 match[6]: Optional hash table ID to put the hash for the entry
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800604 */
Karthikeyan Ramasubramaniandc498932023-05-02 22:10:57 -0600605 oneline[match[FW_TYPE].rm_eo] = '\0';
606 oneline[match[FW_FILE].rm_eo] = '\0';
607 oneline[match[OPT_LEVEL].rm_eo] = '\0';
Karthikeyan Ramasubramaniand7a5d9e2023-05-03 13:34:41 -0600608 oneline[match[OPT_HASH_TABLE_ID].rm_eo] = '\0';
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800609 retval = 1;
610 } else {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800611 retval = 0;
Zheng Baob1fb8ce2021-09-13 18:00:09 +0800612 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800613
614 return retval;
615}
616
617static int skip_comment_blank_line(char *oneline)
618{
619 int retval;
620
621 if (regexec(&blank_or_comment_expr, oneline, 0, NULL, 0) == 0) {
622 /* skip comment and blank */
623 retval = 1;
624 } else {
625 /* no match */
626 retval = 0;
627 }
628
629 return retval;
630}
631
Karthikeyan Ramasubramaniand7a5d9e2023-05-03 13:34:41 -0600632static char get_level_from_config(char *line, regoff_t level_index, amd_cb_config *cb_config)
Zheng Bao52a18982022-03-01 17:22:52 +0800633{
634 char lvl = 'x';
Karthikeyan Ramasubramaniand7a5d9e2023-05-03 13:34:41 -0600635 /* If the optional level field is present, extract the level char. */
Zheng Bao52a18982022-03-01 17:22:52 +0800636 if (level_index != -1) {
637 if (cb_config->recovery_ab == 0)
638 lvl = line[level_index + 1];
639 else if (strlen(&line[level_index]) >= 3)
640 lvl = line[level_index + 2];
641 }
642
643 assert(lvl == 'x' || lvl == 'X' ||
644 lvl == 'b' || lvl == 'B' ||
645 lvl == '1' || lvl == '2');
646
647 return lvl;
648}
649
Karthikeyan Ramasubramaniand7a5d9e2023-05-03 13:34:41 -0600650static uint8_t get_hash_tbl_id(char *line, regoff_t hash_tbl_index)
651{
652 uint8_t tbl = 0;
653 /* If the optional hash table field is present, extract the table id char. */
654 if (hash_tbl_index != -1)
655 tbl = (uint8_t)atoi(&line[hash_tbl_index + 1]);
656
657 assert(tbl < MAX_NUM_HASH_TABLES);
658 return tbl;
659}
660
Zheng Bao7db76422021-03-27 18:15:35 +0800661static uint8_t process_one_line(char *oneline, regmatch_t *match, char *dir,
Zheng Bao994ff522023-03-09 11:43:55 +0800662 amd_cb_config *cb_config)
Zheng Bao7db76422021-03-27 18:15:35 +0800663{
Karthikeyan Ramasubramaniandc498932023-05-02 22:10:57 -0600664 char *path_filename, *fn = &(oneline[match[FW_FILE].rm_so]);
665 char *fw_type_str = &(oneline[match[FW_TYPE].rm_so]);
Karthikeyan Ramasubramaniandc498932023-05-02 22:10:57 -0600666 regoff_t ch_lvl_index = match[OPT_LEVEL].rm_so == match[OPT_LEVEL].rm_eo ?
667 -1 : match[OPT_LEVEL].rm_so;
Karthikeyan Ramasubramaniand7a5d9e2023-05-03 13:34:41 -0600668 regoff_t ch_hash_tbl_index =
669 match[OPT_HASH_TABLE_ID].rm_so == match[OPT_HASH_TABLE_ID].rm_eo ?
670 -1 : match[OPT_HASH_TABLE_ID].rm_so;
671 char ch_lvl = get_level_from_config(oneline, ch_lvl_index, cb_config);
672 uint8_t ch_hash_tbl = get_hash_tbl_id(oneline, ch_hash_tbl_index);
Zheng Bao7db76422021-03-27 18:15:35 +0800673
674 path_filename = malloc(MAX_LINE_SIZE * 2 + 2);
Martin Roth6bb6ed92023-03-08 14:58:51 -0700675 if (strchr(fn, '/'))
676 snprintf(path_filename, MAX_LINE_SIZE * 2 + 2, "%.*s",
677 MAX_LINE_SIZE, fn);
678 else
679 snprintf(path_filename, MAX_LINE_SIZE * 2 + 2, "%.*s/%.*s",
680 MAX_LINE_SIZE, dir, MAX_LINE_SIZE, fn);
Zheng Bao7db76422021-03-27 18:15:35 +0800681
682 if (find_register_fw_filename_psp_dir(
Karthikeyan Ramasubramaniand7a5d9e2023-05-03 13:34:41 -0600683 fw_type_str, path_filename, ch_lvl, ch_hash_tbl, cb_config) == 0) {
Zheng Bao7db76422021-03-27 18:15:35 +0800684 if (find_register_fw_filename_bios_dir(
685 fw_type_str, path_filename, ch_lvl, cb_config) == 0) {
686 fprintf(stderr, "Module's name \"%s\" is not valid\n", fw_type_str);
687 return 0; /* Stop parsing. */
Zheng Bao7db76422021-03-27 18:15:35 +0800688 }
Zheng Bao7db76422021-03-27 18:15:35 +0800689 }
690 return 1;
691}
692
Zheng Bao010cc992023-01-25 22:58:49 +0800693static bool needs_ish(enum platform platform_type)
694{
695 if (platform_type == PLATFORM_MENDOCINO || platform_type == PLATFORM_PHOENIX || platform_type == PLATFORM_GLINDA)
696 return true;
697 else
698 return false;
699}
700
701static bool is_second_gen(enum platform platform_type)
702{
703 switch (platform_type) {
704 case PLATFORM_CARRIZO:
705 case PLATFORM_STONEYRIDGE:
706 case PLATFORM_RAVEN:
707 case PLATFORM_PICASSO:
708 return false;
709 case PLATFORM_RENOIR:
710 case PLATFORM_LUCIENNE:
711 case PLATFORM_CEZANNE:
712 case PLATFORM_MENDOCINO:
713 case PLATFORM_PHOENIX:
714 case PLATFORM_GLINDA:
715 return true;
716 case PLATFORM_UNKNOWN:
717 default:
718 fprintf(stderr, "Error: Invalid SOC name.\n\n");
719 return false;
720 }
721}
722
Karthikeyan Ramasubramaniandc498932023-05-02 22:10:57 -0600723#define FW_LOCATION "FIRMWARE_LOCATION"
724#define SOC_NAME "SOC_NAME"
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800725/*
726 return value:
727 0: The config file can not be parsed correctly.
728 1: The config file can be parsed correctly.
729 */
Zheng Bao994ff522023-03-09 11:43:55 +0800730uint8_t process_config(FILE *config, amd_cb_config *cb_config)
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800731{
Zheng Bao7db76422021-03-27 18:15:35 +0800732 char oneline[MAX_LINE_SIZE];
Zheng Bao4df5af82022-03-01 17:18:00 +0800733 regmatch_t match[N_MATCHES];
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800734 char dir[MAX_LINE_SIZE] = {'\0'};
Zheng Baodac44612021-05-27 11:11:34 +0800735 uint32_t dir_len;
Zheng Bao4df5af82022-03-01 17:18:00 +0800736 int index;
737
738 for (index = 0; index < N_MATCHES; index++) {
739 match[index].rm_so = -1;
740 match[index].rm_eo = -1;
741 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800742
743 compile_reg_expr(REG_EXTENDED | REG_NEWLINE,
744 blank_or_comment_regex, &blank_or_comment_expr);
745 compile_reg_expr(REG_EXTENDED | REG_NEWLINE,
746 entries_line_regex, &entries_line_expr);
747
748 /* Get a line */
Zheng Bao3384e4a2020-10-06 12:03:11 +0800749 /* Get FIRMWARE_LOCATION in the first loop */
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800750 while (get_input_file_line(config, oneline, MAX_LINE_SIZE) == OK) {
751 /* get a line */
752 if (skip_comment_blank_line(oneline))
753 continue;
754 if (is_valid_entry(oneline, match)) {
Karthikeyan Ramasubramaniandc498932023-05-02 22:10:57 -0600755 if (strcmp(&(oneline[match[FW_TYPE].rm_so]), FW_LOCATION) == 0) {
756 dir_len = match[FW_FILE].rm_eo - match[FW_FILE].rm_so;
Zheng Baodac44612021-05-27 11:11:34 +0800757 assert(dir_len < MAX_LINE_SIZE);
758 snprintf(dir, MAX_LINE_SIZE, "%.*s", dir_len,
Karthikeyan Ramasubramaniandc498932023-05-02 22:10:57 -0600759 &(oneline[match[FW_FILE].rm_so]));
760 } else if (strcmp(&(oneline[match[FW_TYPE].rm_so]), SOC_NAME) == 0) {
761 cb_config->soc_id = identify_platform(
762 &(oneline[match[FW_FILE].rm_so]));
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800763 }
764 }
765 }
766
Zheng Bao010cc992023-01-25 22:58:49 +0800767 cb_config->second_gen = is_second_gen(cb_config->soc_id);
768
769 if (needs_ish(cb_config->soc_id))
770 cb_config->need_ish = true;
771
772 if (cb_config->need_ish)
773 cb_config->recovery_ab = true;
774
775 if (cb_config->recovery_ab)
776 cb_config->multi_level = true;
777
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800778 if (dir[0] == '\0') {
779 fprintf(stderr, "No line with FIRMWARE_LOCATION\n");
780 return 0;
781 }
782
783 fseek(config, 0, SEEK_SET);
784 /* Get a line */
785 while (get_input_file_line(config, oneline, MAX_LINE_SIZE) == OK) {
786 /* get a line */
787 if (skip_comment_blank_line(oneline))
788 continue;
789 if (is_valid_entry(oneline, match)) {
Karthikeyan Ramasubramaniandc498932023-05-02 22:10:57 -0600790 if (strcmp(&(oneline[match[FW_TYPE].rm_so]), FW_LOCATION) == 0 ||
791 strcmp(&(oneline[match[FW_TYPE].rm_so]), SOC_NAME) == 0) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800792 continue;
793 } else {
Zheng Bao994ff522023-03-09 11:43:55 +0800794 if (process_one_line(oneline, match, dir,
Zheng Bao7db76422021-03-27 18:15:35 +0800795 cb_config) == 0)
796 return 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800797 }
798 } else {
799 fprintf(stderr, "AMDFWTOOL config file line can't be parsed \"%s\"\n", oneline);
800 return 0;
801 }
802 }
803 return 1;
804}