[SeaBIOS] [PATCH 3/6] Make __call16 use C calling convention and support two passed parameters.

Kevin O'Connor kevin at koconnor.net
Thu Oct 3 03:39:34 CEST 2013


Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
 src/romlayout.S | 10 ++++++++--
 src/stacks.c    | 30 +++++++++++-------------------
 2 files changed, 19 insertions(+), 21 deletions(-)

diff --git a/src/romlayout.S b/src/romlayout.S
index 2a5ddff..652992f 100644
--- a/src/romlayout.S
+++ b/src/romlayout.S
@@ -128,21 +128,27 @@ transition16big:
         jmpl *%edx
 
 // Call a 16bit SeaBIOS function from SeaBIOS 32bit C code.
-// %ebx = calling function
+// %ecx = calling function
 // Clobbers: %ecx, %edx, flags, segment registers, idt/gdt
         DECLFUNC __call16
         .global __call16big
         .code32
 __call16:
+        pushl %edx
+        pushl %ecx
         movl $1f, %edx
         jmp transition16
 __call16big:
+        pushl %edx
+        pushl %ecx
         movl $1f, %edx
         jmp transition16big
 
         // Make call.
         .code16gcc
-1:      calll *%ebx
+1:      popl %ecx
+        popl %edx
+        calll *%ecx
         // Return via transition32
         movl $(2f + BUILD_BIOS_ADDR), %edx
         jmp transition32
diff --git a/src/stacks.c b/src/stacks.c
index 6e6a7b3..ad615d2 100644
--- a/src/stacks.c
+++ b/src/stacks.c
@@ -166,31 +166,23 @@ call32(void *func, u32 eax, u32 errret)
 
 // Call a 16bit SeaBIOS function from a 32bit SeaBIOS function.
 static inline u32
-call16(u32 eax, void *func)
+call16(u32 eax, u32 edx, void *func)
 {
     ASSERT32FLAT();
     if (getesp() > BUILD_STACK_ADDR)
         panic("call16 with invalid stack\n");
-    asm volatile(
-        "calll __call16"
-        : "+a" (eax)
-        : "b" ((u32)func - BUILD_BIOS_ADDR)
-        : "ecx", "edx", "cc", "memory");
-    return eax;
+    extern u32 __call16(u32 eax, u32 edx, void *func);
+    return __call16(eax, edx, func - BUILD_BIOS_ADDR);
 }
 
 static inline u32
-call16big(u32 eax, void *func)
+call16big(u32 eax, u32 edx, void *func)
 {
     ASSERT32FLAT();
     if (getesp() > BUILD_STACK_ADDR)
         panic("call16big with invalid stack\n");
-    asm volatile(
-        "calll __call16big"
-        : "+a" (eax)
-        : "b" ((u32)func - BUILD_BIOS_ADDR)
-        : "ecx", "edx", "cc", "memory");
-    return eax;
+    extern u32 __call16big(u32 eax, u32 edx, void *func);
+    return __call16big(eax, edx, func - BUILD_BIOS_ADDR);
 }
 
 
@@ -223,14 +215,14 @@ farcall16(struct bregs *callregs)
         return;
     }
     extern void _cfunc16__farcall16(void);
-    call16((u32)callregs, _cfunc16__farcall16);
+    call16((u32)callregs, 0, _cfunc16__farcall16);
 }
 
 inline void
 farcall16big(struct bregs *callregs)
 {
     extern void _cfunc16__farcall16(void);
-    call16big((u32)callregs, _cfunc16__farcall16);
+    call16big((u32)callregs, 0, _cfunc16__farcall16);
 }
 
 // Invoke a 16bit software interrupt.
@@ -380,13 +372,13 @@ yield(void)
     }
     extern void _cfunc16_check_irqs(void);
     if (!CONFIG_THREADS) {
-        call16big(0, _cfunc16_check_irqs);
+        call16big(0, 0, _cfunc16_check_irqs);
         return;
     }
     struct thread_info *cur = getCurThread();
     if (cur == &MainThread)
         // Permit irqs to fire
-        call16big(0, _cfunc16_check_irqs);
+        call16big(0, 0, _cfunc16_check_irqs);
 
     // Switch to the next thread
     switch_next(cur);
@@ -416,7 +408,7 @@ yield_toirq(void)
         return;
     }
     extern void _cfunc16_wait_irq(void);
-    call16big(0, _cfunc16_wait_irq);
+    call16big(0, 0, _cfunc16_wait_irq);
 }
 
 // Wait for all threads (other than the main thread) to complete.
-- 
1.8.3.1




More information about the SeaBIOS mailing list