162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef _ASM_X86_EFI_H 362306a36Sopenharmony_ci#define _ASM_X86_EFI_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <asm/fpu/api.h> 662306a36Sopenharmony_ci#include <asm/processor-flags.h> 762306a36Sopenharmony_ci#include <asm/tlb.h> 862306a36Sopenharmony_ci#include <asm/nospec-branch.h> 962306a36Sopenharmony_ci#include <asm/mmu_context.h> 1062306a36Sopenharmony_ci#include <asm/ibt.h> 1162306a36Sopenharmony_ci#include <linux/build_bug.h> 1262306a36Sopenharmony_ci#include <linux/kernel.h> 1362306a36Sopenharmony_ci#include <linux/pgtable.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ciextern unsigned long efi_fw_vendor, efi_config_table; 1662306a36Sopenharmony_ciextern unsigned long efi_mixed_mode_stack_pa; 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci/* 1962306a36Sopenharmony_ci * We map the EFI regions needed for runtime services non-contiguously, 2062306a36Sopenharmony_ci * with preserved alignment on virtual addresses starting from -4G down 2162306a36Sopenharmony_ci * for a total max space of 64G. This way, we provide for stable runtime 2262306a36Sopenharmony_ci * services addresses across kernels so that a kexec'd kernel can still 2362306a36Sopenharmony_ci * use them. 2462306a36Sopenharmony_ci * 2562306a36Sopenharmony_ci * This is the main reason why we're doing stable VA mappings for RT 2662306a36Sopenharmony_ci * services. 2762306a36Sopenharmony_ci */ 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci#define EFI32_LOADER_SIGNATURE "EL32" 3062306a36Sopenharmony_ci#define EFI64_LOADER_SIGNATURE "EL64" 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci#define ARCH_EFI_IRQ_FLAGS_MASK X86_EFLAGS_IF 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci#define EFI_UNACCEPTED_UNIT_SIZE PMD_SIZE 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci/* 3762306a36Sopenharmony_ci * The EFI services are called through variadic functions in many cases. These 3862306a36Sopenharmony_ci * functions are implemented in assembler and support only a fixed number of 3962306a36Sopenharmony_ci * arguments. The macros below allows us to check at build time that we don't 4062306a36Sopenharmony_ci * try to call them with too many arguments. 4162306a36Sopenharmony_ci * 4262306a36Sopenharmony_ci * __efi_nargs() will return the number of arguments if it is 7 or less, and 4362306a36Sopenharmony_ci * cause a BUILD_BUG otherwise. The limitations of the C preprocessor make it 4462306a36Sopenharmony_ci * impossible to calculate the exact number of arguments beyond some 4562306a36Sopenharmony_ci * pre-defined limit. The maximum number of arguments currently supported by 4662306a36Sopenharmony_ci * any of the thunks is 7, so this is good enough for now and can be extended 4762306a36Sopenharmony_ci * in the obvious way if we ever need more. 4862306a36Sopenharmony_ci */ 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci#define __efi_nargs(...) __efi_nargs_(__VA_ARGS__) 5162306a36Sopenharmony_ci#define __efi_nargs_(...) __efi_nargs__(0, ##__VA_ARGS__, \ 5262306a36Sopenharmony_ci __efi_arg_sentinel(9), __efi_arg_sentinel(8), \ 5362306a36Sopenharmony_ci __efi_arg_sentinel(7), __efi_arg_sentinel(6), \ 5462306a36Sopenharmony_ci __efi_arg_sentinel(5), __efi_arg_sentinel(4), \ 5562306a36Sopenharmony_ci __efi_arg_sentinel(3), __efi_arg_sentinel(2), \ 5662306a36Sopenharmony_ci __efi_arg_sentinel(1), __efi_arg_sentinel(0)) 5762306a36Sopenharmony_ci#define __efi_nargs__(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, n, ...) \ 5862306a36Sopenharmony_ci __take_second_arg(n, \ 5962306a36Sopenharmony_ci ({ BUILD_BUG_ON_MSG(1, "__efi_nargs limit exceeded"); 10; })) 6062306a36Sopenharmony_ci#define __efi_arg_sentinel(n) , n 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci/* 6362306a36Sopenharmony_ci * __efi_nargs_check(f, n, ...) will cause a BUILD_BUG if the ellipsis 6462306a36Sopenharmony_ci * represents more than n arguments. 6562306a36Sopenharmony_ci */ 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci#define __efi_nargs_check(f, n, ...) \ 6862306a36Sopenharmony_ci __efi_nargs_check_(f, __efi_nargs(__VA_ARGS__), n) 6962306a36Sopenharmony_ci#define __efi_nargs_check_(f, p, n) __efi_nargs_check__(f, p, n) 7062306a36Sopenharmony_ci#define __efi_nargs_check__(f, p, n) ({ \ 7162306a36Sopenharmony_ci BUILD_BUG_ON_MSG( \ 7262306a36Sopenharmony_ci (p) > (n), \ 7362306a36Sopenharmony_ci #f " called with too many arguments (" #p ">" #n ")"); \ 7462306a36Sopenharmony_ci}) 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_cistatic inline void efi_fpu_begin(void) 7762306a36Sopenharmony_ci{ 7862306a36Sopenharmony_ci /* 7962306a36Sopenharmony_ci * The UEFI calling convention (UEFI spec 2.3.2 and 2.3.4) requires 8062306a36Sopenharmony_ci * that FCW and MXCSR (64-bit) must be initialized prior to calling 8162306a36Sopenharmony_ci * UEFI code. (Oddly the spec does not require that the FPU stack 8262306a36Sopenharmony_ci * be empty.) 8362306a36Sopenharmony_ci */ 8462306a36Sopenharmony_ci kernel_fpu_begin_mask(KFPU_387 | KFPU_MXCSR); 8562306a36Sopenharmony_ci} 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_cistatic inline void efi_fpu_end(void) 8862306a36Sopenharmony_ci{ 8962306a36Sopenharmony_ci kernel_fpu_end(); 9062306a36Sopenharmony_ci} 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci#ifdef CONFIG_X86_32 9362306a36Sopenharmony_ci#define EFI_X86_KERNEL_ALLOC_LIMIT (SZ_512M - 1) 9462306a36Sopenharmony_ci#else /* !CONFIG_X86_32 */ 9562306a36Sopenharmony_ci#define EFI_X86_KERNEL_ALLOC_LIMIT EFI_ALLOC_LIMIT 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ciextern asmlinkage u64 __efi_call(void *fp, ...); 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ciextern bool efi_disable_ibt_for_runtime; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci#define efi_call(...) ({ \ 10262306a36Sopenharmony_ci __efi_nargs_check(efi_call, 7, __VA_ARGS__); \ 10362306a36Sopenharmony_ci __efi_call(__VA_ARGS__); \ 10462306a36Sopenharmony_ci}) 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci#undef arch_efi_call_virt 10762306a36Sopenharmony_ci#define arch_efi_call_virt(p, f, args...) ({ \ 10862306a36Sopenharmony_ci u64 ret, ibt = ibt_save(efi_disable_ibt_for_runtime); \ 10962306a36Sopenharmony_ci ret = efi_call((void *)p->f, args); \ 11062306a36Sopenharmony_ci ibt_restore(ibt); \ 11162306a36Sopenharmony_ci ret; \ 11262306a36Sopenharmony_ci}) 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci#ifdef CONFIG_KASAN 11562306a36Sopenharmony_ci/* 11662306a36Sopenharmony_ci * CONFIG_KASAN may redefine memset to __memset. __memset function is present 11762306a36Sopenharmony_ci * only in kernel binary. Since the EFI stub linked into a separate binary it 11862306a36Sopenharmony_ci * doesn't have __memset(). So we should use standard memset from 11962306a36Sopenharmony_ci * arch/x86/boot/compressed/string.c. The same applies to memcpy and memmove. 12062306a36Sopenharmony_ci */ 12162306a36Sopenharmony_ci#undef memcpy 12262306a36Sopenharmony_ci#undef memset 12362306a36Sopenharmony_ci#undef memmove 12462306a36Sopenharmony_ci#endif 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci#endif /* CONFIG_X86_32 */ 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ciextern int __init efi_memblock_x86_reserve_range(void); 12962306a36Sopenharmony_ciextern void __init efi_print_memmap(void); 13062306a36Sopenharmony_ciextern void __init efi_map_region(efi_memory_desc_t *md); 13162306a36Sopenharmony_ciextern void __init efi_map_region_fixed(efi_memory_desc_t *md); 13262306a36Sopenharmony_ciextern void efi_sync_low_kernel_mappings(void); 13362306a36Sopenharmony_ciextern int __init efi_alloc_page_tables(void); 13462306a36Sopenharmony_ciextern int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages); 13562306a36Sopenharmony_ciextern void __init efi_runtime_update_mappings(void); 13662306a36Sopenharmony_ciextern void __init efi_dump_pagetable(void); 13762306a36Sopenharmony_ciextern void __init efi_apply_memmap_quirks(void); 13862306a36Sopenharmony_ciextern int __init efi_reuse_config(u64 tables, int nr_tables); 13962306a36Sopenharmony_ciextern void efi_delete_dummy_variable(void); 14062306a36Sopenharmony_ciextern void efi_crash_gracefully_on_page_fault(unsigned long phys_addr); 14162306a36Sopenharmony_ciextern void efi_free_boot_services(void); 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_civoid arch_efi_call_virt_setup(void); 14462306a36Sopenharmony_civoid arch_efi_call_virt_teardown(void); 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci/* kexec external ABI */ 14762306a36Sopenharmony_cistruct efi_setup_data { 14862306a36Sopenharmony_ci u64 fw_vendor; 14962306a36Sopenharmony_ci u64 __unused; 15062306a36Sopenharmony_ci u64 tables; 15162306a36Sopenharmony_ci u64 smbios; 15262306a36Sopenharmony_ci u64 reserved[8]; 15362306a36Sopenharmony_ci}; 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ciextern u64 efi_setup; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci#ifdef CONFIG_EFI 15862306a36Sopenharmony_ciextern u64 __efi64_thunk(u32, ...); 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci#define efi64_thunk(...) ({ \ 16162306a36Sopenharmony_ci u64 __pad[3]; /* must have space for 3 args on the stack */ \ 16262306a36Sopenharmony_ci __efi_nargs_check(efi64_thunk, 9, __VA_ARGS__); \ 16362306a36Sopenharmony_ci __efi64_thunk(__VA_ARGS__, __pad); \ 16462306a36Sopenharmony_ci}) 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_cistatic inline bool efi_is_mixed(void) 16762306a36Sopenharmony_ci{ 16862306a36Sopenharmony_ci if (!IS_ENABLED(CONFIG_EFI_MIXED)) 16962306a36Sopenharmony_ci return false; 17062306a36Sopenharmony_ci return IS_ENABLED(CONFIG_X86_64) && !efi_enabled(EFI_64BIT); 17162306a36Sopenharmony_ci} 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_cistatic inline bool efi_runtime_supported(void) 17462306a36Sopenharmony_ci{ 17562306a36Sopenharmony_ci if (IS_ENABLED(CONFIG_X86_64) == efi_enabled(EFI_64BIT)) 17662306a36Sopenharmony_ci return true; 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci return IS_ENABLED(CONFIG_EFI_MIXED); 17962306a36Sopenharmony_ci} 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ciextern void parse_efi_setup(u64 phys_addr, u32 data_len); 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ciextern void efi_thunk_runtime_setup(void); 18462306a36Sopenharmony_ciefi_status_t efi_set_virtual_address_map(unsigned long memory_map_size, 18562306a36Sopenharmony_ci unsigned long descriptor_size, 18662306a36Sopenharmony_ci u32 descriptor_version, 18762306a36Sopenharmony_ci efi_memory_desc_t *virtual_map, 18862306a36Sopenharmony_ci unsigned long systab_phys); 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci/* arch specific definitions used by the stub code */ 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci#ifdef CONFIG_EFI_MIXED 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci#define EFI_ALLOC_LIMIT (efi_is_64bit() ? ULONG_MAX : U32_MAX) 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci#define ARCH_HAS_EFISTUB_WRAPPERS 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_cistatic inline bool efi_is_64bit(void) 19962306a36Sopenharmony_ci{ 20062306a36Sopenharmony_ci extern const bool efi_is64; 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci return efi_is64; 20362306a36Sopenharmony_ci} 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_cistatic inline bool efi_is_native(void) 20662306a36Sopenharmony_ci{ 20762306a36Sopenharmony_ci return efi_is_64bit(); 20862306a36Sopenharmony_ci} 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci#define efi_table_attr(inst, attr) \ 21162306a36Sopenharmony_ci (efi_is_native() ? (inst)->attr \ 21262306a36Sopenharmony_ci : efi_mixed_table_attr((inst), attr)) 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci#define efi_mixed_table_attr(inst, attr) \ 21562306a36Sopenharmony_ci (__typeof__(inst->attr)) \ 21662306a36Sopenharmony_ci _Generic(inst->mixed_mode.attr, \ 21762306a36Sopenharmony_ci u32: (unsigned long)(inst->mixed_mode.attr), \ 21862306a36Sopenharmony_ci default: (inst->mixed_mode.attr)) 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci/* 22162306a36Sopenharmony_ci * The following macros allow translating arguments if necessary from native to 22262306a36Sopenharmony_ci * mixed mode. The use case for this is to initialize the upper 32 bits of 22362306a36Sopenharmony_ci * output parameters, and where the 32-bit method requires a 64-bit argument, 22462306a36Sopenharmony_ci * which must be split up into two arguments to be thunked properly. 22562306a36Sopenharmony_ci * 22662306a36Sopenharmony_ci * As examples, the AllocatePool boot service returns the address of the 22762306a36Sopenharmony_ci * allocation, but it will not set the high 32 bits of the address. To ensure 22862306a36Sopenharmony_ci * that the full 64-bit address is initialized, we zero-init the address before 22962306a36Sopenharmony_ci * calling the thunk. 23062306a36Sopenharmony_ci * 23162306a36Sopenharmony_ci * The FreePages boot service takes a 64-bit physical address even in 32-bit 23262306a36Sopenharmony_ci * mode. For the thunk to work correctly, a native 64-bit call of 23362306a36Sopenharmony_ci * free_pages(addr, size) 23462306a36Sopenharmony_ci * must be translated to 23562306a36Sopenharmony_ci * efi64_thunk(free_pages, addr & U32_MAX, addr >> 32, size) 23662306a36Sopenharmony_ci * so that the two 32-bit halves of addr get pushed onto the stack separately. 23762306a36Sopenharmony_ci */ 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_cistatic inline void *efi64_zero_upper(void *p) 24062306a36Sopenharmony_ci{ 24162306a36Sopenharmony_ci ((u32 *)p)[1] = 0; 24262306a36Sopenharmony_ci return p; 24362306a36Sopenharmony_ci} 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_cistatic inline u32 efi64_convert_status(efi_status_t status) 24662306a36Sopenharmony_ci{ 24762306a36Sopenharmony_ci return (u32)(status | (u64)status >> 32); 24862306a36Sopenharmony_ci} 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci#define __efi64_split(val) (val) & U32_MAX, (u64)(val) >> 32 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci#define __efi64_argmap_free_pages(addr, size) \ 25362306a36Sopenharmony_ci ((addr), 0, (size)) 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci#define __efi64_argmap_get_memory_map(mm_size, mm, key, size, ver) \ 25662306a36Sopenharmony_ci ((mm_size), (mm), efi64_zero_upper(key), efi64_zero_upper(size), (ver)) 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci#define __efi64_argmap_allocate_pool(type, size, buffer) \ 25962306a36Sopenharmony_ci ((type), (size), efi64_zero_upper(buffer)) 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci#define __efi64_argmap_create_event(type, tpl, f, c, event) \ 26262306a36Sopenharmony_ci ((type), (tpl), (f), (c), efi64_zero_upper(event)) 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci#define __efi64_argmap_set_timer(event, type, time) \ 26562306a36Sopenharmony_ci ((event), (type), lower_32_bits(time), upper_32_bits(time)) 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci#define __efi64_argmap_wait_for_event(num, event, index) \ 26862306a36Sopenharmony_ci ((num), (event), efi64_zero_upper(index)) 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_ci#define __efi64_argmap_handle_protocol(handle, protocol, interface) \ 27162306a36Sopenharmony_ci ((handle), (protocol), efi64_zero_upper(interface)) 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci#define __efi64_argmap_locate_protocol(protocol, reg, interface) \ 27462306a36Sopenharmony_ci ((protocol), (reg), efi64_zero_upper(interface)) 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci#define __efi64_argmap_locate_device_path(protocol, path, handle) \ 27762306a36Sopenharmony_ci ((protocol), (path), efi64_zero_upper(handle)) 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci#define __efi64_argmap_exit(handle, status, size, data) \ 28062306a36Sopenharmony_ci ((handle), efi64_convert_status(status), (size), (data)) 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci/* PCI I/O */ 28362306a36Sopenharmony_ci#define __efi64_argmap_get_location(protocol, seg, bus, dev, func) \ 28462306a36Sopenharmony_ci ((protocol), efi64_zero_upper(seg), efi64_zero_upper(bus), \ 28562306a36Sopenharmony_ci efi64_zero_upper(dev), efi64_zero_upper(func)) 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci/* LoadFile */ 28862306a36Sopenharmony_ci#define __efi64_argmap_load_file(protocol, path, policy, bufsize, buf) \ 28962306a36Sopenharmony_ci ((protocol), (path), (policy), efi64_zero_upper(bufsize), (buf)) 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci/* Graphics Output Protocol */ 29262306a36Sopenharmony_ci#define __efi64_argmap_query_mode(gop, mode, size, info) \ 29362306a36Sopenharmony_ci ((gop), (mode), efi64_zero_upper(size), efi64_zero_upper(info)) 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci/* TCG2 protocol */ 29662306a36Sopenharmony_ci#define __efi64_argmap_hash_log_extend_event(prot, fl, addr, size, ev) \ 29762306a36Sopenharmony_ci ((prot), (fl), 0ULL, (u64)(addr), 0ULL, (u64)(size), 0ULL, ev) 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci/* DXE services */ 30062306a36Sopenharmony_ci#define __efi64_argmap_get_memory_space_descriptor(phys, desc) \ 30162306a36Sopenharmony_ci (__efi64_split(phys), (desc)) 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci#define __efi64_argmap_set_memory_space_attributes(phys, size, flags) \ 30462306a36Sopenharmony_ci (__efi64_split(phys), __efi64_split(size), __efi64_split(flags)) 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci/* file protocol */ 30762306a36Sopenharmony_ci#define __efi64_argmap_open(prot, newh, fname, mode, attr) \ 30862306a36Sopenharmony_ci ((prot), efi64_zero_upper(newh), (fname), __efi64_split(mode), \ 30962306a36Sopenharmony_ci __efi64_split(attr)) 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci#define __efi64_argmap_set_position(pos) (__efi64_split(pos)) 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci/* file system protocol */ 31462306a36Sopenharmony_ci#define __efi64_argmap_open_volume(prot, file) \ 31562306a36Sopenharmony_ci ((prot), efi64_zero_upper(file)) 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci/* Memory Attribute Protocol */ 31862306a36Sopenharmony_ci#define __efi64_argmap_get_memory_attributes(protocol, phys, size, flags) \ 31962306a36Sopenharmony_ci ((protocol), __efi64_split(phys), __efi64_split(size), (flags)) 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci#define __efi64_argmap_set_memory_attributes(protocol, phys, size, flags) \ 32262306a36Sopenharmony_ci ((protocol), __efi64_split(phys), __efi64_split(size), __efi64_split(flags)) 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci#define __efi64_argmap_clear_memory_attributes(protocol, phys, size, flags) \ 32562306a36Sopenharmony_ci ((protocol), __efi64_split(phys), __efi64_split(size), __efi64_split(flags)) 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci/* 32862306a36Sopenharmony_ci * The macros below handle the plumbing for the argument mapping. To add a 32962306a36Sopenharmony_ci * mapping for a specific EFI method, simply define a macro 33062306a36Sopenharmony_ci * __efi64_argmap_<method name>, following the examples above. 33162306a36Sopenharmony_ci */ 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci#define __efi64_thunk_map(inst, func, ...) \ 33462306a36Sopenharmony_ci efi64_thunk(inst->mixed_mode.func, \ 33562306a36Sopenharmony_ci __efi64_argmap(__efi64_argmap_ ## func(__VA_ARGS__), \ 33662306a36Sopenharmony_ci (__VA_ARGS__))) 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci#define __efi64_argmap(mapped, args) \ 33962306a36Sopenharmony_ci __PASTE(__efi64_argmap__, __efi_nargs(__efi_eat mapped))(mapped, args) 34062306a36Sopenharmony_ci#define __efi64_argmap__0(mapped, args) __efi_eval mapped 34162306a36Sopenharmony_ci#define __efi64_argmap__1(mapped, args) __efi_eval args 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ci#define __efi_eat(...) 34462306a36Sopenharmony_ci#define __efi_eval(...) __VA_ARGS__ 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_cistatic inline efi_status_t __efi64_widen_efi_status(u64 status) 34762306a36Sopenharmony_ci{ 34862306a36Sopenharmony_ci /* use rotate to move the value of bit #31 into position #63 */ 34962306a36Sopenharmony_ci return ror64(rol32(status, 1), 1); 35062306a36Sopenharmony_ci} 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_ci/* The macro below handles dispatching via the thunk if needed */ 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci#define efi_fn_call(inst, func, ...) \ 35562306a36Sopenharmony_ci (efi_is_native() ? (inst)->func(__VA_ARGS__) \ 35662306a36Sopenharmony_ci : efi_mixed_call((inst), func, ##__VA_ARGS__)) 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci#define efi_mixed_call(inst, func, ...) \ 35962306a36Sopenharmony_ci _Generic(inst->func(__VA_ARGS__), \ 36062306a36Sopenharmony_ci efi_status_t: \ 36162306a36Sopenharmony_ci __efi64_widen_efi_status( \ 36262306a36Sopenharmony_ci __efi64_thunk_map(inst, func, ##__VA_ARGS__)), \ 36362306a36Sopenharmony_ci u64: ({ BUILD_BUG(); ULONG_MAX; }), \ 36462306a36Sopenharmony_ci default: \ 36562306a36Sopenharmony_ci (__typeof__(inst->func(__VA_ARGS__))) \ 36662306a36Sopenharmony_ci __efi64_thunk_map(inst, func, ##__VA_ARGS__)) 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ci#else /* CONFIG_EFI_MIXED */ 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_cistatic inline bool efi_is_64bit(void) 37162306a36Sopenharmony_ci{ 37262306a36Sopenharmony_ci return IS_ENABLED(CONFIG_X86_64); 37362306a36Sopenharmony_ci} 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ci#endif /* CONFIG_EFI_MIXED */ 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ciextern bool efi_reboot_required(void); 37862306a36Sopenharmony_ciextern bool efi_is_table_address(unsigned long phys_addr); 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ciextern void efi_reserve_boot_services(void); 38162306a36Sopenharmony_ci#else 38262306a36Sopenharmony_cistatic inline void parse_efi_setup(u64 phys_addr, u32 data_len) {} 38362306a36Sopenharmony_cistatic inline bool efi_reboot_required(void) 38462306a36Sopenharmony_ci{ 38562306a36Sopenharmony_ci return false; 38662306a36Sopenharmony_ci} 38762306a36Sopenharmony_cistatic inline bool efi_is_table_address(unsigned long phys_addr) 38862306a36Sopenharmony_ci{ 38962306a36Sopenharmony_ci return false; 39062306a36Sopenharmony_ci} 39162306a36Sopenharmony_cistatic inline void efi_reserve_boot_services(void) 39262306a36Sopenharmony_ci{ 39362306a36Sopenharmony_ci} 39462306a36Sopenharmony_ci#endif /* CONFIG_EFI */ 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci#ifdef CONFIG_EFI_FAKE_MEMMAP 39762306a36Sopenharmony_ciextern void __init efi_fake_memmap_early(void); 39862306a36Sopenharmony_ciextern void __init efi_fake_memmap(void); 39962306a36Sopenharmony_ci#else 40062306a36Sopenharmony_cistatic inline void efi_fake_memmap_early(void) 40162306a36Sopenharmony_ci{ 40262306a36Sopenharmony_ci} 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_cistatic inline void efi_fake_memmap(void) 40562306a36Sopenharmony_ci{ 40662306a36Sopenharmony_ci} 40762306a36Sopenharmony_ci#endif 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_ciextern int __init efi_memmap_alloc(unsigned int num_entries, 41062306a36Sopenharmony_ci struct efi_memory_map_data *data); 41162306a36Sopenharmony_ciextern void __efi_memmap_free(u64 phys, unsigned long size, 41262306a36Sopenharmony_ci unsigned long flags); 41362306a36Sopenharmony_ci#define __efi_memmap_free __efi_memmap_free 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_ciextern int __init efi_memmap_install(struct efi_memory_map_data *data); 41662306a36Sopenharmony_ciextern int __init efi_memmap_split_count(efi_memory_desc_t *md, 41762306a36Sopenharmony_ci struct range *range); 41862306a36Sopenharmony_ciextern void __init efi_memmap_insert(struct efi_memory_map *old_memmap, 41962306a36Sopenharmony_ci void *buf, struct efi_mem_range *mem); 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci#define arch_ima_efi_boot_mode \ 42262306a36Sopenharmony_ci ({ extern struct boot_params boot_params; boot_params.secure_boot; }) 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci#ifdef CONFIG_EFI_RUNTIME_MAP 42562306a36Sopenharmony_ciint efi_get_runtime_map_size(void); 42662306a36Sopenharmony_ciint efi_get_runtime_map_desc_size(void); 42762306a36Sopenharmony_ciint efi_runtime_map_copy(void *buf, size_t bufsz); 42862306a36Sopenharmony_ci#else 42962306a36Sopenharmony_cistatic inline int efi_get_runtime_map_size(void) 43062306a36Sopenharmony_ci{ 43162306a36Sopenharmony_ci return 0; 43262306a36Sopenharmony_ci} 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_cistatic inline int efi_get_runtime_map_desc_size(void) 43562306a36Sopenharmony_ci{ 43662306a36Sopenharmony_ci return 0; 43762306a36Sopenharmony_ci} 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_cistatic inline int efi_runtime_map_copy(void *buf, size_t bufsz) 44062306a36Sopenharmony_ci{ 44162306a36Sopenharmony_ci return 0; 44262306a36Sopenharmony_ci} 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_ci#endif 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_ci#endif /* _ASM_X86_EFI_H */ 447