Skip to content

Commit

Permalink
Merge tag 'efi-core-2020-06-01' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/tip/tip

Pull EFI updates from Ingo Molnar:
 "The EFI changes for this cycle are:

   - preliminary changes for RISC-V

   - Add support for setting the resolution on the EFI framebuffer

   - Simplify kernel image loading for arm64

   - Move .bss into .data via the linker script instead of relying on
     symbol annotations.

   - Get rid of __pure getters to access global variables

   - Clean up the config table matching arrays

   - 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

   - Simplify GDT handling in early mixed mode thunking code

   - Some other minor fixes and cleanups"

* tag 'efi-core-2020-06-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (79 commits)
  efi/x86: Don't blow away existing initrd
  efi/x86: Drop the special GDT for the EFI thunk
  efi/libstub: Add missing prototype for PE/COFF entry point
  efi/efivars: Add missing kobject_put() in sysfs entry creation error path
  efi/libstub: Use pool allocation for the command line
  efi/libstub: Don't parse overlong command lines
  efi/libstub: Use snprintf with %ls to convert the command line
  efi/libstub: Get the exact UTF-8 length
  efi/libstub: Use %ls for filename
  efi/libstub: Add UTF-8 decoding to efi_puts
  efi/printf: Add support for wchar_t (UTF-16)
  efi/gop: Add an option to list out the available GOP modes
  efi/libstub: Add definitions for console input and events
  efi/libstub: Implement printk-style logging
  efi/printf: Turn vsprintf into vsnprintf
  efi/printf: Abort on invalid format
  efi/printf: Refactor code to consolidate padding and output
  efi/printf: Handle null string input
  efi/printf: Factor out integer argument retrieval
  efi/printf: Factor out width/precision parsing
  ...
  • Loading branch information
Linus Torvalds committed Jun 1, 2020
2 parents a7092c8 + e9524fb commit 58ff3b7
Show file tree
Hide file tree
Showing 38 changed files with 2,050 additions and 829 deletions.
38 changes: 35 additions & 3 deletions Documentation/fb/efifb.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
What is efifb?
==============

This is a generic EFI platform driver for Intel based Apple computers.
efifb is only for EFI booted Intel Macs.
This is a generic EFI platform driver for systems with UEFI firmware. The
system must be booted via the EFI stub for this to be usable. efifb supports
both firmware with Graphics Output Protocol (GOP) displays as well as older
systems with only Universal Graphics Adapter (UGA) displays.

Supported Hardware
==================
Expand All @@ -12,11 +14,14 @@ Supported Hardware
- Macbook
- Macbook Pro 15"/17"
- MacMini
- ARM/ARM64/X86 systems with UEFI firmware

How to use it?
==============

efifb does not have any kind of autodetection of your machine.
For UGA displays, efifb does not have any kind of autodetection of your
machine.

You have to add the following kernel parameters in your elilo.conf::

Macbook :
Expand All @@ -28,6 +33,9 @@ You have to add the following kernel parameters in your elilo.conf::
Macbook Pro 17", iMac 20" :
video=efifb:i20

For GOP displays, efifb can autodetect the display's resolution and framebuffer
address, so these should work out of the box without any special parameters.

Accepted options:

======= ===========================================================
Expand All @@ -36,4 +44,28 @@ nowc Don't map the framebuffer write combined. This can be used
when large amounts of console data are written.
======= ===========================================================

Options for GOP displays:

mode=n
The EFI stub will set the mode of the display to mode number n if
possible.

<xres>x<yres>[-(rgb|bgr|<bpp>)]
The EFI stub will search for a display mode that matches the specified
horizontal and vertical resolution, and optionally bit depth, and set
the mode of the display to it if one is found. The bit depth can either
"rgb" or "bgr" to match specifically those pixel formats, or a number
for a mode with matching bits per pixel.

auto
The EFI stub will choose the mode with the highest resolution (product
of horizontal and vertical resolution). If there are multiple modes
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>
2 changes: 1 addition & 1 deletion arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1955,7 +1955,7 @@ config EFI
select UCS2_STRING
select EFI_PARAMS_FROM_FDT
select EFI_STUB
select EFI_ARMSTUB
select EFI_GENERIC_STUB
select EFI_RUNTIME_WRAPPERS
---help---
This option provides support for runtime services provided
Expand Down
2 changes: 1 addition & 1 deletion arch/arm/boot/compressed/efi-header.S
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion arch/arm/boot/compressed/vmlinux.lds.S
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ SECTIONS
* The EFI stub always executes from RAM, and runs strictly before the
* decompressor, so we can make an exception for its r/w data, and keep it
*/
*(.data.efistub)
*(.data.efistub .bss.efistub)
__pecoff_data_end = .;

