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