[SeaBIOS] [PATCH 3/5] Unify inline assembler in variants of call16 functions

Kevin O'Connor kevin at koconnor.net
Mon Sep 14 14:26:24 CET 2015


The assembler between call16(), call16big() and call16_sloppy() are
very similar.  Rework the functions so that a single version of the
inline assembly can be used for all variants.

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

diff --git a/src/romlayout.S b/src/romlayout.S
index d78737b..e223cdc 100644
--- a/src/romlayout.S
+++ b/src/romlayout.S
@@ -71,15 +71,6 @@ transition32_nmi_off:
         .global transition16big
         .code32
 transition16:
-#if CONFIG_DISABLE_A20
-        // disable a20
-        movl %eax, %ecx
-        inb $PORT_A20, %al
-        andb $~A20_ENABLE_BIT, %al
-        outb %al, $PORT_A20
-        movl %ecx, %eax
-#endif
-
         // Reset data segment limits
         movl $SEG32_MODE16_DS, %ecx
         movw %cx, %ds
diff --git a/src/stacks.c b/src/stacks.c
index 7c6ccd2..f92a484 100644
--- a/src/stacks.c
+++ b/src/stacks.c
@@ -13,6 +13,7 @@
 #include "output.h" // dprintf
 #include "romfile.h" // romfile_loadint
 #include "stacks.h" // struct mutex_s
+#include "string.h" // memset
 #include "util.h" // useRTC
 
 #define MAIN_STACK_MAX (1024*1024)
@@ -30,8 +31,8 @@ struct {
     struct descloc_s gdt;
 } Call16Data VARLOW;
 
-#define C16_SLOPPY 1
-#define C16_SMM    2
+#define C16_BIG 1
+#define C16_SMM 2
 
 int HaveSmmCall32 VARFSEG;
 
@@ -91,7 +92,7 @@ call32_post(void)
     return method;
 }
 
-// 16bit handler code called from call16_sloppy() / call16_smm()
+// 16bit handler code called from call16_back() / call16_smm()
 u32 VISIBLE16
 call16_helper(u32 eax, u32 edx, u32 (*func)(u32 eax, u32 edx))
 {
@@ -202,7 +203,7 @@ static u32
 call32_sloppy(void *func, u32 eax)
 {
     ASSERT16();
-    call32_prep(C16_SLOPPY);
+    call32_prep(C16_BIG);
     u32 bkup_ss, bkup_esp;
     asm volatile(
         // Backup ss/esp / set esp to flat stack location
@@ -232,37 +233,45 @@ call32_sloppy(void *func, u32 eax)
     return eax;
 }
 
-// Jump back to 16bit mode while in 32bit mode from call32_sloppy()
+// Call a 16bit SeaBIOS function, restoring the mode from last call32().
 static u32
-call16_sloppy(u32 eax, u32 edx, void *func)
+call16_back(u32 eax, u32 edx, void *func)
 {
     ASSERT32FLAT();
     if (getesp() > MAIN_STACK_MAX)
-        panic("call16_sloppy with invalid stack\n");
+        panic("call16_back with invalid stack\n");
+    if (CONFIG_CALL32_SMM && Call16Data.method == C16_SMM)
+        return call16_smm(eax, edx, func);
+
+    extern void transition16big(void);
+    extern void transition16(void);
+    void *thunk = transition16;
+    if (Call16Data.method == C16_BIG || in_post())
+        thunk = transition16big;
     func -= BUILD_BIOS_ADDR;
     u32 stackseg = Call16Data.ss;
     asm volatile(
         // Transition to 16bit mode
         "  movl $(1f - " __stringify(BUILD_BIOS_ADDR) "), %%edx\n"
-        "  jmp transition16big\n"
+        "  jmp *%%ecx\n"
         // Setup ss/esp and call func
         ASM32_SWITCH16
-        "1:movl %3, %%ecx\n"
-        "  shll $4, %3\n"
+        "1:movl %2, %%ecx\n"
+        "  shll $4, %2\n"
         "  movw %%cx, %%ss\n"
-        "  subl %3, %%esp\n"
+        "  subl %2, %%esp\n"
         "  movw %%cx, %%ds\n"
-        "  movl %2, %%edx\n"
-        "  movl %1, %%ecx\n"
+        "  movl %4, %%edx\n"
+        "  movl %3, %%ecx\n"
         "  calll _cfunc16_call16_helper\n"
         // Return to 32bit and restore esp
         "  movl $2f, %%edx\n"
         "  jmp transition32\n"
         ASM32_BACK32
-        "2:addl %3, %%esp\n"
-        : "+a" (eax)
-        : "r" (func), "r" (edx), "r" (stackseg)
-        : "edx", "ecx", "cc", "memory");
+        "2:addl %2, %%esp\n"
+        : "+a" (eax), "+c"(thunk), "+r"(stackseg)
+        : "r" (func), "r" (edx)
+        : "edx", "cc", "memory");
     return eax;
 }
 
@@ -280,31 +289,16 @@ call32(void *func, u32 eax, u32 errret)
     return call32_sloppy(func, eax);
 }
 