/*
Expand Down
8 changes: 0 additions & 8 deletions arch/arm/include/asm/efi.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,6 @@ void efi_virtmap_unload(void);

/* arch specific definitions used by the stub code */

#define efi_bs_call(func, ...) efi_system_table()->boottime->func(__VA_ARGS__)
#define efi_rt_call(func, ...) efi_system_table()->runtime->func(__VA_ARGS__)
#define efi_is_native() (true)

#define efi_table_attr(inst, attr) (inst->attr)

#define efi_call_proto(inst, func, ...) inst->func(inst, ##__VA_ARGS__)

struct screen_info *alloc_screen_info(void);
void free_screen_info(struct screen_info *si);

Expand Down
2 changes: 1 addition & 1 deletion arch/arm64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1786,7 +1786,7 @@ config EFI
select EFI_PARAMS_FROM_FDT
select EFI_RUNTIME_WRAPPERS
select EFI_STUB
select EFI_ARMSTUB
select EFI_GENERIC_STUB
default y
help
This option provides support for runtime services provided
Expand Down
8 changes: 0 additions & 8 deletions arch/arm64/include/asm/efi.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,6 @@ static inline unsigned long efi_get_max_initrd_addr(unsigned long dram_base,
return (image_addr & ~(SZ_1G - 1UL)) + (1UL << (VA_BITS_MIN - 1));
}

#define efi_bs_call(func, ...) efi_system_table()->boottime->func(__VA_ARGS__)
#define efi_rt_call(func, ...) efi_system_table()->runtime->func(__VA_ARGS__)
#define efi_is_native() (true)

#define efi_table_attr(inst, attr) (inst->attr)

#define efi_call_proto(inst, func, ...) inst->func(inst, ##__VA_ARGS__)

#define alloc_screen_info(x...) &screen_info

static inline void free_screen_info(struct screen_info *si)
Expand Down
2 changes: 1 addition & 1 deletion arch/arm64/kernel/efi-entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion arch/arm64/kernel/efi-header.S
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
12 changes: 6 additions & 6 deletions arch/ia64/kernel/efi.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ unsigned long hcdp_phys = EFI_INVALID_TABLE_ADDR;
unsigned long sal_systab_phys = EFI_INVALID_TABLE_ADDR;

static const efi_config_table_type_t arch_tables[] __initconst = {
{ESI_TABLE_GUID, "ESI", &esi_phys},
{HCDP_TABLE_GUID, "HCDP", &hcdp_phys},
{MPS_TABLE_GUID, "MPS", &mps_phys},
{PROCESSOR_ABSTRACTION_LAYER_OVERWRITE_GUID, "PALO", &palo_phys},
{SAL_SYSTEM_TABLE_GUID, "SALsystab", &sal_systab_phys},
{NULL_GUID, NULL, 0},
{ESI_TABLE_GUID, &esi_phys, "ESI" },
{HCDP_TABLE_GUID, &hcdp_phys, "HCDP" },
{MPS_TABLE_GUID, &mps_phys, "MPS" },
{PROCESSOR_ABSTRACTION_LAYER_OVERWRITE_GUID, &palo_phys, "PALO" },
{SAL_SYSTEM_TABLE_GUID, &sal_systab_phys, "SALsystab" },
{},
};

extern efi_status_t efi_call_phys (void *, ...);
Expand Down
19 changes: 3 additions & 16 deletions arch/x86/boot/compressed/efi_thunk_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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)
1 change: 1 addition & 0 deletions arch/x86/boot/compressed/vmlinux.lds.S
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ SECTIONS
_data = . ;
*(.data)
*(.data.*)
*(.bss.efistub)
_edata = . ;
}
. = ALIGN(L1_CACHE_BYTES);
Expand Down
50 changes: 41 additions & 9 deletions arch/x86/include/asm/efi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -225,14 +226,21 @@ efi_status_t efi_set_virtual_address_map(unsigned long memory_map_size,

/* arch specific definitions used by the stub code */

__attribute_const__ bool efi_is_64bit(void);
#ifdef CONFIG_EFI_MIXED

#define ARCH_HAS_EFISTUB_WRAPPERS

static inline bool efi_is_64bit(void)
{
extern const bool efi_is64;

return efi_is64;
}

static inline bool efi_is_native(void)
{
if (!IS_ENABLED(CONFIG_X86_64))
return true;
if (!IS_ENABLED(CONFIG_EFI_MIXED))
return true;
return efi_is_64bit();
}

Expand Down Expand Up @@ -286,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))

