diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2009-02-27 20:14:05 -0500 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2009-02-27 20:14:05 -0500 |
commit | 9caf78634dd5e95611e222b047e60957fd2a22ce (patch) | |
tree | a8d903c0d1b142dc5877aa1ed6c0eaeed0d3b328 /src | |
parent | 1eba429e3988b84fe1b095defdbeac37a480c25f (diff) | |
download | seabios-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.S | 17 | ||||
-rw-r--r-- | src/util.c | 4 |
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 : @@ -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 |