-// Call a 16bit SeaBIOS function from a 32bit SeaBIOS function.
+// Call a 16bit SeaBIOS function in regular ("non-big") mode.
 static u32
 call16(u32 eax, u32 edx, void *func)
 {
     ASSERT32FLAT();
     if (getesp() > BUILD_STACK_ADDR)
         panic("call16 with invalid stack\n");
-    func -= BUILD_BIOS_ADDR;
-    asm volatile(
-        // Transition to 16bit mode
-        "  movl $(1f - " __stringify(BUILD_BIOS_ADDR) "), %%edx\n"
-        "  jmp transition16\n"
-        // Call func
-        ASM32_SWITCH16
-        "1:movl %2, %%edx\n"
-        "  calll *%1\n"
-        // Return to 32bit
-        "  movl $2f, %%edx\n"
-        "  jmp transition32\n"
-        ASM32_BACK32
-        "2:\n"
-        : "+a" (eax)
-        : "r" (func), "r" (edx)
-        : "edx", "ecx", "cc", "memory");
-    return eax;
+    memset(&Call16Data, 0, sizeof(Call16Data));
+    Call16Data.a20 = !CONFIG_DISABLE_A20;
+    return call16_back(eax, edx, func);
 }
 
 // Call a 16bit SeaBIOS function in "big real" mode.
@@ -314,38 +308,10 @@ call16big(u32 eax, u32 edx, void *func)
     ASSERT32FLAT();
     if (getesp() > BUILD_STACK_ADDR)
         panic("call16big with invalid stack\n");
-    func -= BUILD_BIOS_ADDR;
-    asm volatile(
-        // Transition to 16bit mode
-        "  movl $(1f - " __stringify(BUILD_BIOS_ADDR) "), %%edx\n"
-        "  jmp transition16big\n"
-        // Call func
-        ASM32_SWITCH16
-        "1:movl %2, %%edx\n"
-        "  calll *%1\n"
-        // Return to 32bit
-        "  movl $2f, %%edx\n"
-        "  jmp transition32\n"
-        ASM32_BACK32
-        "2:\n"
-        : "+a" (eax)
-        : "r" (func), "r" (edx)
-        : "edx", "ecx", "cc", "memory");
-    return eax;
-}
-
-// Call a 16bit SeaBIOS function, restoring the mode from last call32().
-static u32
-call16_back(u32 eax, u32 edx, void *func)
-{
-    ASSERT32FLAT();
-    if (CONFIG_CALL32_SMM && Call16Data.method == C16_SMM)
-        return call16_smm(eax, edx, func);
-    if (Call16Data.method == C16_SLOPPY)
-        return call16_sloppy(eax, edx, func);
-    if (in_post())
-        return call16big(eax, edx, func);
-    return call16(eax, edx, func);
+    memset(&Call16Data, 0, sizeof(Call16Data));
+    Call16Data.method = C16_BIG;
+    Call16Data.a20 = 1;
+    return call16_back(eax, edx, func);
 }
 
 
-- 
2.4.3




More information about the SeaBIOS mailing list