blob: 0c2e71d94f4ad0ad467d895b1b26a4d28781022e [file] [log] [blame]
Zheng Baoc5e28ab2020-10-28 11:38:09 +08001#include <stdio.h>
2#include <regex.h>
3#include <string.h>
4#include <stdlib.h>
Idwer Vollering93df1d92020-12-30 00:01:59 +01005#include <stdint.h>
Zheng Baoc5e28ab2020-10-28 11:38:09 +08006
7#include "amdfwtool.h"
8
9/* TODO: a empty line does not matched. */
10static const char blank_or_comment_regex[] =
11 /* a blank line */
12 "(^[[:space:]]*$)"
13 "|" /* or ... */
14 /* a line consisting of: optional whitespace followed by */
15 "(^[[:space:]]*"
16 /* a '#' character and optionally, additional characters */
17 "#.*$)";
18static regex_t blank_or_comment_expr;
19
20static const char entries_line_regex[] =
21 /* optional whitespace */
22 "^[[:space:]]*"
23 /* followed by a chunk of nonwhitespace for macro field */
24 "([^[:space:]]+)"
25 /* followed by one or more whitespace characters */
26 "[[:space:]]+"
27 /* followed by a chunk of nonwhitespace for filename field */
28 "([^[:space:]]+)"
29 /* followed by optional whitespace */
30 "[[:space:]]*$";
31static regex_t entries_line_expr;
32
33void compile_reg_expr(int cflags, const char *expr, regex_t *reg)
34{
35 static const size_t ERROR_BUF_SIZE = 256;
36 char error_msg[ERROR_BUF_SIZE];
37 int result;
38
39 result = regcomp(reg, expr, cflags);
40 if (result != 0) {
41 regerror(result, reg, error_msg, ERROR_BUF_SIZE);
Zheng Bao77a2c672020-10-01 17:05:43 +080042 fprintf(stderr, "%s\n", error_msg);
Zheng Baoc5e28ab2020-10-28 11:38:09 +080043 }
44}
45
46extern amd_fw_entry amd_psp_fw_table[];
47extern amd_bios_entry amd_bios_table[];
48
49static uint8_t find_register_fw_filename_psp_dir(char *fw_name, char *filename,
50 amd_cb_config *cb_config)
51{
52 amd_fw_type fw_type = AMD_FW_INVALID;
53 amd_fw_entry *psp_tableptr;
54 uint8_t subprog;
55
56 if (strcmp(fw_name, "PSPBTLDR_WL_FILE") == 0) {
57 if (cb_config->have_whitelist == 1) {
58 fw_type = AMD_FW_PSP_BOOTLOADER;
59 subprog = 0;
60 } else {
61 fw_type = AMD_FW_SKIP;
62 }
63 } else if (strcmp(fw_name, "PSPBTLDR_FILE") == 0) {
64 if (cb_config->have_whitelist == 0) {
65 fw_type = AMD_FW_PSP_BOOTLOADER;
66 subprog = 0;
67 } else {
68 fw_type = AMD_FW_SKIP;
69 }
70 } else if (strcmp(fw_name, "AMD_PUBKEY_FILE") == 0) {
71 fw_type = AMD_FW_PSP_PUBKEY;
72 subprog = 0;
73 } else if (strcmp(fw_name, "PSPRCVR_FILE") == 0) {
74 fw_type = AMD_FW_PSP_RECOVERY;
75 subprog = 0;
76 } else if (strcmp(fw_name, "PUBSIGNEDKEY_FILE") == 0) {
77 fw_type = AMD_FW_PSP_RTM_PUBKEY;
78 subprog = 0;
79 } else if (strcmp(fw_name, "PSPNVRAM_FILE") == 0) {
80 fw_type = AMD_FW_PSP_NVRAM;
81 subprog = 0;
82 } else if (strcmp(fw_name, "SMUSCS_FILE") == 0) {
83 fw_type = AMD_FW_PSP_SMUSCS;
84 subprog = 0;
85 } else if (strcmp(fw_name, "PSPTRUSTLETS_FILE") == 0) {
86 fw_type = AMD_FW_PSP_TRUSTLETS;
87 subprog = 0;
88 } else if (strcmp(fw_name, "PSPSECUREDEBUG_FILE") == 0) {
89 fw_type = AMD_FW_PSP_SECURED_DEBUG;
90 subprog = 0;
91 } else if (strcmp(fw_name, "PSP_SMUFW1_SUB0_FILE") == 0) {
92 fw_type = AMD_FW_PSP_SMU_FIRMWARE;
93 subprog = 0;
Zheng Baobf29a0d2020-12-03 23:00:48 +080094 } else if (strcmp(fw_name, "PSP_HW_IPCFG_FILE") == 0) {
95 fw_type = AMD_HW_IPCFG;
96 subprog = 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +080097 } else if (strcmp(fw_name, "PSP_SMUFW1_SUB1_FILE") == 0) {
98 fw_type = AMD_FW_PSP_SMU_FIRMWARE;
99 subprog = 1;
100 } else if (strcmp(fw_name, "PSP_SMUFW1_SUB2_FILE") == 0) {
101 fw_type = AMD_FW_PSP_SMU_FIRMWARE;
102 subprog = 2;
103 } else if (strcmp(fw_name, "PSP_SMUFW2_SUB0_FILE") == 0) {
104 fw_type = AMD_FW_PSP_SMU_FIRMWARE2;
105 subprog = 0;
106 } else if (strcmp(fw_name, "PSP_SMUFW2_SUB1_FILE") == 0) {
107 fw_type = AMD_FW_PSP_SMU_FIRMWARE2;
108 subprog = 1;
109 } else if (strcmp(fw_name, "PSP_SMUFW2_SUB2_FILE") == 0) {
110 fw_type = AMD_FW_PSP_SMU_FIRMWARE2;
111 subprog = 2;
112 } else if (strcmp(fw_name, "PSP_SEC_DBG_KEY_FILE") == 0) {
113 if (cb_config->unlock_secure == 1) {
114 fw_type = AMD_FW_PSP_SECURED_DEBUG;
115 subprog = 0;
116 } else {
117 fw_type = AMD_FW_SKIP;
118 }
119 } else if (strcmp(fw_name, "PSP_SEC_DEBUG_FILE") == 0) {
120 if (cb_config->unlock_secure == 1) {
121 fw_type = AMD_DEBUG_UNLOCK;
122 subprog = 0;
123 } else {
124 fw_type = AMD_FW_SKIP;
125 }
126 } else if (strcmp(fw_name, "PSP_ABL0_FILE") == 0) {
127 fw_type = AMD_ABL0;
128 subprog = 0;
129 } else if (strcmp(fw_name, "PSP_ABL1_FILE") == 0) {
130 fw_type = AMD_ABL1;
131 subprog = 0;
132 } else if (strcmp(fw_name, "PSP_ABL2_FILE") == 0) {
133 fw_type = AMD_ABL2;
134 subprog = 0;
135 } else if (strcmp(fw_name, "PSP_ABL3_FILE") == 0) {
136 fw_type = AMD_ABL3;
137 subprog = 0;
138 } else if (strcmp(fw_name, "PSP_ABL4_FILE") == 0) {
139 fw_type = AMD_ABL4;
140 subprog = 0;
141 } else if (strcmp(fw_name, "PSP_ABL5_FILE") == 0) {
142 fw_type = AMD_ABL5;
143 subprog = 0;
144 } else if (strcmp(fw_name, "PSP_ABL6_FILE") == 0) {
145 fw_type = AMD_ABL6;
146 subprog = 0;
147 } else if (strcmp(fw_name, "PSP_ABL7_FILE") == 0) {
148 fw_type = AMD_ABL7;
149 subprog = 0;
150 } else if (strcmp(fw_name, "PSPSECUREOS_FILE") == 0) {
151 if (cb_config->use_secureos == 1) {
152 fw_type = AMD_FW_PSP_SECURED_OS;
153 subprog = 0;
154 } else {
155 fw_type = AMD_FW_SKIP;
156 }
157 } else if (strcmp(fw_name, "PSPTRUSTLETS_FILE") == 0) {
158 if (cb_config->use_secureos) {
159 fw_type = AMD_FW_PSP_TRUSTLETS;
160 subprog = 0;
161 } else {
162 fw_type = AMD_FW_SKIP;
163 }
164 } else if (strcmp(fw_name, "TRUSTLETKEY_FILE") == 0) {
165 if (cb_config->use_secureos) {
166 fw_type = AMD_FW_PSP_TRUSTLETKEY;
167 subprog = 0;
168 } else {
169 fw_type = AMD_FW_SKIP;
170 }
171 } else if (strcmp(fw_name, "PSP_IKEK_FILE") == 0) {
172 fw_type = AMD_WRAPPED_IKEK;
173 subprog = 0;
Zheng Baobf29a0d2020-12-03 23:00:48 +0800174 } else if (strcmp(fw_name, "PSP_SECG0_FILE") == 0) {
175 fw_type = AMD_SEC_GASKET;
176 subprog = 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800177 } else if (strcmp(fw_name, "PSP_SECG1_FILE") == 0) {
178 fw_type = AMD_SEC_GASKET;
179 subprog = 1;
180 } else if (strcmp(fw_name, "PSP_SECG2_FILE") == 0) {
181 fw_type = AMD_SEC_GASKET;
182 subprog = 2;
Zheng Baobf29a0d2020-12-03 23:00:48 +0800183 } else if (strcmp(fw_name, "PSP_MP2FW0_FILE") == 0) {
184 if (cb_config->load_mp2_fw == 1) {
185 fw_type = AMD_MP2_FW;
186 subprog = 0;
187 } else {
188 fw_type = AMD_FW_SKIP;
189 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800190 } else if (strcmp(fw_name, "PSP_MP2FW1_FILE") == 0) {
191 if (cb_config->load_mp2_fw == 1) {
192 fw_type = AMD_MP2_FW;
193 subprog = 1;
194 } else {
195 fw_type = AMD_FW_SKIP;
196 }
197 } else if (strcmp(fw_name, "PSP_MP2FW2_FILE") == 0) {
198 if (cb_config->load_mp2_fw == 1) {
199 fw_type = AMD_MP2_FW;
200 subprog = 2;
201 } else {
202 fw_type = AMD_FW_SKIP;
203 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800204 } else if (strcmp(fw_name, "PSP_DRIVERS_FILE") == 0) {
205 fw_type = AMD_DRIVER_ENTRIES;
206 subprog = 0;
207 } else if (strcmp(fw_name, "PSP_S0I3_FILE") == 0) {
208 if (cb_config->s0i3 == 1) {
209 fw_type = AMD_S0I3_DRIVER;
210 subprog = 0;
211 } else {
212 fw_type = AMD_FW_SKIP;
213 }
Zheng Baobf29a0d2020-12-03 23:00:48 +0800214 } else if (strcmp(fw_name, "AMD_DRIVER_ENTRIES") == 0) {
215 fw_type = AMD_DRIVER_ENTRIES;
216 subprog = 0;
217 } else if (strcmp(fw_name, "VBIOS_BTLOADER_FILE") == 0) {
218 fw_type = AMD_VBIOS_BTLOADER;
219 subprog = 0;
220 } else if (strcmp(fw_name, "SECURE_POLICY_L1_FILE") == 0) {
221 fw_type = AMD_FW_TOS_SEC_POLICY;
222 subprog = 0;
223 } else if (strcmp(fw_name, "UNIFIEDUSB_FILE") == 0) {
224 fw_type = AMD_FW_USB_PHY;
225 subprog = 0;
226 } else if (strcmp(fw_name, "DRTMTA_FILE") == 0) {
227 fw_type = AMD_FW_DRTM_TA;
228 subprog = 0;
229 } else if (strcmp(fw_name, "KEYDBBL_FILE") == 0) {
230 fw_type = AMD_FW_KEYDB_BL;
231 subprog = 0;
232 } else if (strcmp(fw_name, "KEYDB_TOS_FILE") == 0) {
233 fw_type = AMD_FW_KEYDB_TOS;
234 subprog = 0;
235 } else if (strcmp(fw_name, "DMCUERAMDCN21_FILE") == 0) {
236 fw_type = AMD_FW_DMCU_ERAM;
237 subprog = 0;
238 } else if (strcmp(fw_name, "DMCUINTVECTORSDCN21_FILE") == 0) {
239 fw_type = AMD_FW_DMCU_ISR;
240 subprog = 0;
241 } else if (strcmp(fw_name, "PSP_KVM_ENGINE_DUMMY_FILE") == 0) {
242 fw_type = AMD_FW_KVM_IMAGE;
243 subprog = 0;
244 } else if (strcmp(fw_name, "RPMC_FILE") == 0) {
245 fw_type = AMD_RPMC_NVRAM;
246 subprog = 0;
Zheng Baob993cb22021-02-02 18:48:23 +0800247 } else if (strcmp(fw_name, "PSPBTLDR_AB_FILE") == 0) {
248 fw_type = AMD_FW_PSP_BOOTLOADER_AB;
249 subprog = 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800250 } else {
251 fw_type = AMD_FW_INVALID;
252 /* TODO: Add more */
253 }
Zheng Baobf29a0d2020-12-03 23:00:48 +0800254
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800255 /* Search and fill the filename */
256 psp_tableptr = &amd_psp_fw_table[0];
257 if (fw_type != AMD_FW_SKIP && fw_type != AMD_FW_INVALID) {
258 while (psp_tableptr->type != AMD_FW_INVALID) {
259 /* instance are not used in PSP table */
260 if (psp_tableptr->type == fw_type && psp_tableptr->subprog == subprog) {
261 psp_tableptr->filename = filename;
262 break;
263 }
264 psp_tableptr++;
265 }
266 }
267 if (fw_type == AMD_FW_INVALID)
268 return 0;
269 else
270 return 1;
271}
272
273static uint8_t find_register_fw_filename_bios_dir(char *fw_name, char *filename,
274 amd_cb_config *cb_config)
275{
276 amd_bios_type fw_type = AMD_BIOS_INVALID;
277 amd_bios_entry *bhd_tableptr;
Felix Heldea3417b2020-11-20 20:08:42 +0100278 uint8_t subprog = 0;
279 uint8_t instance = 0;
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800280
281 (void) (cb_config); /* Remove warning and reserved for future. */
282
283 if (strcmp(fw_name, "PSP_PMUI_FILE1") == 0) {
284 fw_type = AMD_BIOS_PMUI;
285 subprog = 0;
286 instance = 1;
287 } else if (strcmp(fw_name, "PSP_PMUI_FILE2") == 0) {
288 fw_type = AMD_BIOS_PMUI;
289 subprog = 0;
290 instance = 4;
291 } else if (strcmp(fw_name, "PSP_PMUI_FILE3") == 0) {
292 fw_type = AMD_BIOS_PMUI;
293 subprog = 1;
294 instance = 1;
295 } else if (strcmp(fw_name, "PSP_PMUI_FILE4") == 0) {
296 fw_type = AMD_BIOS_PMUI;
297 subprog = 1;
298 instance = 4;
299 } else if (strcmp(fw_name, "PSP_PMUD_FILE1") == 0) {
300 fw_type = AMD_BIOS_PMUD;
301 subprog = 0;
302 instance = 1;
303 } else if (strcmp(fw_name, "PSP_PMUD_FILE2") == 0) {
304 fw_type = AMD_BIOS_PMUD;
305 subprog = 0;
306 instance = 4;
307 } else if (strcmp(fw_name, "PSP_PMUD_FILE3") == 0) {
308 fw_type = AMD_BIOS_PMUD;
309 subprog = 1;
310 instance = 1;
311 } else if (strcmp(fw_name, "PSP_PMUD_FILE4") == 0) {
312 fw_type = AMD_BIOS_PMUD;
313 subprog = 1;
314 instance = 4;
Zheng Baobf29a0d2020-12-03 23:00:48 +0800315 } else if (strcmp(fw_name, "RTM_PUBKEY_FILE") == 0) {
316 fw_type = AMD_BIOS_RTM_PUBKEY;
317 subprog = 0;
318 instance = 0;
Zheng Bao50143732020-11-14 21:54:06 +0800319 } else if (strcmp(fw_name, "PSP_MP2CFG_FILE") == 0) {
320 if (cb_config->load_mp2_fw == 1) {
321 fw_type = AMD_BIOS_MP2_CFG;
322 subprog = 0;
323 } else {
Martin Rotha8e31ca2021-02-13 21:42:46 -0700324 fw_type = AMD_BIOS_SKIP;
Zheng Bao50143732020-11-14 21:54:06 +0800325 }
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800326 } else {
327 fw_type = AMD_BIOS_INVALID;
328 }
329
330 bhd_tableptr = amd_bios_table;
331
332 if (fw_type != AMD_BIOS_INVALID && fw_type != AMD_BIOS_SKIP) {
333 while (bhd_tableptr->type != AMD_BIOS_INVALID) {
334 if (bhd_tableptr->type == fw_type &&
335 bhd_tableptr->subpr == subprog &&
336 bhd_tableptr->inst == instance) {
337 bhd_tableptr->filename = filename;
338 break;
339 }
340 bhd_tableptr++;
341 }
342 }
343 if (fw_type == AMD_BIOS_INVALID)
344 return 0;
345 else
346 return 1;
347}
348
349#define MAX_LINE_SIZE 1024
350
351int get_input_file_line(FILE *f, char line[], int line_buf_size)
352{
353 if (fgets(line, line_buf_size, f) == NULL)
354 return LINE_EOF;
355
356 /* If the file contains a line that is too long, then it's best
357 * to let the user know right away rather than passing back a
358 * truncated result that will lead to problems later on.
359 */
360 line[strlen(line) - 1] = '\0';
361
362 if (strlen(line) == ((size_t) (line_buf_size - 1))) {
Zheng Bao77a2c672020-10-01 17:05:43 +0800363 fprintf(stderr, "The line size in config file should be lower than %d bytes.\n",
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800364 MAX_LINE_SIZE);
365 exit(1);
366 }
367
368 return OK;
369}
370
371static int is_valid_entry(char *oneline, regmatch_t *match)
372{
373 int retval;
374
375 if (regexec(&entries_line_expr, oneline, 3, match, 0) == 0) {
376 oneline[match[1].rm_eo] = '\0';
377 oneline[match[2].rm_eo] = '\0';
378 retval = 1;
379 } else
380 retval = 0;
381
382 return retval;
383}
384
385static int skip_comment_blank_line(char *oneline)
386{
387 int retval;
388
389 if (regexec(&blank_or_comment_expr, oneline, 0, NULL, 0) == 0) {
390 /* skip comment and blank */
391 retval = 1;
392 } else {
393 /* no match */
394 retval = 0;
395 }
396
397 return retval;
398}
399
400#define N_MATCHES 4
401/*
402 return value:
403 0: The config file can not be parsed correctly.
404 1: The config file can be parsed correctly.
405 */
406uint8_t process_config(FILE *config, amd_cb_config *cb_config, uint8_t print_deps)
407{
408 char oneline[MAX_LINE_SIZE], *path_filename;
409 regmatch_t match[N_MATCHES];
410 char dir[MAX_LINE_SIZE] = {'\0'};
411
412 compile_reg_expr(REG_EXTENDED | REG_NEWLINE,
413 blank_or_comment_regex, &blank_or_comment_expr);
414 compile_reg_expr(REG_EXTENDED | REG_NEWLINE,
415 entries_line_regex, &entries_line_expr);
416
417 /* Get a line */
Zheng Bao3384e4a2020-10-06 12:03:11 +0800418 /* Get FIRMWARE_LOCATION in the first loop */
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800419 while (get_input_file_line(config, oneline, MAX_LINE_SIZE) == OK) {
420 /* get a line */
421 if (skip_comment_blank_line(oneline))
422 continue;
423 if (is_valid_entry(oneline, match)) {
Zheng Bao3384e4a2020-10-06 12:03:11 +0800424 if (strcmp(&(oneline[match[1].rm_so]), "FIRMWARE_LOCATION") == 0) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800425 strcpy(dir, &(oneline[match[2].rm_so]));
426 break;
427 }
428 }
429 }
430
431 if (dir[0] == '\0') {
432 fprintf(stderr, "No line with FIRMWARE_LOCATION\n");
433 return 0;
434 }
435
436 fseek(config, 0, SEEK_SET);
437 /* Get a line */
438 while (get_input_file_line(config, oneline, MAX_LINE_SIZE) == OK) {
439 /* get a line */
440 if (skip_comment_blank_line(oneline))
441 continue;
442 if (is_valid_entry(oneline, match)) {
Zheng Bao3384e4a2020-10-06 12:03:11 +0800443 if (strcmp(&(oneline[match[1].rm_so]), "FIRMWARE_LOCATION") == 0) {
Zheng Baoc5e28ab2020-10-28 11:38:09 +0800444 continue;
445 } else {
446 path_filename = malloc(MAX_LINE_SIZE);
447 strcpy(path_filename, dir);
448 strcat(path_filename, "/");
449 strcat(path_filename, &(oneline[match[2].rm_so]));
450
451 if (find_register_fw_filename_psp_dir(
452 &(oneline[match[1].rm_so]),
453 path_filename, cb_config) == 0) {
454 if (find_register_fw_filename_bios_dir(
455 &(oneline[match[1].rm_so]),
456 path_filename, cb_config) == 0) {
457 fprintf(stderr, "Module's name \"%s\" is not valid\n", oneline);
458 return 0; /* Stop parsing. */
459 } else {
460 if (print_deps)
461 printf(" %s ", path_filename);
462 }
463 } else {
464 if (print_deps)
465 printf(" %s ", path_filename);
466 }
467 }
468 } else {
469 fprintf(stderr, "AMDFWTOOL config file line can't be parsed \"%s\"\n", oneline);
470 return 0;
471 }
472 }
473 return 1;
474}