// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (c) 2022, Heinrich Schuchardt */ #define LOG_CATEGORY LOGC_EFI #include #include #include #include #undef BOOTEFI_NAME /* * The constants below come from: * * https://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml#processor-architecture */ #if HOST_ARCH == HOST_ARCH_X86_64 #define HOST_BOOTEFI_NAME "BOOTX64.EFI" #define HOST_PXE_ARCH 0x6 #elif HOST_ARCH == HOST_ARCH_X86 #define HOST_BOOTEFI_NAME "BOOTIA32.EFI" #define HOST_PXE_ARCH 0x7 #elif HOST_ARCH == HOST_ARCH_AARCH64 #define HOST_BOOTEFI_NAME "BOOTAA64.EFI" #define HOST_PXE_ARCH 0xb #elif HOST_ARCH == HOST_ARCH_ARM #define HOST_BOOTEFI_NAME "BOOTARM.EFI" #define HOST_PXE_ARCH 0xa #elif HOST_ARCH == HOST_ARCH_RISCV32 #define HOST_BOOTEFI_NAME "BOOTRISCV32.EFI" #define HOST_PXE_ARCH 0x19 #elif HOST_ARCH == HOST_ARCH_RISCV64 #define HOST_BOOTEFI_NAME "BOOTRISCV64.EFI" #define HOST_PXE_ARCH 0x1b #else #error Unsupported Host architecture #endif #if defined(CONFIG_SANDBOX) #define BOOTEFI_NAME "BOOTSBOX.EFI" #elif defined(CONFIG_ARM64) #define BOOTEFI_NAME "BOOTAA64.EFI" #elif defined(CONFIG_ARM) #define BOOTEFI_NAME "BOOTARM.EFI" #elif defined(CONFIG_X86_64) #define BOOTEFI_NAME "BOOTX64.EFI" #elif defined(CONFIG_X86) #define BOOTEFI_NAME "BOOTIA32.EFI" #elif defined(CONFIG_ARCH_RV32I) #define BOOTEFI_NAME "BOOTRISCV32.EFI" #elif defined(CONFIG_ARCH_RV64I) #define BOOTEFI_NAME "BOOTRISCV64.EFI" #else #error Unsupported UEFI architecture #endif #if defined(CONFIG_CMD_EFIDEBUG) || defined(CONFIG_EFI_LOAD_FILE2_INITRD) /* GUID used by Linux to identify the LoadFile2 protocol with the initrd */ const efi_guid_t efi_lf2_initrd_guid = EFI_INITRD_MEDIA_GUID; #endif const char *efi_get_basename(void) { return efi_use_host_arch() ? HOST_BOOTEFI_NAME : BOOTEFI_NAME; } int efi_get_pxe_arch(void) { if (efi_use_host_arch()) return HOST_PXE_ARCH; /* http://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xml */ if (IS_ENABLED(CONFIG_ARM64)) return 0xb; else if (IS_ENABLED(CONFIG_ARM)) return 0xa; else if (IS_ENABLED(CONFIG_X86_64)) return 0x6; else if (IS_ENABLED(CONFIG_X86)) return 0x7; else if (IS_ENABLED(CONFIG_ARCH_RV32I)) return 0x19; else if (IS_ENABLED(CONFIG_ARCH_RV64I)) return 0x1b; return -EINVAL; } /** * efi_get_distro_fdt_name() - get the filename for reading the .dtb file * * @fname: buffer for filename * @size: buffer size * @seq: sequence number, to cycle through options (0=first) * * Returns: * 0 on success, * -ENOENT if the "fdtfile" env var does not exist, * -EINVAL if there are no more options, * -EALREADY if the control FDT should be used */ int efi_get_distro_fdt_name(char *fname, int size, int seq) { const char *fdt_fname; const char *prefix; /* select the prefix */ switch (seq) { case 0: /* this is the default */ prefix = "/dtb"; break; case 1: prefix = ""; break; case 2: prefix = "/dtb/current"; break; case 3: prefix = "/dtbs"; break; default: return log_msg_ret("pref", -EINVAL); } fdt_fname = env_get("fdtfile"); if (fdt_fname) { snprintf(fname, size, "%s/%s", prefix, fdt_fname); log_debug("Using device tree: %s\n", fname); } else if (IS_ENABLED(CONFIG_OF_HAS_PRIOR_STAGE)) { strcpy(fname, ""); return log_msg_ret("pref", -EALREADY); /* Use this fallback only for 32-bit ARM */ } else if (IS_ENABLED(CONFIG_ARM) && !IS_ENABLED(CONFIG_ARM64)) { const char *soc = env_get("soc"); const char *board = env_get("board"); const char *boardver = env_get("boardver"); /* cf the code in label_boot() which seems very complex */ snprintf(fname, size, "%s/%s%s%s%s.dtb", prefix, soc ? soc : "", soc ? "-" : "", board ? board : "", boardver ? boardver : ""); log_debug("Using default device tree: %s\n", fname); } else { return log_msg_ret("env", -ENOENT); } return 0; }