2dc6ba8337a7bf65a0c9570573c8144a9ef1a36a
[platform/kernel/u-boot.git] / lib / efi_loader / efi_setup.c
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  */
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  */
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  */
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
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  */
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  */
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  */
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_ESRT)) {
231                 ret = efi_esrt_register();
232                 if (ret != EFI_SUCCESS)
233                         goto out;
234         }
235
236         if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) {
237                 ret = efi_tcg2_register();
238                 if (ret != EFI_SUCCESS)
239                         goto out;
240         }
241
242         /* Secure boot */
243         ret = efi_init_secure_boot();
244         if (ret != EFI_SUCCESS)
245                 goto out;
246
247         /* Indicate supported runtime services */
248         ret = efi_init_runtime_supported();
249         if (ret != EFI_SUCCESS)
250                 goto out;
251
252         /* Initialize EFI driver uclass */
253         ret = efi_driver_init();
254         if (ret != EFI_SUCCESS)
255                 goto out;
256
257         if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT)) {
258                 ret = efi_load_capsule_drivers();
259                 if (ret != EFI_SUCCESS)
260                         goto out;
261         }
262
263 #if defined(CONFIG_LCD) || defined(CONFIG_DM_VIDEO)
264         ret = efi_gop_register();
265         if (ret != EFI_SUCCESS)
266                 goto out;
267 #endif
268 #ifdef CONFIG_NET
269         ret = efi_net_register();
270         if (ret != EFI_SUCCESS)
271                 goto out;
272 #endif
273 #ifdef CONFIG_GENERATE_ACPI_TABLE
274         ret = efi_acpi_register();
275         if (ret != EFI_SUCCESS)
276                 goto out;
277 #endif
278 #ifdef CONFIG_GENERATE_SMBIOS_TABLE
279         ret = efi_smbios_register();
280         if (ret != EFI_SUCCESS)
281                 goto out;
282 #endif
283         ret = efi_watchdog_register();
284         if (ret != EFI_SUCCESS)
285                 goto out;
286
287         ret = efi_init_capsule();
288         if (ret != EFI_SUCCESS)
289                 goto out;
290
291         /* Initialize EFI runtime services */
292         ret = efi_reset_system_init();
293         if (ret != EFI_SUCCESS)
294                 goto out;
295
296         /* Execute capsules after reboot */
297         if (IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK) &&
298             !IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK_EARLY))
299                 ret = efi_launch_capsules();
300 out:
301         efi_obj_list_initialized = ret;
302         return ret;
303 }