1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 21965aae3SH. Peter Anvin #ifndef _ASM_X86_EFI_H 31965aae3SH. Peter Anvin #define _ASM_X86_EFI_H 4bb898558SAl Viro 5df6b35f4SIngo Molnar #include <asm/fpu/api.h> 69788375dSMark Rutland #include <asm/processor-flags.h> 7c9f2a9a6SMatt Fleming #include <asm/tlb.h> 8dd84441aSDavid Woodhouse #include <asm/nospec-branch.h> 97e904a91SSai Praneeth #include <asm/mmu_context.h> 10fe379fa4SPeter Zijlstra #include <asm/ibt.h> 1114b864f4SArvind Sankar #include <linux/build_bug.h> 129b47c527SArvind Sankar #include <linux/kernel.h> 1365fddcfcSMike Rapoport #include <linux/pgtable.h> 14744937b0SIngo Molnar 159cd437acSArd Biesheuvel extern unsigned long efi_fw_vendor, efi_config_table; 163e1e00c0SArd Biesheuvel extern unsigned long efi_mixed_mode_stack_pa; 179cd437acSArd Biesheuvel 18d2f7cbe7SBorislav Petkov /* 19d2f7cbe7SBorislav Petkov * We map the EFI regions needed for runtime services non-contiguously, 20d2f7cbe7SBorislav Petkov * with preserved alignment on virtual addresses starting from -4G down 21d2f7cbe7SBorislav Petkov * for a total max space of 64G. This way, we provide for stable runtime 22d2f7cbe7SBorislav Petkov * services addresses across kernels so that a kexec'd kernel can still 23d2f7cbe7SBorislav Petkov * use them. 24d2f7cbe7SBorislav Petkov * 25d2f7cbe7SBorislav Petkov * This is the main reason why we're doing stable VA mappings for RT 26d2f7cbe7SBorislav Petkov * services. 27d2f7cbe7SBorislav Petkov */ 28d2f7cbe7SBorislav Petkov 29b8ff87a6SMatt Fleming #define EFI32_LOADER_SIGNATURE "EL32" 30b8ff87a6SMatt Fleming #define EFI64_LOADER_SIGNATURE "EL64" 31b8ff87a6SMatt Fleming 329788375dSMark Rutland #define ARCH_EFI_IRQ_FLAGS_MASK X86_EFLAGS_IF 33bb898558SAl Viro 34*745e3ed8SKirill A. Shutemov #define EFI_UNACCEPTED_UNIT_SIZE PMD_SIZE 35*745e3ed8SKirill A. Shutemov 3614b864f4SArvind Sankar /* 3714b864f4SArvind Sankar * The EFI services are called through variadic functions in many cases. These 3814b864f4SArvind Sankar * functions are implemented in assembler and support only a fixed number of 3914b864f4SArvind Sankar * arguments. The macros below allows us to check at build time that we don't 4014b864f4SArvind Sankar * try to call them with too many arguments. 4114b864f4SArvind Sankar * 4214b864f4SArvind Sankar * __efi_nargs() will return the number of arguments if it is 7 or less, and 4314b864f4SArvind Sankar * cause a BUILD_BUG otherwise. The limitations of the C preprocessor make it 4414b864f4SArvind Sankar * impossible to calculate the exact number of arguments beyond some 4514b864f4SArvind Sankar * pre-defined limit. The maximum number of arguments currently supported by 4614b864f4SArvind Sankar * any of the thunks is 7, so this is good enough for now and can be extended 4714b864f4SArvind Sankar * in the obvious way if we ever need more. 4814b864f4SArvind Sankar */ 4914b864f4SArvind Sankar 5014b864f4SArvind Sankar #define __efi_nargs(...) __efi_nargs_(__VA_ARGS__) 5114b864f4SArvind Sankar #define __efi_nargs_(...) __efi_nargs__(0, ##__VA_ARGS__, \ 5244f155b4SArd Biesheuvel __efi_arg_sentinel(9), __efi_arg_sentinel(8), \ 5314b864f4SArvind Sankar __efi_arg_sentinel(7), __efi_arg_sentinel(6), \ 5414b864f4SArvind Sankar __efi_arg_sentinel(5), __efi_arg_sentinel(4), \ 5514b864f4SArvind Sankar __efi_arg_sentinel(3), __efi_arg_sentinel(2), \ 5614b864f4SArvind Sankar __efi_arg_sentinel(1), __efi_arg_sentinel(0)) 5744f155b4SArd Biesheuvel #define __efi_nargs__(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, n, ...) \ 5814b864f4SArvind Sankar __take_second_arg(n, \ 5944f155b4SArd Biesheuvel ({ BUILD_BUG_ON_MSG(1, "__efi_nargs limit exceeded"); 10; })) 6014b864f4SArvind Sankar #define __efi_arg_sentinel(n) , n 6114b864f4SArvind Sankar 6214b864f4SArvind Sankar /* 6314b864f4SArvind Sankar * __efi_nargs_check(f, n, ...) will cause a BUILD_BUG if the ellipsis 6414b864f4SArvind Sankar * represents more than n arguments. 6514b864f4SArvind Sankar */ 6614b864f4SArvind Sankar 6714b864f4SArvind Sankar #define __efi_nargs_check(f, n, ...) \ 6814b864f4SArvind Sankar __efi_nargs_check_(f, __efi_nargs(__VA_ARGS__), n) 6914b864f4SArvind Sankar #define __efi_nargs_check_(f, p, n) __efi_nargs_check__(f, p, n) 7014b864f4SArvind Sankar #define __efi_nargs_check__(f, p, n) ({ \ 7114b864f4SArvind Sankar BUILD_BUG_ON_MSG( \ 7214b864f4SArvind Sankar (p) > (n), \ 7314b864f4SArvind Sankar #f " called with too many arguments (" #p ">" #n ")"); \ 7414b864f4SArvind Sankar }) 7514b864f4SArvind Sankar 76b0dc553cSAndy Lutomirski static inline void efi_fpu_begin(void) 77b0dc553cSAndy Lutomirski { 78b0dc553cSAndy Lutomirski /* 79b0dc553cSAndy Lutomirski * The UEFI calling convention (UEFI spec 2.3.2 and 2.3.4) requires 80b0dc553cSAndy Lutomirski * that FCW and MXCSR (64-bit) must be initialized prior to calling 81b0dc553cSAndy Lutomirski * UEFI code. (Oddly the spec does not require that the FPU stack 82b0dc553cSAndy Lutomirski * be empty.) 83b0dc553cSAndy Lutomirski */ 84b0dc553cSAndy Lutomirski kernel_fpu_begin_mask(KFPU_387 | KFPU_MXCSR); 85b0dc553cSAndy Lutomirski } 86b0dc553cSAndy Lutomirski 87b0dc553cSAndy Lutomirski static inline void efi_fpu_end(void) 88b0dc553cSAndy Lutomirski { 89b0dc553cSAndy Lutomirski kernel_fpu_end(); 90b0dc553cSAndy Lutomirski } 91b0dc553cSAndy Lutomirski 929788375dSMark Rutland #ifdef CONFIG_X86_32 93dd84441aSDavid Woodhouse #define arch_efi_call_virt_setup() \ 94dd84441aSDavid Woodhouse ({ \ 95b0dc553cSAndy Lutomirski efi_fpu_begin(); \ 96dd84441aSDavid Woodhouse firmware_restrict_branch_speculation_start(); \ 97dd84441aSDavid Woodhouse }) 98dd84441aSDavid Woodhouse 99dd84441aSDavid Woodhouse #define arch_efi_call_virt_teardown() \ 100dd84441aSDavid Woodhouse ({ \ 101dd84441aSDavid Woodhouse firmware_restrict_branch_speculation_end(); \ 102b0dc553cSAndy Lutomirski efi_fpu_end(); \ 103dd84441aSDavid Woodhouse }) 104dd84441aSDavid Woodhouse 105bb898558SAl Viro #else /* !CONFIG_X86_32 */ 106bb898558SAl Viro 10762fa6e69SMatt Fleming #define EFI_LOADER_SIGNATURE "EL64" 108bb898558SAl Viro 10914b864f4SArvind Sankar extern asmlinkage u64 __efi_call(void *fp, ...); 11014b864f4SArvind Sankar 11193be2859SArd Biesheuvel extern bool efi_disable_ibt_for_runtime; 11293be2859SArd Biesheuvel 11314b864f4SArvind Sankar #define efi_call(...) ({ \ 11414b864f4SArvind Sankar __efi_nargs_check(efi_call, 7, __VA_ARGS__); \ 11514b864f4SArvind Sankar __efi_call(__VA_ARGS__); \ 11614b864f4SArvind Sankar }) 117bb898558SAl Viro 118bc25f9dbSMark Rutland #define arch_efi_call_virt_setup() \ 119d2f7cbe7SBorislav Petkov ({ \ 120d2f7cbe7SBorislav Petkov efi_sync_low_kernel_mappings(); \ 121b0dc553cSAndy Lutomirski efi_fpu_begin(); \ 122dd84441aSDavid Woodhouse firmware_restrict_branch_speculation_start(); \ 123514b1a84SArd Biesheuvel efi_enter_mm(); \ 124bc25f9dbSMark Rutland }) 125bc25f9dbSMark Rutland 1268add9a3aSSudeep Holla #undef arch_efi_call_virt 127fe379fa4SPeter Zijlstra #define arch_efi_call_virt(p, f, args...) ({ \ 12893be2859SArd Biesheuvel u64 ret, ibt = ibt_save(efi_disable_ibt_for_runtime); \ 129fe379fa4SPeter Zijlstra ret = efi_call((void *)p->f, args); \ 130fe379fa4SPeter Zijlstra ibt_restore(ibt); \ 131fe379fa4SPeter Zijlstra ret; \ 132fe379fa4SPeter Zijlstra }) 133bc25f9dbSMark Rutland 134bc25f9dbSMark Rutland #define arch_efi_call_virt_teardown() \ 135bc25f9dbSMark Rutland ({ \ 136514b1a84SArd Biesheuvel efi_leave_mm(); \ 137dd84441aSDavid Woodhouse firmware_restrict_branch_speculation_end(); \ 138b0dc553cSAndy Lutomirski efi_fpu_end(); \ 139d2f7cbe7SBorislav Petkov }) 140d2f7cbe7SBorislav Petkov 141a523841eSAndrey Ryabinin #ifdef CONFIG_KASAN 142769a8089SAndrey Ryabinin /* 143769a8089SAndrey Ryabinin * CONFIG_KASAN may redefine memset to __memset. __memset function is present 144769a8089SAndrey Ryabinin * only in kernel binary. Since the EFI stub linked into a separate binary it 145769a8089SAndrey Ryabinin * doesn't have __memset(). So we should use standard memset from 146769a8089SAndrey Ryabinin * arch/x86/boot/compressed/string.c. The same applies to memcpy and memmove. 147769a8089SAndrey Ryabinin */ 148769a8089SAndrey Ryabinin #undef memcpy 149769a8089SAndrey Ryabinin #undef memset 150769a8089SAndrey Ryabinin #undef memmove 151a523841eSAndrey Ryabinin #endif 152769a8089SAndrey Ryabinin 153bb898558SAl Viro #endif /* CONFIG_X86_32 */ 154bb898558SAl Viro 1554e78eb05SMathias Krause extern int __init efi_memblock_x86_reserve_range(void); 1560bbea1ceSTaku Izumi extern void __init efi_print_memmap(void); 157d2f7cbe7SBorislav Petkov extern void __init efi_map_region(efi_memory_desc_t *md); 1583b266496SDave Young extern void __init efi_map_region_fixed(efi_memory_desc_t *md); 159d2f7cbe7SBorislav Petkov extern void efi_sync_low_kernel_mappings(void); 16067a9108eSMatt Fleming extern int __init efi_alloc_page_tables(void); 1614e78eb05SMathias Krause extern int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages); 1626d0cc887SSai Praneeth extern void __init efi_runtime_update_mappings(void); 16311cc8512SBorislav Petkov extern void __init efi_dump_pagetable(void); 164a5d90c92SBorislav Petkov extern void __init efi_apply_memmap_quirks(void); 165eeb9db09SSaurabh Tangri extern int __init efi_reuse_config(u64 tables, int nr_tables); 166eeb9db09SSaurabh Tangri extern void efi_delete_dummy_variable(void); 167c46f5223SAndy Lutomirski extern void efi_crash_gracefully_on_page_fault(unsigned long phys_addr); 16847c33a09SSai Praneeth Prakhya extern void efi_free_boot_services(void); 169bb898558SAl Viro 170514b1a84SArd Biesheuvel void efi_enter_mm(void); 171514b1a84SArd Biesheuvel void efi_leave_mm(void); 172514b1a84SArd Biesheuvel 173a088b858SArd Biesheuvel /* kexec external ABI */ 1741fec0533SDave Young struct efi_setup_data { 1751fec0533SDave Young u64 fw_vendor; 176a088b858SArd Biesheuvel u64 __unused; 1771fec0533SDave Young u64 tables; 1781fec0533SDave Young u64 smbios; 1791fec0533SDave Young u64 reserved[8]; 1801fec0533SDave Young }; 1811fec0533SDave Young 1821fec0533SDave Young extern u64 efi_setup; 1831fec0533SDave Young 1846b59e366SSatoru Takeuchi #ifdef CONFIG_EFI 185a61962d8SArd Biesheuvel extern u64 __efi64_thunk(u32, ...); 18614b864f4SArvind Sankar 18714b864f4SArvind Sankar #define efi64_thunk(...) ({ \ 18844f155b4SArd Biesheuvel u64 __pad[3]; /* must have space for 3 args on the stack */ \ 18944f155b4SArd Biesheuvel __efi_nargs_check(efi64_thunk, 9, __VA_ARGS__); \ 19044f155b4SArd Biesheuvel __efi64_thunk(__VA_ARGS__, __pad); \ 19114b864f4SArvind Sankar }) 1926b59e366SSatoru Takeuchi 193a8147dbaSArd Biesheuvel static inline bool efi_is_mixed(void) 1946b59e366SSatoru Takeuchi { 195a8147dbaSArd Biesheuvel if (!IS_ENABLED(CONFIG_EFI_MIXED)) 196a8147dbaSArd Biesheuvel return false; 197a8147dbaSArd Biesheuvel return IS_ENABLED(CONFIG_X86_64) && !efi_enabled(EFI_64BIT); 1986b59e366SSatoru Takeuchi } 1996b59e366SSatoru Takeuchi 2007d453eeeSMatt Fleming static inline bool efi_runtime_supported(void) 2017d453eeeSMatt Fleming { 2026cfcd6f0SArd Biesheuvel if (IS_ENABLED(CONFIG_X86_64) == efi_enabled(EFI_64BIT)) 2037d453eeeSMatt Fleming return true; 2047d453eeeSMatt Fleming 2051f299fadSArd Biesheuvel return IS_ENABLED(CONFIG_EFI_MIXED); 2067d453eeeSMatt Fleming } 2077d453eeeSMatt Fleming 2085c12af0cSDave Young extern void parse_efi_setup(u64 phys_addr, u32 data_len); 2094f9dbcfcSMatt Fleming 2104f9dbcfcSMatt Fleming extern void efi_thunk_runtime_setup(void); 21169829470SArd Biesheuvel efi_status_t efi_set_virtual_address_map(unsigned long memory_map_size, 21269829470SArd Biesheuvel unsigned long descriptor_size, 21369829470SArd Biesheuvel u32 descriptor_version, 21459f2a619SArd Biesheuvel efi_memory_desc_t *virtual_map, 21559f2a619SArd Biesheuvel unsigned long systab_phys); 216243b6754SArd Biesheuvel 217243b6754SArd Biesheuvel /* arch specific definitions used by the stub code */ 218243b6754SArd Biesheuvel 219de8c5520SArvind Sankar #ifdef CONFIG_EFI_MIXED 220de8c5520SArvind Sankar 221de8c5520SArvind Sankar #define ARCH_HAS_EFISTUB_WRAPPERS 2220a755614SArd Biesheuvel 2230a755614SArd Biesheuvel static inline bool efi_is_64bit(void) 2240a755614SArd Biesheuvel { 225de8c5520SArvind Sankar extern const bool efi_is64; 226de8c5520SArvind Sankar 2270a755614SArd Biesheuvel return efi_is64; 2280a755614SArd Biesheuvel } 22927571616SLukas Wunner 230f958efe9SArd Biesheuvel static inline bool efi_is_native(void) 231f958efe9SArd Biesheuvel { 232f958efe9SArd Biesheuvel return efi_is_64bit(); 233f958efe9SArd Biesheuvel } 234f958efe9SArd Biesheuvel 23599ea8b1dSArd Biesheuvel #define efi_table_attr(inst, attr) \ 236a61962d8SArd Biesheuvel (efi_is_native() ? (inst)->attr \ 237a61962d8SArd Biesheuvel : efi_mixed_table_attr((inst), attr)) 238a61962d8SArd Biesheuvel 239a61962d8SArd Biesheuvel #define efi_mixed_table_attr(inst, attr) \ 240a61962d8SArd Biesheuvel (__typeof__(inst->attr)) \ 241a61962d8SArd Biesheuvel _Generic(inst->mixed_mode.attr, \ 242a61962d8SArd Biesheuvel u32: (unsigned long)(inst->mixed_mode.attr), \ 243a61962d8SArd Biesheuvel default: (inst->mixed_mode.attr)) 2443552fdf2SLukas Wunner 245ea7d87f9SArvind Sankar /* 246ea7d87f9SArvind Sankar * The following macros allow translating arguments if necessary from native to 247ea7d87f9SArvind Sankar * mixed mode. The use case for this is to initialize the upper 32 bits of 248ea7d87f9SArvind Sankar * output parameters, and where the 32-bit method requires a 64-bit argument, 249ea7d87f9SArvind Sankar * which must be split up into two arguments to be thunked properly. 250ea7d87f9SArvind Sankar * 251ea7d87f9SArvind Sankar * As examples, the AllocatePool boot service returns the address of the 252ea7d87f9SArvind Sankar * allocation, but it will not set the high 32 bits of the address. To ensure 253ea7d87f9SArvind Sankar * that the full 64-bit address is initialized, we zero-init the address before 254ea7d87f9SArvind Sankar * calling the thunk. 255ea7d87f9SArvind Sankar * 256ea7d87f9SArvind Sankar * The FreePages boot service takes a 64-bit physical address even in 32-bit 257ea7d87f9SArvind Sankar * mode. For the thunk to work correctly, a native 64-bit call of 258ea7d87f9SArvind Sankar * free_pages(addr, size) 259ea7d87f9SArvind Sankar * must be translated to 260ea7d87f9SArvind Sankar * efi64_thunk(free_pages, addr & U32_MAX, addr >> 32, size) 261ea7d87f9SArvind Sankar * so that the two 32-bit halves of addr get pushed onto the stack separately. 262ea7d87f9SArvind Sankar */ 263ea7d87f9SArvind Sankar 264ea7d87f9SArvind Sankar static inline void *efi64_zero_upper(void *p) 265ea7d87f9SArvind Sankar { 266ea7d87f9SArvind Sankar ((u32 *)p)[1] = 0; 267ea7d87f9SArvind Sankar return p; 268ea7d87f9SArvind Sankar } 269ea7d87f9SArvind Sankar 2703b8f44fcSArd Biesheuvel static inline u32 efi64_convert_status(efi_status_t status) 2713b8f44fcSArd Biesheuvel { 2723b8f44fcSArd Biesheuvel return (u32)(status | (u64)status >> 32); 2733b8f44fcSArd Biesheuvel } 2743b8f44fcSArd Biesheuvel 27531f1a0edSArd Biesheuvel #define __efi64_split(val) (val) & U32_MAX, (u64)(val) >> 32 27631f1a0edSArd Biesheuvel 277ea7d87f9SArvind Sankar #define __efi64_argmap_free_pages(addr, size) \ 278ea7d87f9SArvind Sankar ((addr), 0, (size)) 279ea7d87f9SArvind Sankar 280ea7d87f9SArvind Sankar #define __efi64_argmap_get_memory_map(mm_size, mm, key, size, ver) \ 281ea7d87f9SArvind Sankar ((mm_size), (mm), efi64_zero_upper(key), efi64_zero_upper(size), (ver)) 282ea7d87f9SArvind Sankar 283ea7d87f9SArvind Sankar #define __efi64_argmap_allocate_pool(type, size, buffer) \ 284ea7d87f9SArvind Sankar ((type), (size), efi64_zero_upper(buffer)) 285ea7d87f9SArvind Sankar 2869b47c527SArvind Sankar #define __efi64_argmap_create_event(type, tpl, f, c, event) \ 2879b47c527SArvind Sankar ((type), (tpl), (f), (c), efi64_zero_upper(event)) 2889b47c527SArvind Sankar 2899b47c527SArvind Sankar #define __efi64_argmap_set_timer(event, type, time) \ 2909b47c527SArvind Sankar ((event), (type), lower_32_bits(time), upper_32_bits(time)) 2919b47c527SArvind Sankar 2929b47c527SArvind Sankar #define __efi64_argmap_wait_for_event(num, event, index) \ 2939b47c527SArvind Sankar ((num), (event), efi64_zero_upper(index)) 2949b47c527SArvind Sankar 295ea7d87f9SArvind Sankar #define __efi64_argmap_handle_protocol(handle, protocol, interface) \ 296ea7d87f9SArvind Sankar ((handle), (protocol), efi64_zero_upper(interface)) 297ea7d87f9SArvind Sankar 298ea7d87f9SArvind Sankar #define __efi64_argmap_locate_protocol(protocol, reg, interface) \ 299ea7d87f9SArvind Sankar ((protocol), (reg), efi64_zero_upper(interface)) 300ea7d87f9SArvind Sankar 301abd26868SArd Biesheuvel #define __efi64_argmap_locate_device_path(protocol, path, handle) \ 302abd26868SArd Biesheuvel ((protocol), (path), efi64_zero_upper(handle)) 303abd26868SArd Biesheuvel 3043b8f44fcSArd Biesheuvel #define __efi64_argmap_exit(handle, status, size, data) \ 3053b8f44fcSArd Biesheuvel ((handle), efi64_convert_status(status), (size), (data)) 3063b8f44fcSArd Biesheuvel 3074444f854SMatthew Garrett /* PCI I/O */ 3084444f854SMatthew Garrett #define __efi64_argmap_get_location(protocol, seg, bus, dev, func) \ 3094444f854SMatthew Garrett ((protocol), efi64_zero_upper(seg), efi64_zero_upper(bus), \ 3104444f854SMatthew Garrett efi64_zero_upper(dev), efi64_zero_upper(func)) 3114444f854SMatthew Garrett 3122931d526SArd Biesheuvel /* LoadFile */ 3132931d526SArd Biesheuvel #define __efi64_argmap_load_file(protocol, path, policy, bufsize, buf) \ 3142931d526SArd Biesheuvel ((protocol), (path), (policy), efi64_zero_upper(bufsize), (buf)) 3152931d526SArd Biesheuvel 316b4b89a02SArvind Sankar /* Graphics Output Protocol */ 317b4b89a02SArvind Sankar #define __efi64_argmap_query_mode(gop, mode, size, info) \ 318b4b89a02SArvind Sankar ((gop), (mode), efi64_zero_upper(size), efi64_zero_upper(info)) 319b4b89a02SArvind Sankar 3204da87c51SArd Biesheuvel /* TCG2 protocol */ 3214da87c51SArd Biesheuvel #define __efi64_argmap_hash_log_extend_event(prot, fl, addr, size, ev) \ 3224da87c51SArd Biesheuvel ((prot), (fl), 0ULL, (u64)(addr), 0ULL, (u64)(size), 0ULL, ev) 3234da87c51SArd Biesheuvel 32431f1a0edSArd Biesheuvel /* DXE services */ 32531f1a0edSArd Biesheuvel #define __efi64_argmap_get_memory_space_descriptor(phys, desc) \ 32631f1a0edSArd Biesheuvel (__efi64_split(phys), (desc)) 32731f1a0edSArd Biesheuvel 328aa6d1ed1SEvgeniy Baskov #define __efi64_argmap_set_memory_space_attributes(phys, size, flags) \ 32931f1a0edSArd Biesheuvel (__efi64_split(phys), __efi64_split(size), __efi64_split(flags)) 33031f1a0edSArd Biesheuvel 331f8a31244SArd Biesheuvel /* file protocol */ 332f8a31244SArd Biesheuvel #define __efi64_argmap_open(prot, newh, fname, mode, attr) \ 333f8a31244SArd Biesheuvel ((prot), efi64_zero_upper(newh), (fname), __efi64_split(mode), \ 334f8a31244SArd Biesheuvel __efi64_split(attr)) 335f8a31244SArd Biesheuvel 336f8a31244SArd Biesheuvel #define __efi64_argmap_set_position(pos) (__efi64_split(pos)) 337f8a31244SArd Biesheuvel 338f8a31244SArd Biesheuvel /* file system protocol */ 339f8a31244SArd Biesheuvel #define __efi64_argmap_open_volume(prot, file) \ 340f8a31244SArd Biesheuvel ((prot), efi64_zero_upper(file)) 341f8a31244SArd Biesheuvel 34279729f26SEvgeniy Baskov /* Memory Attribute Protocol */ 34345d51654SArd Biesheuvel #define __efi64_argmap_get_memory_attributes(protocol, phys, size, flags) \ 34445d51654SArd Biesheuvel ((protocol), __efi64_split(phys), __efi64_split(size), (flags)) 34545d51654SArd Biesheuvel 34679729f26SEvgeniy Baskov #define __efi64_argmap_set_memory_attributes(protocol, phys, size, flags) \ 34779729f26SEvgeniy Baskov ((protocol), __efi64_split(phys), __efi64_split(size), __efi64_split(flags)) 34879729f26SEvgeniy Baskov 34979729f26SEvgeniy Baskov #define __efi64_argmap_clear_memory_attributes(protocol, phys, size, flags) \ 35079729f26SEvgeniy Baskov ((protocol), __efi64_split(phys), __efi64_split(size), __efi64_split(flags)) 35179729f26SEvgeniy Baskov 352ea7d87f9SArvind Sankar /* 353ea7d87f9SArvind Sankar * The macros below handle the plumbing for the argument mapping. To add a 354ea7d87f9SArvind Sankar * mapping for a specific EFI method, simply define a macro 355ea7d87f9SArvind Sankar * __efi64_argmap_<method name>, following the examples above. 356ea7d87f9SArvind Sankar */ 357ea7d87f9SArvind Sankar 358ea7d87f9SArvind Sankar #define __efi64_thunk_map(inst, func, ...) \ 359ea7d87f9SArvind Sankar efi64_thunk(inst->mixed_mode.func, \ 360ea7d87f9SArvind Sankar __efi64_argmap(__efi64_argmap_ ## func(__VA_ARGS__), \ 361ea7d87f9SArvind Sankar (__VA_ARGS__))) 362ea7d87f9SArvind Sankar 363ea7d87f9SArvind Sankar #define __efi64_argmap(mapped, args) \ 364ea7d87f9SArvind Sankar __PASTE(__efi64_argmap__, __efi_nargs(__efi_eat mapped))(mapped, args) 365ea7d87f9SArvind Sankar #define __efi64_argmap__0(mapped, args) __efi_eval mapped 366ea7d87f9SArvind Sankar #define __efi64_argmap__1(mapped, args) __efi_eval args 367ea7d87f9SArvind Sankar 368ea7d87f9SArvind Sankar #define __efi_eat(...) 369ea7d87f9SArvind Sankar #define __efi_eval(...) __VA_ARGS__ 370ea7d87f9SArvind Sankar 371a61962d8SArd Biesheuvel static inline efi_status_t __efi64_widen_efi_status(u64 status) 372a61962d8SArd Biesheuvel { 373a61962d8SArd Biesheuvel /* use rotate to move the value of bit #31 into position #63 */ 374a61962d8SArd Biesheuvel return ror64(rol32(status, 1), 1); 375a61962d8SArd Biesheuvel } 376ea7d87f9SArvind Sankar 377a61962d8SArd Biesheuvel /* The macro below handles dispatching via the thunk if needed */ 3783552fdf2SLukas Wunner 379a61962d8SArd Biesheuvel #define efi_fn_call(inst, func, ...) \ 380a61962d8SArd Biesheuvel (efi_is_native() ? (inst)->func(__VA_ARGS__) \ 381a61962d8SArd Biesheuvel : efi_mixed_call((inst), func, ##__VA_ARGS__)) 382243b6754SArd Biesheuvel 383a61962d8SArd Biesheuvel #define efi_mixed_call(inst, func, ...) \ 384a61962d8SArd Biesheuvel _Generic(inst->func(__VA_ARGS__), \ 385a61962d8SArd Biesheuvel efi_status_t: \ 386a61962d8SArd Biesheuvel __efi64_widen_efi_status( \ 387a61962d8SArd Biesheuvel __efi64_thunk_map(inst, func, ##__VA_ARGS__)), \ 388a61962d8SArd Biesheuvel u64: ({ BUILD_BUG(); ULONG_MAX; }), \ 389a61962d8SArd Biesheuvel default: \ 390a61962d8SArd Biesheuvel (__typeof__(inst->func(__VA_ARGS__))) \ 391a61962d8SArd Biesheuvel __efi64_thunk_map(inst, func, ##__VA_ARGS__)) 3923ba75c13SBaskov Evgeniy 393de8c5520SArvind Sankar #else /* CONFIG_EFI_MIXED */ 394de8c5520SArvind Sankar 395de8c5520SArvind Sankar static inline bool efi_is_64bit(void) 396de8c5520SArvind Sankar { 397de8c5520SArvind Sankar return IS_ENABLED(CONFIG_X86_64); 398de8c5520SArvind Sankar } 399de8c5520SArvind Sankar 400de8c5520SArvind Sankar #endif /* CONFIG_EFI_MIXED */ 401de8c5520SArvind Sankar 40244be28e9SMatt Fleming extern bool efi_reboot_required(void); 403e55f31a5SArd Biesheuvel extern bool efi_is_table_address(unsigned long phys_addr); 40444be28e9SMatt Fleming 4056950e31bSDan Williams extern void efi_reserve_boot_services(void); 4066b59e366SSatoru Takeuchi #else 4075c12af0cSDave Young static inline void parse_efi_setup(u64 phys_addr, u32 data_len) {} 40844be28e9SMatt Fleming static inline bool efi_reboot_required(void) 40944be28e9SMatt Fleming { 41044be28e9SMatt Fleming return false; 41144be28e9SMatt Fleming } 412e55f31a5SArd Biesheuvel static inline bool efi_is_table_address(unsigned long phys_addr) 413e55f31a5SArd Biesheuvel { 414e55f31a5SArd Biesheuvel return false; 415e55f31a5SArd Biesheuvel } 4166950e31bSDan Williams static inline void efi_reserve_boot_services(void) 4176950e31bSDan Williams { 4186950e31bSDan Williams } 419bb898558SAl Viro #endif /* CONFIG_EFI */ 420bb898558SAl Viro 421199c8471SDan Williams #ifdef CONFIG_EFI_FAKE_MEMMAP 422199c8471SDan Williams extern void __init efi_fake_memmap_early(void); 4234059ba65SArd Biesheuvel extern void __init efi_fake_memmap(void); 424199c8471SDan Williams #else 425199c8471SDan Williams static inline void efi_fake_memmap_early(void) 426199c8471SDan Williams { 427199c8471SDan Williams } 4284059ba65SArd Biesheuvel 4294059ba65SArd Biesheuvel static inline void efi_fake_memmap(void) 4304059ba65SArd Biesheuvel { 4314059ba65SArd Biesheuvel } 432199c8471SDan Williams #endif 433199c8471SDan Williams 434fdc6d38dSArd Biesheuvel extern int __init efi_memmap_alloc(unsigned int num_entries, 435fdc6d38dSArd Biesheuvel struct efi_memory_map_data *data); 436fdc6d38dSArd Biesheuvel extern void __efi_memmap_free(u64 phys, unsigned long size, 437fdc6d38dSArd Biesheuvel unsigned long flags); 438fdc6d38dSArd Biesheuvel #define __efi_memmap_free __efi_memmap_free 439fdc6d38dSArd Biesheuvel 440fdc6d38dSArd Biesheuvel extern int __init efi_memmap_install(struct efi_memory_map_data *data); 441fdc6d38dSArd Biesheuvel extern int __init efi_memmap_split_count(efi_memory_desc_t *md, 442fdc6d38dSArd Biesheuvel struct range *range); 443fdc6d38dSArd Biesheuvel extern void __init efi_memmap_insert(struct efi_memory_map *old_memmap, 444fdc6d38dSArd Biesheuvel void *buf, struct efi_mem_range *mem); 445fdc6d38dSArd Biesheuvel 44625519d68SChester Lin #define arch_ima_efi_boot_mode \ 44725519d68SChester Lin ({ extern struct boot_params boot_params; boot_params.secure_boot; }) 44825519d68SChester Lin 4491fff234dSArd Biesheuvel #ifdef CONFIG_EFI_RUNTIME_MAP 4501fff234dSArd Biesheuvel int efi_get_runtime_map_size(void); 4511fff234dSArd Biesheuvel int efi_get_runtime_map_desc_size(void); 4521fff234dSArd Biesheuvel int efi_runtime_map_copy(void *buf, size_t bufsz); 4531fff234dSArd Biesheuvel #else 4541fff234dSArd Biesheuvel static inline int efi_get_runtime_map_size(void) 4551fff234dSArd Biesheuvel { 4561fff234dSArd Biesheuvel return 0; 4571fff234dSArd Biesheuvel } 4581fff234dSArd Biesheuvel 4591fff234dSArd Biesheuvel static inline int efi_get_runtime_map_desc_size(void) 4601fff234dSArd Biesheuvel { 4611fff234dSArd Biesheuvel return 0; 4621fff234dSArd Biesheuvel } 4631fff234dSArd Biesheuvel 4641fff234dSArd Biesheuvel static inline int efi_runtime_map_copy(void *buf, size_t bufsz) 4651fff234dSArd Biesheuvel { 4661fff234dSArd Biesheuvel return 0; 4671fff234dSArd Biesheuvel } 4681fff234dSArd Biesheuvel 4691fff234dSArd Biesheuvel #endif 4701fff234dSArd Biesheuvel 4711965aae3SH. Peter Anvin #endif /* _ASM_X86_EFI_H */ 472