Commit 24e88ab0 authored by Ard Biesheuvel's avatar Ard Biesheuvel

Merge tag 'efi-loongarch-for-v6.1-2' into HEAD

Second shared stable tag between EFI and LoongArch trees

This is necessary because the EFI libstub refactoring patches are mostly
directed at enabling LoongArch to wire up generic EFI boot support
without being forced to consume DT properties that conflict with
information that EFI also provides, e.g., memory map and reservations,
etc.
parents a241d94b 40cd01a9
...@@ -65,10 +65,6 @@ linux,uefi-mmap-desc-size 32-bit Size in bytes of each entry in the UEFI ...@@ -65,10 +65,6 @@ linux,uefi-mmap-desc-size 32-bit Size in bytes of each entry in the UEFI
linux,uefi-mmap-desc-ver 32-bit Version of the mmap descriptor format. linux,uefi-mmap-desc-ver 32-bit Version of the mmap descriptor format.
linux,initrd-start 64-bit Physical start address of an initrd
linux,initrd-end 64-bit Physical end address of an initrd
kaslr-seed 64-bit Entropy used to randomize the kernel image kaslr-seed 64-bit Entropy used to randomize the kernel image
base address location. base address location.
========================== ====== =========================================== ========================== ====== ===========================================
...@@ -104,8 +104,6 @@ config LOONGARCH ...@@ -104,8 +104,6 @@ config LOONGARCH
select MODULES_USE_ELF_RELA if MODULES select MODULES_USE_ELF_RELA if MODULES
select NEED_PER_CPU_EMBED_FIRST_CHUNK select NEED_PER_CPU_EMBED_FIRST_CHUNK
select NEED_PER_CPU_PAGE_FIRST_CHUNK select NEED_PER_CPU_PAGE_FIRST_CHUNK
select OF
select OF_EARLY_FLATTREE
select PCI select PCI
select PCI_DOMAINS_GENERIC select PCI_DOMAINS_GENERIC
select PCI_ECAM if ACPI select PCI_ECAM if ACPI
...@@ -311,7 +309,6 @@ config DMI ...@@ -311,7 +309,6 @@ config DMI
config EFI config EFI
bool "EFI runtime service support" bool "EFI runtime service support"
select UCS2_STRING select UCS2_STRING
select EFI_PARAMS_FROM_FDT
select EFI_RUNTIME_WRAPPERS select EFI_RUNTIME_WRAPPERS
help help
This enables the kernel to use EFI runtime services that are This enables the kernel to use EFI runtime services that are
......
...@@ -36,7 +36,7 @@ struct loongson_system_configuration { ...@@ -36,7 +36,7 @@ struct loongson_system_configuration {
}; };
extern u64 efi_system_table; extern u64 efi_system_table;
extern unsigned long fw_arg0, fw_arg1; extern unsigned long fw_arg0, fw_arg1, fw_arg2;
extern struct loongson_board_info b_info; extern struct loongson_board_info b_info;
extern struct loongson_system_configuration loongson_sysconf; extern struct loongson_system_configuration loongson_sysconf;
......
...@@ -27,8 +27,13 @@ ...@@ -27,8 +27,13 @@
static unsigned long efi_nr_tables; static unsigned long efi_nr_tables;
static unsigned long efi_config_table; static unsigned long efi_config_table;
static unsigned long __initdata boot_memmap = EFI_INVALID_TABLE_ADDR;
static efi_system_table_t *efi_systab; static efi_system_table_t *efi_systab;
static efi_config_table_type_t arch_tables[] __initdata = {{},}; static efi_config_table_type_t arch_tables[] __initdata = {
{LINUX_EFI_BOOT_MEMMAP_GUID, &boot_memmap, "MEMMAP" },
{},
};
void __init efi_runtime_init(void) void __init efi_runtime_init(void)
{ {
...@@ -51,6 +56,7 @@ void __init efi_init(void) ...@@ -51,6 +56,7 @@ void __init efi_init(void)
{ {
int size; int size;
void *config_tables; void *config_tables;
struct efi_boot_memmap *tbl;
if (!efi_system_table) if (!efi_system_table)
return; return;
...@@ -61,6 +67,8 @@ void __init efi_init(void) ...@@ -61,6 +67,8 @@ void __init efi_init(void)
return; return;
} }
efi_systab_report_header(&efi_systab->hdr, efi_systab->fw_vendor);
set_bit(EFI_64BIT, &efi.flags); set_bit(EFI_64BIT, &efi.flags);
efi_nr_tables = efi_systab->nr_tables; efi_nr_tables = efi_systab->nr_tables;
efi_config_table = (unsigned long)efi_systab->tables; efi_config_table = (unsigned long)efi_systab->tables;
...@@ -70,6 +78,26 @@ void __init efi_init(void) ...@@ -70,6 +78,26 @@ void __init efi_init(void)
efi_config_parse_tables(config_tables, efi_systab->nr_tables, arch_tables); efi_config_parse_tables(config_tables, efi_systab->nr_tables, arch_tables);
early_memunmap(config_tables, efi_nr_tables * size); early_memunmap(config_tables, efi_nr_tables * size);
set_bit(EFI_CONFIG_TABLES, &efi.flags);
if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI) if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI)
memblock_reserve(screen_info.lfb_base, screen_info.lfb_size); memblock_reserve(screen_info.lfb_base, screen_info.lfb_size);
if (boot_memmap == EFI_INVALID_TABLE_ADDR)
return;
tbl = early_memremap_ro(boot_memmap, sizeof(*tbl));
if (tbl) {
struct efi_memory_map_data data;
data.phys_map = boot_memmap + sizeof(*tbl);
data.size = tbl->map_size;
data.desc_size = tbl->desc_size;
data.desc_version = tbl->desc_ver;
if (efi_memmap_init_early(&data) < 0)
panic("Unable to map EFI memory map.\n");
early_memunmap(tbl, sizeof(*tbl));
}
} }
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include <linux/efi.h> #include <linux/efi.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/memblock.h> #include <linux/memblock.h>
#include <linux/of_fdt.h>
#include <asm/early_ioremap.h> #include <asm/early_ioremap.h>
#include <asm/bootinfo.h> #include <asm/bootinfo.h>
#include <asm/loongson.h> #include <asm/loongson.h>
...@@ -20,21 +19,17 @@ EXPORT_SYMBOL(loongson_sysconf); ...@@ -20,21 +19,17 @@ EXPORT_SYMBOL(loongson_sysconf);
void __init init_environ(void) void __init init_environ(void)
{ {
int efi_boot = fw_arg0; int efi_boot = fw_arg0;
struct efi_memory_map_data data; char *cmdline = early_memremap_ro(fw_arg1, COMMAND_LINE_SIZE);
void *fdt_ptr = early_memremap_ro(fw_arg1, SZ_64K);
if (efi_boot) if (efi_boot)
set_bit(EFI_BOOT, &efi.flags); set_bit(EFI_BOOT, &efi.flags);
else else
clear_bit(EFI_BOOT, &efi.flags); clear_bit(EFI_BOOT, &efi.flags);
early_init_dt_scan(fdt_ptr); strscpy(boot_command_line, cmdline, COMMAND_LINE_SIZE);
early_init_fdt_reserve_self(); early_memunmap(cmdline, COMMAND_LINE_SIZE);
efi_system_table = efi_get_fdt_params(&data);
efi_memmap_init_early(&data); efi_system_table = fw_arg2;
memblock_reserve(data.phys_map & PAGE_MASK,
PAGE_ALIGN(data.size + (data.phys_map & ~PAGE_MASK)));
} }
static int __init init_cpu_fullname(void) static int __init init_cpu_fullname(void)
......
...@@ -67,6 +67,8 @@ SYM_CODE_START(kernel_entry) # kernel entry point ...@@ -67,6 +67,8 @@ SYM_CODE_START(kernel_entry) # kernel entry point
st.d a0, t0, 0 # firmware arguments st.d a0, t0, 0 # firmware arguments
la t0, fw_arg1 la t0, fw_arg1
st.d a1, t0, 0 st.d a1, t0, 0
la t0, fw_arg2
st.d a2, t0, 0
/* KSave3 used for percpu base, initialized as 0 */ /* KSave3 used for percpu base, initialized as 0 */
csrwr zero, PERCPU_BASE_KS csrwr zero, PERCPU_BASE_KS
......
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
struct screen_info screen_info __section(".data"); struct screen_info screen_info __section(".data");
unsigned long fw_arg0, fw_arg1; unsigned long fw_arg0, fw_arg1, fw_arg2;
DEFINE_PER_CPU(unsigned long, kernelsp); DEFINE_PER_CPU(unsigned long, kernelsp);
struct cpuinfo_loongarch cpu_data[NR_CPUS] __read_mostly; struct cpuinfo_loongarch cpu_data[NR_CPUS] __read_mostly;
...@@ -187,7 +187,6 @@ early_param("mem", early_parse_mem); ...@@ -187,7 +187,6 @@ early_param("mem", early_parse_mem);
void __init platform_init(void) void __init platform_init(void)
{ {
efi_init();
#ifdef CONFIG_ACPI_TABLE_UPGRADE #ifdef CONFIG_ACPI_TABLE_UPGRADE
acpi_table_upgrade(); acpi_table_upgrade();
#endif #endif
...@@ -347,6 +346,7 @@ void __init setup_arch(char **cmdline_p) ...@@ -347,6 +346,7 @@ void __init setup_arch(char **cmdline_p)
*cmdline_p = boot_command_line; *cmdline_p = boot_command_line;
init_environ(); init_environ();
efi_init();
memblock_init(); memblock_init();
parse_early_param(); parse_early_param();
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/efi.h> #include <linux/efi.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/initrd.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/kexec.h> #include <linux/kexec.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
...@@ -55,6 +56,7 @@ EXPORT_SYMBOL(efi); ...@@ -55,6 +56,7 @@ EXPORT_SYMBOL(efi);
unsigned long __ro_after_init efi_rng_seed = EFI_INVALID_TABLE_ADDR; unsigned long __ro_after_init efi_rng_seed = EFI_INVALID_TABLE_ADDR;
static unsigned long __initdata mem_reserve = EFI_INVALID_TABLE_ADDR; static unsigned long __initdata mem_reserve = EFI_INVALID_TABLE_ADDR;
static unsigned long __initdata rt_prop = EFI_INVALID_TABLE_ADDR; static unsigned long __initdata rt_prop = EFI_INVALID_TABLE_ADDR;
static unsigned long __initdata initrd = EFI_INVALID_TABLE_ADDR;
struct mm_struct efi_mm = { struct mm_struct efi_mm = {
.mm_rb = RB_ROOT, .mm_rb = RB_ROOT,
...@@ -532,6 +534,7 @@ static const efi_config_table_type_t common_tables[] __initconst = { ...@@ -532,6 +534,7 @@ static const efi_config_table_type_t common_tables[] __initconst = {
{LINUX_EFI_TPM_EVENT_LOG_GUID, &efi.tpm_log, "TPMEventLog" }, {LINUX_EFI_TPM_EVENT_LOG_GUID, &efi.tpm_log, "TPMEventLog" },
{LINUX_EFI_TPM_FINAL_LOG_GUID, &efi.tpm_final_log, "TPMFinalLog" }, {LINUX_EFI_TPM_FINAL_LOG_GUID, &efi.tpm_final_log, "TPMFinalLog" },
{LINUX_EFI_MEMRESERVE_TABLE_GUID, &mem_reserve, "MEMRESERVE" }, {LINUX_EFI_MEMRESERVE_TABLE_GUID, &mem_reserve, "MEMRESERVE" },
{LINUX_EFI_INITRD_MEDIA_GUID, &initrd, "INITRD" },
{EFI_RT_PROPERTIES_TABLE_GUID, &rt_prop, "RTPROP" }, {EFI_RT_PROPERTIES_TABLE_GUID, &rt_prop, "RTPROP" },
#ifdef CONFIG_EFI_RCI2_TABLE #ifdef CONFIG_EFI_RCI2_TABLE
{DELLEMC_EFI_RCI2_TABLE_GUID, &rci2_table_phys }, {DELLEMC_EFI_RCI2_TABLE_GUID, &rci2_table_phys },
...@@ -674,6 +677,18 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables, ...@@ -674,6 +677,18 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
} }
} }
if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) &&
initrd != EFI_INVALID_TABLE_ADDR && phys_initrd_size == 0) {
struct linux_efi_initrd *tbl;
tbl = early_memremap(initrd, sizeof(*tbl));
if (tbl) {
phys_initrd_start = tbl->base;
phys_initrd_size = tbl->size;
early_memunmap(tbl, sizeof(*tbl));
}
}
return 0; return 0;
} }
......
...@@ -29,7 +29,7 @@ cflags-$(CONFIG_RISCV) := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \ ...@@ -29,7 +29,7 @@ cflags-$(CONFIG_RISCV) := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \
cflags-$(CONFIG_LOONGARCH) := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \ cflags-$(CONFIG_LOONGARCH) := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \
-fpie -fpie
cflags-$(CONFIG_EFI_GENERIC_STUB) += -I$(srctree)/scripts/dtc/libfdt cflags-$(CONFIG_EFI_PARAMS_FROM_FDT) += -I$(srctree)/scripts/dtc/libfdt
KBUILD_CFLAGS := $(cflags-y) -Os -DDISABLE_BRANCH_PROFILING \ KBUILD_CFLAGS := $(cflags-y) -Os -DDISABLE_BRANCH_PROFILING \
-include $(srctree)/include/linux/hidden.h \ -include $(srctree)/include/linux/hidden.h \
...@@ -59,15 +59,17 @@ lib-y := efi-stub-helper.o gop.o secureboot.o tpm.o \ ...@@ -59,15 +59,17 @@ lib-y := efi-stub-helper.o gop.o secureboot.o tpm.o \
skip_spaces.o lib-cmdline.o lib-ctype.o \ skip_spaces.o lib-cmdline.o lib-ctype.o \
alignedmem.o relocate.o vsprintf.o alignedmem.o relocate.o vsprintf.o
# include the stub's generic dependencies from lib/ when building for ARM/arm64 # include the stub's libfdt dependencies from lib/ when needed
efi-deps-y := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c libfdt-deps := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c \
fdt_empty_tree.c fdt_sw.c
lib-$(CONFIG_EFI_PARAMS_FROM_FDT) += fdt.o \
$(patsubst %.c,lib-%.o,$(libfdt-deps))
$(obj)/lib-%.o: $(srctree)/lib/%.c FORCE $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE
$(call if_changed_rule,cc_o_c) $(call if_changed_rule,cc_o_c)
lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o fdt.o string.o intrinsics.o \ lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o string.o intrinsics.o systable.o
$(patsubst %.c,lib-%.o,$(efi-deps-y)) \
systable.o
lib-$(CONFIG_ARM) += arm32-stub.o lib-$(CONFIG_ARM) += arm32-stub.o
lib-$(CONFIG_ARM64) += arm64-stub.o lib-$(CONFIG_ARM64) += arm64-stub.o
......
...@@ -42,26 +42,17 @@ efi_status_t check_platform_features(void) ...@@ -42,26 +42,17 @@ efi_status_t check_platform_features(void)
*/ */
static bool check_image_region(u64 base, u64 size) static bool check_image_region(u64 base, u64 size)
{ {
unsigned long map_size, desc_size, buff_size; struct efi_boot_memmap *map;
efi_memory_desc_t *memory_map;
struct efi_boot_memmap map;
efi_status_t status; efi_status_t status;
bool ret = false; bool ret = false;
int map_offset; int map_offset;
map.map = &memory_map; status = efi_get_memory_map(&map, false);
map.map_size = &map_size;
map.desc_size = &desc_size;
map.desc_ver = NULL;
map.key_ptr = NULL;
map.buff_size = &buff_size;
status = efi_get_memory_map(&map);
if (status != EFI_SUCCESS) if (status != EFI_SUCCESS)
return false; return false;
for (map_offset = 0; map_offset < map_size; map_offset += desc_size) { for (map_offset = 0; map_offset < map->map_size; map_offset += map->desc_size) {
efi_memory_desc_t *md = (void *)memory_map + map_offset; efi_memory_desc_t *md = (void *)map->map + map_offset;
u64 end = md->phys_addr + md->num_pages * EFI_PAGE_SIZE; u64 end = md->phys_addr + md->num_pages * EFI_PAGE_SIZE;
/* /*
...@@ -74,7 +65,7 @@ static bool check_image_region(u64 base, u64 size) ...@@ -74,7 +65,7 @@ static bool check_image_region(u64 base, u64 size)
} }
} }
efi_bs_call(free_pool, memory_map); efi_bs_call(free_pool, map);
return ret; return ret;
} }
......
...@@ -420,7 +420,6 @@ char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len) ...@@ -420,7 +420,6 @@ char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len)
/** /**
* efi_exit_boot_services() - Exit boot services * efi_exit_boot_services() - Exit boot services
* @handle: handle of the exiting image * @handle: handle of the exiting image
* @map: pointer to receive the memory map
* @priv: argument to be passed to @priv_func * @priv: argument to be passed to @priv_func
* @priv_func: function to process the memory map before exiting boot services * @priv_func: function to process the memory map before exiting boot services
* *
...@@ -433,26 +432,26 @@ char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len) ...@@ -433,26 +432,26 @@ char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len)
* *
* Return: status code * Return: status code
*/ */
efi_status_t efi_exit_boot_services(void *handle, efi_status_t efi_exit_boot_services(void *handle, void *priv,
struct efi_boot_memmap *map,
void *priv,
efi_exit_boot_map_processing priv_func) efi_exit_boot_map_processing priv_func)
{ {
struct efi_boot_memmap *map;
efi_status_t status; efi_status_t status;
status = efi_get_memory_map(map); status = efi_get_memory_map(&map, true);
if (status != EFI_SUCCESS) if (status != EFI_SUCCESS)
goto fail; return status;
status = priv_func(map, priv); status = priv_func(map, priv);
if (status != EFI_SUCCESS) if (status != EFI_SUCCESS) {
goto free_map; efi_bs_call(free_pool, map);
return status;
}
if (efi_disable_pci_dma) if (efi_disable_pci_dma)
efi_pci_disable_bridge_busmaster(); efi_pci_disable_bridge_busmaster();
status = efi_bs_call(exit_boot_services, handle, *map->key_ptr); status = efi_bs_call(exit_boot_services, handle, map->map_key);
if (status == EFI_INVALID_PARAMETER) { if (status == EFI_INVALID_PARAMETER) {
/* /*
...@@ -468,35 +467,26 @@ efi_status_t efi_exit_boot_services(void *handle, ...@@ -468,35 +467,26 @@ efi_status_t efi_exit_boot_services(void *handle,
* buffer should account for any changes in the map so the call * buffer should account for any changes in the map so the call
* to get_memory_map() is expected to succeed here. * to get_memory_map() is expected to succeed here.
*/ */
*map->map_size = *map->buff_size; map->map_size = map->buff_size;
status = efi_bs_call(get_memory_map, status = efi_bs_call(get_memory_map,
map->map_size, &map->map_size,
*map->map, &map->map,
map->key_ptr, &map->map_key,
map->desc_size, &map->desc_size,
map->desc_ver); &map->desc_ver);
/* exit_boot_services() was called, thus cannot free */ /* exit_boot_services() was called, thus cannot free */
if (status != EFI_SUCCESS) if (status != EFI_SUCCESS)
goto fail; return status;
status = priv_func(map, priv); status = priv_func(map, priv);
/* exit_boot_services() was called, thus cannot free */ /* exit_boot_services() was called, thus cannot free */
if (status != EFI_SUCCESS) if (status != EFI_SUCCESS)
goto fail; return status;
status = efi_bs_call(exit_boot_services, handle, *map->key_ptr); status = efi_bs_call(exit_boot_services, handle, map->map_key);
} }
/* exit_boot_services() was called, thus cannot free */
if (status != EFI_SUCCESS)
goto fail;
return EFI_SUCCESS;
free_map:
efi_bs_call(free_pool, *map->map);
fail:
return status; return status;
} }
...@@ -561,20 +551,16 @@ static const struct { ...@@ -561,20 +551,16 @@ static const struct {
* * %EFI_SUCCESS if the initrd was loaded successfully, in which * * %EFI_SUCCESS if the initrd was loaded successfully, in which
* case @load_addr and @load_size are assigned accordingly * case @load_addr and @load_size are assigned accordingly
* * %EFI_NOT_FOUND if no LoadFile2 protocol exists on the initrd device path * * %EFI_NOT_FOUND if no LoadFile2 protocol exists on the initrd device path
* * %EFI_INVALID_PARAMETER if load_addr == NULL or load_size == NULL
* * %EFI_OUT_OF_RESOURCES if memory allocation failed * * %EFI_OUT_OF_RESOURCES if memory allocation failed
* * %EFI_LOAD_ERROR in all other cases * * %EFI_LOAD_ERROR in all other cases
*/ */
static static
efi_status_t efi_load_initrd_dev_path(unsigned long *load_addr, efi_status_t efi_load_initrd_dev_path(struct linux_efi_initrd *initrd,
unsigned long *load_size,
unsigned long max) unsigned long max)
{ {
efi_guid_t lf2_proto_guid = EFI_LOAD_FILE2_PROTOCOL_GUID; efi_guid_t lf2_proto_guid = EFI_LOAD_FILE2_PROTOCOL_GUID;
efi_device_path_protocol_t *dp; efi_device_path_protocol_t *dp;
efi_load_file2_protocol_t *lf2; efi_load_file2_protocol_t *lf2;
unsigned long initrd_addr;
unsigned long initrd_size;
efi_handle_t handle; efi_handle_t handle;
efi_status_t status; efi_status_t status;
...@@ -588,42 +574,37 @@ efi_status_t efi_load_initrd_dev_path(unsigned long *load_addr, ...@@ -588,42 +574,37 @@ efi_status_t efi_load_initrd_dev_path(unsigned long *load_addr,
if (status != EFI_SUCCESS) if (status != EFI_SUCCESS)
return status; return status;
status = efi_call_proto(lf2, load_file, dp, false, &initrd_size, NULL); initrd->size = 0;
status = efi_call_proto(lf2, load_file, dp, false, &initrd->size, NULL);
if (status != EFI_BUFFER_TOO_SMALL) if (status != EFI_BUFFER_TOO_SMALL)
return EFI_LOAD_ERROR; return EFI_LOAD_ERROR;
status = efi_allocate_pages(initrd_size, &initrd_addr, max); status = efi_allocate_pages(initrd->size, &initrd->base, max);
if (status != EFI_SUCCESS) if (status != EFI_SUCCESS)
return status; return status;
status = efi_call_proto(lf2, load_file, dp, false, &initrd_size, status = efi_call_proto(lf2, load_file, dp, false, &initrd->size,
(void *)initrd_addr); (void *)initrd->base);
if (status != EFI_SUCCESS) { if (status != EFI_SUCCESS) {
efi_free(initrd_size, initrd_addr); efi_free(initrd->size, initrd->base);
return EFI_LOAD_ERROR; return EFI_LOAD_ERROR;
} }
*load_addr = initrd_addr;
*load_size = initrd_size;
return EFI_SUCCESS; return EFI_SUCCESS;
} }
static static
efi_status_t efi_load_initrd_cmdline(efi_loaded_image_t *image, efi_status_t efi_load_initrd_cmdline(efi_loaded_image_t *image,
unsigned long *load_addr, struct linux_efi_initrd *initrd,
unsigned long *load_size,
unsigned long soft_limit, unsigned long soft_limit,
unsigned long hard_limit) unsigned long hard_limit)
{ {
if (!IS_ENABLED(CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER) || if (!IS_ENABLED(CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER) ||
(IS_ENABLED(CONFIG_X86) && (!efi_is_native() || image == NULL))) { (IS_ENABLED(CONFIG_X86) && (!efi_is_native() || image == NULL)))
*load_addr = *load_size = 0; return EFI_UNSUPPORTED;
return EFI_SUCCESS;
}
return handle_cmdline_files(image, L"initrd=", sizeof(L"initrd=") - 2, return handle_cmdline_files(image, L"initrd=", sizeof(L"initrd=") - 2,
soft_limit, hard_limit, soft_limit, hard_limit,
load_addr, load_size); &initrd->base, &initrd->size);
} }
static const struct { static const struct {
...@@ -670,42 +651,60 @@ static void efi_measure_initrd(unsigned long load_addr, unsigned long load_size) ...@@ -670,42 +651,60 @@ static void efi_measure_initrd(unsigned long load_addr, unsigned long load_size)
/** /**
* efi_load_initrd() - Load initial RAM disk * efi_load_initrd() - Load initial RAM disk
* @image: EFI loaded image protocol * @image: EFI loaded image protocol
* @load_addr: pointer to loaded initrd
* @load_size: size of loaded initrd
* @soft_limit: preferred address for loading the initrd * @soft_limit: preferred address for loading the initrd
* @hard_limit: upper limit address for loading the initrd * @hard_limit: upper limit address for loading the initrd
* *
* Return: status code * Return: status code
*/ */
efi_status_t efi_load_initrd(efi_loaded_image_t *image, efi_status_t efi_load_initrd(efi_loaded_image_t *image,
unsigned long *load_addr,
unsigned long *load_size,
unsigned long soft_limit, unsigned long soft_limit,
unsigned long hard_limit) unsigned long hard_limit,
const struct linux_efi_initrd **out)
{ {
efi_status_t status; efi_guid_t tbl_guid = LINUX_EFI_INITRD_MEDIA_GUID;
efi_status_t status = EFI_SUCCESS;
struct linux_efi_initrd initrd, *tbl;
if (efi_noinitrd) { if (!IS_ENABLED(CONFIG_BLK_DEV_INITRD) || efi_noinitrd)
*load_addr = *load_size = 0; return EFI_SUCCESS;
status = EFI_SUCCESS;
} else { status = efi_load_initrd_dev_path(&initrd, hard_limit);
status = efi_load_initrd_dev_path(load_addr, load_size, hard_limit); if (status == EFI_SUCCESS) {
if (status == EFI_SUCCESS) { efi_info("Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path\n");
efi_info("Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path\n"); if (initrd.size > 0)
if (*load_size > 0) efi_measure_initrd(initrd.base, initrd.size);
efi_measure_initrd(*load_addr, *load_size); } else if (status == EFI_NOT_FOUND) {
} else if (status == EFI_NOT_FOUND) { status = efi_load_initrd_cmdline(image, &initrd, soft_limit,
status = efi_load_initrd_cmdline(image, load_addr, load_size, hard_limit);
soft_limit, hard_limit); /* command line loader disabled or no initrd= passed? */
if (status == EFI_SUCCESS && *load_size > 0) if (status == EFI_UNSUPPORTED || status == EFI_NOT_READY)
efi_info("Loaded initrd from command line option\n"); return EFI_SUCCESS;
} if (status == EFI_SUCCESS)
if (status != EFI_SUCCESS) { efi_info("Loaded initrd from command line option\n");
efi_err("Failed to load initrd: 0x%lx\n", status);
*load_addr = *load_size = 0;
}
} }
if (status != EFI_SUCCESS)
goto failed;
status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, sizeof(initrd),
(void **)&tbl);
if (status != EFI_SUCCESS)
goto free_initrd;
*tbl = initrd;
status = efi_bs_call(install_configuration_table, &tbl_guid, tbl);
if (status != EFI_SUCCESS)
goto free_tbl;
if (out)
*out = tbl;
return EFI_SUCCESS;
free_tbl:
efi_bs_call(free_pool, tbl);
free_initrd:
efi_free(initrd.size, initrd.base);
failed:
efi_err("Failed to load initrd: 0x%lx\n", status);
return status; return status;
} }
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
*/ */
#include <linux/efi.h> #include <linux/efi.h>
#include <linux/libfdt.h>
#include <asm/efi.h> #include <asm/efi.h>
#include "efistub.h" #include "efistub.h"
...@@ -130,16 +129,11 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, ...@@ -130,16 +129,11 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
unsigned long image_addr; unsigned long image_addr;
unsigned long image_size = 0; unsigned long image_size = 0;
/* addr/point and size pairs for memory management*/ /* addr/point and size pairs for memory management*/
unsigned long initrd_addr = 0;
unsigned long initrd_size = 0;
unsigned long fdt_addr = 0; /* Original DTB */
unsigned long fdt_size = 0;
char *cmdline_ptr = NULL; char *cmdline_ptr = NULL;
int cmdline_size = 0; int cmdline_size = 0;
efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID; efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID;
unsigned long reserve_addr = 0; unsigned long reserve_addr = 0;
unsigned long reserve_size = 0; unsigned long reserve_size = 0;
enum efi_secureboot_mode secure_boot;
struct screen_info *si; struct screen_info *si;
efi_properties_table_t *prop_tbl; efi_properties_table_t *prop_tbl;
...@@ -215,40 +209,8 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, ...@@ -215,40 +209,8 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
/* Ask the firmware to clear memory on unclean shutdown */ /* Ask the firmware to clear memory on unclean shutdown */
efi_enable_reset_attack_mitigation(); efi_enable_reset_attack_mitigation();
secure_boot = efi_get_secureboot(); efi_load_initrd(image, ULONG_MAX, efi_get_max_initrd_addr(image_addr),
NULL);
/*
* Unauthenticated device tree data is a security hazard, so ignore
* 'dtb=' unless UEFI Secure Boot is disabled. We assume that secure
* boot is enabled if we can't determine its state.
*/
if (!IS_ENABLED(CONFIG_EFI_ARMSTUB_DTB_LOADER) ||
secure_boot != efi_secureboot_mode_disabled) {
if (strstr(cmdline_ptr, "dtb="))
efi_err("Ignoring DTB from command line.\n");
} else {
status = efi_load_dtb(image, &fdt_addr, &fdt_size);
if (status != EFI_SUCCESS) {
efi_err("Failed to load device tree!\n");
goto fail_free_image;
}
}
if (fdt_addr) {
efi_info("Using DTB from command line\n");
} else {
/* Look for a device tree configuration table entry. */
fdt_addr = (uintptr_t)get_fdt(&fdt_size);
if (fdt_addr)
efi_info("Using DTB from configuration table\n");
}
if (!fdt_addr)
efi_info("Generating empty DTB\n");
efi_load_initrd(image, &initrd_addr, &initrd_size, ULONG_MAX,
efi_get_max_initrd_addr(image_addr));
efi_random_get_seed(); efi_random_get_seed();
...@@ -290,25 +252,8 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, ...@@ -290,25 +252,8 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
install_memreserve_table(); install_memreserve_table();
status = allocate_new_fdt_and_exit_boot(handle, &fdt_addr, status = efi_boot_kernel(handle, image, image_addr, cmdline_ptr);
initrd_addr, initrd_size,
cmdline_ptr, fdt_addr, fdt_size);
if (status != EFI_SUCCESS)
goto fail_free_initrd;
if (IS_ENABLED(CONFIG_ARM))
efi_handle_post_ebs_state();
efi_enter_kernel(image_addr, fdt_addr, fdt_totalsize((void *)fdt_addr));
/* not reached */
fail_free_initrd:
efi_err("Failed to update FDT and exit boot services\n");
efi_free(initrd_size, initrd_addr);
efi_free(fdt_size, fdt_addr);
fail_free_image:
efi_free(image_size, image_addr); efi_free(image_size, image_addr);
efi_free(reserve_size, reserve_addr); efi_free(reserve_size, reserve_addr);
fail_free_screeninfo: fail_free_screeninfo:
...@@ -319,6 +264,35 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, ...@@ -319,6 +264,35 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
return status; return status;
} }
/*
* efi_allocate_virtmap() - create a pool allocation for the virtmap
*
* Create an allocation that is of sufficient size to hold all the memory
* descriptors that will be passed to SetVirtualAddressMap() to inform the
* firmware about the virtual mapping that will be used under the OS to call
* into the firmware.
*/
efi_status_t efi_alloc_virtmap(efi_memory_desc_t **virtmap,
unsigned long *desc_size, u32 *desc_ver)
{
unsigned long size, mmap_key;
efi_status_t status;
/*
* Use the size of the current memory map as an upper bound for the
* size of the buffer we need to pass to SetVirtualAddressMap() to
* cover all EFI_MEMORY_RUNTIME regions.
*/
size = 0;
status = efi_bs_call(get_memory_map, &size, NULL, &mmap_key, desc_size,
desc_ver);
if (status != EFI_BUFFER_TOO_SMALL)
return EFI_LOAD_ERROR;
return efi_bs_call(allocate_pool, EFI_LOADER_DATA, size,
(void **)virtmap);
}
/* /*
* efi_get_virtmap() - create a virtual mapping for the EFI memory map * efi_get_virtmap() - create a virtual mapping for the EFI memory map
* *
...@@ -334,6 +308,8 @@ void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size, ...@@ -334,6 +308,8 @@ void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size,
efi_memory_desc_t *in, *out = runtime_map; efi_memory_desc_t *in, *out = runtime_map;
int l; int l;
*count = 0;
for (l = 0; l < map_size; l += desc_size) { for (l = 0; l < map_size; l += desc_size) {
u64 paddr, size; u64 paddr, size;
......
...@@ -160,15 +160,6 @@ void efi_set_u64_split(u64 data, u32 *lo, u32 *hi) ...@@ -160,15 +160,6 @@ void efi_set_u64_split(u64 data, u32 *lo, u32 *hi)
*/ */
#define EFI_MMAP_NR_SLACK_SLOTS 8 #define EFI_MMAP_NR_SLACK_SLOTS 8
struct efi_boot_memmap {
efi_memory_desc_t **map;
unsigned long *map_size;
unsigned long *desc_size;
u32 *desc_ver;
unsigned long *key_ptr;
unsigned long *buff_size;
};
typedef struct efi_generic_dev_path efi_device_path_protocol_t; typedef struct efi_generic_dev_path efi_device_path_protocol_t;
union efi_device_path_to_text_protocol { union efi_device_path_to_text_protocol {
...@@ -871,20 +862,16 @@ typedef efi_status_t (*efi_exit_boot_map_processing)( ...@@ -871,20 +862,16 @@ typedef efi_status_t (*efi_exit_boot_map_processing)(
struct efi_boot_memmap *map, struct efi_boot_memmap *map,
void *priv); void *priv);
efi_status_t efi_exit_boot_services(void *handle, efi_status_t efi_exit_boot_services(void *handle, void *priv,
struct efi_boot_memmap *map,
void *priv,
efi_exit_boot_map_processing priv_func); efi_exit_boot_map_processing priv_func);
efi_status_t allocate_new_fdt_and_exit_boot(void *handle, efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image,
unsigned long *new_fdt_addr, unsigned long kernel_addr, char *cmdline_ptr);
u64 initrd_addr, u64 initrd_size,
char *cmdline_ptr,
unsigned long fdt_addr,
unsigned long fdt_size);
void *get_fdt(unsigned long *fdt_size); void *get_fdt(unsigned long *fdt_size);
efi_status_t efi_alloc_virtmap(efi_memory_desc_t **virtmap,
unsigned long *desc_size, u32 *desc_ver);
void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size, void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size,
unsigned long desc_size, efi_memory_desc_t *runtime_map, unsigned long desc_size, efi_memory_desc_t *runtime_map,
int *count); int *count);
...@@ -910,7 +897,8 @@ void efi_apply_loadoptions_quirk(const void **load_options, u32 *load_options_si ...@@ -910,7 +897,8 @@ void efi_apply_loadoptions_quirk(const void **load_options, u32 *load_options_si
char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len); char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len);
efi_status_t efi_get_memory_map(struct efi_boot_memmap *map); efi_status_t efi_get_memory_map(struct efi_boot_memmap **map,
bool install_cfg_tbl);
efi_status_t efi_allocate_pages(unsigned long size, unsigned long *addr, efi_status_t efi_allocate_pages(unsigned long size, unsigned long *addr,
unsigned long max); unsigned long max);
...@@ -953,10 +941,9 @@ static inline efi_status_t efi_load_dtb(efi_loaded_image_t *image, ...@@ -953,10 +941,9 @@ static inline efi_status_t efi_load_dtb(efi_loaded_image_t *image,
} }
efi_status_t efi_load_initrd(efi_loaded_image_t *image, efi_status_t efi_load_initrd(efi_loaded_image_t *image,
unsigned long *load_addr,
unsigned long *load_size,
unsigned long soft_limit, unsigned long soft_limit,
unsigned long hard_limit); unsigned long hard_limit,
const struct linux_efi_initrd **out);
/* /*
* This function handles the architcture specific differences between arm and * This function handles the architcture specific differences between arm and
* arm64 regarding where the kernel image must be loaded and any memory that * arm64 regarding where the kernel image must be loaded and any memory that
......
...@@ -28,8 +28,7 @@ static void fdt_update_cell_size(void *fdt) ...@@ -28,8 +28,7 @@ static void fdt_update_cell_size(void *fdt)
} }
static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size, static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size,
void *fdt, int new_fdt_size, char *cmdline_ptr, void *fdt, int new_fdt_size, char *cmdline_ptr)
u64 initrd_addr, u64 initrd_size)
{ {
int node, num_rsv; int node, num_rsv;
int status; int status;
...@@ -93,21 +92,6 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size, ...@@ -93,21 +92,6 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size,
goto fdt_set_fail; goto fdt_set_fail;
} }
/* Set initrd address/end in device tree, if present */
if (initrd_size != 0) {
u64 initrd_image_end;
u64 initrd_image_start = cpu_to_fdt64(initrd_addr);
status = fdt_setprop_var(fdt, node, "linux,initrd-start", initrd_image_start);
if (status)
goto fdt_set_fail;
initrd_image_end = cpu_to_fdt64(initrd_addr + initrd_size);
status = fdt_setprop_var(fdt, node, "linux,initrd-end", initrd_image_end);
if (status)
goto fdt_set_fail;
}
/* Add FDT entries for EFI runtime services in chosen node. */ /* Add FDT entries for EFI runtime services in chosen node. */
node = fdt_subnode_offset(fdt, 0, "chosen"); node = fdt_subnode_offset(fdt, 0, "chosen");
fdt_val64 = cpu_to_fdt64((u64)(unsigned long)efi_system_table); fdt_val64 = cpu_to_fdt64((u64)(unsigned long)efi_system_table);
...@@ -170,25 +154,25 @@ static efi_status_t update_fdt_memmap(void *fdt, struct efi_boot_memmap *map) ...@@ -170,25 +154,25 @@ static efi_status_t update_fdt_memmap(void *fdt, struct efi_boot_memmap *map)
if (node < 0) if (node < 0)
return EFI_LOAD_ERROR; return EFI_LOAD_ERROR;
fdt_val64 = cpu_to_fdt64((unsigned long)*map->map); fdt_val64 = cpu_to_fdt64((unsigned long)map->map);
err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-mmap-start", fdt_val64); err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-mmap-start", fdt_val64);
if (err) if (err)
return EFI_LOAD_ERROR; return EFI_LOAD_ERROR;
fdt_val32 = cpu_to_fdt32(*map->map_size); fdt_val32 = cpu_to_fdt32(map->map_size);
err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-mmap-size", fdt_val32); err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-mmap-size", fdt_val32);
if (err) if (err)
return EFI_LOAD_ERROR; return EFI_LOAD_ERROR;
fdt_val32 = cpu_to_fdt32(*map->desc_size); fdt_val32 = cpu_to_fdt32(map->desc_size);
err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-mmap-desc-size", fdt_val32); err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-mmap-desc-size", fdt_val32);
if (err) if (err)
return EFI_LOAD_ERROR; return EFI_LOAD_ERROR;
fdt_val32 = cpu_to_fdt32(*map->desc_ver); fdt_val32 = cpu_to_fdt32(map->desc_ver);
err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-mmap-desc-ver", fdt_val32); err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-mmap-desc-ver", fdt_val32);
if (err) if (err)
...@@ -198,22 +182,25 @@ static efi_status_t update_fdt_memmap(void *fdt, struct efi_boot_memmap *map) ...@@ -198,22 +182,25 @@ static efi_status_t update_fdt_memmap(void *fdt, struct efi_boot_memmap *map)
} }
struct exit_boot_struct { struct exit_boot_struct {
struct efi_boot_memmap *boot_memmap;
efi_memory_desc_t *runtime_map; efi_memory_desc_t *runtime_map;
int *runtime_entry_count; int runtime_entry_count;
void *new_fdt_addr; void *new_fdt_addr;
}; };
static efi_status_t exit_boot_func(struct efi_boot_memmap *map, static efi_status_t exit_boot_func(struct efi_boot_memmap *map, void *priv)
void *priv)
{ {
struct exit_boot_struct *p = priv; struct exit_boot_struct *p = priv;
p->boot_memmap = map;
/* /*
* Update the memory map with virtual addresses. The function will also * Update the memory map with virtual addresses. The function will also
* populate @runtime_map with copies of just the EFI_MEMORY_RUNTIME * populate @runtime_map with copies of just the EFI_MEMORY_RUNTIME
* entries so that we can pass it straight to SetVirtualAddressMap() * entries so that we can pass it straight to SetVirtualAddressMap()
*/ */
efi_get_virtmap(*map->map, *map->map_size, *map->desc_size, efi_get_virtmap(map->map, map->map_size, map->desc_size,
p->runtime_map, p->runtime_entry_count); p->runtime_map, &p->runtime_entry_count);
return update_fdt_memmap(p->new_fdt_addr, map); return update_fdt_memmap(p->new_fdt_addr, map);
} }
...@@ -223,86 +210,86 @@ static efi_status_t exit_boot_func(struct efi_boot_memmap *map, ...@@ -223,86 +210,86 @@ static efi_status_t exit_boot_func(struct efi_boot_memmap *map,
#endif #endif
/* /*
* Allocate memory for a new FDT, then add EFI, commandline, and * Allocate memory for a new FDT, then add EFI and commandline related fields
* initrd related fields to the FDT. This routine increases the * to the FDT. This routine increases the FDT allocation size until the
* FDT allocation size until the allocated memory is large * allocated memory is large enough. EFI allocations are in EFI_PAGE_SIZE
* enough. EFI allocations are in EFI_PAGE_SIZE granules, * granules, which are fixed at 4K bytes, so in most cases the first allocation
* which are fixed at 4K bytes, so in most cases the first * should succeed. EFI boot services are exited at the end of this function.
* allocation should succeed. * There must be no allocations between the get_memory_map() call and the
* EFI boot services are exited at the end of this function. * exit_boot_services() call, so the exiting of boot services is very tightly
* There must be no allocations between the get_memory_map() * tied to the creation of the FDT with the final memory map in it.
* call and the exit_boot_services() call, so the exiting of
* boot services is very tightly tied to the creation of the FDT
* with the final memory map in it.
*/ */
static
efi_status_t allocate_new_fdt_and_exit_boot(void *handle, efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
efi_loaded_image_t *image,
unsigned long *new_fdt_addr, unsigned long *new_fdt_addr,
u64 initrd_addr, u64 initrd_size, char *cmdline_ptr)
char *cmdline_ptr,
unsigned long fdt_addr,
unsigned long fdt_size)
{ {
unsigned long map_size, desc_size, buff_size; unsigned long desc_size;
u32 desc_ver; u32 desc_ver;
unsigned long mmap_key;
efi_memory_desc_t *memory_map, *runtime_map;
efi_status_t status; efi_status_t status;
int runtime_entry_count;
struct efi_boot_memmap map;
struct exit_boot_struct priv; struct exit_boot_struct priv;
unsigned long fdt_addr = 0;
unsigned long fdt_size = 0;
map.map = &runtime_map; if (!efi_novamap) {
map.map_size = &map_size; status = efi_alloc_virtmap(&priv.runtime_map, &desc_size,
map.desc_size = &desc_size; &desc_ver);
map.desc_ver = &desc_ver; if (status != EFI_SUCCESS) {
map.key_ptr = &mmap_key; efi_err("Unable to retrieve UEFI memory map.\n");
map.buff_size = &buff_size; return status;
}
}
/* /*
* Get a copy of the current memory map that we will use to prepare * Unauthenticated device tree data is a security hazard, so ignore
* the input for SetVirtualAddressMap(). We don't have to worry about * 'dtb=' unless UEFI Secure Boot is disabled. We assume that secure
* subsequent allocations adding entries, since they could not affect * boot is enabled if we can't determine its state.
* the number of EFI_MEMORY_RUNTIME regions.
*/ */
status = efi_get_memory_map(&map); if (!IS_ENABLED(CONFIG_EFI_ARMSTUB_DTB_LOADER) ||
if (status != EFI_SUCCESS) { efi_get_secureboot() != efi_secureboot_mode_disabled) {
efi_err("Unable to retrieve UEFI memory map.\n"); if (strstr(cmdline_ptr, "dtb="))
return status; efi_err("Ignoring DTB from command line.\n");
} else {
status = efi_load_dtb(image, &fdt_addr, &fdt_size);
if (status != EFI_SUCCESS && status != EFI_NOT_READY) {
efi_err("Failed to load device tree!\n");
goto fail;
}
} }
if (fdt_addr) {
efi_info("Using DTB from command line\n");
} else {
/* Look for a device tree configuration table entry. */
fdt_addr = (uintptr_t)get_fdt(&fdt_size);
if (fdt_addr)
efi_info("Using DTB from configuration table\n");
}
if (!fdt_addr)
efi_info("Generating empty DTB\n");
efi_info("Exiting boot services...\n"); efi_info("Exiting boot services...\n");
map.map = &memory_map;
status = efi_allocate_pages(MAX_FDT_SIZE, new_fdt_addr, ULONG_MAX); status = efi_allocate_pages(MAX_FDT_SIZE, new_fdt_addr, ULONG_MAX);
if (status != EFI_SUCCESS) { if (status != EFI_SUCCESS) {
efi_err("Unable to allocate memory for new device tree.\n"); efi_err("Unable to allocate memory for new device tree.\n");
goto fail; goto fail;
} }
/*
* Now that we have done our final memory allocation (and free)
* we can get the memory map key needed for exit_boot_services().
*/
status = efi_get_memory_map(&map);
if (status != EFI_SUCCESS)
goto fail_free_new_fdt;
status = update_fdt((void *)fdt_addr, fdt_size, status = update_fdt((void *)fdt_addr, fdt_size,
(void *)*new_fdt_addr, MAX_FDT_SIZE, cmdline_ptr, (void *)*new_fdt_addr, MAX_FDT_SIZE, cmdline_ptr);
initrd_addr, initrd_size);
if (status != EFI_SUCCESS) { if (status != EFI_SUCCESS) {
efi_err("Unable to construct new device tree.\n"); efi_err("Unable to construct new device tree.\n");
goto fail_free_new_fdt; goto fail_free_new_fdt;
} }
runtime_entry_count = 0; priv.new_fdt_addr = (void *)*new_fdt_addr;
priv.runtime_map = runtime_map;
priv.runtime_entry_count = &runtime_entry_count;
priv.new_fdt_addr = (void *)*new_fdt_addr;
status = efi_exit_boot_services(handle, &map, &priv, exit_boot_func); status = efi_exit_boot_services(handle, &priv, exit_boot_func);
if (status == EFI_SUCCESS) { if (status == EFI_SUCCESS) {
efi_set_virtual_address_map_t *svam; efi_set_virtual_address_map_t *svam;
...@@ -312,8 +299,8 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, ...@@ -312,8 +299,8 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
/* Install the new virtual address map */ /* Install the new virtual address map */
svam = efi_system_table->runtime->set_virtual_address_map; svam = efi_system_table->runtime->set_virtual_address_map;
status = svam(runtime_entry_count * desc_size, desc_size, status = svam(priv.runtime_entry_count * desc_size, desc_size,
desc_ver, runtime_map); desc_ver, priv.runtime_map);
/* /*
* We are beyond the point of no return here, so if the call to * We are beyond the point of no return here, so if the call to
...@@ -321,6 +308,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, ...@@ -321,6 +308,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
* incoming kernel but proceed normally otherwise. * incoming kernel but proceed normally otherwise.
*/ */
if (status != EFI_SUCCESS) { if (status != EFI_SUCCESS) {
efi_memory_desc_t *p;
int l; int l;
/* /*
...@@ -329,8 +317,9 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, ...@@ -329,8 +317,9 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
* the incoming kernel that no virtual translation has * the incoming kernel that no virtual translation has
* been installed. * been installed.
*/ */
for (l = 0; l < map_size; l += desc_size) { for (l = 0; l < priv.boot_memmap->map_size;
efi_memory_desc_t *p = (void *)memory_map + l; l += priv.boot_memmap->desc_size) {
p = (void *)priv.boot_memmap->map + l;
if (p->attribute & EFI_MEMORY_RUNTIME) if (p->attribute & EFI_MEMORY_RUNTIME)
p->virt_addr = 0; p->virt_addr = 0;
...@@ -345,11 +334,33 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, ...@@ -345,11 +334,33 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
efi_free(MAX_FDT_SIZE, *new_fdt_addr); efi_free(MAX_FDT_SIZE, *new_fdt_addr);
fail: fail:
efi_system_table->boottime->free_pool(runtime_map); efi_free(fdt_size, fdt_addr);
efi_bs_call(free_pool, priv.runtime_map);
return EFI_LOAD_ERROR; return EFI_LOAD_ERROR;
} }
efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image,
unsigned long kernel_addr, char *cmdline_ptr)
{
unsigned long fdt_addr;
efi_status_t status;
status = allocate_new_fdt_and_exit_boot(handle, image, &fdt_addr,
cmdline_ptr);
if (status != EFI_SUCCESS) {
efi_err("Failed to update FDT and exit boot services\n");
return status;
}
if (IS_ENABLED(CONFIG_ARM))
efi_handle_post_ebs_state();
efi_enter_kernel(kernel_addr, fdt_addr, fdt_totalsize((void *)fdt_addr));
/* not reached */
}
void *get_fdt(unsigned long *fdt_size) void *get_fdt(unsigned long *fdt_size)
{ {
void *fdt; void *fdt;
......
...@@ -256,6 +256,9 @@ efi_status_t handle_cmdline_files(efi_loaded_image_t *image, ...@@ -256,6 +256,9 @@ efi_status_t handle_cmdline_files(efi_loaded_image_t *image,
if (volume) if (volume)
volume->close(volume); volume->close(volume);
if (*load_size == 0)
return EFI_NOT_READY;
return EFI_SUCCESS; return EFI_SUCCESS;
err_close_file: err_close_file:
......
...@@ -9,7 +9,8 @@ ...@@ -9,7 +9,8 @@
#include <asm/addrspace.h> #include <asm/addrspace.h>
#include "efistub.h" #include "efistub.h"
typedef void __noreturn (*kernel_entry_t)(bool efi, unsigned long fdt); typedef void __noreturn (*kernel_entry_t)(bool efi, unsigned long cmdline,
unsigned long systab);
extern int kernel_asize; extern int kernel_asize;
extern int kernel_fsize; extern int kernel_fsize;
...@@ -42,19 +43,60 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, ...@@ -42,19 +43,60 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
return status; return status;
} }
void __noreturn efi_enter_kernel(unsigned long entrypoint, unsigned long fdt, unsigned long fdt_size) struct exit_boot_struct {
efi_memory_desc_t *runtime_map;
int runtime_entry_count;
};
static efi_status_t exit_boot_func(struct efi_boot_memmap *map, void *priv)
{
struct exit_boot_struct *p = priv;
/*
* Update the memory map with virtual addresses. The function will also
* populate @runtime_map with copies of just the EFI_MEMORY_RUNTIME
* entries so that we can pass it straight to SetVirtualAddressMap()
*/
efi_get_virtmap(map->map, map->map_size, map->desc_size,
p->runtime_map, &p->runtime_entry_count);
return EFI_SUCCESS;
}
efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image,
unsigned long kernel_addr, char *cmdline_ptr)
{ {
kernel_entry_t real_kernel_entry; kernel_entry_t real_kernel_entry;
struct exit_boot_struct priv;
unsigned long desc_size;
efi_status_t status;
u32 desc_ver;
status = efi_alloc_virtmap(&priv.runtime_map, &desc_size, &desc_ver);
if (status != EFI_SUCCESS) {
efi_err("Unable to retrieve UEFI memory map.\n");
return status;
}
efi_info("Exiting boot services\n");
efi_novamap = false;
status = efi_exit_boot_services(handle, &priv, exit_boot_func);
if (status != EFI_SUCCESS)
return status;
/* Install the new virtual address map */
efi_rt_call(set_virtual_address_map,
priv.runtime_entry_count * desc_size, desc_size,
desc_ver, priv.runtime_map);
/* Config Direct Mapping */ /* Config Direct Mapping */
csr_write64(CSR_DMW0_INIT, LOONGARCH_CSR_DMWIN0); csr_write64(CSR_DMW0_INIT, LOONGARCH_CSR_DMWIN0);
csr_write64(CSR_DMW1_INIT, LOONGARCH_CSR_DMWIN1); csr_write64(CSR_DMW1_INIT, LOONGARCH_CSR_DMWIN1);
real_kernel_entry = (kernel_entry_t) real_kernel_entry = (kernel_entry_t)
((unsigned long)&kernel_entry - entrypoint + VMLINUX_LOAD_ADDRESS); ((unsigned long)&kernel_entry - kernel_addr + VMLINUX_LOAD_ADDRESS);
if (!efi_novamap) real_kernel_entry(true, (unsigned long)cmdline_ptr,
real_kernel_entry(true, fdt); (unsigned long)efi_system_table);
else
real_kernel_entry(false, fdt);
} }
...@@ -5,71 +5,66 @@ ...@@ -5,71 +5,66 @@
#include "efistub.h" #include "efistub.h"
static inline bool mmap_has_headroom(unsigned long buff_size,
unsigned long map_size,
unsigned long desc_size)
{
unsigned long slack = buff_size - map_size;
return slack / desc_size >= EFI_MMAP_NR_SLACK_SLOTS;
}
/** /**
* efi_get_memory_map() - get memory map * efi_get_memory_map() - get memory map
* @map: on return pointer to memory map * @map: pointer to memory map pointer to which to assign the
* newly allocated memory map
* @install_cfg_tbl: whether or not to install the boot memory map as a
* configuration table
* *
* Retrieve the UEFI memory map. The allocated memory leaves room for * Retrieve the UEFI memory map. The allocated memory leaves room for
* up to EFI_MMAP_NR_SLACK_SLOTS additional memory map entries. * up to EFI_MMAP_NR_SLACK_SLOTS additional memory map entries.
* *
* Return: status code * Return: status code
*/ */
efi_status_t efi_get_memory_map(struct efi_boot_memmap *map) efi_status_t efi_get_memory_map(struct efi_boot_memmap **map,
bool install_cfg_tbl)
{ {
efi_memory_desc_t *m = NULL; int memtype = install_cfg_tbl ? EFI_ACPI_RECLAIM_MEMORY
: EFI_LOADER_DATA;
efi_guid_t tbl_guid = LINUX_EFI_BOOT_MEMMAP_GUID;
struct efi_boot_memmap *m, tmp;
efi_status_t status; efi_status_t status;
unsigned long key; unsigned long size;
u32 desc_version;
tmp.map_size = 0;
*map->desc_size = sizeof(*m); status = efi_bs_call(get_memory_map, &tmp.map_size, NULL, &tmp.map_key,
*map->map_size = *map->desc_size * 32; &tmp.desc_size, &tmp.desc_ver);
*map->buff_size = *map->map_size; if (status != EFI_BUFFER_TOO_SMALL)
again: return EFI_LOAD_ERROR;
status = efi_bs_call(allocate_pool, EFI_LOADER_DATA,
*map->map_size, (void **)&m); size = tmp.map_size + tmp.desc_size * EFI_MMAP_NR_SLACK_SLOTS;
status = efi_bs_call(allocate_pool, memtype, sizeof(*m) + size,
(void **)&m);
if (status != EFI_SUCCESS) if (status != EFI_SUCCESS)
goto fail; return status;
*map->desc_size = 0; if (install_cfg_tbl) {
key = 0;
status = efi_bs_call(get_memory_map, map->map_size, m,
&key, map->desc_size, &desc_version);
if (status == EFI_BUFFER_TOO_SMALL ||
!mmap_has_headroom(*map->buff_size, *map->map_size,
*map->desc_size)) {
efi_bs_call(free_pool, m);
/* /*
* Make sure there is some entries of headroom so that the * Installing a configuration table might allocate memory, and
* buffer can be reused for a new map after allocations are * this may modify the memory map. This means we should install
* no longer permitted. Its unlikely that the map will grow to * the configuration table first, and re-install or delete it
* exceed this headroom once we are ready to trigger * as needed.
* ExitBootServices()
*/ */
*map->map_size += *map->desc_size * EFI_MMAP_NR_SLACK_SLOTS; status = efi_bs_call(install_configuration_table, &tbl_guid, m);
*map->buff_size = *map->map_size; if (status != EFI_SUCCESS)
goto again; goto free_map;
} }
if (status == EFI_SUCCESS) { m->buff_size = m->map_size = size;
if (map->key_ptr) status = efi_bs_call(get_memory_map, &m->map_size, m->map, &m->map_key,
*map->key_ptr = key; &m->desc_size, &m->desc_ver);
if (map->desc_ver) if (status != EFI_SUCCESS)
*map->desc_ver = desc_version; goto uninstall_table;
} else {
efi_bs_call(free_pool, m); *map = m;
} return EFI_SUCCESS;
fail: uninstall_table:
*map->map = m; if (install_cfg_tbl)
efi_bs_call(install_configuration_table, &tbl_guid, NULL);
free_map:
efi_bs_call(free_pool, m);
return status; return status;
} }
......
...@@ -55,22 +55,13 @@ efi_status_t efi_random_alloc(unsigned long size, ...@@ -55,22 +55,13 @@ efi_status_t efi_random_alloc(unsigned long size,
unsigned long *addr, unsigned long *addr,
unsigned long random_seed) unsigned long random_seed)
{ {
unsigned long map_size, desc_size, total_slots = 0, target_slot; unsigned long total_slots = 0, target_slot;
unsigned long total_mirrored_slots = 0; unsigned long total_mirrored_slots = 0;
unsigned long buff_size; struct efi_boot_memmap *map;
efi_status_t status; efi_status_t status;
efi_memory_desc_t *memory_map;
int map_offset; int map_offset;
struct efi_boot_memmap map;
map.map = &memory_map; status = efi_get_memory_map(&map, false);
map.map_size = &map_size;
map.desc_size = &desc_size;
map.desc_ver = NULL;
map.key_ptr = NULL;
map.buff_size = &buff_size;
status = efi_get_memory_map(&map);
if (status != EFI_SUCCESS) if (status != EFI_SUCCESS)
return status; return status;
...@@ -80,8 +71,8 @@ efi_status_t efi_random_alloc(unsigned long size, ...@@ -80,8 +71,8 @@ efi_status_t efi_random_alloc(unsigned long size,
size = round_up(size, EFI_ALLOC_ALIGN); size = round_up(size, EFI_ALLOC_ALIGN);
/* count the suitable slots in each memory map entry */ /* count the suitable slots in each memory map entry */
for (map_offset = 0; map_offset < map_size; map_offset += desc_size) { for (map_offset = 0; map_offset < map->map_size; map_offset += map->desc_size) {
efi_memory_desc_t *md = (void *)memory_map + map_offset; efi_memory_desc_t *md = (void *)map->map + map_offset;
unsigned long slots; unsigned long slots;
slots = get_entry_num_slots(md, size, ilog2(align)); slots = get_entry_num_slots(md, size, ilog2(align));
...@@ -109,8 +100,8 @@ efi_status_t efi_random_alloc(unsigned long size, ...@@ -109,8 +100,8 @@ efi_status_t efi_random_alloc(unsigned long size,
* to calculate the randomly chosen address, and allocate it directly * to calculate the randomly chosen address, and allocate it directly
* using EFI_ALLOCATE_ADDRESS. * using EFI_ALLOCATE_ADDRESS.
*/ */
for (map_offset = 0; map_offset < map_size; map_offset += desc_size) { for (map_offset = 0; map_offset < map->map_size; map_offset += map->desc_size) {
efi_memory_desc_t *md = (void *)memory_map + map_offset; efi_memory_desc_t *md = (void *)map->map + map_offset;
efi_physical_addr_t target; efi_physical_addr_t target;
unsigned long pages; unsigned long pages;
...@@ -133,7 +124,7 @@ efi_status_t efi_random_alloc(unsigned long size, ...@@ -133,7 +124,7 @@ efi_status_t efi_random_alloc(unsigned long size,
break; break;
} }
efi_bs_call(free_pool, memory_map); efi_bs_call(free_pool, map);
return status; return status;
} }
...@@ -23,21 +23,12 @@ ...@@ -23,21 +23,12 @@
efi_status_t efi_low_alloc_above(unsigned long size, unsigned long align, efi_status_t efi_low_alloc_above(unsigned long size, unsigned long align,
unsigned long *addr, unsigned long min) unsigned long *addr, unsigned long min)
{ {
unsigned long map_size, desc_size, buff_size; struct efi_boot_memmap *map;
efi_memory_desc_t *map;
efi_status_t status; efi_status_t status;
unsigned long nr_pages; unsigned long nr_pages;
int i; int i;
struct efi_boot_memmap boot_map;
boot_map.map = &map; status = efi_get_memory_map(&map, false);
boot_map.map_size = &map_size;
boot_map.desc_size = &desc_size;
boot_map.desc_ver = NULL;
boot_map.key_ptr = NULL;
boot_map.buff_size = &buff_size;
status = efi_get_memory_map(&boot_map);
if (status != EFI_SUCCESS) if (status != EFI_SUCCESS)
goto fail; goto fail;
...@@ -52,12 +43,12 @@ efi_status_t efi_low_alloc_above(unsigned long size, unsigned long align, ...@@ -52,12 +43,12 @@ efi_status_t efi_low_alloc_above(unsigned long size, unsigned long align,
size = round_up(size, EFI_ALLOC_ALIGN); size = round_up(size, EFI_ALLOC_ALIGN);
nr_pages = size / EFI_PAGE_SIZE; nr_pages = size / EFI_PAGE_SIZE;
for (i = 0; i < map_size / desc_size; i++) { for (i = 0; i < map->map_size / map->desc_size; i++) {
efi_memory_desc_t *desc; efi_memory_desc_t *desc;
unsigned long m = (unsigned long)map; unsigned long m = (unsigned long)map->map;
u64 start, end; u64 start, end;
desc = efi_early_memdesc_ptr(m, desc_size, i); desc = efi_early_memdesc_ptr(m, map->desc_size, i);
if (desc->type != EFI_CONVENTIONAL_MEMORY) if (desc->type != EFI_CONVENTIONAL_MEMORY)
continue; continue;
...@@ -87,7 +78,7 @@ efi_status_t efi_low_alloc_above(unsigned long size, unsigned long align, ...@@ -87,7 +78,7 @@ efi_status_t efi_low_alloc_above(unsigned long size, unsigned long align,
} }
} }
if (i == map_size / desc_size) if (i == map->map_size / map->desc_size)
status = EFI_NOT_FOUND; status = EFI_NOT_FOUND;
efi_bs_call(free_pool, map); efi_bs_call(free_pool, map);
......
...@@ -716,32 +716,22 @@ static efi_status_t exit_boot_func(struct efi_boot_memmap *map, ...@@ -716,32 +716,22 @@ static efi_status_t exit_boot_func(struct efi_boot_memmap *map,
efi_set_u64_split((unsigned long)efi_system_table, efi_set_u64_split((unsigned long)efi_system_table,
&p->efi->efi_systab, &p->efi->efi_systab_hi); &p->efi->efi_systab, &p->efi->efi_systab_hi);
p->efi->efi_memdesc_size = *map->desc_size; p->efi->efi_memdesc_size = map->desc_size;
p->efi->efi_memdesc_version = *map->desc_ver; p->efi->efi_memdesc_version = map->desc_ver;
efi_set_u64_split((unsigned long)*map->map, efi_set_u64_split((unsigned long)map->map,
&p->efi->efi_memmap, &p->efi->efi_memmap_hi); &p->efi->efi_memmap, &p->efi->efi_memmap_hi);
p->efi->efi_memmap_size = *map->map_size; p->efi->efi_memmap_size = map->map_size;
return EFI_SUCCESS; return EFI_SUCCESS;
} }
static efi_status_t exit_boot(struct boot_params *boot_params, void *handle) static efi_status_t exit_boot(struct boot_params *boot_params, void *handle)
{ {
unsigned long map_sz, key, desc_size, buff_size;
efi_memory_desc_t *mem_map;
struct setup_data *e820ext = NULL; struct setup_data *e820ext = NULL;
__u32 e820ext_size = 0; __u32 e820ext_size = 0;
efi_status_t status; efi_status_t status;
__u32 desc_version;
struct efi_boot_memmap map;
struct exit_boot_struct priv; struct exit_boot_struct priv;
map.map = &mem_map;
map.map_size = &map_sz;
map.desc_size = &desc_size;
map.desc_ver = &desc_version;
map.key_ptr = &key;
map.buff_size = &buff_size;
priv.boot_params = boot_params; priv.boot_params = boot_params;
priv.efi = &boot_params->efi_info; priv.efi = &boot_params->efi_info;
...@@ -750,7 +740,7 @@ static efi_status_t exit_boot(struct boot_params *boot_params, void *handle) ...@@ -750,7 +740,7 @@ static efi_status_t exit_boot(struct boot_params *boot_params, void *handle)
return status; return status;
/* Might as well exit boot services now */ /* Might as well exit boot services now */
status = efi_exit_boot_services(handle, &map, &priv, exit_boot_func); status = efi_exit_boot_services(handle, &priv, exit_boot_func);
if (status != EFI_SUCCESS) if (status != EFI_SUCCESS)
return status; return status;
...@@ -776,7 +766,7 @@ unsigned long efi_main(efi_handle_t handle, ...@@ -776,7 +766,7 @@ unsigned long efi_main(efi_handle_t handle,
unsigned long bzimage_addr = (unsigned long)startup_32; unsigned long bzimage_addr = (unsigned long)startup_32;
unsigned long buffer_start, buffer_end; unsigned long buffer_start, buffer_end;
struct setup_header *hdr = &boot_params->hdr; struct setup_header *hdr = &boot_params->hdr;
unsigned long addr, size; const struct linux_efi_initrd *initrd = NULL;
efi_status_t status; efi_status_t status;
efi_system_table = sys_table_arg; efi_system_table = sys_table_arg;
...@@ -871,17 +861,18 @@ unsigned long efi_main(efi_handle_t handle, ...@@ -871,17 +861,18 @@ unsigned long efi_main(efi_handle_t handle,
* arguments will be processed only if image is not NULL, which will be * arguments will be processed only if image is not NULL, which will be
* the case only if we were loaded via the PE entry point. * the case only if we were loaded via the PE entry point.
*/ */
status = efi_load_initrd(image, &addr, &size, hdr->initrd_addr_max, status = efi_load_initrd(image, hdr->initrd_addr_max, ULONG_MAX,
ULONG_MAX); &initrd);
if (status != EFI_SUCCESS) if (status != EFI_SUCCESS)
goto fail; goto fail;
if (size > 0) { if (initrd && initrd->size > 0) {
efi_set_u64_split(addr, &hdr->ramdisk_image, efi_set_u64_split(initrd->base, &hdr->ramdisk_image,
&boot_params->ext_ramdisk_image); &boot_params->ext_ramdisk_image);
efi_set_u64_split(size, &hdr->ramdisk_size, efi_set_u64_split(initrd->size, &hdr->ramdisk_size,
&boot_params->ext_ramdisk_size); &boot_params->ext_ramdisk_size);
} }
/* /*
* If the boot loader gave us a value for secure_boot then we use that, * If the boot loader gave us a value for secure_boot then we use that,
* otherwise we ask the BIOS. * otherwise we ask the BIOS.
......
...@@ -414,6 +414,7 @@ void efi_native_runtime_setup(void); ...@@ -414,6 +414,7 @@ void efi_native_runtime_setup(void);
#define LINUX_EFI_ZBOOT_MEDIA_GUID EFI_GUID(0xe565a30d, 0x47da, 0x4dbd, 0xb3, 0x54, 0x9b, 0xb5, 0xc8, 0x4f, 0x8b, 0xe2) #define LINUX_EFI_ZBOOT_MEDIA_GUID EFI_GUID(0xe565a30d, 0x47da, 0x4dbd, 0xb3, 0x54, 0x9b, 0xb5, 0xc8, 0x4f, 0x8b, 0xe2)
#define LINUX_EFI_MOK_VARIABLE_TABLE_GUID EFI_GUID(0xc451ed2b, 0x9694, 0x45d3, 0xba, 0xba, 0xed, 0x9f, 0x89, 0x88, 0xa3, 0x89) #define LINUX_EFI_MOK_VARIABLE_TABLE_GUID EFI_GUID(0xc451ed2b, 0x9694, 0x45d3, 0xba, 0xba, 0xed, 0x9f, 0x89, 0x88, 0xa3, 0x89)
#define LINUX_EFI_COCO_SECRET_AREA_GUID EFI_GUID(0xadf956ad, 0xe98c, 0x484c, 0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47) #define LINUX_EFI_COCO_SECRET_AREA_GUID EFI_GUID(0xadf956ad, 0xe98c, 0x484c, 0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47)
#define LINUX_EFI_BOOT_MEMMAP_GUID EFI_GUID(0x800f683f, 0xd08b, 0x423a, 0xa2, 0x93, 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4)
#define RISCV_EFI_BOOT_PROTOCOL_GUID EFI_GUID(0xccd15fec, 0x6f73, 0x4eec, 0x83, 0x95, 0x3e, 0x69, 0xe4, 0xb9, 0x40, 0xbf) #define RISCV_EFI_BOOT_PROTOCOL_GUID EFI_GUID(0xccd15fec, 0x6f73, 0x4eec, 0x83, 0x95, 0x3e, 0x69, 0xe4, 0xb9, 0x40, 0xbf)
...@@ -522,6 +523,15 @@ typedef union { ...@@ -522,6 +523,15 @@ typedef union {
efi_system_table_32_t mixed_mode; efi_system_table_32_t mixed_mode;
} efi_system_table_t; } efi_system_table_t;
struct efi_boot_memmap {
unsigned long map_size;
unsigned long desc_size;
u32 desc_ver;
unsigned long map_key;
unsigned long buff_size;
efi_memory_desc_t map[];
};
/* /*
* Architecture independent structure for describing a memory map for the * Architecture independent structure for describing a memory map for the
* benefit of efi_memmap_init_early(), and for passing context between * benefit of efi_memmap_init_early(), and for passing context between
...@@ -1334,6 +1344,11 @@ struct linux_efi_coco_secret_area { ...@@ -1334,6 +1344,11 @@ struct linux_efi_coco_secret_area {
u64 size; u64 size;
}; };
struct linux_efi_initrd {
unsigned long base;
unsigned long size;
};
/* Header of a populated EFI secret area */ /* Header of a populated EFI secret area */
#define EFI_SECRET_TABLE_HEADER_GUID EFI_GUID(0x1e74f542, 0x71dd, 0x4d66, 0x96, 0x3e, 0xef, 0x42, 0x87, 0xff, 0x17, 0x3b) #define EFI_SECRET_TABLE_HEADER_GUID EFI_GUID(0x1e74f542, 0x71dd, 0x4d66, 0x96, 0x3e, 0xef, 0x42, 0x87, 0xff, 0x17, 0x3b)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment