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