Save/restore %ebp in __call16 instead of in caller (call16).
authorKevin O'Connor <kevin@koconnor.net>
Sat, 28 Feb 2009 01:14:05 +0000 (20:14 -0500)
committerKevin O'Connor <kevin@koconnor.net>
Sat, 28 Feb 2009 01:14:05 +0000 (20:14 -0500)
The Ubuntu gcc compiler apparently miscompiles code when %ebp is in an
    assembler clobber list.
Also, don't clobber %eax in transition32 - a minor cleanup.

src/romlayout.S
src/util.c

index 96aa836c9c5cd326041dd3ba7f2555204f0d02af..319d7b44f8c277050e71ced2b2b4a854c1f38ba1 100644 (file)
@@ -174,9 +174,11 @@ entry_post:
  ****************************************************************/
 
 // Place CPU into 32bit mode from 16bit mode.
-// Clobbers: %eax, flags, stack registers, cr0, idt/gdt
+// Clobbers: flags, segment registers, cr0, idt/gdt
         DECLFUNC transition32
 transition32:
+        pushl %eax
+
         // Disable irqs
         cli
 
@@ -207,11 +209,12 @@ transition32:
         movw %ax, %fs
         movw %ax, %gs
 
+        popl %eax
         retl
 
 // Call a 16bit function from 32bit mode.
 // %eax = address of struct bregs
-// Clobbers: all gp registers, flags, stack registers, cr0, idt/gdt
+// Clobbers: %e[bcd]x, %e[ds]i, flags, segment registers, idt/gdt
         DECLFUNC __call16_from32
         .global __call16big_from32
 __call16_from32:
@@ -278,10 +281,11 @@ __call16big_from32:
 
 // Call a 16bit function from 16bit mode with a specified cpu register state
 // %eax = address of struct bregs
-// Clobbers: all gp registers, es
+// Clobbers: %e[bcd]x, %e[ds]i, flags
         DECLFUNC __call16
 __call16:
-        // Save eax
+        // Save %eax, %ebp
+        pushl %ebp
         pushl %eax
 
         // Setup for iretw call
@@ -323,8 +327,9 @@ __call16:
         movl %ebx, BREGS_ebx(%eax)
         movl %edx, BREGS_edx(%eax)
 
-        // Remove %eax
+        // Remove %eax, restore %ebp
         popl %eax
+        popl %ebp
 
         cld
 
@@ -403,7 +408,7 @@ post32:
 
         .code16gcc
 
-        // IRQ trampolines
+// IRQ trampolines
         .macro IRQ_TRAMPOLINE num
         DECLFUNC irq_trampoline_0x\num
         irq_trampoline_0x\num :
index 2c925fed1c51eab2181cb2f1fdf13a52af50e003..7358040ed322560f0f7e1c31a16a29d0a6976552 100644 (file)
@@ -22,7 +22,7 @@ call16(struct bregs *callregs)
 #endif
         : "+a" (callregs), "+m" (*callregs)
         :
-        : "ebx", "ecx", "edx", "esi", "edi", "ebp", "cc", "memory");
+        : "ebx", "ecx", "edx", "esi", "edi", "cc", "memory");
 }
 
 inline void
@@ -36,7 +36,7 @@ call16big(struct bregs *callregs)
         "calll __call16big_from32\n"
         : "+a" (callregs), "+m" (*callregs)
         :
-        : "ebx", "ecx", "edx", "esi", "edi", "ebp", "cc", "memory");
+        : "ebx", "ecx", "edx", "esi", "edi", "cc", "memory");
 }
 
 inline void