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 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_SUPPORT)) { 132 u16 var_name16[12]; 133 134 efi_create_indexed_name(var_name16, sizeof(var_name16), 135 "Capsule", CONFIG_EFI_CAPSULE_MAX); 136 137 ret = efi_set_variable_int(u"CapsuleMax", 138 &efi_guid_capsule_report, 139 EFI_VARIABLE_READ_ONLY | 140 EFI_VARIABLE_BOOTSERVICE_ACCESS | 141 EFI_VARIABLE_RUNTIME_ACCESS, 142 22, var_name16, false); 143 if (ret != EFI_SUCCESS) 144 printf("EFI: cannot initialize CapsuleMax variable\n"); 145 } 146 147 return ret; 148} 149 150/** 151 * efi_init_os_indications() - indicate supported features for OS requests 152 * 153 * Set the OsIndicationsSupported variable. 154 * 155 * Return: status code 156 */ 157static efi_status_t efi_init_os_indications(void) 158{ 159 u64 os_indications_supported = 0; 160 161 if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT)) 162 os_indications_supported |= 163 EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED; 164 165 if (IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK)) 166 os_indications_supported |= 167 EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED; 168 169 if (IS_ENABLED(CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT)) 170 os_indications_supported |= 171 EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED; 172 173 return efi_set_variable_int(u"OsIndicationsSupported", 174 &efi_global_variable_guid, 175 EFI_VARIABLE_BOOTSERVICE_ACCESS | 176 EFI_VARIABLE_RUNTIME_ACCESS | 177 EFI_VARIABLE_READ_ONLY, 178 sizeof(os_indications_supported), 179 &os_indications_supported, false); 180} 181 182/** 183 * efi_init_early() - handle initialization at early stage 184 * 185 * expected to be called in board_init_r(). 186 * 187 * Return: status code 188 */ 189int efi_init_early(void) 190{ 191 efi_status_t ret; 192 193 /* Allow unaligned memory access */ 194 allow_unaligned(); 195 196 /* Initialize root node */ 197 ret = efi_root_node_register(); 198 if (ret != EFI_SUCCESS) 199 goto out; 200 201 ret = efi_console_register(); 202 if (ret != EFI_SUCCESS) 203 goto out; 204 205 /* Initialize EFI driver uclass */ 206 ret = efi_driver_init(); 207 if (ret != EFI_SUCCESS) 208 goto out; 209 210 return 0; 211out: 212 /* never re-init UEFI subsystem */ 213 efi_obj_list_initialized = ret; 214 215 return -1; 216} 217 218/** 219 * efi_init_obj_list() - Initialize and populate EFI object list 220 * 221 * Return: status code 222 */ 223efi_status_t efi_init_obj_list(void) 224{ 225 efi_status_t ret = EFI_SUCCESS; 226 227 /* Initialize once only */ 228 if (efi_obj_list_initialized != OBJ_LIST_NOT_INITIALIZED) 229 return efi_obj_list_initialized; 230 231 /* Set up console modes */ 232 efi_setup_console_size(); 233 234 /* 235 * Probe block devices to find the ESP. 236 * efi_disks_register() must be called before efi_init_variables(). 237 */ 238 ret = efi_disks_register(); 239 if (ret != EFI_SUCCESS) 240 goto out; 241 242 /* Initialize variable services */ 243 ret = efi_init_variables(); 244 if (ret != EFI_SUCCESS) 245 goto out; 246 247 if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) { 248 /* update boot option after variable service initialized */ 249 ret = efi_bootmgr_update_media_device_boot_option(); 250 if (ret != EFI_SUCCESS) 251 goto out; 252 } 253 254 /* Define supported languages */ 255 ret = efi_init_platform_lang(); 256 if (ret != EFI_SUCCESS) 257 goto out; 258 259 /* Indicate supported features */ 260 ret = efi_init_os_indications(); 261 if (ret != EFI_SUCCESS) 262 goto out; 263 264 /* Initialize system table */ 265 ret = efi_initialize_system_table(); 266 if (ret != EFI_SUCCESS) 267 goto out; 268 269 if (IS_ENABLED(CONFIG_EFI_ECPT)) { 270 ret = efi_ecpt_register(); 271 if (ret != EFI_SUCCESS) 272 goto out; 273 } 274 275 if (IS_ENABLED(CONFIG_EFI_ESRT)) { 276 ret = efi_esrt_register(); 277 if (ret != EFI_SUCCESS) 278 goto out; 279 } 280 281 if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) { 282 ret = efi_tcg2_register(); 283 if (ret != EFI_SUCCESS) 284 goto out; 285 286 ret = efi_tcg2_do_initial_measurement(); 287 if (ret == EFI_SECURITY_VIOLATION) 288 goto out; 289 } 290 291 /* Install EFI_RNG_PROTOCOL */ 292 if (IS_ENABLED(CONFIG_EFI_RNG_PROTOCOL)) { 293 ret = efi_rng_register(); 294 if (ret != EFI_SUCCESS) 295 goto out; 296 } 297 298 if (IS_ENABLED(CONFIG_EFI_RISCV_BOOT_PROTOCOL)) { 299 ret = efi_riscv_register(); 300 if (ret != EFI_SUCCESS) 301 goto out; 302 } 303 304 /* Secure boot */ 305 ret = efi_init_secure_boot(); 306 if (ret != EFI_SUCCESS) 307 goto out; 308 309 /* Indicate supported runtime services */ 310 ret = efi_init_runtime_supported(); 311 if (ret != EFI_SUCCESS) 312 goto out; 313 314 if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT)) { 315 ret = efi_load_capsule_drivers(); 316 if (ret != EFI_SUCCESS) 317 goto out; 318 } 319 320 if (IS_ENABLED(CONFIG_VIDEO)) { 321 ret = efi_gop_register(); 322 if (ret != EFI_SUCCESS) 323 goto out; 324 } 325#ifdef CONFIG_NETDEVICES 326 ret = efi_net_register(); 327 if (ret != EFI_SUCCESS) 328 goto out; 329#endif 330 if (IS_ENABLED(CONFIG_ACPI)) { 331 ret = efi_acpi_register(); 332 if (ret != EFI_SUCCESS) 333 goto out; 334 } 335 if (IS_ENABLED(CONFIG_SMBIOS)) { 336 ret = efi_smbios_register(); 337 if (ret != EFI_SUCCESS) 338 goto out; 339 } 340 ret = efi_watchdog_register(); 341 if (ret != EFI_SUCCESS) 342 goto out; 343 344 ret = efi_init_capsule(); 345 if (ret != EFI_SUCCESS) 346 goto out; 347 348 /* Initialize EFI runtime services */ 349 ret = efi_reset_system_init(); 350 if (ret != EFI_SUCCESS) 351 goto out; 352 353 /* Execute capsules after reboot */ 354 if (IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK) && 355 !IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK_EARLY)) 356 ret = efi_launch_capsules(); 357out: 358 efi_obj_list_initialized = ret; 359 return ret; 360} 361