[SeaBIOS] [PATCH 4/6] Update _farcall16() to pass segment of callregs explicitly.

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


Don't use implicit passing of %es for the segment of the callregs pointer.

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

diff --git a/src/romlayout.S b/src/romlayout.S
index 652992f..8415c9f 100644
--- a/src/romlayout.S
+++ b/src/romlayout.S
@@ -161,32 +161,33 @@ __call16big:
  ****************************************************************/
 
 // Far call a 16bit function from 16bit mode with a specified cpu register state
-// %es:%eax = address of struct bregs
-// Clobbers: %e[bcd]x, %e[ds]i, flags
+// %eax = address of struct bregs, %edx = segment of struct bregs
+// Clobbers: %e[bc]x, %e[ds]i, flags
         .code16gcc
         DECLFUNC __farcall16
 __farcall16:
-        // Save %eax, %ebp
+        // Save %edx/%eax, %ebp
         pushl %ebp
         pushl %eax
-        pushl %es
+        pushl %edx
 
         // Setup for iretw call
+        movl %edx, %ds
         pushw %cs
         pushw $1f                       // return point
-        pushw %es:BREGS_flags(%eax)     // flags
-        pushl %es:BREGS_code(%eax)      // CS:IP
+        pushw BREGS_flags(%eax)         // flags
+        pushl BREGS_code(%eax)          // CS:IP
 
         // Load calling registers.
-        movl %es:BREGS_edi(%eax), %edi
-        movl %es:BREGS_esi(%eax), %esi
-        movl %es:BREGS_ebp(%eax), %ebp
-        movl %es:BREGS_ebx(%eax), %ebx
-        movl %es:BREGS_edx(%eax), %edx
-        movl %es:BREGS_ecx(%eax), %ecx
-        movw %es:BREGS_ds(%eax), %ds
-        pushl %es:BREGS_eax(%eax)
-        movw %es:BREGS_es(%eax), %es
+        movl BREGS_edi(%eax), %edi
+        movl BREGS_esi(%eax), %esi
+        movl BREGS_ebp(%eax), %ebp
+        movl BREGS_ebx(%eax), %ebx
+        movl BREGS_edx(%eax), %edx
+        movl BREGS_ecx(%eax), %ecx
+        movw BREGS_es(%eax), %es
+        pushl BREGS_eax(%eax)
+        movw BREGS_ds(%eax), %ds
         popl %eax
 
         // Invoke call
@@ -196,27 +197,27 @@ __farcall16:
         pushfw
         cli
         cld
-        pushw %es
+        pushw %ds
         pushl %eax
-        movw 0x08(%esp), %es
+        movw 0x08(%esp), %ds
         movl 0x0c(%esp), %eax
-        popl %es:BREGS_eax(%eax)
-        popw %es:BREGS_es(%eax)
-        popw %es:BREGS_flags(%eax)
+        popl BREGS_eax(%eax)
+        popw BREGS_es(%eax)
+        popw BREGS_flags(%eax)
 
         // Store remaining registers
-        movl %edi, %es:BREGS_edi(%eax)
-        movl %esi, %es:BREGS_esi(%eax)
-        movl %ebp, %es:BREGS_ebp(%eax)
-        movl %ebx, %es:BREGS_ebx(%eax)
-        movl %edx, %es:BREGS_edx(%eax)
-        movl %ecx, %es:BREGS_ecx(%eax)
-        movw %ds, %es:BREGS_ds(%eax)
+        movl %edi, BREGS_edi(%eax)
+        movl %esi, BREGS_esi(%eax)
+        movl %ebp, BREGS_ebp(%eax)
+        movl %ebx, BREGS_ebx(%eax)
+        movl %edx, BREGS_edx(%eax)
+        movl %ecx, BREGS_ecx(%eax)
+        movw %es, BREGS_ds(%eax)
         movw %ss, %cx
         movw %cx, %ds                   // Restore %ds == %ss
 
-        // Remove %es/%eax, restore %ebp
-        popl %eax
+        // Remove %edx/%eax, restore %ebp
+        popl %edx
         popl %eax
         popl %ebp
 
diff --git a/src/stacks.c b/src/stacks.c
index ad615d2..563ce1c 100644
--- a/src/stacks.c
+++ b/src/stacks.c
@@ -192,26 +192,25 @@ call16big(u32 eax, u32 edx, void *func)
 
 // Far call 16bit code with a specified register state.
 void VISIBLE16
-_farcall16(struct bregs *callregs)
+_farcall16(struct bregs *callregs, u16 callregseg)
 {
     ASSERT16();
     if (on_extra_stack()) {
-        stack_hop_back((u32)callregs, 0, _farcall16);
+        stack_hop_back((u32)callregs, callregseg, _farcall16);
         return;
     }
     asm volatile(
         "calll __farcall16\n"
-        : "+a" (callregs), "+m" (*callregs)
-        : "m" (__segment_ES)
-        : "ebx", "ecx", "edx", "esi", "edi", "cc", "memory");
+        : "+a" (callregs), "+m" (*callregs), "+d" (callregseg)
+        :
+        : "ebx", "ecx", "esi", "edi", "cc", "memory");
 }
 
 inline void
 farcall16(struct bregs *callregs)
 {
     if (MODE16) {
-        SET_SEG(ES, GET_SEG(SS));
-        _farcall16(callregs);
+        _farcall16(callregs, GET_SEG(SS));
         return;
     }
     extern void _cfunc16__farcall16(void);
-- 
1.8.3.1




More information about the SeaBIOS mailing list