Coverage Report

Created: 2026-03-11 06:21

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