[SeaBIOS] [PATCH 2/4] Create assembler macros for saving and restoring 'struct bregs'

Kevin O'Connor kevin at koconnor.net
Tue Oct 21 20:53:43 CEST 2014


Create macros SAVEBREGS_POP_DSEAX and RESTOREBREGS_DSEAX for saving
and restoring the cpu state.  These are similar to the existing
PUSHBREGS and POPBREGS macros.

This also fixes a bug in __farcall16 which inadvertently restored %ds
in %es and vice-versa.

Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
 src/entryfuncs.S  | 44 ++++++++++++++++++++++++++++++++++++++++----
 src/romlayout.S   | 49 +++++--------------------------------------------
 vgasrc/vgaentry.S | 22 ++--------------------
 3 files changed, 47 insertions(+), 68 deletions(-)

diff --git a/src/entryfuncs.S b/src/entryfuncs.S
index 8438604..4e6151e 100644
--- a/src/entryfuncs.S
+++ b/src/entryfuncs.S
@@ -1,16 +1,17 @@
 // Macros for entering C code
 //
-// Copyright (C) 2008,2009  Kevin O'Connor <kevin at koconnor.net>
+// Copyright (C) 2008-2014  Kevin O'Connor <kevin at koconnor.net>
 //
 // This file may be distributed under the terms of the GNU LGPLv3 license.
 
 
 /****************************************************************
- * Entry macros
+ * Macros for save and restore of 'struct bregs' registers
  ****************************************************************/
 
+        // Save registers (matches struct bregs) to stack
         .macro PUSHBREGS
-        pushl %eax              // Save registers (matches struct bregs)
+        pushl %eax
         pushl %ecx
         pushl %edx
         pushl %ebx
@@ -21,8 +22,9 @@
         pushw %ds
         .endm
 
+        // Restore registers (from struct bregs) from stack
         .macro POPBREGS
-        popw %ds                // Restore registers (from struct bregs)
+        popw %ds
         popw %es
         popl %edi
         popl %esi
@@ -33,6 +35,40 @@
         popl %eax
         .endm
 
+        // Save registers to struct bregs at %ds:%eax.  The caller
+        // should "pushw %ds ; pushl %eax" prior to calling - this macro
+        // will pop them off.
+        .macro SAVEBREGS_POP_DSEAX
+        popl BREGS_eax(%eax)
+        popw 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_es(%eax)
+        .endm
+
+        // Restore registers from struct bregs at %ds:%eax
+        .macro RESTOREBREGS_DSEAX
+        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
+        .endm
+
+
+/****************************************************************
+ * Entry macros
+ ****************************************************************/
+
         // Call a C function - this does the minimal work necessary to
         // call into C.  It sets up %ds, backs up %es, and backs up
         // those registers that are call clobbered by the C compiler.
diff --git a/src/romlayout.S b/src/romlayout.S
index 4ebbdee..a623138 100644
--- a/src/romlayout.S
+++ b/src/romlayout.S
@@ -151,19 +151,8 @@ __farcall16:
         pushw BREGS_flags(%eax)         // flags
         pushl BREGS_code(%eax)          // CS:IP
 
-        // Load calling registers.
-        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
+        // Load calling registers and invoke call
+        RESTOREBREGS_DSEAX
         iretw                           // XXX - just do a lcalll
 1:
         // Store flags, es, eax
@@ -174,18 +163,8 @@ __farcall16:
         pushl %eax
         movw 0x08(%esp), %ds
         movl 0x0c(%esp), %eax
-        popl BREGS_eax(%eax)
-        popw BREGS_es(%eax)
+        SAVEBREGS_POP_DSEAX
         popw BREGS_flags(%eax)
-
-        // Store remaining registers
-        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
 
@@ -508,16 +487,8 @@ irqentry_arg_extrastack:
         movl %eax, %ds
         movl StackPos, %eax
         subl $BREGS_size+8, %eax
-        popl BREGS_eax(%eax)    // Backup registers
-        popw 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)
+        SAVEBREGS_POP_DSEAX     // Save registers on extra stack
         popl %ecx
-        movw %es, BREGS_es(%eax)
         movl %esp, BREGS_size+0(%eax)
         movw %ss, BREGS_size+4(%eax)
         popl BREGS_code(%eax)
@@ -535,17 +506,7 @@ irqentry_arg_extrastack:
         popw %dx
         pushw BREGS_flags(%eax)
         pushl BREGS_code(%eax)
-        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
-        pushw BREGS_ds(%eax)
-        pushl BREGS_eax(%eax)
-        popl %eax
-        popw %ds
+        RESTOREBREGS_DSEAX
         iretw
 
         // Main entry point for interrupts with args
diff --git a/vgasrc/vgaentry.S b/vgasrc/vgaentry.S
index 3c2c885..5d45380 100644
--- a/vgasrc/vgaentry.S
+++ b/vgasrc/vgaentry.S
@@ -113,15 +113,7 @@ entry_10_extrastack:
         pushl %eax
         movw %cs:ExtraStackSeg, %ds
         movl $(CONFIG_VGA_EXTRA_STACK_SIZE-BREGS_size-8), %eax
-        popl BREGS_eax(%eax)    // Backup registers
-        popw 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_es(%eax)
+        SAVEBREGS_POP_DSEAX     // Save registers on extra stack
         movl %esp, BREGS_size+0(%eax)
         movw %ss, BREGS_size+4(%eax)
         popl BREGS_code(%eax)
@@ -139,15 +131,5 @@ entry_10_extrastack:
         popw %dx
         pushw BREGS_flags(%eax)
         pushl BREGS_code(%eax)
-        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
-        pushw BREGS_ds(%eax)
-        pushl BREGS_eax(%eax)
-        popl %eax
-        popw %ds
+        RESTOREBREGS_DSEAX
         iretw
-- 
1.9.3




More information about the SeaBIOS mailing list