Skip to content

Commit

Permalink
x86/efi: Delete most of the efi_call* macros
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Matt Fleming committed Apr 17, 2014
1 parent c625d1c commit 62fa6e6
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 172 deletions.
2 changes: 1 addition & 1 deletion arch/x86/boot/compressed/head_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ efi32_config:
.global efi64_config
efi64_config:
.fill 11,8,0
.quad efi_call6
.quad efi_call
.byte 1
#endif /* CONFIG_EFI_STUB */

Expand Down
74 changes: 8 additions & 66 deletions arch/x86/include/asm/efi.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,92 +27,34 @@

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.
*/

#define efi_call_virt(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)

#else /* !CONFIG_X86_32 */

extern u64 efi_call0(void *fp);
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) \
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_LOADER_SIGNATURE "EL64"

extern u64 asmlinkage efi_call(void *fp, ...);

#define efi_call_phys(f, args...) efi_call((f), args)

#define efi_call_virt(f, ...) \
({ \
efi_status_t __s; \
\
efi_sync_low_kernel_mappings(); \
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(); \
__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,
u32 type, u64 attribute);

Expand Down
48 changes: 23 additions & 25 deletions arch/x86/platform/efi/efi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

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);
return status;
}
Expand All @@ -121,7 +121,7 @@ static efi_status_t virt_efi_set_time(efi_time_t *tm)
efi_status_t status;

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);
return status;
}
Expand All @@ -134,8 +134,7 @@ static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled,
efi_status_t status;

spin_lock_irqsave(&rtc_lock, flags);
status = efi_call_virt3(get_wakeup_time,
enabled, pending, tm);
status = efi_call_virt(get_wakeup_time, enabled, pending, tm);
spin_unlock_irqrestore(&rtc_lock, flags);
return status;
}
Expand All @@ -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;

spin_lock_irqsave(&rtc_lock, flags);
status = efi_call_virt2(set_wakeup_time,
enabled, tm);
status = efi_call_virt(set_wakeup_time, enabled, tm);
spin_unlock_irqrestore(&rtc_lock, flags);
return status;
}
Expand All @@ -158,17 +156,17 @@ static efi_status_t virt_efi_get_variable(efi_char16_t *name,
unsigned long *data_size,
void *data)
{
return efi_call_virt5(get_variable,
name, vendor, attr,
data_size, data);
return efi_call_virt(get_variable,
name, vendor, attr,
data_size, data);
}

static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,
efi_char16_t *name,
efi_guid_t *vendor)
{
return efi_call_virt3(get_next_variable,
name_size, name, vendor);
return efi_call_virt(get_next_variable,
name_size, name, vendor);
}

static efi_status_t virt_efi_set_variable(efi_char16_t *name,
Expand All @@ -177,9 +175,9 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name,
unsigned long data_size,
void *data)
{
return efi_call_virt5(set_variable,
name, vendor, attr,
data_size, data);
return efi_call_virt(set_variable,
name, vendor, attr,
data_size, data);
}

static efi_status_t virt_efi_query_variable_info(u32 attr,
Expand All @@ -190,22 +188,22 @@ static efi_status_t virt_efi_query_variable_info(u32 attr,
if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
return EFI_UNSUPPORTED;

return efi_call_virt4(query_variable_info, attr, storage_space,
remaining_space, max_variable_size);
return efi_call_virt(query_variable_info, attr, storage_space,
remaining_space, max_variable_size);
}

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,
efi_status_t status,
unsigned long data_size,
efi_char16_t *data)
{
efi_call_virt4(reset_system, reset_type, status,
data_size, data);
efi_call_virt(reset_system, reset_type, status,
data_size, data);
}

static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules,
Expand All @@ -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)
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,
Expand All @@ -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)
return EFI_UNSUPPORTED;

return efi_call_virt4(query_capsule_caps, capsules, count, max_size,
reset_type);
return efi_call_virt(query_capsule_caps, capsules, count, max_size,
reset_type);
}

static efi_status_t __init phys_efi_set_virtual_address_map(
Expand All @@ -239,9 +237,9 @@ static efi_status_t __init phys_efi_set_virtual_address_map(
efi_status_t status;

efi_call_phys_prelog();
status = efi_call_phys4(efi_phys.set_virtual_address_map,
memory_map_size, descriptor_size,
descriptor_version, virtual_map);
status = efi_call_phys(efi_phys.set_virtual_address_map,
memory_map_size, descriptor_size,
descriptor_version, virtual_map);
efi_call_phys_epilog();
return status;
}
Expand Down
81 changes: 2 additions & 79 deletions arch/x86/platform/efi/efi_stub_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -73,84 +73,7 @@
2:
.endm

ENTRY(efi_call0)
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)
ENTRY(efi_call)
SAVE_XMM
mov (%rsp), %rax
mov 8(%rax), %rax
Expand All @@ -166,7 +89,7 @@ ENTRY(efi_call6)
addq $48, %rsp
RESTORE_XMM
ret
ENDPROC(efi_call6)
ENDPROC(efi_call)

#ifdef CONFIG_EFI_MIXED

Expand Down
2 changes: 1 addition & 1 deletion arch/x86/platform/uv/bios_uv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

ret = efi_call6((void *)__va(tab->function), (u64)which,
ret = efi_call((void *)__va(tab->function), (u64)which,
a1, a2, a3, a4, a5);
return ret;
}
Expand Down

0 comments on commit 62fa6e6

Please sign in to comment.