summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2016-02-19 00:23:38 +0100
committerMichael Brown2016-02-19 00:23:38 +0100
commit31b5c2e753dbcb3d5023bccc8e644d0bcb56b2ad (patch)
tree536967f3f34fba94970a31cbde3fe1d2cf657cce
parent[librm] Convert prot_call() to a real-mode near call (diff)
downloadipxe-31b5c2e753dbcb3d5023bccc8e644d0bcb56b2ad.tar.gz
ipxe-31b5c2e753dbcb3d5023bccc8e644d0bcb56b2ad.tar.xz
ipxe-31b5c2e753dbcb3d5023bccc8e644d0bcb56b2ad.zip
[librm] Provide an abstraction wrapper for prot_call
Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/arch/i386/include/bits/compiler.h2
-rw-r--r--src/arch/i386/interface/syslinux/comboot_call.c18
-rw-r--r--src/arch/x86/core/dumpregs.c5
-rw-r--r--src/arch/x86/include/librm.h23
-rw-r--r--src/arch/x86/interface/pcbios/bios_console.c8
-rw-r--r--src/arch/x86/interface/pcbios/bios_reboot.c2
-rw-r--r--src/arch/x86/interface/pcbios/int13.c6
-rw-r--r--src/arch/x86/interface/pxe/pxe_entry.S5
-rw-r--r--src/arch/x86/prefix/dskprefix.S6
-rw-r--r--src/arch/x86/prefix/exeprefix.S5
-rw-r--r--src/arch/x86/prefix/hdprefix.S6
-rw-r--r--src/arch/x86/prefix/libprefix.S5
-rw-r--r--src/arch/x86/prefix/lkrnprefix.S5
-rw-r--r--src/arch/x86/prefix/nbiprefix.S6
-rw-r--r--src/arch/x86/prefix/pxeprefix.S4
-rw-r--r--src/arch/x86/prefix/romprefix.S6
-rw-r--r--src/arch/x86/prefix/undiloader.S5
-rw-r--r--src/arch/x86/transitions/librm.S6
-rw-r--r--src/arch/x86/transitions/librm_test.c12
-rw-r--r--src/arch/x86_64/include/bits/compiler.h2
20 files changed, 77 insertions, 60 deletions
diff --git a/src/arch/i386/include/bits/compiler.h b/src/arch/i386/include/bits/compiler.h
index 87201135..7c4a0939 100644
--- a/src/arch/i386/include/bits/compiler.h
+++ b/src/arch/i386/include/bits/compiler.h
@@ -9,7 +9,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifndef ASSEMBLY
/** Declare a function with standard calling conventions */
-#define __asmcall __attribute__ (( cdecl, regparm(0) ))
+#define __asmcall __attribute__ (( used, cdecl, regparm(0) ))
/**
* Declare a function with libgcc implicit linkage
diff --git a/src/arch/i386/interface/syslinux/comboot_call.c b/src/arch/i386/interface/syslinux/comboot_call.c
index 277ec447..56597781 100644
--- a/src/arch/i386/interface/syslinux/comboot_call.c
+++ b/src/arch/i386/interface/syslinux/comboot_call.c
@@ -660,34 +660,28 @@ void hook_comboot_interrupts ( ) {
__asm__ __volatile__ (
TEXT16_CODE ( "\nint20_wrapper:\n\t"
- "pushl %0\n\t"
- "call prot_call\n\t"
+ VIRT_CALL ( int20 )
"clc\n\t"
"call patch_cf\n\t"
- "iret\n\t" )
- : : "i" ( int20 ) );
+ "iret\n\t" ) );
hook_bios_interrupt ( 0x20, ( intptr_t ) int20_wrapper, &int20_vector );
__asm__ __volatile__ (
TEXT16_CODE ( "\nint21_wrapper:\n\t"
- "pushl %0\n\t"
- "call prot_call\n\t"
+ VIRT_CALL ( int21 )
"clc\n\t"
"call patch_cf\n\t"
- "iret\n\t" )
- : : "i" ( int21 ) );
+ "iret\n\t" ) );
hook_bios_interrupt ( 0x21, ( intptr_t ) int21_wrapper, &int21_vector );
__asm__ __volatile__ (
TEXT16_CODE ( "\nint22_wrapper:\n\t"
- "pushl %0\n\t"
- "call prot_call\n\t"
+ VIRT_CALL ( int22 )
"clc\n\t"
"call patch_cf\n\t"
- "iret\n\t" )
- : : "i" ( int22) );
+ "iret\n\t" ) );
hook_bios_interrupt ( 0x22, ( intptr_t ) int22_wrapper, &int22_vector );
}
diff --git a/src/arch/x86/core/dumpregs.c b/src/arch/x86/core/dumpregs.c
index 9f0b0818..37d62a7b 100644
--- a/src/arch/x86/core/dumpregs.c
+++ b/src/arch/x86/core/dumpregs.c
@@ -6,9 +6,8 @@ void __asmcall _dump_regs ( struct i386_all_regs *ix86 ) {
__asm__ __volatile__ (
TEXT16_CODE ( ".globl dump_regs\n\t"
"\ndump_regs:\n\t"
- "pushl $_dump_regs\n\t"
- "call prot_call\n\t"
- "ret\n\t" ) : : );
+ VIRT_CALL ( _dump_regs )
+ "ret\n\t" ) );
printf ( "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
"ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
diff --git a/src/arch/x86/include/librm.h b/src/arch/x86/include/librm.h
index 379e085a..2786027a 100644
--- a/src/arch/x86/include/librm.h
+++ b/src/arch/x86/include/librm.h
@@ -19,7 +19,19 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define LONG_DS 0x40
#endif
-#ifndef ASSEMBLY
+#ifdef ASSEMBLY
+
+/**
+ * Call C function from real-mode code
+ *
+ * @v function C function
+ */
+.macro virtcall function
+ pushl $\function
+ call prot_call
+.endm
+
+#else /* ASSEMBLY */
#ifdef UACCESS_LIBRM
#define UACCESS_PREFIX_librm
@@ -27,6 +39,15 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#define UACCESS_PREFIX_librm __librm_
#endif
+/**
+ * Call C function from real-mode code
+ *
+ * @v function C function
+ */
+#define VIRT_CALL( function ) \
+ "pushl $( " #function " )\n\t" \
+ "call prot_call\n\t"
+
/* Variables in librm.S */
extern unsigned long virt_offset;
diff --git a/src/arch/x86/interface/pcbios/bios_console.c b/src/arch/x86/interface/pcbios/bios_console.c
index 72d5b209..c081a41e 100644
--- a/src/arch/x86/interface/pcbios/bios_console.c
+++ b/src/arch/x86/interface/pcbios/bios_console.c
@@ -531,14 +531,12 @@ static void bios_inject_startup ( void ) {
__asm__ __volatile__ (
TEXT16_CODE ( "\nint16_wrapper:\n\t"
"pushfw\n\t"
- "cmpb $0, %%cs:bios_inject_lock\n\t"
+ "cmpb $0, %cs:bios_inject_lock\n\t"
"jnz 1f\n\t"
- "pushl %0\n\t"
- "call prot_call\n\t"
+ VIRT_CALL ( bios_inject )
"\n1:\n\t"
"popfw\n\t"
- "ljmp *%%cs:int16_vector\n\t" )
- : : "i" ( bios_inject ) );
+ "ljmp *%cs:int16_vector\n\t" ) );
/* Hook INT 16 */
hook_bios_interrupt ( 0x16, ( ( intptr_t ) int16_wrapper ),
diff --git a/src/arch/x86/interface/pcbios/bios_reboot.c b/src/arch/x86/interface/pcbios/bios_reboot.c
index 10a1ecb8..ed18dde0 100644
--- a/src/arch/x86/interface/pcbios/bios_reboot.c
+++ b/src/arch/x86/interface/pcbios/bios_reboot.c
@@ -46,7 +46,7 @@ static void bios_reboot ( int warm ) {
put_real ( flag, BDA_SEG, BDA_REBOOT );
/* Jump to system reset vector */
- __asm__ __volatile__ ( REAL_CODE ( "ljmp $0xf000, $0xfff0" ) : : );
+ __asm__ __volatile__ ( REAL_CODE ( "ljmp $0xf000, $0xfff0" ) );
}
PROVIDE_REBOOT ( pcbios, reboot, bios_reboot );
diff --git a/src/arch/x86/interface/pcbios/int13.c b/src/arch/x86/interface/pcbios/int13.c
index 7fe247b5..38880e4f 100644
--- a/src/arch/x86/interface/pcbios/int13.c
+++ b/src/arch/x86/interface/pcbios/int13.c
@@ -1480,8 +1480,7 @@ static void int13_hook_vector ( void ) {
/* Clear OF, set CF, call int13() */
"orb $0, %%al\n\t"
"stc\n\t"
- "pushl %0\n\t"
- "call prot_call\n\t"
+ VIRT_CALL ( int13 )
/* Chain if OF not set */
"jo 1f\n\t"
"pushfw\n\t"
@@ -1512,8 +1511,7 @@ static void int13_hook_vector ( void ) {
"\n3:\n\t"
"movw %%bp, %%sp\n\t"
"popw %%bp\n\t"
- "iret\n\t" )
- : : "i" ( int13 ) );
+ "iret\n\t" ) : : );
hook_bios_interrupt ( 0x13, ( intptr_t ) int13_wrapper, &int13_vector );
}
diff --git a/src/arch/x86/interface/pxe/pxe_entry.S b/src/arch/x86/interface/pxe/pxe_entry.S
index 2ce1ced2..663aa842 100644
--- a/src/arch/x86/interface/pxe/pxe_entry.S
+++ b/src/arch/x86/interface/pxe/pxe_entry.S
@@ -24,6 +24,8 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
+#include <librm.h>
+
.arch i386
/****************************************************************************
@@ -120,8 +122,7 @@ pxenv_null_entry:
.section ".text16", "ax", @progbits
.code16
pxenv_entry:
- pushl $pxe_api_call
- call prot_call
+ virtcall pxe_api_call
lret
.size pxenv_entry, . - pxenv_entry
diff --git a/src/arch/x86/prefix/dskprefix.S b/src/arch/x86/prefix/dskprefix.S
index 041ec4c4..0503f113 100644
--- a/src/arch/x86/prefix/dskprefix.S
+++ b/src/arch/x86/prefix/dskprefix.S
@@ -18,6 +18,8 @@
FILE_LICENCE ( GPL2_ONLY )
+#include <librm.h>
+
.equ BOOTSEG, 0x07C0 /* original address of boot-sector */
.equ SYSSEG, 0x1000 /* system loaded at SYSSEG<<4 */
@@ -370,8 +372,8 @@ start_runtime:
lret
.section ".text16", "awx", @progbits
1:
- pushl $main
- call prot_call
+ /* Run iPXE */
+ virtcall main
/* Uninstall iPXE */
call uninstall
diff --git a/src/arch/x86/prefix/exeprefix.S b/src/arch/x86/prefix/exeprefix.S
index 9598122b..c351456e 100644
--- a/src/arch/x86/prefix/exeprefix.S
+++ b/src/arch/x86/prefix/exeprefix.S
@@ -24,6 +24,8 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
+#include <librm.h>
+
/* Initial temporary stack size */
#define EXE_STACK_SIZE 0x400
@@ -148,8 +150,7 @@ _exe_start:
movl %esi, cmdline_phys
/* Run iPXE */
- pushl $main
- call prot_call
+ virtcall main
/* Uninstall iPXE */
call uninstall
diff --git a/src/arch/x86/prefix/hdprefix.S b/src/arch/x86/prefix/hdprefix.S
index 6caf12fc..24f5d385 100644
--- a/src/arch/x86/prefix/hdprefix.S
+++ b/src/arch/x86/prefix/hdprefix.S
@@ -1,5 +1,7 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
+#include <librm.h>
+
.text
.arch i386
.section ".prefix", "awx", @progbits
@@ -99,8 +101,8 @@ start_image:
lret
.section ".text16", "awx", @progbits
1:
- pushl $main
- call prot_call
+ /* Run iPXE */
+ virtcall main
/* Uninstall iPXE */
call uninstall
diff --git a/src/arch/x86/prefix/libprefix.S b/src/arch/x86/prefix/libprefix.S
index 7eb1e501..425f5148 100644
--- a/src/arch/x86/prefix/libprefix.S
+++ b/src/arch/x86/prefix/libprefix.S
@@ -24,6 +24,8 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
+#include <librm.h>
+
.arch i386
/* Image compression enabled */
@@ -887,8 +889,7 @@ payload_death_message:
* ready for the copy to the new location.
*/
progress " relocate\n"
- pushl $relocate
- call prot_call
+ virtcall relocate
/* Jump back to .prefix segment */
pushw $1f
diff --git a/src/arch/x86/prefix/lkrnprefix.S b/src/arch/x86/prefix/lkrnprefix.S
index 41a5b467..922181f0 100644
--- a/src/arch/x86/prefix/lkrnprefix.S
+++ b/src/arch/x86/prefix/lkrnprefix.S
@@ -1,5 +1,7 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
+#include <librm.h>
+
#define BZI_LOAD_HIGH_ADDR 0x100000
.text
@@ -197,8 +199,7 @@ no_cmd_line:
movl %ecx, initrd_len
/* Run iPXE */
- pushl $main
- call prot_call
+ virtcall main
/* Uninstall iPXE */
call uninstall
diff --git a/src/arch/x86/prefix/nbiprefix.S b/src/arch/x86/prefix/nbiprefix.S
index c25c254e..de38e4af 100644
--- a/src/arch/x86/prefix/nbiprefix.S
+++ b/src/arch/x86/prefix/nbiprefix.S
@@ -1,5 +1,7 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
+#include <librm.h>
+
.text
.arch i386
.code16
@@ -66,8 +68,8 @@ _nbi_start:
lret
.section ".text16", "awx", @progbits
1:
- pushl $main
- call prot_call
+ /* Run iPXE */
+ virtcall main
/* Uninstall iPXE */
call uninstall
diff --git a/src/arch/x86/prefix/pxeprefix.S b/src/arch/x86/prefix/pxeprefix.S
index 2c6d7abb..52ea1803 100644
--- a/src/arch/x86/prefix/pxeprefix.S
+++ b/src/arch/x86/prefix/pxeprefix.S
@@ -16,6 +16,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
.org 0
.code16
+#include <librm.h>
#include <undi.h>
#define STACK_MAGIC ( 'L' + ( 'R' << 8 ) + ( 'E' << 16 ) + ( 'T' << 24 ) )
@@ -820,8 +821,7 @@ run_ipxe:
movl %ecx, cached_dhcpack_phys
/* Run main program */
- pushl $main
- call prot_call
+ virtcall main
/* Uninstall iPXE */
call uninstall
diff --git a/src/arch/x86/prefix/romprefix.S b/src/arch/x86/prefix/romprefix.S
index 941e2ce6..f4ca2067 100644
--- a/src/arch/x86/prefix/romprefix.S
+++ b/src/arch/x86/prefix/romprefix.S
@@ -8,6 +8,7 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
+#include <librm.h>
#include <config/general.h>
#include <config/branding.h>
@@ -806,9 +807,8 @@ exec: /* Set %ds = %cs */
#endif /* AUTOBOOT_ROM_FILTER */
.endif
- /* Call main() */
- pushl $main
- call prot_call
+ /* Run iPXE */
+ virtcall main
/* Set up flat real mode for return to BIOS */
call flatten_real_mode
diff --git a/src/arch/x86/prefix/undiloader.S b/src/arch/x86/prefix/undiloader.S
index fb42637c..530b48e8 100644
--- a/src/arch/x86/prefix/undiloader.S
+++ b/src/arch/x86/prefix/undiloader.S
@@ -1,5 +1,7 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
+#include <librm.h>
+
.text
.code16
.arch i386
@@ -45,8 +47,7 @@ undiloader:
.section ".text16", "ax", @progbits
1:
/* Call UNDI loader C code */
- pushl $pxe_loader_call
- call prot_call
+ virtcall pxe_loader_call
1: /* Restore registers and return */
popw %bx
diff --git a/src/arch/x86/transitions/librm.S b/src/arch/x86/transitions/librm.S
index 46c1ab97..49a30851 100644
--- a/src/arch/x86/transitions/librm.S
+++ b/src/arch/x86/transitions/librm.S
@@ -131,8 +131,7 @@ init_librm:
addl $gdt, gdt_base
/* Initialise IDT */
- pushl $init_idt
- call prot_call
+ virtcall init_idt
/* Restore registers */
negl %edi
@@ -554,8 +553,7 @@ flatten_real_mode:
movb $0x8f, real_cs + 6
movb $0x8f, real_ds + 6
/* Call dummy protected-mode function */
- pushl $flatten_dummy
- call prot_call
+ virtcall flatten_dummy
/* Restore GDT */
movb $0x00, real_cs + 6
movb $0x00, real_ds + 6
diff --git a/src/arch/x86/transitions/librm_test.c b/src/arch/x86/transitions/librm_test.c
index fc318ec7..3f9ead21 100644
--- a/src/arch/x86/transitions/librm_test.c
+++ b/src/arch/x86/transitions/librm_test.c
@@ -56,9 +56,9 @@ static struct profiler real_call_profiler __profiler = { .name = "real_call" };
static struct profiler prot_call_profiler __profiler = { .name = "prot_call" };
/**
- * Dummy protected-mode function
+ * Dummy function for profiling tests
*/
-static void librm_test_prot_call ( void ) {
+static __asmcall void librm_test_call ( struct i386_all_regs *ix86 __unused ) {
/* Do nothing */
}
@@ -97,7 +97,7 @@ static void librm_test_exec ( void ) {
/* Profile complete real-mode call cycle */
for ( i = 0 ; i < PROFILE_COUNT ; i++ ) {
profile_start ( &real_call_profiler );
- __asm__ __volatile__ ( REAL_CODE ( "" ) : : );
+ __asm__ __volatile__ ( REAL_CODE ( "" ) );
profile_stop ( &real_call_profiler );
}
@@ -105,12 +105,10 @@ static void librm_test_exec ( void ) {
for ( i = 0 ; i < PROFILE_COUNT ; i++ ) {
__asm__ __volatile__ ( REAL_CODE ( "rdtsc\n\t"
"movl %k0, %k2\n\t"
- "pushl %k3\n\t"
- "call prot_call\n\t"
+ VIRT_CALL ( librm_test_call )
"rdtsc\n\t" )
: "=a" ( stopped ), "=d" ( discard_d ),
- "=R" ( started )
- : "i" ( librm_test_prot_call ) );
+ "=R" ( started ) : );
profile_start_at ( &prot_call_profiler, started );
profile_stop_at ( &prot_call_profiler, stopped );
}
diff --git a/src/arch/x86_64/include/bits/compiler.h b/src/arch/x86_64/include/bits/compiler.h
index f70b2e51..98c560e7 100644
--- a/src/arch/x86_64/include/bits/compiler.h
+++ b/src/arch/x86_64/include/bits/compiler.h
@@ -7,7 +7,7 @@
#ifndef ASSEMBLY
/** Declare a function with standard calling conventions */
-#define __asmcall __attribute__ (( regparm(0) ))
+#define __asmcall __attribute__ (( used, regparm(0) ))
/** Declare a function with libgcc implicit linkage */
#define __libgcc