aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2009-02-27 20:14:05 -0500
committerKevin O'Connor <kevin@koconnor.net>2009-02-27 20:14:05 -0500
commit9caf78634dd5e95611e222b047e60957fd2a22ce (patch)
treea8d903c0d1b142dc5877aa1ed6c0eaeed0d3b328 /src
parent1eba429e3988b84fe1b095defdbeac37a480c25f (diff)
downloadseabios-hppa-9caf78634dd5e95611e222b047e60957fd2a22ce.zip
seabios-hppa-9caf78634dd5e95611e222b047e60957fd2a22ce.tar.gz
seabios-hppa-9caf78634dd5e95611e222b047e60957fd2a22ce.tar.bz2
Save/restore %ebp in __call16 instead of in caller (call16).
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.
Diffstat (limited to 'src')
-rw-r--r--src/romlayout.S17
-rw-r--r--src/util.c4
2 files changed, 13 insertions, 8 deletions
diff --git a/src/romlayout.S b/src/romlayout.S
index 96aa836..319d7b4 100644
--- a/src/romlayout.S
+++ b/src/romlayout.S
@@ -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 :
diff --git a/src/util.c b/src/util.c
index 2c925fe..7358040 100644
--- a/src/util.c
+++ b/src/util.c
@@ -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