aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2013-09-29 20:21:40 -0400
committerKevin O'Connor <kevin@koconnor.net>2013-10-14 21:37:56 -0400
commit2d9775628dc56fbf2e7d649eac940016336a5d19 (patch)
tree43ea373d7a62a8d8791d9a4603fcb2af89e99b8c
parent9e75b08bd476aaa6abbd0bfdd7c5cf5a682148e5 (diff)
downloadseabios-2d9775628dc56fbf2e7d649eac940016336a5d19.tar.gz
Update _farcall16() to pass segment of callregs explicitly.
Don't use implicit passing of %es for the segment of the callregs pointer. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
-rw-r--r--src/romlayout.S59
-rw-r--r--src/stacks.c13
2 files changed, 36 insertions, 36 deletions
diff --git a/src/romlayout.S b/src/romlayout.S
index 652992fd..8415c9f4 100644
--- a/src/romlayout.S
+++ b/src/romlayout.S
@@ -161,32 +161,33 @@ __call16big:
****************************************************************/
// Far call a 16bit function from 16bit mode with a specified cpu register state
-// %es:%eax = address of struct bregs
-// Clobbers: %e[bcd]x, %e[ds]i, flags
+// %eax = address of struct bregs, %edx = segment of struct bregs
+// Clobbers: %e[bc]x, %e[ds]i, flags
.code16gcc
DECLFUNC __farcall16
__farcall16:
- // Save %eax, %ebp
+ // Save %edx/%eax, %ebp
pushl %ebp
pushl %eax
- pushl %es
+ pushl %edx
// Setup for iretw call
+ movl %edx, %ds
pushw %cs
pushw $1f // return point
- pushw %es:BREGS_flags(%eax) // flags
- pushl %es:BREGS_code(%eax) // CS:IP
+ pushw BREGS_flags(%eax) // flags
+ pushl BREGS_code(%eax) // CS:IP
// Load calling registers.
- movl %es:BREGS_edi(%eax), %edi
- movl %es:BREGS_esi(%eax), %esi
- movl %es:BREGS_ebp(%eax), %ebp
- movl %es:BREGS_ebx(%eax), %ebx
- movl %es:BREGS_edx(%eax), %edx
- movl %es:BREGS_ecx(%eax), %ecx
- movw %es:BREGS_ds(%eax), %ds
- pushl %es:BREGS_eax(%eax)
- movw %es:BREGS_es(%eax), %es
+ 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
@@ -196,27 +197,27 @@ __farcall16:
pushfw
cli
cld
- pushw %es
+ pushw %ds
pushl %eax
- movw 0x08(%esp), %es
+ movw 0x08(%esp), %ds
movl 0x0c(%esp), %eax
- popl %es:BREGS_eax(%eax)
- popw %es:BREGS_es(%eax)
- popw %es:BREGS_flags(%eax)
+ popl BREGS_eax(%eax)
+ popw BREGS_es(%eax)
+ popw BREGS_flags(%eax)
// Store remaining registers
- movl %edi, %es:BREGS_edi(%eax)
- movl %esi, %es:BREGS_esi(%eax)
- movl %ebp, %es:BREGS_ebp(%eax)
- movl %ebx, %es:BREGS_ebx(%eax)
- movl %edx, %es:BREGS_edx(%eax)
- movl %ecx, %es:BREGS_ecx(%eax)
- movw %ds, %es: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_ds(%eax)
movw %ss, %cx
movw %cx, %ds // Restore %ds == %ss
- // Remove %es/%eax, restore %ebp
- popl %eax
+ // Remove %edx/%eax, restore %ebp
+ popl %edx
popl %eax
popl %ebp
diff --git a/src/stacks.c b/src/stacks.c
index ad615d2c..563ce1c3 100644
--- a/src/stacks.c
+++ b/src/stacks.c
@@ -192,26 +192,25 @@ call16big(u32 eax, u32 edx, void *func)
// Far call 16bit code with a specified register state.
void VISIBLE16
-_farcall16(struct bregs *callregs)
+_farcall16(struct bregs *callregs, u16 callregseg)
{
ASSERT16();
if (on_extra_stack()) {
- stack_hop_back((u32)callregs, 0, _farcall16);
+ stack_hop_back((u32)callregs, callregseg, _farcall16);
return;
}
asm volatile(
"calll __farcall16\n"
- : "+a" (callregs), "+m" (*callregs)
- : "m" (__segment_ES)
- : "ebx", "ecx", "edx", "esi", "edi", "cc", "memory");
+ : "+a" (callregs), "+m" (*callregs), "+d" (callregseg)
+ :
+ : "ebx", "ecx", "esi", "edi", "cc", "memory");
}
inline void
farcall16(struct bregs *callregs)
{
if (MODE16) {
- SET_SEG(ES, GET_SEG(SS));
- _farcall16(callregs);
+ _farcall16(callregs, GET_SEG(SS));
return;
}
extern void _cfunc16__farcall16(void);