x86/efi: Delete most of the efi_call* macros
We really only need one phys and one virt function call, and then only one assembly function to make firmware calls. Since we are not using the C type system anyway, we're not really losing much by deleting the macros apart from no longer having a check that we are passing the correct number of parameters. The lack of duplicated code seems like a worthwhile trade-off. Cc: Ricardo Neri <ricardo.neri-calderon@linux.intel.com> Cc: Borislav Petkov <bp@suse.de> Signed-off-by: Matt Fleming <matt.fleming@intel.com>
This commit is contained in:
parent
c625d1c203
commit
62fa6e69a4
@ -452,7 +452,7 @@ efi32_config:
|
|||||||
.global efi64_config
|
.global efi64_config
|
||||||
efi64_config:
|
efi64_config:
|
||||||
.fill 11,8,0
|
.fill 11,8,0
|
||||||
.quad efi_call6
|
.quad efi_call
|
||||||
.byte 1
|
.byte 1
|
||||||
#endif /* CONFIG_EFI_STUB */
|
#endif /* CONFIG_EFI_STUB */
|
||||||
|
|
||||||
|
@ -27,16 +27,6 @@
|
|||||||
|
|
||||||
extern unsigned long asmlinkage efi_call_phys(void *, ...);
|
extern unsigned long asmlinkage efi_call_phys(void *, ...);
|
||||||
|
|
||||||
#define efi_call_phys0(f) efi_call_phys(f)
|
|
||||||
#define efi_call_phys1(f, a1) efi_call_phys(f, a1)
|
|
||||||
#define efi_call_phys2(f, a1, a2) efi_call_phys(f, a1, a2)
|
|
||||||
#define efi_call_phys3(f, a1, a2, a3) efi_call_phys(f, a1, a2, a3)
|
|
||||||
#define efi_call_phys4(f, a1, a2, a3, a4) \
|
|
||||||
efi_call_phys(f, a1, a2, a3, a4)
|
|
||||||
#define efi_call_phys5(f, a1, a2, a3, a4, a5) \
|
|
||||||
efi_call_phys(f, a1, a2, a3, a4, a5)
|
|
||||||
#define efi_call_phys6(f, a1, a2, a3, a4, a5, a6) \
|
|
||||||
efi_call_phys(f, a1, a2, a3, a4, a5, a6)
|
|
||||||
/*
|
/*
|
||||||
* Wrap all the virtual calls in a way that forces the parameters on the stack.
|
* Wrap all the virtual calls in a way that forces the parameters on the stack.
|
||||||
*/
|
*/
|
||||||
@ -44,75 +34,27 @@ extern unsigned long asmlinkage efi_call_phys(void *, ...);
|
|||||||
#define efi_call_virt(f, args...) \
|
#define efi_call_virt(f, args...) \
|
||||||
((efi_##f##_t __attribute__((regparm(0)))*)efi.systab->runtime->f)(args)
|
((efi_##f##_t __attribute__((regparm(0)))*)efi.systab->runtime->f)(args)
|
||||||
|
|
||||||
#define efi_call_virt0(f) efi_call_virt(f)
|
|
||||||
#define efi_call_virt1(f, a1) efi_call_virt(f, a1)
|
|
||||||
#define efi_call_virt2(f, a1, a2) efi_call_virt(f, a1, a2)
|
|
||||||
#define efi_call_virt3(f, a1, a2, a3) efi_call_virt(f, a1, a2, a3)
|
|
||||||
#define efi_call_virt4(f, a1, a2, a3, a4) \
|
|
||||||
efi_call_virt(f, a1, a2, a3, a4)
|
|
||||||
#define efi_call_virt5(f, a1, a2, a3, a4, a5) \
|
|
||||||
efi_call_virt(f, a1, a2, a3, a4, a5)
|
|
||||||
#define efi_call_virt6(f, a1, a2, a3, a4, a5, a6) \
|
|
||||||
efi_call_virt(f, a1, a2, a3, a4, a5, a6)
|
|
||||||
|
|
||||||
#define efi_ioremap(addr, size, type, attr) ioremap_cache(addr, size)
|
#define efi_ioremap(addr, size, type, attr) ioremap_cache(addr, size)
|
||||||
|
|
||||||
#else /* !CONFIG_X86_32 */
|
#else /* !CONFIG_X86_32 */
|
||||||
|
|
||||||
extern u64 efi_call0(void *fp);
|
#define EFI_LOADER_SIGNATURE "EL64"
|
||||||
extern u64 efi_call1(void *fp, u64 arg1);
|
|
||||||
extern u64 efi_call2(void *fp, u64 arg1, u64 arg2);
|
|
||||||
extern u64 efi_call3(void *fp, u64 arg1, u64 arg2, u64 arg3);
|
|
||||||
extern u64 efi_call4(void *fp, u64 arg1, u64 arg2, u64 arg3, u64 arg4);
|
|
||||||
extern u64 efi_call5(void *fp, u64 arg1, u64 arg2, u64 arg3,
|
|
||||||
u64 arg4, u64 arg5);
|
|
||||||
extern u64 efi_call6(void *fp, u64 arg1, u64 arg2, u64 arg3,
|
|
||||||
u64 arg4, u64 arg5, u64 arg6);
|
|
||||||
|
|
||||||
#define efi_call_phys0(f) \
|
extern u64 asmlinkage efi_call(void *fp, ...);
|
||||||
efi_call0((f))
|
|
||||||
#define efi_call_phys1(f, a1) \
|
|
||||||
efi_call1((f), (u64)(a1))
|
|
||||||
#define efi_call_phys2(f, a1, a2) \
|
|
||||||
efi_call2((f), (u64)(a1), (u64)(a2))
|
|
||||||
#define efi_call_phys3(f, a1, a2, a3) \
|
|
||||||
efi_call3((f), (u64)(a1), (u64)(a2), (u64)(a3))
|
|
||||||
#define efi_call_phys4(f, a1, a2, a3, a4) \
|
|
||||||
efi_call4((f), (u64)(a1), (u64)(a2), (u64)(a3), \
|
|
||||||
(u64)(a4))
|
|
||||||
#define efi_call_phys5(f, a1, a2, a3, a4, a5) \
|
|
||||||
efi_call5((f), (u64)(a1), (u64)(a2), (u64)(a3), \
|
|
||||||
(u64)(a4), (u64)(a5))
|
|
||||||
#define efi_call_phys6(f, a1, a2, a3, a4, a5, a6) \
|
|
||||||
efi_call6((f), (u64)(a1), (u64)(a2), (u64)(a3), \
|
|
||||||
(u64)(a4), (u64)(a5), (u64)(a6))
|
|
||||||
|
|
||||||
#define _efi_call_virtX(x, f, ...) \
|
#define efi_call_phys(f, args...) efi_call((f), args)
|
||||||
|
|
||||||
|
#define efi_call_virt(f, ...) \
|
||||||
({ \
|
({ \
|
||||||
efi_status_t __s; \
|
efi_status_t __s; \
|
||||||
\
|
\
|
||||||
efi_sync_low_kernel_mappings(); \
|
efi_sync_low_kernel_mappings(); \
|
||||||
preempt_disable(); \
|
preempt_disable(); \
|
||||||
__s = efi_call##x((void *)efi.systab->runtime->f, __VA_ARGS__); \
|
__s = efi_call((void *)efi.systab->runtime->f, __VA_ARGS__); \
|
||||||
preempt_enable(); \
|
preempt_enable(); \
|
||||||
__s; \
|
__s; \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define efi_call_virt0(f) \
|
|
||||||
_efi_call_virtX(0, f)
|
|
||||||
#define efi_call_virt1(f, a1) \
|
|
||||||
_efi_call_virtX(1, f, (u64)(a1))
|
|
||||||
#define efi_call_virt2(f, a1, a2) \
|
|
||||||
_efi_call_virtX(2, f, (u64)(a1), (u64)(a2))
|
|
||||||
#define efi_call_virt3(f, a1, a2, a3) \
|
|
||||||
_efi_call_virtX(3, f, (u64)(a1), (u64)(a2), (u64)(a3))
|
|
||||||
#define efi_call_virt4(f, a1, a2, a3, a4) \
|
|
||||||
_efi_call_virtX(4, f, (u64)(a1), (u64)(a2), (u64)(a3), (u64)(a4))
|
|
||||||
#define efi_call_virt5(f, a1, a2, a3, a4, a5) \
|
|
||||||
_efi_call_virtX(5, f, (u64)(a1), (u64)(a2), (u64)(a3), (u64)(a4), (u64)(a5))
|
|
||||||
#define efi_call_virt6(f, a1, a2, a3, a4, a5, a6) \
|
|
||||||
_efi_call_virtX(6, f, (u64)(a1), (u64)(a2), (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6))
|
|
||||||
|
|
||||||
extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size,
|
extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size,
|
||||||
u32 type, u64 attribute);
|
u32 type, u64 attribute);
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
|
|||||||
efi_status_t status;
|
efi_status_t status;
|
||||||
|
|
||||||
spin_lock_irqsave(&rtc_lock, flags);
|
spin_lock_irqsave(&rtc_lock, flags);
|
||||||
status = efi_call_virt2(get_time, tm, tc);
|
status = efi_call_virt(get_time, tm, tc);
|
||||||
spin_unlock_irqrestore(&rtc_lock, flags);
|
spin_unlock_irqrestore(&rtc_lock, flags);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -121,7 +121,7 @@ static efi_status_t virt_efi_set_time(efi_time_t *tm)
|
|||||||
efi_status_t status;
|
efi_status_t status;
|
||||||
|
|
||||||
spin_lock_irqsave(&rtc_lock, flags);
|
spin_lock_irqsave(&rtc_lock, flags);
|
||||||
status = efi_call_virt1(set_time, tm);
|
status = efi_call_virt(set_time, tm);
|
||||||
spin_unlock_irqrestore(&rtc_lock, flags);
|
spin_unlock_irqrestore(&rtc_lock, flags);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -134,8 +134,7 @@ static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled,
|
|||||||
efi_status_t status;
|
efi_status_t status;
|
||||||
|
|
||||||
spin_lock_irqsave(&rtc_lock, flags);
|
spin_lock_irqsave(&rtc_lock, flags);
|
||||||
status = efi_call_virt3(get_wakeup_time,
|
status = efi_call_virt(get_wakeup_time, enabled, pending, tm);
|
||||||
enabled, pending, tm);
|
|
||||||
spin_unlock_irqrestore(&rtc_lock, flags);
|
spin_unlock_irqrestore(&rtc_lock, flags);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -146,8 +145,7 @@ static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
|
|||||||
efi_status_t status;
|
efi_status_t status;
|
||||||
|
|
||||||
spin_lock_irqsave(&rtc_lock, flags);
|
spin_lock_irqsave(&rtc_lock, flags);
|
||||||
status = efi_call_virt2(set_wakeup_time,
|
status = efi_call_virt(set_wakeup_time, enabled, tm);
|
||||||
enabled, tm);
|
|
||||||
spin_unlock_irqrestore(&rtc_lock, flags);
|
spin_unlock_irqrestore(&rtc_lock, flags);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -158,17 +156,17 @@ static efi_status_t virt_efi_get_variable(efi_char16_t *name,
|
|||||||
unsigned long *data_size,
|
unsigned long *data_size,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
return efi_call_virt5(get_variable,
|
return efi_call_virt(get_variable,
|
||||||
name, vendor, attr,
|
name, vendor, attr,
|
||||||
data_size, data);
|
data_size, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,
|
static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,
|
||||||
efi_char16_t *name,
|
efi_char16_t *name,
|
||||||
efi_guid_t *vendor)
|
efi_guid_t *vendor)
|
||||||
{
|
{
|
||||||
return efi_call_virt3(get_next_variable,
|
return efi_call_virt(get_next_variable,
|
||||||
name_size, name, vendor);
|
name_size, name, vendor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static efi_status_t virt_efi_set_variable(efi_char16_t *name,
|
static efi_status_t virt_efi_set_variable(efi_char16_t *name,
|
||||||
@ -177,9 +175,9 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name,
|
|||||||
unsigned long data_size,
|
unsigned long data_size,
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
return efi_call_virt5(set_variable,
|
return efi_call_virt(set_variable,
|
||||||
name, vendor, attr,
|
name, vendor, attr,
|
||||||
data_size, data);
|
data_size, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static efi_status_t virt_efi_query_variable_info(u32 attr,
|
static efi_status_t virt_efi_query_variable_info(u32 attr,
|
||||||
@ -190,13 +188,13 @@ static efi_status_t virt_efi_query_variable_info(u32 attr,
|
|||||||
if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
|
if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
|
|
||||||
return efi_call_virt4(query_variable_info, attr, storage_space,
|
return efi_call_virt(query_variable_info, attr, storage_space,
|
||||||
remaining_space, max_variable_size);
|
remaining_space, max_variable_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static efi_status_t virt_efi_get_next_high_mono_count(u32 *count)
|
static efi_status_t virt_efi_get_next_high_mono_count(u32 *count)
|
||||||
{
|
{
|
||||||
return efi_call_virt1(get_next_high_mono_count, count);
|
return efi_call_virt(get_next_high_mono_count, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void virt_efi_reset_system(int reset_type,
|
static void virt_efi_reset_system(int reset_type,
|
||||||
@ -204,8 +202,8 @@ static void virt_efi_reset_system(int reset_type,
|
|||||||
unsigned long data_size,
|
unsigned long data_size,
|
||||||
efi_char16_t *data)
|
efi_char16_t *data)
|
||||||
{
|
{
|
||||||
efi_call_virt4(reset_system, reset_type, status,
|
efi_call_virt(reset_system, reset_type, status,
|
||||||
data_size, data);
|
data_size, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules,
|
static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules,
|
||||||
@ -215,7 +213,7 @@ static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules,
|
|||||||
if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
|
if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
|
|
||||||
return efi_call_virt3(update_capsule, capsules, count, sg_list);
|
return efi_call_virt(update_capsule, capsules, count, sg_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules,
|
static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules,
|
||||||
@ -226,8 +224,8 @@ static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules,
|
|||||||
if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
|
if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
|
||||||
return EFI_UNSUPPORTED;
|
return EFI_UNSUPPORTED;
|
||||||
|
|
||||||
return efi_call_virt4(query_capsule_caps, capsules, count, max_size,
|
return efi_call_virt(query_capsule_caps, capsules, count, max_size,
|
||||||
reset_type);
|
reset_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
static efi_status_t __init phys_efi_set_virtual_address_map(
|
static efi_status_t __init phys_efi_set_virtual_address_map(
|
||||||
@ -239,9 +237,9 @@ static efi_status_t __init phys_efi_set_virtual_address_map(
|
|||||||
efi_status_t status;
|
efi_status_t status;
|
||||||
|
|
||||||
efi_call_phys_prelog();
|
efi_call_phys_prelog();
|
||||||
status = efi_call_phys4(efi_phys.set_virtual_address_map,
|
status = efi_call_phys(efi_phys.set_virtual_address_map,
|
||||||
memory_map_size, descriptor_size,
|
memory_map_size, descriptor_size,
|
||||||
descriptor_version, virtual_map);
|
descriptor_version, virtual_map);
|
||||||
efi_call_phys_epilog();
|
efi_call_phys_epilog();
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -73,84 +73,7 @@
|
|||||||
2:
|
2:
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
ENTRY(efi_call0)
|
ENTRY(efi_call)
|
||||||
SAVE_XMM
|
|
||||||
subq $32, %rsp
|
|
||||||
SWITCH_PGT
|
|
||||||
call *%rdi
|
|
||||||
RESTORE_PGT
|
|
||||||
addq $32, %rsp
|
|
||||||
RESTORE_XMM
|
|
||||||
ret
|
|
||||||
ENDPROC(efi_call0)
|
|
||||||
|
|
||||||
ENTRY(efi_call1)
|
|
||||||
SAVE_XMM
|
|
||||||
subq $32, %rsp
|
|
||||||
mov %rsi, %rcx
|
|
||||||
SWITCH_PGT
|
|
||||||
call *%rdi
|
|
||||||
RESTORE_PGT
|
|
||||||
addq $32, %rsp
|
|
||||||
RESTORE_XMM
|
|
||||||
ret
|
|
||||||
ENDPROC(efi_call1)
|
|
||||||
|
|
||||||
ENTRY(efi_call2)
|
|
||||||
SAVE_XMM
|
|
||||||
subq $32, %rsp
|
|
||||||
mov %rsi, %rcx
|
|
||||||
SWITCH_PGT
|
|
||||||
call *%rdi
|
|
||||||
RESTORE_PGT
|
|
||||||
addq $32, %rsp
|
|
||||||
RESTORE_XMM
|
|
||||||
ret
|
|
||||||
ENDPROC(efi_call2)
|
|
||||||
|
|
||||||
ENTRY(efi_call3)
|
|
||||||
SAVE_XMM
|
|
||||||
subq $32, %rsp
|
|
||||||
mov %rcx, %r8
|
|
||||||
mov %rsi, %rcx
|
|
||||||
SWITCH_PGT
|
|
||||||
call *%rdi
|
|
||||||
RESTORE_PGT
|
|
||||||
addq $32, %rsp
|
|
||||||
RESTORE_XMM
|
|
||||||
ret
|
|
||||||
ENDPROC(efi_call3)
|
|
||||||
|
|
||||||
ENTRY(efi_call4)
|
|
||||||
SAVE_XMM
|
|
||||||
subq $32, %rsp
|
|
||||||
mov %r8, %r9
|
|
||||||
mov %rcx, %r8
|
|
||||||
mov %rsi, %rcx
|
|
||||||
SWITCH_PGT
|
|
||||||
call *%rdi
|
|
||||||
RESTORE_PGT
|
|
||||||
addq $32, %rsp
|
|
||||||
RESTORE_XMM
|
|
||||||
ret
|
|
||||||
ENDPROC(efi_call4)
|
|
||||||
|
|
||||||
ENTRY(efi_call5)
|
|
||||||
SAVE_XMM
|
|
||||||
subq $48, %rsp
|
|
||||||
mov %r9, 32(%rsp)
|
|
||||||
mov %r8, %r9
|
|
||||||
mov %rcx, %r8
|
|
||||||
mov %rsi, %rcx
|
|
||||||
SWITCH_PGT
|
|
||||||
call *%rdi
|
|
||||||
RESTORE_PGT
|
|
||||||
addq $48, %rsp
|
|
||||||
RESTORE_XMM
|
|
||||||
ret
|
|
||||||
ENDPROC(efi_call5)
|
|
||||||
|
|
||||||
ENTRY(efi_call6)
|
|
||||||
SAVE_XMM
|
SAVE_XMM
|
||||||
mov (%rsp), %rax
|
mov (%rsp), %rax
|
||||||
mov 8(%rax), %rax
|
mov 8(%rax), %rax
|
||||||
@ -166,7 +89,7 @@ ENTRY(efi_call6)
|
|||||||
addq $48, %rsp
|
addq $48, %rsp
|
||||||
RESTORE_XMM
|
RESTORE_XMM
|
||||||
ret
|
ret
|
||||||
ENDPROC(efi_call6)
|
ENDPROC(efi_call)
|
||||||
|
|
||||||
#ifdef CONFIG_EFI_MIXED
|
#ifdef CONFIG_EFI_MIXED
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ s64 uv_bios_call(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5)
|
|||||||
*/
|
*/
|
||||||
return BIOS_STATUS_UNIMPLEMENTED;
|
return BIOS_STATUS_UNIMPLEMENTED;
|
||||||
|
|
||||||
ret = efi_call6((void *)__va(tab->function), (u64)which,
|
ret = efi_call((void *)__va(tab->function), (u64)which,
|
||||||
a1, a2, a3, a4, a5);
|
a1, a2, a3, a4, a5);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user