18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef _ASM_X86_EFI_H 38c2ecf20Sopenharmony_ci#define _ASM_X86_EFI_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <asm/fpu/api.h> 68c2ecf20Sopenharmony_ci#include <asm/processor-flags.h> 78c2ecf20Sopenharmony_ci#include <asm/tlb.h> 88c2ecf20Sopenharmony_ci#include <asm/nospec-branch.h> 98c2ecf20Sopenharmony_ci#include <asm/mmu_context.h> 108c2ecf20Sopenharmony_ci#include <linux/build_bug.h> 118c2ecf20Sopenharmony_ci#include <linux/kernel.h> 128c2ecf20Sopenharmony_ci#include <linux/pgtable.h> 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ciextern unsigned long efi_fw_vendor, efi_config_table; 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci/* 178c2ecf20Sopenharmony_ci * We map the EFI regions needed for runtime services non-contiguously, 188c2ecf20Sopenharmony_ci * with preserved alignment on virtual addresses starting from -4G down 198c2ecf20Sopenharmony_ci * for a total max space of 64G. This way, we provide for stable runtime 208c2ecf20Sopenharmony_ci * services addresses across kernels so that a kexec'd kernel can still 218c2ecf20Sopenharmony_ci * use them. 228c2ecf20Sopenharmony_ci * 238c2ecf20Sopenharmony_ci * This is the main reason why we're doing stable VA mappings for RT 248c2ecf20Sopenharmony_ci * services. 258c2ecf20Sopenharmony_ci */ 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#define EFI32_LOADER_SIGNATURE "EL32" 288c2ecf20Sopenharmony_ci#define EFI64_LOADER_SIGNATURE "EL64" 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci#define ARCH_EFI_IRQ_FLAGS_MASK X86_EFLAGS_IF 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci/* 338c2ecf20Sopenharmony_ci * The EFI services are called through variadic functions in many cases. These 348c2ecf20Sopenharmony_ci * functions are implemented in assembler and support only a fixed number of 358c2ecf20Sopenharmony_ci * arguments. The macros below allows us to check at build time that we don't 368c2ecf20Sopenharmony_ci * try to call them with too many arguments. 378c2ecf20Sopenharmony_ci * 388c2ecf20Sopenharmony_ci * __efi_nargs() will return the number of arguments if it is 7 or less, and 398c2ecf20Sopenharmony_ci * cause a BUILD_BUG otherwise. The limitations of the C preprocessor make it 408c2ecf20Sopenharmony_ci * impossible to calculate the exact number of arguments beyond some 418c2ecf20Sopenharmony_ci * pre-defined limit. The maximum number of arguments currently supported by 428c2ecf20Sopenharmony_ci * any of the thunks is 7, so this is good enough for now and can be extended 438c2ecf20Sopenharmony_ci * in the obvious way if we ever need more. 448c2ecf20Sopenharmony_ci */ 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci#define __efi_nargs(...) __efi_nargs_(__VA_ARGS__) 478c2ecf20Sopenharmony_ci#define __efi_nargs_(...) __efi_nargs__(0, ##__VA_ARGS__, \ 488c2ecf20Sopenharmony_ci __efi_arg_sentinel(7), __efi_arg_sentinel(6), \ 498c2ecf20Sopenharmony_ci __efi_arg_sentinel(5), __efi_arg_sentinel(4), \ 508c2ecf20Sopenharmony_ci __efi_arg_sentinel(3), __efi_arg_sentinel(2), \ 518c2ecf20Sopenharmony_ci __efi_arg_sentinel(1), __efi_arg_sentinel(0)) 528c2ecf20Sopenharmony_ci#define __efi_nargs__(_0, _1, _2, _3, _4, _5, _6, _7, n, ...) \ 538c2ecf20Sopenharmony_ci __take_second_arg(n, \ 548c2ecf20Sopenharmony_ci ({ BUILD_BUG_ON_MSG(1, "__efi_nargs limit exceeded"); 8; })) 558c2ecf20Sopenharmony_ci#define __efi_arg_sentinel(n) , n 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci/* 588c2ecf20Sopenharmony_ci * __efi_nargs_check(f, n, ...) will cause a BUILD_BUG if the ellipsis 598c2ecf20Sopenharmony_ci * represents more than n arguments. 608c2ecf20Sopenharmony_ci */ 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci#define __efi_nargs_check(f, n, ...) \ 638c2ecf20Sopenharmony_ci __efi_nargs_check_(f, __efi_nargs(__VA_ARGS__), n) 648c2ecf20Sopenharmony_ci#define __efi_nargs_check_(f, p, n) __efi_nargs_check__(f, p, n) 658c2ecf20Sopenharmony_ci#define __efi_nargs_check__(f, p, n) ({ \ 668c2ecf20Sopenharmony_ci BUILD_BUG_ON_MSG( \ 678c2ecf20Sopenharmony_ci (p) > (n), \ 688c2ecf20Sopenharmony_ci #f " called with too many arguments (" #p ">" #n ")"); \ 698c2ecf20Sopenharmony_ci}) 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_32 728c2ecf20Sopenharmony_ci#define arch_efi_call_virt_setup() \ 738c2ecf20Sopenharmony_ci({ \ 748c2ecf20Sopenharmony_ci kernel_fpu_begin(); \ 758c2ecf20Sopenharmony_ci firmware_restrict_branch_speculation_start(); \ 768c2ecf20Sopenharmony_ci}) 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci#define arch_efi_call_virt_teardown() \ 798c2ecf20Sopenharmony_ci({ \ 808c2ecf20Sopenharmony_ci firmware_restrict_branch_speculation_end(); \ 818c2ecf20Sopenharmony_ci kernel_fpu_end(); \ 828c2ecf20Sopenharmony_ci}) 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci#define arch_efi_call_virt(p, f, args...) p->f(args) 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci#else /* !CONFIG_X86_32 */ 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci#define EFI_LOADER_SIGNATURE "EL64" 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ciextern asmlinkage u64 __efi_call(void *fp, ...); 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci#define efi_call(...) ({ \ 938c2ecf20Sopenharmony_ci __efi_nargs_check(efi_call, 7, __VA_ARGS__); \ 948c2ecf20Sopenharmony_ci __efi_call(__VA_ARGS__); \ 958c2ecf20Sopenharmony_ci}) 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci/* 988c2ecf20Sopenharmony_ci * struct efi_scratch - Scratch space used while switching to/from efi_mm 998c2ecf20Sopenharmony_ci * @phys_stack: stack used during EFI Mixed Mode 1008c2ecf20Sopenharmony_ci * @prev_mm: store/restore stolen mm_struct while switching to/from efi_mm 1018c2ecf20Sopenharmony_ci */ 1028c2ecf20Sopenharmony_cistruct efi_scratch { 1038c2ecf20Sopenharmony_ci u64 phys_stack; 1048c2ecf20Sopenharmony_ci struct mm_struct *prev_mm; 1058c2ecf20Sopenharmony_ci} __packed; 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci#define arch_efi_call_virt_setup() \ 1088c2ecf20Sopenharmony_ci({ \ 1098c2ecf20Sopenharmony_ci efi_sync_low_kernel_mappings(); \ 1108c2ecf20Sopenharmony_ci kernel_fpu_begin(); \ 1118c2ecf20Sopenharmony_ci firmware_restrict_branch_speculation_start(); \ 1128c2ecf20Sopenharmony_ci efi_switch_mm(&efi_mm); \ 1138c2ecf20Sopenharmony_ci}) 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci#define arch_efi_call_virt(p, f, args...) \ 1168c2ecf20Sopenharmony_ci efi_call((void *)p->f, args) \ 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci#define arch_efi_call_virt_teardown() \ 1198c2ecf20Sopenharmony_ci({ \ 1208c2ecf20Sopenharmony_ci efi_switch_mm(efi_scratch.prev_mm); \ 1218c2ecf20Sopenharmony_ci firmware_restrict_branch_speculation_end(); \ 1228c2ecf20Sopenharmony_ci kernel_fpu_end(); \ 1238c2ecf20Sopenharmony_ci}) 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci#ifdef CONFIG_KASAN 1268c2ecf20Sopenharmony_ci/* 1278c2ecf20Sopenharmony_ci * CONFIG_KASAN may redefine memset to __memset. __memset function is present 1288c2ecf20Sopenharmony_ci * only in kernel binary. Since the EFI stub linked into a separate binary it 1298c2ecf20Sopenharmony_ci * doesn't have __memset(). So we should use standard memset from 1308c2ecf20Sopenharmony_ci * arch/x86/boot/compressed/string.c. The same applies to memcpy and memmove. 1318c2ecf20Sopenharmony_ci */ 1328c2ecf20Sopenharmony_ci#undef memcpy 1338c2ecf20Sopenharmony_ci#undef memset 1348c2ecf20Sopenharmony_ci#undef memmove 1358c2ecf20Sopenharmony_ci#endif 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci#endif /* CONFIG_X86_32 */ 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ciextern struct efi_scratch efi_scratch; 1408c2ecf20Sopenharmony_ciextern int __init efi_memblock_x86_reserve_range(void); 1418c2ecf20Sopenharmony_ciextern void __init efi_print_memmap(void); 1428c2ecf20Sopenharmony_ciextern void __init efi_map_region(efi_memory_desc_t *md); 1438c2ecf20Sopenharmony_ciextern void __init efi_map_region_fixed(efi_memory_desc_t *md); 1448c2ecf20Sopenharmony_ciextern void efi_sync_low_kernel_mappings(void); 1458c2ecf20Sopenharmony_ciextern int __init efi_alloc_page_tables(void); 1468c2ecf20Sopenharmony_ciextern int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages); 1478c2ecf20Sopenharmony_ciextern void __init efi_runtime_update_mappings(void); 1488c2ecf20Sopenharmony_ciextern void __init efi_dump_pagetable(void); 1498c2ecf20Sopenharmony_ciextern void __init efi_apply_memmap_quirks(void); 1508c2ecf20Sopenharmony_ciextern int __init efi_reuse_config(u64 tables, int nr_tables); 1518c2ecf20Sopenharmony_ciextern void efi_delete_dummy_variable(void); 1528c2ecf20Sopenharmony_ciextern void efi_switch_mm(struct mm_struct *mm); 1538c2ecf20Sopenharmony_ciextern void efi_recover_from_page_fault(unsigned long phys_addr); 1548c2ecf20Sopenharmony_ciextern void efi_free_boot_services(void); 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci/* kexec external ABI */ 1578c2ecf20Sopenharmony_cistruct efi_setup_data { 1588c2ecf20Sopenharmony_ci u64 fw_vendor; 1598c2ecf20Sopenharmony_ci u64 __unused; 1608c2ecf20Sopenharmony_ci u64 tables; 1618c2ecf20Sopenharmony_ci u64 smbios; 1628c2ecf20Sopenharmony_ci u64 reserved[8]; 1638c2ecf20Sopenharmony_ci}; 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ciextern u64 efi_setup; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci#ifdef CONFIG_EFI 1688c2ecf20Sopenharmony_ciextern efi_status_t __efi64_thunk(u32, ...); 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci#define efi64_thunk(...) ({ \ 1718c2ecf20Sopenharmony_ci __efi_nargs_check(efi64_thunk, 6, __VA_ARGS__); \ 1728c2ecf20Sopenharmony_ci __efi64_thunk(__VA_ARGS__); \ 1738c2ecf20Sopenharmony_ci}) 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_cistatic inline bool efi_is_mixed(void) 1768c2ecf20Sopenharmony_ci{ 1778c2ecf20Sopenharmony_ci if (!IS_ENABLED(CONFIG_EFI_MIXED)) 1788c2ecf20Sopenharmony_ci return false; 1798c2ecf20Sopenharmony_ci return IS_ENABLED(CONFIG_X86_64) && !efi_enabled(EFI_64BIT); 1808c2ecf20Sopenharmony_ci} 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_cistatic inline bool efi_runtime_supported(void) 1838c2ecf20Sopenharmony_ci{ 1848c2ecf20Sopenharmony_ci if (IS_ENABLED(CONFIG_X86_64) == efi_enabled(EFI_64BIT)) 1858c2ecf20Sopenharmony_ci return true; 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci return IS_ENABLED(CONFIG_EFI_MIXED); 1888c2ecf20Sopenharmony_ci} 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ciextern void parse_efi_setup(u64 phys_addr, u32 data_len); 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ciextern void efifb_setup_from_dmi(struct screen_info *si, const char *opt); 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ciextern void efi_thunk_runtime_setup(void); 1958c2ecf20Sopenharmony_ciefi_status_t efi_set_virtual_address_map(unsigned long memory_map_size, 1968c2ecf20Sopenharmony_ci unsigned long descriptor_size, 1978c2ecf20Sopenharmony_ci u32 descriptor_version, 1988c2ecf20Sopenharmony_ci efi_memory_desc_t *virtual_map, 1998c2ecf20Sopenharmony_ci unsigned long systab_phys); 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci/* arch specific definitions used by the stub code */ 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci#ifdef CONFIG_EFI_MIXED 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci#define ARCH_HAS_EFISTUB_WRAPPERS 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_cistatic inline bool efi_is_64bit(void) 2088c2ecf20Sopenharmony_ci{ 2098c2ecf20Sopenharmony_ci extern const bool efi_is64; 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci return efi_is64; 2128c2ecf20Sopenharmony_ci} 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_cistatic inline bool efi_is_native(void) 2158c2ecf20Sopenharmony_ci{ 2168c2ecf20Sopenharmony_ci if (!IS_ENABLED(CONFIG_X86_64)) 2178c2ecf20Sopenharmony_ci return true; 2188c2ecf20Sopenharmony_ci return efi_is_64bit(); 2198c2ecf20Sopenharmony_ci} 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci#define efi_mixed_mode_cast(attr) \ 2228c2ecf20Sopenharmony_ci __builtin_choose_expr( \ 2238c2ecf20Sopenharmony_ci __builtin_types_compatible_p(u32, __typeof__(attr)), \ 2248c2ecf20Sopenharmony_ci (unsigned long)(attr), (attr)) 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci#define efi_table_attr(inst, attr) \ 2278c2ecf20Sopenharmony_ci (efi_is_native() \ 2288c2ecf20Sopenharmony_ci ? inst->attr \ 2298c2ecf20Sopenharmony_ci : (__typeof__(inst->attr)) \ 2308c2ecf20Sopenharmony_ci efi_mixed_mode_cast(inst->mixed_mode.attr)) 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci/* 2338c2ecf20Sopenharmony_ci * The following macros allow translating arguments if necessary from native to 2348c2ecf20Sopenharmony_ci * mixed mode. The use case for this is to initialize the upper 32 bits of 2358c2ecf20Sopenharmony_ci * output parameters, and where the 32-bit method requires a 64-bit argument, 2368c2ecf20Sopenharmony_ci * which must be split up into two arguments to be thunked properly. 2378c2ecf20Sopenharmony_ci * 2388c2ecf20Sopenharmony_ci * As examples, the AllocatePool boot service returns the address of the 2398c2ecf20Sopenharmony_ci * allocation, but it will not set the high 32 bits of the address. To ensure 2408c2ecf20Sopenharmony_ci * that the full 64-bit address is initialized, we zero-init the address before 2418c2ecf20Sopenharmony_ci * calling the thunk. 2428c2ecf20Sopenharmony_ci * 2438c2ecf20Sopenharmony_ci * The FreePages boot service takes a 64-bit physical address even in 32-bit 2448c2ecf20Sopenharmony_ci * mode. For the thunk to work correctly, a native 64-bit call of 2458c2ecf20Sopenharmony_ci * free_pages(addr, size) 2468c2ecf20Sopenharmony_ci * must be translated to 2478c2ecf20Sopenharmony_ci * efi64_thunk(free_pages, addr & U32_MAX, addr >> 32, size) 2488c2ecf20Sopenharmony_ci * so that the two 32-bit halves of addr get pushed onto the stack separately. 2498c2ecf20Sopenharmony_ci */ 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_cistatic inline void *efi64_zero_upper(void *p) 2528c2ecf20Sopenharmony_ci{ 2538c2ecf20Sopenharmony_ci ((u32 *)p)[1] = 0; 2548c2ecf20Sopenharmony_ci return p; 2558c2ecf20Sopenharmony_ci} 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_cistatic inline u32 efi64_convert_status(efi_status_t status) 2588c2ecf20Sopenharmony_ci{ 2598c2ecf20Sopenharmony_ci return (u32)(status | (u64)status >> 32); 2608c2ecf20Sopenharmony_ci} 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci#define __efi64_argmap_free_pages(addr, size) \ 2638c2ecf20Sopenharmony_ci ((addr), 0, (size)) 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci#define __efi64_argmap_get_memory_map(mm_size, mm, key, size, ver) \ 2668c2ecf20Sopenharmony_ci ((mm_size), (mm), efi64_zero_upper(key), efi64_zero_upper(size), (ver)) 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci#define __efi64_argmap_allocate_pool(type, size, buffer) \ 2698c2ecf20Sopenharmony_ci ((type), (size), efi64_zero_upper(buffer)) 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci#define __efi64_argmap_create_event(type, tpl, f, c, event) \ 2728c2ecf20Sopenharmony_ci ((type), (tpl), (f), (c), efi64_zero_upper(event)) 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci#define __efi64_argmap_set_timer(event, type, time) \ 2758c2ecf20Sopenharmony_ci ((event), (type), lower_32_bits(time), upper_32_bits(time)) 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ci#define __efi64_argmap_wait_for_event(num, event, index) \ 2788c2ecf20Sopenharmony_ci ((num), (event), efi64_zero_upper(index)) 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci#define __efi64_argmap_handle_protocol(handle, protocol, interface) \ 2818c2ecf20Sopenharmony_ci ((handle), (protocol), efi64_zero_upper(interface)) 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci#define __efi64_argmap_locate_protocol(protocol, reg, interface) \ 2848c2ecf20Sopenharmony_ci ((protocol), (reg), efi64_zero_upper(interface)) 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci#define __efi64_argmap_locate_device_path(protocol, path, handle) \ 2878c2ecf20Sopenharmony_ci ((protocol), (path), efi64_zero_upper(handle)) 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_ci#define __efi64_argmap_exit(handle, status, size, data) \ 2908c2ecf20Sopenharmony_ci ((handle), efi64_convert_status(status), (size), (data)) 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_ci/* PCI I/O */ 2938c2ecf20Sopenharmony_ci#define __efi64_argmap_get_location(protocol, seg, bus, dev, func) \ 2948c2ecf20Sopenharmony_ci ((protocol), efi64_zero_upper(seg), efi64_zero_upper(bus), \ 2958c2ecf20Sopenharmony_ci efi64_zero_upper(dev), efi64_zero_upper(func)) 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci/* LoadFile */ 2988c2ecf20Sopenharmony_ci#define __efi64_argmap_load_file(protocol, path, policy, bufsize, buf) \ 2998c2ecf20Sopenharmony_ci ((protocol), (path), (policy), efi64_zero_upper(bufsize), (buf)) 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci/* Graphics Output Protocol */ 3028c2ecf20Sopenharmony_ci#define __efi64_argmap_query_mode(gop, mode, size, info) \ 3038c2ecf20Sopenharmony_ci ((gop), (mode), efi64_zero_upper(size), efi64_zero_upper(info)) 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_ci/* 3068c2ecf20Sopenharmony_ci * The macros below handle the plumbing for the argument mapping. To add a 3078c2ecf20Sopenharmony_ci * mapping for a specific EFI method, simply define a macro 3088c2ecf20Sopenharmony_ci * __efi64_argmap_<method name>, following the examples above. 3098c2ecf20Sopenharmony_ci */ 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci#define __efi64_thunk_map(inst, func, ...) \ 3128c2ecf20Sopenharmony_ci efi64_thunk(inst->mixed_mode.func, \ 3138c2ecf20Sopenharmony_ci __efi64_argmap(__efi64_argmap_ ## func(__VA_ARGS__), \ 3148c2ecf20Sopenharmony_ci (__VA_ARGS__))) 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_ci#define __efi64_argmap(mapped, args) \ 3178c2ecf20Sopenharmony_ci __PASTE(__efi64_argmap__, __efi_nargs(__efi_eat mapped))(mapped, args) 3188c2ecf20Sopenharmony_ci#define __efi64_argmap__0(mapped, args) __efi_eval mapped 3198c2ecf20Sopenharmony_ci#define __efi64_argmap__1(mapped, args) __efi_eval args 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci#define __efi_eat(...) 3228c2ecf20Sopenharmony_ci#define __efi_eval(...) __VA_ARGS__ 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci/* The three macros below handle dispatching via the thunk if needed */ 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ci#define efi_call_proto(inst, func, ...) \ 3278c2ecf20Sopenharmony_ci (efi_is_native() \ 3288c2ecf20Sopenharmony_ci ? inst->func(inst, ##__VA_ARGS__) \ 3298c2ecf20Sopenharmony_ci : __efi64_thunk_map(inst, func, inst, ##__VA_ARGS__)) 3308c2ecf20Sopenharmony_ci 3318c2ecf20Sopenharmony_ci#define efi_bs_call(func, ...) \ 3328c2ecf20Sopenharmony_ci (efi_is_native() \ 3338c2ecf20Sopenharmony_ci ? efi_system_table->boottime->func(__VA_ARGS__) \ 3348c2ecf20Sopenharmony_ci : __efi64_thunk_map(efi_table_attr(efi_system_table, \ 3358c2ecf20Sopenharmony_ci boottime), \ 3368c2ecf20Sopenharmony_ci func, __VA_ARGS__)) 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci#define efi_rt_call(func, ...) \ 3398c2ecf20Sopenharmony_ci (efi_is_native() \ 3408c2ecf20Sopenharmony_ci ? efi_system_table->runtime->func(__VA_ARGS__) \ 3418c2ecf20Sopenharmony_ci : __efi64_thunk_map(efi_table_attr(efi_system_table, \ 3428c2ecf20Sopenharmony_ci runtime), \ 3438c2ecf20Sopenharmony_ci func, __VA_ARGS__)) 3448c2ecf20Sopenharmony_ci 3458c2ecf20Sopenharmony_ci#else /* CONFIG_EFI_MIXED */ 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_cistatic inline bool efi_is_64bit(void) 3488c2ecf20Sopenharmony_ci{ 3498c2ecf20Sopenharmony_ci return IS_ENABLED(CONFIG_X86_64); 3508c2ecf20Sopenharmony_ci} 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_ci#endif /* CONFIG_EFI_MIXED */ 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ciextern bool efi_reboot_required(void); 3558c2ecf20Sopenharmony_ciextern bool efi_is_table_address(unsigned long phys_addr); 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ciextern void efi_find_mirror(void); 3588c2ecf20Sopenharmony_ciextern void efi_reserve_boot_services(void); 3598c2ecf20Sopenharmony_ci#else 3608c2ecf20Sopenharmony_cistatic inline void parse_efi_setup(u64 phys_addr, u32 data_len) {} 3618c2ecf20Sopenharmony_cistatic inline bool efi_reboot_required(void) 3628c2ecf20Sopenharmony_ci{ 3638c2ecf20Sopenharmony_ci return false; 3648c2ecf20Sopenharmony_ci} 3658c2ecf20Sopenharmony_cistatic inline bool efi_is_table_address(unsigned long phys_addr) 3668c2ecf20Sopenharmony_ci{ 3678c2ecf20Sopenharmony_ci return false; 3688c2ecf20Sopenharmony_ci} 3698c2ecf20Sopenharmony_cistatic inline void efi_find_mirror(void) 3708c2ecf20Sopenharmony_ci{ 3718c2ecf20Sopenharmony_ci} 3728c2ecf20Sopenharmony_cistatic inline void efi_reserve_boot_services(void) 3738c2ecf20Sopenharmony_ci{ 3748c2ecf20Sopenharmony_ci} 3758c2ecf20Sopenharmony_ci#endif /* CONFIG_EFI */ 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci#ifdef CONFIG_EFI_FAKE_MEMMAP 3788c2ecf20Sopenharmony_ciextern void __init efi_fake_memmap_early(void); 3798c2ecf20Sopenharmony_ci#else 3808c2ecf20Sopenharmony_cistatic inline void efi_fake_memmap_early(void) 3818c2ecf20Sopenharmony_ci{ 3828c2ecf20Sopenharmony_ci} 3838c2ecf20Sopenharmony_ci#endif 3848c2ecf20Sopenharmony_ci 3858c2ecf20Sopenharmony_ci#endif /* _ASM_X86_EFI_H */ 386