]> xenbits.xensource.com Git - seabios.git/commitdiff
Use an aligned stack offset when entering on the extra stack
authorKevin O'Connor <kevin@koconnor.net>
Wed, 5 Nov 2014 14:05:36 +0000 (09:05 -0500)
committerKevin O'Connor <kevin@koconnor.net>
Wed, 12 Nov 2014 17:17:57 +0000 (12:17 -0500)
The size of 'struct bregs' is not evenly divisible by four and where
the assembler placed a 'struct bregs' on the extra stack as part of
entering into the C functions it caused the C functions to run with a
non-aligned stack.  It's technically not correct to use an unaligned
stack and it is certainly less efficient.

This patch avoids using BREGS_size (the sizeof struct bregs) and
instead introduces PUSHBREGS_size (the size of the general purpose
registers in struct bregs) in the assembler.  Where the code actually
did use the %cs:%ip and flags, an extra 8 (instead of 6) bytes are
added to maintain a sane alignment.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
src/asm-offsets.c
src/entryfuncs.S
src/romlayout.S
vgasrc/vgaentry.S

index 576bf343f7f0e94a5d7da4a4b79fb3ba076e36f2..b98f3b5a87c510ac46f16fdd2bdd13e731ad5ac9 100644 (file)
@@ -20,5 +20,4 @@ void foo(void)
     OFFSET(BREGS_edi, bregs, edi);
     OFFSET(BREGS_flags, bregs, flags);
     OFFSET(BREGS_code, bregs, code);
-    DEFINE(BREGS_size, sizeof(struct bregs));
 }
index cc1f433245954b348a451ffc657461228a233d67..7368bb6d56abdff66c9424de7924f22d2eefd2ce 100644 (file)
@@ -9,6 +9,8 @@
  * Macros for save and restore of 'struct bregs' registers
  ****************************************************************/
 
+#define PUSHBREGS_size 32
+
         // Save registers (matches struct bregs) to stack
         .macro PUSHBREGS
         pushl %eax
index 7a5df0e9448c1f9e2ffad890c3fbddc390df1bc2..c1751e1da4246020d0cede9f85e002b6fb91696d 100644 (file)
@@ -257,7 +257,7 @@ entry_pmm:
         movw %cx, %ds
         shll $4, %ecx
         movl $_cfunc32flat_handle_pmm, %eax // Setup: call32(handle_pmm, args, -1)
-        leal BREGS_size-6+12(%esp, %ecx), %edx // %edx points to start of args
+        leal PUSHBREGS_size+12(%esp, %ecx), %edx // %edx points to start of args
         movl $-1, %ecx
         calll call32
         movw %ax, BREGS_eax(%esp)       // Modify %ax:%dx to return %eax
@@ -284,7 +284,7 @@ entry_pnp_real:
         PUSHBREGS
         movw %ss, %cx           // Move %ss to %ds
         movw %cx, %ds
-        leal BREGS_size-6+12(%esp), %eax  // %eax points to start of u16 args
+        leal PUSHBREGS_size+12(%esp), %eax  // %eax points to start of u16 args
         calll handle_pnp
         movw %ax, BREGS_eax(%esp)   // Modify %eax to return %ax
         POPBREGS
@@ -433,11 +433,11 @@ irqentry_extrastack:
         movl $_zonelow_seg, %eax
         movl %eax, %ds
         movl StackPos, %eax
-        subl $BREGS_size+8, %eax
+        subl $PUSHBREGS_size+8, %eax
         SAVEBREGS_POP_DSEAX
         popl %ecx
-        movl %esp, BREGS_size(%eax)
-        movw %ss, BREGS_size+4(%eax)
+        movl %esp, PUSHBREGS_size(%eax)
+        movw %ss, PUSHBREGS_size+4(%eax)
 
         movw %ds, %dx           // Setup %ss/%esp and call function
         movw %dx, %ss
@@ -445,8 +445,8 @@ irqentry_extrastack:
         calll *%ecx
 
         movl %esp, %eax         // Restore registers and return
