Commit d1343da3 authored by Ingo Molnar's avatar Ingo Molnar

Merge tag 'efi-changes-for-v5.8' of...

Merge tag 'efi-changes-for-v5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi into efi/core

More EFI changes for v5.8:

 - Rename pr_efi/pr_efi_err to efi_info/efi_err, and use them consistently
 - Simplify and unify initrd loading
 - Parse the builtin command line on x86 (if provided)
 - Implement printk() support, including support for wide character strings
 - Some fixes for issues introduced by the first batch of v5.8 changes
 - Fix a missing prototypes warning
 - Simplify GDT handling in early mixed mode thunking code
 - Some other minor fixes and cleanups

Conflicts:
	drivers/firmware/efi/libstub/efistub.h
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents a5d8e55b 9241dfe7
......@@ -63,4 +63,9 @@ auto
with the highest resolution, it will choose one with the highest color
depth.
list
The EFI stub will list out all the display modes that are available. A
specific mode can then be chosen using one of the above options for the
next boot.
Edgar Hucek <gimli@dark-green.com>
......@@ -60,7 +60,7 @@ optional_header:
.long __pecoff_code_size @ SizeOfCode
.long __pecoff_data_size @ SizeOfInitializedData
.long 0 @ SizeOfUninitializedData
.long efi_entry - start @ AddressOfEntryPoint
.long efi_pe_entry - start @ AddressOfEntryPoint
.long start_offset @ BaseOfCode
.long __pecoff_data_start - start @ BaseOfData
......
......@@ -14,7 +14,7 @@
SYM_CODE_START(efi_enter_kernel)
/*
* efi_entry() will have copied the kernel image if necessary and we
* efi_pe_entry() will have copied the kernel image if necessary and we
* end up here with device tree address in x1 and the kernel entry
* point stored in x0. Save those values in registers which are
* callee preserved.
......
......@@ -27,7 +27,7 @@ optional_header:
.long __initdata_begin - efi_header_end // SizeOfCode
.long __pecoff_data_size // SizeOfInitializedData
.long 0 // SizeOfUninitializedData
.long __efistub_efi_entry - _head // AddressOfEntryPoint
.long __efistub_efi_pe_entry - _head // AddressOfEntryPoint
.long efi_header_end - _head // BaseOfCode
extra_header_fields:
......
......@@ -28,8 +28,6 @@ SYM_FUNC_START(__efi64_thunk)
push %rbx
leaq 1f(%rip), %rbp
leaq efi_gdt64(%rip), %rbx
movl %ebx, 2(%rbx) /* Fixup the gdt base address */
movl %ds, %eax
push %rax
......@@ -48,7 +46,8 @@ SYM_FUNC_START(__efi64_thunk)
movl %r8d, 0xc(%rsp)
movl %r9d, 0x10(%rsp)
sgdt 0x14(%rsp)
leaq 0x14(%rsp), %rbx
sgdt (%rbx)
/*
* Switch to gdt with 32-bit segments. This is the firmware GDT
......@@ -68,8 +67,7 @@ SYM_FUNC_START(__efi64_thunk)
pushq %rax
lretq
1: lgdt 0x14(%rsp)
addq $32, %rsp
1: addq $32, %rsp
movq %rdi, %rax
pop %rbx
......@@ -175,14 +173,3 @@ SYM_DATA_END(efi32_boot_cs)
SYM_DATA_START(efi32_boot_ds)
.word 0
SYM_DATA_END(efi32_boot_ds)
SYM_DATA_START(efi_gdt64)
.word efi_gdt64_end - efi_gdt64
.long 0 /* Filled out by user */
.word 0
.quad 0x0000000000000000 /* NULL descriptor */
.quad 0x00af9a000000ffff /* __KERNEL_CS */
.quad 0x00cf92000000ffff /* __KERNEL_DS */
.quad 0x0080890000000000 /* TS descriptor */
.quad 0x0000000000000000 /* TS continued */
SYM_DATA_END_LABEL(efi_gdt64, SYM_L_LOCAL, efi_gdt64_end)
......@@ -9,6 +9,7 @@
#include <asm/nospec-branch.h>
#include <asm/mmu_context.h>
#include <linux/build_bug.h>
#include <linux/kernel.h>
extern unsigned long efi_fw_vendor, efi_config_table;
......@@ -225,13 +226,15 @@ efi_status_t efi_set_virtual_address_map(unsigned long memory_map_size,
/* arch specific definitions used by the stub code */
extern const bool efi_is64;
#ifdef CONFIG_EFI_MIXED
#define ARCH_HAS_EFISTUB_WRAPPERS
static inline bool efi_is_64bit(void)
{
if (IS_ENABLED(CONFIG_EFI_MIXED))
return efi_is64;
return IS_ENABLED(CONFIG_X86_64);
extern const bool efi_is64;
return efi_is64;
}
static inline bool efi_is_native(void)
......@@ -291,6 +294,15 @@ static inline u32 efi64_convert_status(efi_status_t status)
#define __efi64_argmap_allocate_pool(type, size, buffer) \
((type), (size), efi64_zero_upper(buffer))
#define __efi64_argmap_create_event(type, tpl, f, c, event) \
((type), (tpl), (f), (c), efi64_zero_upper(event))
#define __efi64_argmap_set_timer(event, type, time) \
((event), (type), lower_32_bits(time), upper_32_bits(time))
#define __efi64_argmap_wait_for_event(num, event, index) \
((num), (event), efi64_zero_upper(index))
#define __efi64_argmap_handle_protocol(handle, protocol, interface) \
((handle), (protocol), efi64_zero_upper(interface))
......@@ -356,6 +368,15 @@ static inline u32 efi64_convert_status(efi_status_t status)
runtime), \
func, __VA_ARGS__))
#else /* CONFIG_EFI_MIXED */
static inline bool efi_is_64bit(void)
{
return IS_ENABLED(CONFIG_X86_64);
}
#endif /* CONFIG_EFI_MIXED */
extern bool efi_reboot_required(void);
extern bool efi_is_table_address(unsigned long phys_addr);
......
......@@ -29,7 +29,7 @@ static efi_system_table_t efi_systab_xen __initdata = {
.fw_vendor = EFI_INVALID_TABLE_ADDR, /* Initialized later. */
.fw_revision = 0, /* Initialized later. */
.con_in_handle = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
.con_in = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
.con_in = NULL, /* Not used under Xen. */
.con_out_handle = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
.con_out = NULL, /* Not used under Xen. */
.stderr_handle = EFI_INVALID_TABLE_ADDR, /* Not used under Xen. */
......
......@@ -522,8 +522,10 @@ efivar_create_sysfs_entry(struct efivar_entry *new_var)
ret = kobject_init_and_add(&new_var->kobj, &efivar_ktype,
NULL, "%s", short_name);
kfree(short_name);
if (ret)
if (ret) {
kobject_put(&new_var->kobj);
return ret;
}
kobject_uevent(&new_var->kobj, KOBJ_ADD);
if (efivar_entry_add(new_var, &efivar_sysfs_list)) {
......
......@@ -7,7 +7,7 @@
#
cflags-$(CONFIG_X86_32) := -march=i386
cflags-$(CONFIG_X86_64) := -mcmodel=small
cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ -O2 \
cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ \
-fPIC -fno-strict-aliasing -mno-red-zone \
-mno-mmx -mno-sse -fshort-wchar \
-Wno-pointer-sign \
......@@ -25,11 +25,12 @@ cflags-$(CONFIG_ARM) := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \
cflags-$(CONFIG_EFI_GENERIC_STUB) += -I$(srctree)/scripts/dtc/libfdt
KBUILD_CFLAGS := $(cflags-y) -DDISABLE_BRANCH_PROFILING \
KBUILD_CFLAGS := $(cflags-y) -Os -DDISABLE_BRANCH_PROFILING \
-include $(srctree)/drivers/firmware/efi/libstub/hidden.h \
-D__NO_FORTIFY \
$(call cc-option,-ffreestanding) \
$(call cc-option,-fno-stack-protector) \
$(call cc-option,-fno-addrsig) \
-D__DISABLE_EXPORTS
GCOV_PROFILE := n
......@@ -43,7 +44,7 @@ KCOV_INSTRUMENT := n
lib-y := efi-stub-helper.o gop.o secureboot.o tpm.o \
file.o mem.o random.o randomalloc.o pci.o \
skip_spaces.o lib-cmdline.o lib-ctype.o \
alignedmem.o relocate.o
alignedmem.o relocate.o vsprintf.o
# include the stub's generic dependencies from lib/ when building for ARM/arm64
efi-deps-y := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c
......
......@@ -18,7 +18,7 @@ efi_status_t check_platform_features(void)
/* LPAE kernels need compatible hardware */
block = cpuid_feature_extract(CPUID_EXT_MMFR0, 0);
if (block < 5) {
pr_efi_err("This LPAE kernel is not supported by your CPU\n");
efi_err("This LPAE kernel is not supported by your CPU\n");
return EFI_UNSUPPORTED;
}
return EFI_SUCCESS;
......@@ -120,7 +120,7 @@ static efi_status_t reserve_kernel_base(unsigned long dram_base,
*/
status = efi_get_memory_map(&map);
if (status != EFI_SUCCESS) {
pr_efi_err("reserve_kernel_base(): Unable to retrieve memory map.\n");
efi_err("reserve_kernel_base(): Unable to retrieve memory map.\n");
return status;
}
......@@ -162,7 +162,7 @@ static efi_status_t reserve_kernel_base(unsigned long dram_base,
(end - start) / EFI_PAGE_SIZE,
&start);
if (status != EFI_SUCCESS) {
pr_efi_err("reserve_kernel_base(): alloc failed.\n");
efi_err("reserve_kernel_base(): alloc failed.\n");
goto out;
}
break;
......@@ -219,7 +219,7 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
status = reserve_kernel_base(kernel_base, reserve_addr, reserve_size);
if (status != EFI_SUCCESS) {
pr_efi_err("Unable to allocate memory for uncompressed kernel.\n");
efi_err("Unable to allocate memory for uncompressed kernel.\n");
return status;
}
......@@ -232,7 +232,7 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
status = efi_relocate_kernel(image_addr, *image_size, *image_size,
kernel_base + MAX_UNCOMP_KERNEL_SIZE, 0, 0);
if (status != EFI_SUCCESS) {
pr_efi_err("Failed to relocate kernel.\n");
efi_err("Failed to relocate kernel.\n");
efi_free(*reserve_size, *reserve_addr);
*reserve_size = 0;
return status;
......@@ -244,7 +244,7 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
* address at which the zImage is loaded.
*/
if (*image_addr + *image_size > dram_base + ZIMAGE_OFFSET_LIMIT) {
pr_efi_err("Failed to relocate kernel, no low memory available.\n");
efi_err("Failed to relocate kernel, no low memory available.\n");
efi_free(*reserve_size, *reserve_addr);
*reserve_size = 0;
efi_free(*image_size, *image_addr);
......
......@@ -26,9 +26,9 @@ efi_status_t check_platform_features(void)
tg = (read_cpuid(ID_AA64MMFR0_EL1) >> ID_AA64MMFR0_TGRAN_SHIFT) & 0xf;
if (tg != ID_AA64MMFR0_TGRAN_SUPPORTED) {
if (IS_ENABLED(CONFIG_ARM64_64K_PAGES))
pr_efi_err("This 64 KB granular kernel is not supported by your CPU\n");
efi_err("This 64 KB granular kernel is not supported by your CPU\n");
else
pr_efi_err("This 16 KB granular kernel is not supported by your CPU\n");
efi_err("This 16 KB granular kernel is not supported by your CPU\n");
return EFI_UNSUPPORTED;
}
return EFI_SUCCESS;
......@@ -59,18 +59,18 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
status = efi_get_random_bytes(sizeof(phys_seed),
(u8 *)&phys_seed);
if (status == EFI_NOT_FOUND) {
pr_efi("EFI_RNG_PROTOCOL unavailable, no randomness supplied\n");
efi_info("EFI_RNG_PROTOCOL unavailable, no randomness supplied\n");
} else if (status != EFI_SUCCESS) {
pr_efi_err("efi_get_random_bytes() failed\n");
efi_err("efi_get_random_bytes() failed\n");
return status;
}
} else {
pr_efi("KASLR disabled on kernel command line\n");
efi_info("KASLR disabled on kernel command line\n");
}
}
if (image->image_base != _text)
pr_efi_err("FIRMWARE BUG: efi_loaded_image_t::image_base has bogus value\n");
efi_err("FIRMWARE BUG: efi_loaded_image_t::image_base has bogus value\n");
kernel_size = _edata - _text;
kernel_memsize = kernel_size + (_end - _edata);
......@@ -102,7 +102,7 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
ULONG_MAX, min_kimg_align);
if (status != EFI_SUCCESS) {
pr_efi_err("Failed to relocate kernel\n");
efi_err("Failed to relocate kernel\n");
*reserve_size = 0;
return status;
}
......
......@@ -73,7 +73,7 @@ static void install_memreserve_table(void)
status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, sizeof(*rsv),
(void **)&rsv);
if (status != EFI_SUCCESS) {
pr_efi_err("Failed to allocate memreserve entry!\n");
efi_err("Failed to allocate memreserve entry!\n");
return;
}
......@@ -84,7 +84,7 @@ static void install_memreserve_table(void)
status = efi_bs_call(install_configuration_table,
&memreserve_table_guid, rsv);
if (status != EFI_SUCCESS)
pr_efi_err("Failed to install memreserve config table!\n");
efi_err("Failed to install memreserve config table!\n");
}
static unsigned long get_dram_base(void)
......@@ -144,7 +144,8 @@ asmlinkage void __noreturn efi_enter_kernel(unsigned long entrypoint,
* for both archictectures, with the arch-specific code provided in the
* handle_kernel_image() function.
*/
efi_status_t efi_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg)
efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
efi_system_table_t *sys_table_arg)
{
efi_loaded_image_t *image;
efi_status_t status;
......@@ -186,13 +187,13 @@ efi_status_t efi_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg)
status = efi_system_table->boottime->handle_protocol(handle,
&loaded_image_proto, (void *)&image);
if (status != EFI_SUCCESS) {
pr_efi_err("Failed to get loaded image protocol\n");
efi_err("Failed to get loaded image protocol\n");
goto fail;
}
dram_base = get_dram_base();
if (dram_base == EFI_ERROR) {
pr_efi_err("Failed to find DRAM base\n");
efi_err("Failed to find DRAM base\n");
status = EFI_LOAD_ERROR;
goto fail;
}
......@@ -202,22 +203,32 @@ efi_status_t efi_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg)
* protocol. We are going to copy the command line into the
* device tree, so this can be allocated anywhere.
*/
cmdline_ptr = efi_convert_cmdline(image, &cmdline_size, ULONG_MAX);
cmdline_ptr = efi_convert_cmdline(image, &cmdline_size);
if (!cmdline_ptr) {
pr_efi_err("getting command line via LOADED_IMAGE_PROTOCOL\n");
efi_err("getting command line via LOADED_IMAGE_PROTOCOL\n");
status = EFI_OUT_OF_RESOURCES;
goto fail;
}
if (IS_ENABLED(CONFIG_CMDLINE_EXTEND) ||
IS_ENABLED(CONFIG_CMDLINE_FORCE) ||
cmdline_size == 0)
efi_parse_options(CONFIG_CMDLINE);
cmdline_size == 0) {
status = efi_parse_options(CONFIG_CMDLINE);
if (status != EFI_SUCCESS) {
efi_err("Failed to parse options\n");
goto fail_free_cmdline;
}
}
if (!IS_ENABLED(CONFIG_CMDLINE_FORCE) && cmdline_size > 0)
efi_parse_options(cmdline_ptr);
if (!IS_ENABLED(CONFIG_CMDLINE_FORCE) && cmdline_size > 0) {
status = efi_parse_options(cmdline_ptr);
if (status != EFI_SUCCESS) {
efi_err("Failed to parse options\n");
goto fail_free_cmdline;
}
}
pr_efi("Booting Linux Kernel...\n");
efi_info("Booting Linux Kernel...\n");
si = setup_graphics();
......@@ -226,8 +237,8 @@ efi_status_t efi_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg)
&reserve_size,
dram_base, image);
if (status != EFI_SUCCESS) {
pr_efi_err("Failed to relocate kernel\n");
goto fail_free_cmdline;
efi_err("Failed to relocate kernel\n");
goto fail_free_screeninfo;
}
efi_retrieve_tpm2_eventlog();
......@@ -245,42 +256,34 @@ efi_status_t efi_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg)
if (!IS_ENABLED(CONFIG_EFI_ARMSTUB_DTB_LOADER) ||
secure_boot != efi_secureboot_mode_disabled) {
if (strstr(cmdline_ptr, "dtb="))
pr_efi("Ignoring DTB from command line.\n");
efi_err("Ignoring DTB from command line.\n");
} else {
status = efi_load_dtb(image, &fdt_addr, &fdt_size);
if (status != EFI_SUCCESS) {
pr_efi_err("Failed to load device tree!\n");
efi_err("Failed to load device tree!\n");
goto fail_free_image;
}
}
if (fdt_addr) {
pr_efi("Using DTB from command line\n");
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)
pr_efi("Using DTB from configuration table\n");
efi_info("Using DTB from configuration table\n");
}
if (!fdt_addr)
pr_efi("Generating empty DTB\n");
efi_info("Generating empty DTB\n");
if (!efi_noinitrd) {
max_addr = efi_get_max_initrd_addr(dram_base, image_addr);
status = efi_load_initrd_dev_path(&initrd_addr, &initrd_size,
max_addr);
if (status == EFI_SUCCESS) {
pr_efi("Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path\n");
} else if (status == EFI_NOT_FOUND) {
status = efi_load_initrd(image, &initrd_addr, &initrd_size,
ULONG_MAX, max_addr);
if (status == EFI_SUCCESS && initrd_size > 0)
pr_efi("Loaded initrd from command line option\n");
}
status = efi_load_initrd(image, &initrd_addr, &initrd_size,
ULONG_MAX, max_addr);
if (status != EFI_SUCCESS)
pr_efi_err("Failed to load initrd!\n");
efi_err("Failed to load initrd!\n");
}
efi_random_get_seed();
......@@ -330,7 +333,7 @@ efi_status_t efi_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg)
/* not reached */
fail_free_initrd:
pr_efi_err("Failed to update FDT and exit boot services\n");
efi_err("Failed to update FDT and exit boot services\n");
efi_free(initrd_size, initrd_addr);
efi_free(fdt_size, fdt_addr);
......@@ -338,9 +341,10 @@ efi_status_t efi_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg)
fail_free_image:
efi_free(image_size, image_addr);
efi_free(reserve_size, reserve_addr);
fail_free_cmdline:
fail_free_screeninfo:
free_screen_info(si);
efi_free(cmdline_size, (unsigned long)cmdline_ptr);
fail_free_cmdline:
efi_bs_call(free_pool, cmdline_ptr);
fail:
return status;
}
......
......@@ -3,6 +3,13 @@
#ifndef _DRIVERS_FIRMWARE_EFI_EFISTUB_H
#define _DRIVERS_FIRMWARE_EFI_EFISTUB_H
#include <linux/compiler.h>
#include <linux/efi.h>
#include <linux/kernel.h>
#include <linux/kern_levels.h>
#include <linux/types.h>
#include <asm/efi.h>
/* error code which can't be mistaken for valid address */
#define EFI_ERROR (~0UL)
......@@ -28,32 +35,30 @@
extern bool efi_nochunk;
extern bool efi_nokaslr;
extern bool efi_noinitrd;
extern bool efi_quiet;
extern int efi_loglevel;
extern bool efi_novamap;
extern const efi_system_table_t *efi_system_table;
#ifndef efi_bs_call
efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
efi_system_table_t *sys_table_arg);
#ifndef ARCH_HAS_EFISTUB_WRAPPERS
#define efi_is_native() (true)
#define efi_bs_call(func, ...) efi_system_table->boottime->func(__VA_ARGS__)
#endif
#ifndef efi_rt_call
#define efi_rt_call(func, ...) efi_system_table->runtime->func(__VA_ARGS__)
#endif
#ifndef efi_is_native
#define efi_is_native() (true)
#endif
#ifndef efi_table_attr
#define efi_table_attr(inst, attr) (inst->attr)
#endif
#ifndef efi_call_proto
#define efi_call_proto(inst, func, ...) inst->func(inst, ##__VA_ARGS__)
#endif
#define pr_efi(msg) do { \
if (!efi_quiet) efi_printk("EFI stub: "msg); \
} while (0)
#endif
#define pr_efi_err(msg) efi_printk("EFI stub: ERROR: "msg)
#define efi_info(fmt, ...) \
efi_printk(KERN_INFO fmt, ##__VA_ARGS__)
#define efi_err(fmt, ...) \
efi_printk(KERN_ERR "ERROR: " fmt, ##__VA_ARGS__)
#define efi_debug(fmt, ...) \
efi_printk(KERN_DEBUG "DEBUG: " fmt, ##__VA_ARGS__)
/* Helper macros for the usual case of using simple C variables: */
#ifndef fdt_setprop_inplace_var
......@@ -87,6 +92,13 @@ extern const efi_system_table_t *efi_system_table;
((handle = efi_get_handle_at((array), i)) || true); \
i++)
static inline
void efi_set_u64_split(u64 data, u32 *lo, u32 *hi)
{
*lo = lower_32_bits(data);
*hi = upper_32_bits(data);
}
/*
* Allocation types for calls to boottime->allocate_pages.
*/
......@@ -102,6 +114,16 @@ extern const efi_system_table_t *efi_system_table;
#define EFI_LOCATE_BY_REGISTER_NOTIFY 1
#define EFI_LOCATE_BY_PROTOCOL 2
/*
* boottime->stall takes the time period in microseconds
*/
#define EFI_USEC_PER_SEC 1000000
/*
* boottime->set_timer takes the time in 100ns units
*/
#define EFI_100NSEC_PER_USEC ((u64)10)
/*
* An efi_boot_memmap is used by efi_get_memory_map() to return the
* EFI memory map in a dynamically allocated buffer.
......@@ -126,6 +148,39 @@ struct efi_boot_memmap {
typedef struct efi_generic_dev_path efi_device_path_protocol_t;
typedef void *efi_event_t;
/* Note that notifications won't work in mixed mode */
typedef void (__efiapi *efi_event_notify_t)(efi_event_t, void *);
#define EFI_EVT_TIMER 0x80000000U
#define EFI_EVT_RUNTIME 0x40000000U
#define EFI_EVT_NOTIFY_WAIT 0x00000100U
#define EFI_EVT_NOTIFY_SIGNAL 0x00000200U
/*
* boottime->wait_for_event takes an array of events as input.
* Provide a helper to set it up correctly for mixed mode.
*/
static inline
void efi_set_event_at(efi_event_t *events, size_t idx, efi_event_t event)
{
if (efi_is_native())
events[idx] = event;
else
((u32 *)events)[idx] = (u32)(unsigned long)event;
}
#define EFI_TPL_APPLICATION 4
#define EFI_TPL_CALLBACK 8
#define EFI_TPL_NOTIFY 16
#define EFI_TPL_HIGH_LEVEL 31
typedef enum {
EfiTimerCancel,
EfiTimerPeriodic,
EfiTimerRelative
} EFI_TIMER_DELAY;
/*
* EFI Boot Services table
*/
......@@ -144,11 +199,16 @@ union efi_boot_services {
efi_status_t (__efiapi *allocate_pool)(int, unsigned long,
void **);
efi_status_t (__efiapi *free_pool)(void *);
void *create_event;
void *set_timer;
void *wait_for_event;
efi_status_t (__efiapi *create_event)(u32, unsigned long,
efi_event_notify_t, void *,
efi_event_t *);
efi_status_t (__efiapi *set_timer)(efi_event_t,
EFI_TIMER_DELAY, u64);
efi_status_t (__efiapi *wait_for_event)(unsigned long,
efi_event_t *,
unsigned long *);
void *signal_event;
void *close_event;
efi_status_t (__efiapi *close_event)(efi_event_t);
void *check_event;
void *install_protocol_interface;
void *reinstall_protocol_interface;
......@@ -175,7 +235,7 @@ union efi_boot_services {
efi_status_t (__efiapi *exit_boot_services)(efi_handle_t,
unsigned long);
void *get_next_monotonic_count;
void *stall;
efi_status_t (__efiapi *stall)(unsigned long);
void *set_watchdog_timer;
void *connect_controller;
efi_status_t (__efiapi *disconnect_controller)(efi_handle_t,
......@@ -260,6 +320,27 @@ union efi_uga_draw_protocol {
} mixed_mode;
};
typedef struct {
u16 scan_code;
efi_char16_t unicode_char;
} efi_input_key_t;
union efi_simple_text_input_protocol {
struct {
void *reset;
efi_status_t (__efiapi *read_keystroke)(efi_simple_text_input_protocol_t *,
efi_input_key_t *);
efi_event_t wait_for_key;
};
struct {
u32 reset;
u32 read_keystroke;
u32 wait_for_key;
} mixed_mode;
};
efi_status_t efi_wait_for_key(unsigned long usec, efi_input_key_t *key);
union efi_simple_text_output_protocol {
struct {
void *reset;
......@@ -612,8 +693,6 @@ efi_status_t efi_exit_boot_services(void *handle,
void *priv,
efi_exit_boot_map_processing priv_func);
void efi_char16_printk(efi_char16_t *);
efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
unsigned long *new_fdt_addr,
unsigned long max_addr,
......@@ -637,12 +716,15 @@ efi_status_t check_platform_features(void);
void *get_efi_config_table(efi_guid_t guid);
void efi_printk(char *str);
/* NOTE: These functions do not print a trailing newline after the string */
void efi_char16_puts(efi_char16_t *);
void efi_puts(const char *str);
__printf(1, 2) int efi_printk(char const *fmt, ...);
void efi_free(unsigned long size, unsigned long addr);
char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len,
unsigned long max_addr);
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);
......@@ -683,21 +765,10 @@ static inline efi_status_t efi_load_dtb(efi_loaded_image_t *image,
ULONG_MAX, ULONG_MAX, load_addr, load_size);
}
static inline 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 hard_limit)
{
if (!IS_ENABLED(CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER))
return EFI_SUCCESS;
return handle_cmdline_files(image, L"initrd=", sizeof(L"initrd=") - 2,
soft_limit, hard_limit, load_addr, load_size);
}
efi_status_t efi_load_initrd_dev_path(unsigned long *load_addr,
unsigned long *load_size,
unsigned long max);
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 hard_limit);
#endif
......@@ -39,7 +39,7 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size,
/* Do some checks on provided FDT, if it exists: */
if (orig_fdt) {
if (fdt_check_header(orig_fdt)) {
pr_efi_err("Device Tree header not valid!\n");
efi_err("Device Tree header not valid!\n");
return EFI_LOAD_ERROR;
}
/*
......@@ -47,7 +47,7 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size,
* configuration table:
*/
if (orig_fdt_size && fdt_totalsize(orig_fdt) > orig_fdt_size) {
pr_efi_err("Truncated device tree! foo!\n");
efi_err("Truncated device tree! foo!\n");
return EFI_LOAD_ERROR;
}
}
......@@ -270,16 +270,16 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
*/
status = efi_get_memory_map(&map);
if (status != EFI_SUCCESS) {
pr_efi_err("Unable to retrieve UEFI memory map.\n");
efi_err("Unable to retrieve UEFI memory map.\n");
return status;
}
pr_efi("Exiting boot services and installing virtual address map...\n");
efi_info("Exiting boot services and installing virtual address map...\n");
map.map = &memory_map;
status = efi_allocate_pages(MAX_FDT_SIZE, new_fdt_addr, max_addr);
if (status != EFI_SUCCESS) {
pr_efi_err("Unable to allocate memory for new device tree.\n");
efi_err("Unable to allocate memory for new device tree.\n");
goto fail;
}
......@@ -296,7 +296,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
initrd_addr, initrd_size);
if (status != EFI_SUCCESS) {
pr_efi_err("Unable to construct new device tree.\n");
efi_err("Unable to construct new device tree.\n");
goto fail_free_new_fdt;
}
......@@ -342,7 +342,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle,
return EFI_SUCCESS;
}
pr_efi_err("Exit boot services failed.\n");
efi_err("Exit boot services failed.\n");
fail_free_new_fdt:
efi_free(MAX_FDT_SIZE, *new_fdt_addr);
......@@ -363,7 +363,7 @@ void *get_fdt(unsigned long *fdt_size)
return NULL;
if (fdt_check_header(fdt) != 0) {
pr_efi_err("Invalid header detected on UEFI supplied FDT, ignoring ...\n");
efi_err("Invalid header detected on UEFI supplied FDT, ignoring ...\n");
return NULL;
}
*fdt_size = fdt_totalsize(fdt);
......
......@@ -46,16 +46,14 @@ static efi_status_t efi_open_file(efi_file_protocol_t *volume,
status = volume->open(volume, &fh, fi->filename, EFI_FILE_MODE_READ, 0);
if (status != EFI_SUCCESS) {
pr_efi_err("Failed to open file: ");
efi_char16_printk(fi->filename);
efi_printk("\n");
efi_err("Failed to open file: %ls\n", fi->filename);
return status;
}
info_sz = sizeof(struct finfo);
status = fh->get_info(fh, &info_guid, &info_sz, fi);
if (status != EFI_SUCCESS) {
pr_efi_err("Failed to get file info\n");
efi_err("Failed to get file info\n");
fh->close(fh);
return status;
}
......@@ -75,13 +73,13 @@ static efi_status_t efi_open_volume(efi_loaded_image_t *image,
status = efi_bs_call(handle_protocol, image->device_handle, &fs_proto,
(void **)&io);
if (status != EFI_SUCCESS) {
pr_efi_err("Failed to handle fs_proto\n");
efi_err("Failed to handle fs_proto\n");
return status;
}
status = io->open_volume(io, fh);
if (status != EFI_SUCCESS)
pr_efi_err("Failed to open volume\n");
efi_err("Failed to open volume\n");
return status;
}
......@@ -191,7 +189,7 @@ efi_status_t handle_cmdline_files(efi_loaded_image_t *image,
&alloc_addr,
hard_limit);
if (status != EFI_SUCCESS) {
pr_efi_err("Failed to allocate memory for files\n");
efi_err("Failed to allocate memory for files\n");
goto err_close_file;
}
......@@ -215,7 +213,7 @@ efi_status_t handle_cmdline_files(efi_loaded_image_t *image,
status = file->read(file, &chunksize, addr);
if (status != EFI_SUCCESS) {
pr_efi_err("Failed to read file\n");
efi_err("Failed to read file\n");
goto err_close_file;
}
addr += chunksize;
......
......@@ -19,7 +19,8 @@ enum efi_cmdline_option {
EFI_CMDLINE_NONE,
EFI_CMDLINE_MODE_NUM,
EFI_CMDLINE_RES,
EFI_CMDLINE_AUTO
EFI_CMDLINE_AUTO,
EFI_CMDLINE_LIST
};
static struct {
......@@ -100,6 +101,19 @@ static bool parse_auto(char *option, char **next)
return true;
}
static bool parse_list(char *option, char **next)
{
if (!strstarts(option, "list"))
return false;
option += strlen("list");
if (*option && *option++ != ',')
return false;
cmdline.option = EFI_CMDLINE_LIST;
*next = option;
return true;
}
void efi_parse_option_graphics(char *option)
{
while (*option) {
......@@ -109,6 +123,8 @@ void efi_parse_option_graphics(char *option)
continue;
if (parse_auto(option, &option))
continue;
if (parse_list(option, &option))
continue;
while (*option && *option++ != ',')
;
......@@ -134,14 +150,14 @@ static u32 choose_mode_modenum(efi_graphics_output_protocol_t *gop)
max_mode = efi_table_attr(mode, max_mode);
if (cmdline.mode >= max_mode) {
efi_printk("Requested mode is invalid\n");
efi_err("Requested mode is invalid\n");
return cur_mode;
}
status = efi_call_proto(gop, query_mode, cmdline.mode,
&info_size, &info);
if (status != EFI_SUCCESS) {
efi_printk("Couldn't get mode information\n");
efi_err("Couldn't get mode information\n");
return cur_mode;
}
......@@ -150,7 +166,7 @@ static u32 choose_mode_modenum(efi_graphics_output_protocol_t *gop)
efi_bs_call(free_pool, info);
if (pf == PIXEL_BLT_ONLY || pf >= PIXEL_FORMAT_MAX) {
efi_printk("Invalid PixelFormat\n");
efi_err("Invalid PixelFormat\n");
return cur_mode;
}
......@@ -222,7 +238,7 @@ static u32 choose_mode_res(efi_graphics_output_protocol_t *gop)
return m;
}
efi_printk("Couldn't find requested mode\n");
efi_err("Couldn't find requested mode\n");
return cur_mode;
}
......@@ -290,6 +306,82 @@ static u32 choose_mode_auto(efi_graphics_output_protocol_t *gop)
return best_mode;
}
static u32 choose_mode_list(efi_graphics_output_protocol_t *gop)
{
efi_status_t status;
efi_graphics_output_protocol_mode_t *mode;
efi_graphics_output_mode_info_t *info;
unsigned long info_size;
u32 max_mode, cur_mode;
int pf;
efi_pixel_bitmask_t pi;
u32 m, w, h;
u8 d;
const char *dstr;
bool valid;
efi_input_key_t key;
mode = efi_table_attr(gop, mode);
cur_mode = efi_table_attr(mode, mode);
max_mode = efi_table_attr(mode, max_mode);
efi_printk("Available graphics modes are 0-%u\n", max_mode-1);
efi_puts(" * = current mode\n"
" - = unusable mode\n");
for (m = 0; m < max_mode; m++) {
status = efi_call_proto(gop, query_mode, m,
&info_size, &info);
if (status != EFI_SUCCESS)
continue;
pf = info->pixel_format;
pi = info->pixel_information;
w = info->horizontal_resolution;
h = info->vertical_resolution;
efi_bs_call(free_pool, info);
valid = !(pf == PIXEL_BLT_ONLY || pf >= PIXEL_FORMAT_MAX);
d = 0;
switch (pf) {
case PIXEL_RGB_RESERVED_8BIT_PER_COLOR:
dstr = "rgb";
break;
case PIXEL_BGR_RESERVED_8BIT_PER_COLOR:
dstr = "bgr";
break;
case PIXEL_BIT_MASK:
dstr = "";
d = pixel_bpp(pf, pi);
break;
case PIXEL_BLT_ONLY:
dstr = "blt";
break;
default:
dstr = "xxx";
break;
}
efi_printk("Mode %3u %c%c: Resolution %ux%u-%s%.0hhu\n",
m,
m == cur_mode ? '*' : ' ',
!valid ? '-' : ' ',
w, h, dstr, d);
}
efi_puts("\nPress any key to continue (or wait 10 seconds)\n");
status = efi_wait_for_key(10 * EFI_USEC_PER_SEC, &key);
if (status != EFI_SUCCESS && status != EFI_TIMEOUT) {
efi_err("Unable to read key, continuing in 10 seconds\n");
efi_bs_call(stall, 10 * EFI_USEC_PER_SEC);
}
return cur_mode;
}
static void set_mode(efi_graphics_output_protocol_t *gop)
{
efi_graphics_output_protocol_mode_t *mode;
......@@ -305,6 +397,9 @@ static void set_mode(efi_graphics_output_protocol_t *gop)
case EFI_CMDLINE_AUTO:
new_mode = choose_mode_auto(gop);
break;
case EFI_CMDLINE_LIST:
new_mode = choose_mode_list(gop);
break;
default:
return;
}
......@@ -316,7 +411,7 @@ static void set_mode(efi_graphics_output_protocol_t *gop)
return;
if (efi_call_proto(gop, set_mode, new_mode) != EFI_SUCCESS)
efi_printk("Failed to set requested mode\n");
efi_err("Failed to set requested mode\n");
}
static void find_bits(u32 mask, u8 *pos, u8 *size)
......@@ -422,7 +517,6 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
efi_graphics_output_protocol_t *gop;
efi_graphics_output_protocol_mode_t *mode;
efi_graphics_output_mode_info_t *info;
efi_physical_addr_t fb_base;
gop = find_gop(proto, size, handles);
......@@ -442,9 +536,8 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
si->lfb_width = info->horizontal_resolution;
si->lfb_height = info->vertical_resolution;
fb_base = efi_table_attr(mode, frame_buffer_base);
si->lfb_base = lower_32_bits(fb_base);
si->ext_lfb_base = upper_32_bits(fb_base);
efi_set_u64_split(efi_table_attr(mode, frame_buffer_base),
&si->lfb_base, &si->ext_lfb_base);
if (si->ext_lfb_base)
si->capabilities |= VIDEO_CAPABILITY_64BIT_BASE;
......
......@@ -28,21 +28,21 @@ void efi_pci_disable_bridge_busmaster(void)
if (status != EFI_BUFFER_TOO_SMALL) {
if (status != EFI_SUCCESS && status != EFI_NOT_FOUND)
pr_efi_err("Failed to locate PCI I/O handles'\n");
efi_err("Failed to locate PCI I/O handles'\n");
return;
}
status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, pci_handle_size,
(void **)&pci_handle);
if (status != EFI_SUCCESS) {
pr_efi_err("Failed to allocate memory for 'pci_handle'\n");
efi_err("Failed to allocate memory for 'pci_handle'\n");
return;
}
status = efi_bs_call(locate_handle, EFI_LOCATE_BY_PROTOCOL, &pci_proto,
NULL, &pci_handle_size, pci_handle);
if (status != EFI_SUCCESS) {
pr_efi_err("Failed to locate PCI I/O handles'\n");
efi_err("Failed to locate PCI I/O handles'\n");
goto free_handle;
}
......@@ -69,7 +69,7 @@ void efi_pci_disable_bridge_busmaster(void)
* access to the framebuffer. Drivers for true PCIe graphics
* controllers that are behind a PCIe root port do not use
* DMA to implement the GOP framebuffer anyway [although they
* may use it in their implentation of Gop->Blt()], and so
* may use it in their implementation of Gop->Blt()], and so
* disabling DMA in the PCI bridge should not interfere with
* normal operation of the device.
*/
......@@ -106,7 +106,7 @@ void efi_pci_disable_bridge_busmaster(void)
status = efi_call_proto(pci, pci.write, EfiPciIoWidthUint16,
PCI_COMMAND, 1, &command);
if (status != EFI_SUCCESS)
pr_efi_err("Failed to disable PCI busmastering\n");
efi_err("Failed to disable PCI busmastering\n");
}
free_handle:
......
......@@ -140,7 +140,7 @@ efi_status_t efi_relocate_kernel(unsigned long *image_addr,
* The EFI firmware loader could have placed the kernel image
* anywhere in memory, but the kernel has restrictions on the
* max physical address it can run at. Some architectures
* also have a prefered address, so first try to relocate
* also have a preferred address, so first try to relocate
* to the preferred address. If that fails, allocate as low
* as possible while respecting the required alignment.
*/
......@@ -157,7 +157,7 @@ efi_status_t efi_relocate_kernel(unsigned long *image_addr,
min_addr);
}
if (status != EFI_SUCCESS) {
pr_efi_err("Failed to allocate usable memory for kernel.\n");
efi_err("Failed to allocate usable memory for kernel.\n");
return status;
}
......
......@@ -67,10 +67,10 @@ enum efi_secureboot_mode efi_get_secureboot(void)
return efi_secureboot_mode_disabled;
secure_boot_enabled:
pr_efi("UEFI Secure Boot is enabled.\n");
efi_info("UEFI Secure Boot is enabled.\n");
return efi_secureboot_mode_enabled;
out_efi_err:
pr_efi_err("Could not determine UEFI Secure Boot status.\n");
efi_err("Could not determine UEFI Secure Boot status.\n");
return efi_secureboot_mode_unknown;
}
......@@ -119,7 +119,7 @@ void efi_retrieve_tpm2_eventlog(void)
sizeof(*log_tbl) + log_size, (void **)&log_tbl);
if (status != EFI_SUCCESS) {
efi_printk("Unable to allocate memory for event log\n");
efi_err("Unable to allocate memory for event log\n");
return;
}
......
This diff is collapsed.
......@@ -22,6 +22,7 @@
const efi_system_table_t *efi_system_table;
extern u32 image_offset;
static efi_loaded_image_t *image = NULL;
static efi_status_t
preserve_pci_rom_image(efi_pci_io_protocol_t *pci, struct pci_setup_rom **__rom)
......@@ -49,7 +50,7 @@ preserve_pci_rom_image(efi_pci_io_protocol_t *pci, struct pci_setup_rom **__rom)
status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, size,
(void **)&rom);
if (status != EFI_SUCCESS) {
efi_printk("Failed to allocate memory for 'rom'\n");
efi_err("Failed to allocate memory for 'rom'\n");
return status;
}
......@@ -65,7 +66,7 @@ preserve_pci_rom_image(efi_pci_io_protocol_t *pci, struct pci_setup_rom **__rom)
PCI_VENDOR_ID, 1, &rom->vendor);
if (status != EFI_SUCCESS) {
efi_printk("Failed to read rom->vendor\n");
efi_err("Failed to read rom->vendor\n");
goto free_struct;
}
......@@ -73,7 +74,7 @@ preserve_pci_rom_image(efi_pci_io_protocol_t *pci, struct pci_setup_rom **__rom)
PCI_DEVICE_ID, 1, &rom->devid);
if (status != EFI_SUCCESS) {
efi_printk("Failed to read rom->devid\n");
efi_err("Failed to read rom->devid\n");
goto free_struct;
}
......@@ -118,7 +119,7 @@ static void setup_efi_pci(struct boot_params *params)
(void **)&pci_handle);
if (status != EFI_SUCCESS) {
efi_printk("Failed to allocate memory for 'pci_handle'\n");
efi_err("Failed to allocate memory for 'pci_handle'\n");
return;
}
......@@ -172,7 +173,7 @@ static void retrieve_apple_device_properties(struct boot_params *boot_params)
return;
if (efi_table_attr(p, version) != 0x10000) {
efi_printk("Unsupported properties proto version\n");
efi_err("Unsupported properties proto version\n");
return;
}
......@@ -185,7 +186,7 @@ static void retrieve_apple_device_properties(struct boot_params *boot_params)
size + sizeof(struct setup_data),
(void **)&new);
if (status != EFI_SUCCESS) {
efi_printk("Failed to allocate memory for 'properties'\n");
efi_err("Failed to allocate memory for 'properties'\n");
return;
}
......@@ -355,7 +356,6 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
{
struct boot_params *boot_params;
struct setup_header *hdr;
efi_loaded_image_t *image;
void *image_base;
efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID;
int options_size = 0;
......@@ -372,20 +372,21 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
status = efi_bs_call(handle_protocol, handle, &proto, (void **)&image);
if (status != EFI_SUCCESS) {
efi_printk("Failed to get handle for LOADED_IMAGE_PROTOCOL\n");
efi_err("Failed to get handle for LOADED_IMAGE_PROTOCOL\n");
efi_exit(handle, status);
}
image_base = efi_table_attr(image, image_base);
image_offset = (void *)startup_32 - image_base;
status = efi_allocate_pages(0x4000, (unsigned long *)&boot_params, ULONG_MAX);
status = efi_allocate_pages(sizeof(struct boot_params),
(unsigned long *)&boot_params, ULONG_MAX);
if (status != EFI_SUCCESS) {
efi_printk("Failed to allocate lowmem for boot params\n");
efi_err("Failed to allocate lowmem for boot params\n");
efi_exit(handle, status);
}
memset(boot_params, 0x0, 0x4000);
memset(boot_params, 0x0, sizeof(struct boot_params));
hdr = &boot_params->hdr;
......@@ -403,43 +404,21 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
hdr->type_of_loader = 0x21;
/* Convert unicode cmdline to ascii */
cmdline_ptr = efi_convert_cmdline(image, &options_size, ULONG_MAX);
cmdline_ptr = efi_convert_cmdline(image, &options_size);
if (!cmdline_ptr)
goto fail;
hdr->cmd_line_ptr = (unsigned long)cmdline_ptr;
/* Fill in upper bits of command line address, NOP on 32 bit */
boot_params->ext_cmd_line_ptr = (u64)(unsigned long)cmdline_ptr >> 32;
efi_set_u64_split((unsigned long)cmdline_ptr,
&hdr->cmd_line_ptr, &boot_params->ext_cmd_line_ptr);
hdr->ramdisk_image = 0;
hdr->ramdisk_size = 0;
if (efi_is_native()) {
status = efi_parse_options(cmdline_ptr);
if (status != EFI_SUCCESS)
goto fail2;
if (!efi_noinitrd) {
status = efi_load_initrd(image, &ramdisk_addr,
&ramdisk_size,
hdr->initrd_addr_max,
ULONG_MAX);
if (status != EFI_SUCCESS)
goto fail2;
hdr->ramdisk_image = ramdisk_addr & 0xffffffff;
hdr->ramdisk_size = ramdisk_size & 0xffffffff;
boot_params->ext_ramdisk_image = (u64)ramdisk_addr >> 32;
boot_params->ext_ramdisk_size = (u64)ramdisk_size >> 32;
}
}
efi_stub_entry(handle, sys_table_arg, boot_params);
/* not reached */
fail2:
efi_free(options_size, (unsigned long)cmdline_ptr);
fail:
efi_free(0x4000, (unsigned long)boot_params);
efi_free(sizeof(struct boot_params), (unsigned long)boot_params);
efi_exit(handle, status);
}
......@@ -632,17 +611,14 @@ static efi_status_t exit_boot_func(struct efi_boot_memmap *map,
: EFI32_LOADER_SIGNATURE;
memcpy(&p->efi->efi_loader_signature, signature, sizeof(__u32));
p->efi->efi_systab = (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_memdesc_size = *map->desc_size;
p->efi->efi_memdesc_version = *map->desc_ver;
p->efi->efi_memmap = (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_size = *map->map_size;
#ifdef CONFIG_X86_64
p->efi->efi_systab_hi = (unsigned long)efi_system_table >> 32;
p->efi->efi_memmap_hi = (unsigned long)*map->map >> 32;
#endif
return EFI_SUCCESS;
}
......@@ -698,7 +674,6 @@ unsigned long efi_main(efi_handle_t handle,
unsigned long buffer_start, buffer_end;
struct setup_header *hdr = &boot_params->hdr;
efi_status_t status;
unsigned long cmdline_paddr;
efi_system_table = sys_table_arg;
......@@ -746,7 +721,7 @@ unsigned long efi_main(efi_handle_t handle,
hdr->kernel_alignment,
LOAD_PHYSICAL_ADDR);
if (status != EFI_SUCCESS) {
efi_printk("efi_relocate_kernel() failed!\n");
efi_err("efi_relocate_kernel() failed!\n");
goto fail;
}
/*
......@@ -757,35 +732,46 @@ unsigned long efi_main(efi_handle_t handle,
image_offset = 0;
}
/*
* efi_pe_entry() may have been called before efi_main(), in which
* case this is the second time we parse the cmdline. This is ok,
* parsing the cmdline multiple times does not have side-effects.
*/
cmdline_paddr = ((u64)hdr->cmd_line_ptr |
((u64)boot_params->ext_cmd_line_ptr << 32));
efi_parse_options((char *)cmdline_paddr);
#ifdef CONFIG_CMDLINE_BOOL
status = efi_parse_options(CONFIG_CMDLINE);
if (status != EFI_SUCCESS) {
efi_err("Failed to parse options\n");
goto fail;
}
#endif
if (!IS_ENABLED(CONFIG_CMDLINE_OVERRIDE)) {
unsigned long cmdline_paddr = ((u64)hdr->cmd_line_ptr |
((u64)boot_params->ext_cmd_line_ptr << 32));
status = efi_parse_options((char *)cmdline_paddr);
if (status != EFI_SUCCESS) {
efi_err("Failed to parse options\n");
goto fail;
}
}
/*
* At this point, an initrd may already have been loaded, either by
* the bootloader and passed via bootparams, or loaded from a initrd=
* command line option by efi_pe_entry() above. In either case, we
* permit an initrd loaded from the LINUX_EFI_INITRD_MEDIA_GUID device
* path to supersede it.
* At this point, an initrd may already have been loaded by the
* bootloader and passed via bootparams. We permit an initrd loaded
* from the LINUX_EFI_INITRD_MEDIA_GUID device path to supersede it.
*
* If the device path is not present, any command-line initrd=
* 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.
*/
if (!efi_noinitrd) {
unsigned long addr, size;
status = efi_load_initrd_dev_path(&addr, &size, ULONG_MAX);
if (status == EFI_SUCCESS) {
hdr->ramdisk_image = (u32)addr;
hdr->ramdisk_size = (u32)size;
boot_params->ext_ramdisk_image = (u64)addr >> 32;
boot_params->ext_ramdisk_size = (u64)size >> 32;
} else if (status != EFI_NOT_FOUND) {
efi_printk("efi_load_initrd_dev_path() failed!\n");
status = efi_load_initrd(image, &addr, &size,
hdr->initrd_addr_max, ULONG_MAX);
if (status != EFI_SUCCESS) {
efi_err("Failed to load initrd!\n");
goto fail;
}
efi_set_u64_split(addr, &hdr->ramdisk_image,
&boot_params->ext_ramdisk_image);
efi_set_u64_split(size, &hdr->ramdisk_size,
&boot_params->ext_ramdisk_size);
}
/*
......@@ -810,13 +796,13 @@ unsigned long efi_main(efi_handle_t handle,
status = exit_boot(boot_params, handle);
if (status != EFI_SUCCESS) {
efi_printk("exit_boot() failed!\n");
efi_err("exit_boot() failed!\n");
goto fail;
}
return bzimage_addr;
fail:
efi_printk("efi_main() failed!\n");
efi_err("efi_main() failed!\n");
efi_exit(handle, status);
}
......@@ -39,6 +39,7 @@
#define EFI_WRITE_PROTECTED ( 8 | (1UL << (BITS_PER_LONG-1)))
#define EFI_OUT_OF_RESOURCES ( 9 | (1UL << (BITS_PER_LONG-1)))
#define EFI_NOT_FOUND (14 | (1UL << (BITS_PER_LONG-1)))
#define EFI_TIMEOUT (18 | (1UL << (BITS_PER_LONG-1)))
#define EFI_ABORTED (21 | (1UL << (BITS_PER_LONG-1)))
#define EFI_SECURITY_VIOLATION (26 | (1UL << (BITS_PER_LONG-1)))
......@@ -426,6 +427,7 @@ typedef struct {
u32 tables;
} efi_system_table_32_t;
typedef union efi_simple_text_input_protocol efi_simple_text_input_protocol_t;
typedef union efi_simple_text_output_protocol efi_simple_text_output_protocol_t;
typedef union {
......@@ -434,7 +436,7 @@ typedef union {
unsigned long fw_vendor; /* physical addr of CHAR16 vendor string */
u32 fw_revision;
unsigned long con_in_handle;
unsigned long con_in;
efi_simple_text_input_protocol_t *con_in;
unsigned long con_out_handle;
efi_simple_text_output_protocol_t *con_out;
unsigned long stderr_handle;
......
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