1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * EFI setup code
4 *
5 * Copyright (c) 2016-2018 Alexander Graf et al.
6 */
7
8 #define LOG_CATEGORY LOGC_EFI
9
10 #include <common.h>
11 #include <efi_loader.h>
12 #include <efi_variable.h>
13 #include <log.h>
14 #include <asm-generic/unaligned.h>
15
16 #define OBJ_LIST_NOT_INITIALIZED 1
17
18 efi_status_t efi_obj_list_initialized = OBJ_LIST_NOT_INITIALIZED;
19
20 /*
21 * Allow unaligned memory access.
22 *
23 * This routine is overridden by architectures providing this feature.
24 */
allow_unaligned(void)25 void __weak allow_unaligned(void)
26 {
27 }
28
29 /**
30 * efi_init_platform_lang() - define supported languages
31 *
32 * Set the PlatformLangCodes and PlatformLang variables.
33 *
34 * Return: status code
35 */
efi_init_platform_lang(void)36 static efi_status_t efi_init_platform_lang(void)
37 {
38 efi_status_t ret;
39 efi_uintn_t data_size = 0;
40 char *lang = CONFIG_EFI_PLATFORM_LANG_CODES;
41 char *pos;
42
43 /*
44 * Variable PlatformLangCodes defines the language codes that the
45 * machine can support.
46 */
47 ret = efi_set_variable_int(u"PlatformLangCodes",
48 &efi_global_variable_guid,
49 EFI_VARIABLE_BOOTSERVICE_ACCESS |
50 EFI_VARIABLE_RUNTIME_ACCESS |
51 EFI_VARIABLE_READ_ONLY,
52 sizeof(CONFIG_EFI_PLATFORM_LANG_CODES),
53 CONFIG_EFI_PLATFORM_LANG_CODES, false);
54 if (ret != EFI_SUCCESS)
55 goto out;
56
57 /*
58 * Variable PlatformLang defines the language that the machine has been
59 * configured for.
60 */
61 ret = efi_get_variable_int(u"PlatformLang",
62 &efi_global_variable_guid,
63 NULL, &data_size, &pos, NULL);
64 if (ret == EFI_BUFFER_TOO_SMALL) {
65 /* The variable is already set. Do not change it. */
66 ret = EFI_SUCCESS;
67 goto out;
68 }
69
70 /*
71 * The list of supported languages is semicolon separated. Use the first
72 * language to initialize PlatformLang.
73 */
74 pos = strchr(lang, ';');
75 if (pos)
76 *pos = 0;
77
78 ret = efi_set_variable_int(u"PlatformLang",
79 &efi_global_variable_guid,
80 EFI_VARIABLE_NON_VOLATILE |
81 EFI_VARIABLE_BOOTSERVICE_ACCESS |
82 EFI_VARIABLE_RUNTIME_ACCESS,
83 1 + strlen(lang), lang, false);
84 out:
85 if (ret != EFI_SUCCESS)
86 printf("EFI: cannot initialize platform language settings\n");
87 return ret;
88 }
89
90 #ifdef CONFIG_EFI_SECURE_BOOT
91 /**
92 * efi_init_secure_boot - initialize secure boot state
93 *
94 * Return: status code
95 */
efi_init_secure_boot(void)96 static efi_status_t efi_init_secure_boot(void)
97 {
98 efi_guid_t signature_types[] = {
99 EFI_CERT_SHA256_GUID,
100 EFI_CERT_X509_GUID,
101 };
102 efi_status_t ret;
103
104 ret = efi_set_variable_int(u"SignatureSupport",
105 &efi_global_variable_guid,
106 EFI_VARIABLE_READ_ONLY |
107 EFI_VARIABLE_BOOTSERVICE_ACCESS |
108 EFI_VARIABLE_RUNTIME_ACCESS,
109 sizeof(signature_types),
110 &signature_types, false);
111 if (ret != EFI_SUCCESS)
112 printf("EFI: cannot initialize SignatureSupport variable\n");
113
114 return ret;
115 }
116 #else
efi_init_secure_boot(void)117 static efi_status_t efi_init_secure_boot(void)
118 {
119 return EFI_SUCCESS;
120 }
121 #endif /* CONFIG_EFI_SECURE_BOOT */
122
123 /**
124 * efi_init_capsule - initialize capsule update state
125 *
126 * Return: status code
127 */
efi_init_capsule(void)128 static efi_status_t efi_init_capsule(void)
129 {
130 efi_status_t ret = EFI_SUCCESS;
131
132 if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT)) {
133 u16 var_name16[12];
134
135 efi_create_indexed_name(var_name16, sizeof(var_name16),
136 "Capsule", CONFIG_EFI_CAPSULE_MAX);
137
138 ret = efi_set_variable_int(u"CapsuleMax",
139 &efi_guid_capsule_report,
140 EFI_VARIABLE_READ_ONLY |
141 EFI_VARIABLE_BOOTSERVICE_ACCESS |
142 EFI_VARIABLE_RUNTIME_ACCESS,
143 22, var_name16, false);
144 if (ret != EFI_SUCCESS)
145 printf("EFI: cannot initialize CapsuleMax variable\n");
146 }
147
148 return ret;
149 }
150
151 /**
152 * efi_init_os_indications() - indicate supported features for OS requests
153 *
154 * Set the OsIndicationsSupported variable.
155 *
156 * Return: status code
157 */
efi_init_os_indications(void)158 static efi_status_t efi_init_os_indications(void)
159 {
160 u64 os_indications_supported = 0;
161
162 if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT))
163 os_indications_supported |=
164 EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED;
165
166 if (IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK))
167 os_indications_supported |=
168 EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED;
169
170 if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT))
171 os_indications_supported |=
172 EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED;
173
174 return efi_set_variable_int(u"OsIndicationsSupported",
175 &efi_global_variable_guid,
176 EFI_VARIABLE_BOOTSERVICE_ACCESS |
177 EFI_VARIABLE_RUNTIME_ACCESS |
178 EFI_VARIABLE_READ_ONLY,
179 sizeof(os_indications_supported),
180 &os_indications_supported, false);
181 }
182
183 /**
184 * efi_init_early() - handle initialization at early stage
185 *
186 * expected to be called in board_init_r().
187 *
188 * Return: status code
189 */
efi_init_early(void)190 int efi_init_early(void)
191 {
192 efi_status_t ret;
193
194 /* Allow unaligned memory access */
195 allow_unaligned();
196
197 /* Initialize root node */
198 ret = efi_root_node_register();
199 if (ret != EFI_SUCCESS)
200 goto out;
201
202 ret = efi_console_register();
203 if (ret != EFI_SUCCESS)
204 goto out;
205
206 /* Initialize EFI driver uclass */
207 ret = efi_driver_init();
208 if (ret != EFI_SUCCESS)
209 goto out;
210
211 return 0;
212 out:
213 /* never re-init UEFI subsystem */
214 efi_obj_list_initialized = ret;
215
216 return -1;
217 }
218
219 /**
220 * efi_init_obj_list() - Initialize and populate EFI object list
221 *
222 * Return: status code
223 */
efi_init_obj_list(void)224 efi_status_t efi_init_obj_list(void)
225 {
226 efi_status_t ret = EFI_SUCCESS;
227
228 /* Initialize once only */
229 if (efi_obj_list_initialized != OBJ_LIST_NOT_INITIALIZED)
230 return efi_obj_list_initialized;
231
232 /* Set up console modes */
233 efi_setup_console_size();
234
235 /*
236 * Probe block devices to find the ESP.
237 * efi_disks_register() must be called before efi_init_variables().
238 */
239 ret = efi_disks_register();
240 if (ret != EFI_SUCCESS)
241 goto out;
242
243 /* Initialize variable services */
244 ret = efi_init_variables();
245 if (ret != EFI_SUCCESS)
246 goto out;
247
248 /* Define supported languages */
249 ret = efi_init_platform_lang();
250 if (ret != EFI_SUCCESS)
251 goto out;
252
253 /* Indicate supported features */
254 ret = efi_init_os_indications();
255 if (ret != EFI_SUCCESS)
256 goto out;
257
258 /* Initialize system table */
259 ret = efi_initialize_system_table();
260 if (ret != EFI_SUCCESS)
261 goto out;
262
263 if (IS_ENABLED(CONFIG_EFI_ECPT)) {
264 ret = efi_ecpt_register();
265 if (ret != EFI_SUCCESS)
266 goto out;
267 }
268
269 if (IS_ENABLED(CONFIG_EFI_ESRT)) {
270 ret = efi_esrt_register();
271 if (ret != EFI_SUCCESS)
272 goto out;
273 }
274
275 if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) {
276 ret = efi_tcg2_register();
277 if (ret != EFI_SUCCESS)
278 goto out;
279
280 ret = efi_tcg2_do_initial_measurement();
281 if (ret == EFI_SECURITY_VIOLATION)
282 goto out;
283 }
284
285 /* Install EFI_RNG_PROTOCOL */
286 if (IS_ENABLED(CONFIG_EFI_RNG_PROTOCOL)) {
287 ret = efi_rng_register();
288 if (ret != EFI_SUCCESS)
289 goto out;
290 }
291
292 if (IS_ENABLED(CONFIG_EFI_RISCV_BOOT_PROTOCOL)) {
293 ret = efi_riscv_register();
294 if (ret != EFI_SUCCESS)
295 goto out;
296 }
297
298 /* Secure boot */
299 ret = efi_init_secure_boot();
300 if (ret != EFI_SUCCESS)
301 goto out;
302
303 /* Indicate supported runtime services */
304 ret = efi_init_runtime_supported();
305 if (ret != EFI_SUCCESS)
306 goto out;
307
308 if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT)) {
309 ret = efi_load_capsule_drivers();
310 if (ret != EFI_SUCCESS)
311 goto out;
312 }
313
314 if (IS_ENABLED(CONFIG_VIDEO)) {
315 ret = efi_gop_register();
316 if (ret != EFI_SUCCESS)
317 goto out;
318 }
319 #ifdef CONFIG_NETDEVICES
320 ret = efi_net_register();
321 if (ret != EFI_SUCCESS)
322 goto out;
323 #endif
324 #ifdef CONFIG_GENERATE_ACPI_TABLE
325 ret = efi_acpi_register();
326 if (ret != EFI_SUCCESS)
327 goto out;
328 #endif
329 #ifdef CONFIG_GENERATE_SMBIOS_TABLE
330 ret = efi_smbios_register();
331 if (ret != EFI_SUCCESS)
332 goto out;
333 #endif
334 ret = efi_watchdog_register();
335 if (ret != EFI_SUCCESS)
336 goto out;
337
338 ret = efi_init_capsule();
339 if (ret != EFI_SUCCESS)
340 goto out;
341
342 /* Initialize EFI runtime services */
343 ret = efi_reset_system_init();
344 if (ret != EFI_SUCCESS)
345 goto out;
346
347 /* Execute capsules after reboot */
348 if (IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK) &&
349 !IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK_EARLY))
350 ret = efi_launch_capsules();
351 out:
352 efi_obj_list_initialized = ret;
353 return ret;
354 }
355