Expand All @@ -307,6 +324,10 @@ static inline u32 efi64_convert_status(efi_status_t status)
#define __efi64_argmap_load_file(protocol, path, policy, bufsize, buf) \
((protocol), (path), (policy), efi64_zero_upper(bufsize), (buf))

/* Graphics Output Protocol */
#define __efi64_argmap_query_mode(gop, mode, size, info) \
((gop), (mode), efi64_zero_upper(size), efi64_zero_upper(info))

/*
* The macros below handle the plumbing for the argument mapping. To add a
* mapping for a specific EFI method, simply define a macro
Expand Down Expand Up @@ -335,15 +356,26 @@ static inline u32 efi64_convert_status(efi_status_t status)

#define efi_bs_call(func, ...) \
(efi_is_native() \
? efi_system_table()->boottime->func(__VA_ARGS__) \
: __efi64_thunk_map(efi_table_attr(efi_system_table(), \
boottime), func, __VA_ARGS__))
? efi_system_table->boottime->func(__VA_ARGS__) \
: __efi64_thunk_map(efi_table_attr(efi_system_table, \
boottime), \
func, __VA_ARGS__))

#define efi_rt_call(func, ...) \
(efi_is_native() \
? efi_system_table()->runtime->func(__VA_ARGS__) \
: __efi64_thunk_map(efi_table_attr(efi_system_table(), \
runtime), func, __VA_ARGS__))
? efi_system_table->runtime->func(__VA_ARGS__) \
: __efi64_thunk_map(efi_table_attr(efi_system_table, \
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);
Expand Down
8 changes: 4 additions & 4 deletions arch/x86/platform/efi/efi.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,12 @@ static unsigned long efi_runtime, efi_nr_tables;
unsigned long efi_fw_vendor, efi_config_table;

static const efi_config_table_type_t arch_tables[] __initconst = {
{EFI_PROPERTIES_TABLE_GUID, "PROP", &prop_phys},
{UGA_IO_PROTOCOL_GUID, "UGA", &uga_phys},
{EFI_PROPERTIES_TABLE_GUID, &prop_phys, "PROP" },
{UGA_IO_PROTOCOL_GUID, &uga_phys, "UGA" },
#ifdef CONFIG_X86_UV
{UV_SYSTEM_TABLE_GUID, "UVsystab", &uv_systab_phys},
{UV_SYSTEM_TABLE_GUID, &uv_systab_phys, "UVsystab" },
#endif
{NULL_GUID, NULL, NULL},
{},
};

static const unsigned long * const efi_tables[] = {
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/xen/efi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down
15 changes: 13 additions & 2 deletions drivers/firmware/efi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,12 @@ config EFI_PARAMS_FROM_FDT
config EFI_RUNTIME_WRAPPERS
bool

config EFI_ARMSTUB
config EFI_GENERIC_STUB
bool

config EFI_ARMSTUB_DTB_LOADER
bool "Enable the DTB loader"
depends on EFI_ARMSTUB
depends on EFI_GENERIC_STUB
default y
help
Select this config option to add support for the dtb= command
Expand All @@ -124,6 +124,17 @@ config EFI_ARMSTUB_DTB_LOADER
functionality for bootloaders that do not have such support
this option is necessary.

config EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER
bool "Enable the command line initrd loader" if !X86
depends on EFI_STUB && (EFI_GENERIC_STUB || X86)
default y
help
Select this config option to add support for the initrd= command
line parameter, allowing an initrd that resides on the same volume
as the kernel image to be loaded into memory.

This method is deprecated.

config EFI_BOOTLOADER_CONTROL
tristate "EFI Bootloader Control"
depends on EFI_VARS
Expand Down
4 changes: 2 additions & 2 deletions drivers/firmware/efi/arm-init.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ static phys_addr_t __init efi_to_phys(unsigned long addr)
static __initdata unsigned long screen_info_table = EFI_INVALID_TABLE_ADDR;

static const efi_config_table_type_t arch_tables[] __initconst = {
{LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID, NULL, &screen_info_table},
{NULL_GUID, NULL, NULL}
{LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID, &screen_info_table},
{}
};

static void __init init_screen_info(void)
Expand Down
Loading

0 comments on commit 58ff3b7

Please sign in to comment.