uboot/lib/efi_loader/efi_setup.c
<<
>>
Prefs
   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
  17efi_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 */
  24void __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 */
  35static 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(u"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(u"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(u"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);
  83out:
  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 */
  95static 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(u"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
 116static 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 */
 127static 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(u"CapsuleMax",
 133                                           &efi_guid_capsule_report,
 134                                           EFI_VARIABLE_READ_ONLY |
 135                                           EFI_VARIABLE_BOOTSERVICE_ACCESS |
 136                                           EFI_VARIABLE_RUNTIME_ACCESS,
 137                                           22, u"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 */
 152static 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(u"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 * __efi_init_early() - handle initialization at early stage
 179 *
 180 * This function is called in efi_init_obj_list() only if
 181 * !CONFIG_EFI_SETUP_EARLY.
 182 *
 183 * Return:      status code
 184 */
 185static efi_status_t __efi_init_early(void)
 186{
 187        efi_status_t ret = EFI_SUCCESS;
 188
 189        /* Allow unaligned memory access */
 190        allow_unaligned();
 191
 192        /* Initialize root node */
 193        ret = efi_root_node_register();
 194        if (ret != EFI_SUCCESS)
 195                goto out;
 196
 197        ret = efi_console_register();
 198        if (ret != EFI_SUCCESS)
 199                goto out;
 200
 201        ret = efi_disk_init();
 202out:
 203        return ret;
 204}
 205
 206/**
 207 * efi_init_early() - handle initialization at early stage
 208 *
 209 * external version of __efi_init_early(); expected to be called in
 210 * board_init_r().
 211 *
 212 * Return:      status code
 213 */
 214int efi_init_early(void)
 215{
 216        efi_status_t ret;
 217
 218        ret = __efi_init_early();
 219        if (ret != EFI_SUCCESS) {
 220                /* never re-init UEFI subsystem */
 221                efi_obj_list_initialized = ret;
 222                return -1;
 223        }
 224        return 0;
 225}
 226
 227/**
 228 * efi_init_obj_list() - Initialize and populate EFI object list
 229 *
 230 * Return:      status code
 231 */
 232efi_status_t efi_init_obj_list(void)
 233{
 234        efi_status_t ret = EFI_SUCCESS;
 235
 236        /* Initialize once only */
 237        if (efi_obj_list_initialized != OBJ_LIST_NOT_INITIALIZED)
 238                return efi_obj_list_initialized;
 239
 240        if (!IS_ENABLED(CONFIG_EFI_SETUP_EARLY)) {
 241                ret = __efi_init_early();
 242                if (ret != EFI_SUCCESS)
 243                        goto out;
 244        }
 245
 246        /* Set up console modes */
 247        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        ret = efi_disks_register();
 254        if (ret != EFI_SUCCESS)
 255                goto out;
 256
 257        /* Initialize variable services */
 258        ret = efi_init_variables();
 259        if (ret != EFI_SUCCESS)
 260                goto out;
 261
 262        /* Define supported languages */
 263        ret = efi_init_platform_lang();
 264        if (ret != EFI_SUCCESS)
 265                goto out;
 266
 267        /* Indicate supported features */
 268        ret = efi_init_os_indications();
 269        if (ret != EFI_SUCCESS)
 270                goto out;
 271
 272        /* Initialize system table */
 273        ret = efi_initialize_system_table();
 274        if (ret != EFI_SUCCESS)
 275                goto out;
 276
 277        if (IS_ENABLED(CONFIG_EFI_ECPT)) {
 278                ret = efi_ecpt_register();
 279                if (ret != EFI_SUCCESS)
 280                        goto out;
 281        }
 282
 283        if (IS_ENABLED(CONFIG_EFI_ESRT)) {
 284                ret = efi_esrt_register();
 285                if (ret != EFI_SUCCESS)
 286                        goto out;
 287        }
 288
 289        if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) {
 290                ret = efi_tcg2_register();
 291                if (ret != EFI_SUCCESS)
 292                        goto out;
 293
 294                ret = efi_tcg2_do_initial_measurement();
 295                if (ret == EFI_SECURITY_VIOLATION)
 296                        goto out;
 297        }
 298
 299        /* Install EFI_RNG_PROTOCOL */
 300        if (IS_ENABLED(CONFIG_EFI_RNG_PROTOCOL)) {
 301                ret = efi_rng_register();
 302                if (ret != EFI_SUCCESS)
 303                        goto out;
 304        }
 305
 306        if (IS_ENABLED(CONFIG_EFI_RISCV_BOOT_PROTOCOL)) {
 307                ret = efi_riscv_register();
 308                if (ret != EFI_SUCCESS)
 309                        goto out;
 310        }
 311
 312        /* Secure boot */
 313        ret = efi_init_secure_boot();
 314        if (ret != EFI_SUCCESS)
 315                goto out;
 316
 317        /* Indicate supported runtime services */
 318        ret = efi_init_runtime_supported();
 319        if (ret != EFI_SUCCESS)
 320                goto out;
 321
 322        /* Initialize EFI driver uclass */
 323        ret = efi_driver_init();
 324        if (ret != EFI_SUCCESS)
 325                goto out;
 326
 327        if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT)) {
 328                ret = efi_load_capsule_drivers();
 329                if (ret != EFI_SUCCESS)
 330                        goto out;
 331        }
 332
 333#if defined(CONFIG_LCD) || defined(CONFIG_DM_VIDEO)
 334        ret = efi_gop_register();
 335        if (ret != EFI_SUCCESS)
 336                goto out;
 337#endif
 338#ifdef CONFIG_NET
 339        ret = efi_net_register();
 340        if (ret != EFI_SUCCESS)
 341                goto out;
 342#endif
 343#ifdef CONFIG_GENERATE_ACPI_TABLE
 344        ret = efi_acpi_register();
 345        if (ret != EFI_SUCCESS)
 346                goto out;
 347#endif
 348#ifdef CONFIG_GENERATE_SMBIOS_TABLE
 349        ret = efi_smbios_register();
 350        if (ret != EFI_SUCCESS)
 351                goto out;
 352#endif
 353        ret = efi_watchdog_register();
 354        if (ret != EFI_SUCCESS)
 355                goto out;
 356
 357        ret = efi_init_capsule();
 358        if (ret != EFI_SUCCESS)
 359                goto out;
 360
 361        /* Initialize EFI runtime services */
 362        ret = efi_reset_system_init();
 363        if (ret != EFI_SUCCESS)
 364                goto out;
 365
 366        /* Execute capsules after reboot */
 367        if (IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK) &&
 368            !IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK_EARLY))
 369                ret = efi_launch_capsules();
 370out:
 371        efi_obj_list_initialized = ret;
 372        return ret;
 373}
 374