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