-        movw BREGS_size+4(%eax), %ss
-        movl BREGS_size(%eax), %esp
+        movw PUSHBREGS_size+4(%eax), %ss
+        movl PUSHBREGS_size(%eax), %esp
         RESTOREBREGS_DSEAX
         iretw
 
@@ -460,11 +460,11 @@ irqentry_arg_extrastack:
         movl $_zonelow_seg, %eax
         movl %eax, %ds
         movl StackPos, %eax
-        subl $BREGS_size+8, %eax
+        subl $PUSHBREGS_size+16, %eax
         SAVEBREGS_POP_DSEAX     // Save registers on extra stack
         popl %ecx
-        movl %esp, BREGS_size+0(%eax)
-        movw %ss, BREGS_size+4(%eax)
+        movl %esp, PUSHBREGS_size+8(%eax)
+        movw %ss, PUSHBREGS_size+12(%eax)
         popl BREGS_code(%eax)
         popw BREGS_flags(%eax)
 
@@ -474,8 +474,8 @@ irqentry_arg_extrastack:
         calll *%ecx
 
         movl %esp, %eax         // Restore registers and return
-        movw BREGS_size+4(%eax), %ss
-        movl BREGS_size+0(%eax), %esp
+        movw PUSHBREGS_size+12(%eax), %ss
+        movl PUSHBREGS_size+8(%eax), %esp
         popl %edx
         popw %dx
         pushw BREGS_flags(%eax)
index c05502d835e2385799d14de402afd5f6afaaddb1..f9cf6568988566b883c2c3b6e5db6ab5cda48f38 100644 (file)
@@ -112,10 +112,10 @@ entry_10_extrastack:
         pushw %ds               // Set %ds:%eax to space on ExtraStack
         pushl %eax
         movw %cs:ExtraStackSeg, %ds
-        movl $(CONFIG_VGA_EXTRA_STACK_SIZE-BREGS_size-8), %eax
+        movl $(CONFIG_VGA_EXTRA_STACK_SIZE-PUSHBREGS_size-16), %eax
         SAVEBREGS_POP_DSEAX     // Save registers on extra stack
-        movl %esp, BREGS_size+0(%eax)
-        movw %ss, BREGS_size+4(%eax)
+        movl %esp, PUSHBREGS_size+8(%eax)
+        movw %ss, PUSHBREGS_size+12(%eax)
         popl BREGS_code(%eax)
         popw BREGS_flags(%eax)
 
@@ -125,8 +125,8 @@ entry_10_extrastack:
         VGA_CALLL handle_10
 
         movl %esp, %eax         // Restore registers and return
-        movw BREGS_size+4(%eax), %ss
-        movl BREGS_size+0(%eax), %esp
+        movw PUSHBREGS_size+12(%eax), %ss
+        movl PUSHBREGS_size+8(%eax), %esp
         popl %edx
         popw %dx
         pushw BREGS_flags(%eax)
@@ -148,10 +148,10 @@ entry_timer_hook_extrastack:
         pushw %ds               // Set %ds:%eax to space on ExtraStack
         pushl %eax
         movw %cs:ExtraStackSeg, %ds
-        movl $(CONFIG_VGA_EXTRA_STACK_SIZE-BREGS_size-8), %eax
+        movl $(CONFIG_VGA_EXTRA_STACK_SIZE-PUSHBREGS_size-8), %eax
         SAVEBREGS_POP_DSEAX
-        movl %esp, BREGS_size(%eax)
-        movw %ss, BREGS_size+4(%eax)
+        movl %esp, PUSHBREGS_size(%eax)
+        movw %ss, PUSHBREGS_size+4(%eax)
 
         movw %ds, %dx           // Setup %ss/%esp and call function
         movw %dx, %ss
@@ -159,7 +159,7 @@ entry_timer_hook_extrastack:
         calll handle_timer_hook
 
         movl %esp, %eax         // Restore registers and return
-        movw BREGS_size+4(%eax), %ss
-        movl BREGS_size(%eax), %esp
+        movw PUSHBREGS_size+4(%eax), %ss
+        movl PUSHBREGS_size(%eax), %esp
         RESTOREBREGS_DSEAX
         ljmpw *%cs:Timer_Hook_Resume