aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2014-09-30 12:13:44 -0400
committerKevin O'Connor <kevin@koconnor.net>2014-10-11 13:41:54 -0400
commit1188480ae5e7834d668b6e922293d37ad9e7f3b9 (patch)
treeca5ffb3b2f485df06fba59c15b0b49b1ad8aa06f
parent2342129449c2191f048d4d86153940fde35719b1 (diff)
downloadseabios-1188480ae5e7834d668b6e922293d37ad9e7f3b9.zip
seabios-1188480ae5e7834d668b6e922293d37ad9e7f3b9.tar.gz
seabios-1188480ae5e7834d668b6e922293d37ad9e7f3b9.tar.bz2
Break up call32() into call32() and call32_sloppy()
This separates call32() into two functions. It also moves the call16_sloppy() code next to the call32_sloppy() code. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
-rw-r--r--src/stacks.c86
1 files changed, 47 insertions, 39 deletions
diff --git a/src/stacks.c b/src/stacks.c
index e3f91e2..63072e4 100644
--- a/src/stacks.c
+++ b/src/stacks.c
@@ -25,16 +25,12 @@ u16 StackSeg VARLOW;
u8 Call32Method VARLOW;
#define C32_SLOPPY 1
-// Call a 32bit SeaBIOS function from a 16bit SeaBIOS function.
-u32 VISIBLE16
-call32(void *func, u32 eax, u32 errret)
+// Call a C function in 32bit mode. This clobbers the 16bit segment
+// selector registers.
+static u32
+call32_sloppy(void *func, u32 eax)
{
ASSERT16();
- u32 cr0 = getcr0();
- if (cr0 & CR0_PE)
- // Called in 16bit protected mode?!
- return errret;
-
// Backup cmos index register and disable nmi
u8 cmosindex = inb(PORT_CMOS_INDEX);
outb(cmosindex | NMI_DISABLE_BIT, PORT_CMOS_INDEX);
@@ -88,45 +84,65 @@ call32(void *func, u32 eax, u32 errret)
return eax;
}
-// Call a 16bit SeaBIOS function from a 32bit SeaBIOS function.
+// Jump back to 16bit mode while in 32bit mode from call32_sloppy()
u32 FUNCFSEG
-call16(u32 eax, u32 edx, void *func)
+call16_sloppy(u32 eax, u32 edx, void *func)
{
ASSERT32FLAT();
- if (getesp() > BUILD_STACK_ADDR)
- panic("call16 with invalid stack\n");
+ if (getesp() > MAIN_STACK_MAX)
+ panic("call16_sloppy with invalid stack\n");
func -= BUILD_BIOS_ADDR;
+ Call32Method = 0;
+ u32 stackseg = GET_LOW(StackSeg);
asm volatile(
// Transition to 16bit mode
" movl $(1f - " __stringify(BUILD_BIOS_ADDR) "), %%edx\n"
- " jmp transition16\n"
- // Call func
+ " jmp transition16big\n"
+ // Setup ss/esp and call func
" .code16\n"
- "1:movl %2, %%edx\n"
+ "1:movl %3, %%ecx\n"
+ " shll $4, %3\n"
+ " movw %%cx, %%ss\n"
+ " subl %3, %%esp\n"
+ " movw %%cx, %%ds\n"
+ " movl %2, %%edx\n"
" calll *%1\n"
- // Return to 32bit
+ // Return to 32bit and restore esp
" movl $2f, %%edx\n"
" jmp transition32\n"
" .code32\n"
- "2:\n"
+ "2:addl %3, %%esp\n"
: "+a" (eax)
- : "r" (func), "r" (edx)
+ : "r" (func), "r" (edx), "r" (stackseg)
: "edx", "ecx", "cc", "memory");
+ Call32Method = C32_SLOPPY;
return eax;
}
-// Call a 16bit SeaBIOS function in "big real" mode.
+// Call a 32bit SeaBIOS function from a 16bit SeaBIOS function.
+u32 VISIBLE16
+call32(void *func, u32 eax, u32 errret)
+{
+ ASSERT16();
+ u32 cr0 = getcr0();
+ if (cr0 & CR0_PE)
+ // Called in 16bit protected mode?!
+ return errret;
+ return call32_sloppy(func, eax);
+}
+
+// Call a 16bit SeaBIOS function from a 32bit SeaBIOS function.
u32 FUNCFSEG
-call16big(u32 eax, u32 edx, void *func)
+call16(u32 eax, u32 edx, void *func)
{
ASSERT32FLAT();
if (getesp() > BUILD_STACK_ADDR)
- panic("call16big with invalid stack\n");
+ panic("call16 with invalid stack\n");
func -= BUILD_BIOS_ADDR;
asm volatile(
// Transition to 16bit mode
" movl $(1f - " __stringify(BUILD_BIOS_ADDR) "), %%edx\n"
- " jmp transition16big\n"
+ " jmp transition16\n"
// Call func
" .code16\n"
"1:movl %2, %%edx\n"
@@ -142,38 +158,30 @@ call16big(u32 eax, u32 edx, void *func)
return eax;
}
-// Jump back to 16bit mode while in 32bit mode from call32()
+// Call a 16bit SeaBIOS function in "big real" mode.
u32 FUNCFSEG
-call16_sloppy(u32 eax, u32 edx, void *func)
+call16big(u32 eax, u32 edx, void *func)
{
ASSERT32FLAT();
- if (getesp() > MAIN_STACK_MAX)
- panic("call16_sloppy with invalid stack\n");
+ if (getesp() > BUILD_STACK_ADDR)
+ panic("call16big with invalid stack\n");
func -= BUILD_BIOS_ADDR;
- Call32Method = 0;
- u32 stackseg = GET_LOW(StackSeg);
asm volatile(
// Transition to 16bit mode
" movl $(1f - " __stringify(BUILD_BIOS_ADDR) "), %%edx\n"
" jmp transition16big\n"
- // Setup ss/esp and call func
+ // Call func
" .code16\n"
- "1:movl %3, %%ecx\n"
- " shll $4, %3\n"
- " movw %%cx, %%ss\n"
- " subl %3, %%esp\n"
- " movw %%cx, %%ds\n"
- " movl %2, %%edx\n"
+ "1:movl %2, %%edx\n"
" calll *%1\n"
- // Return to 32bit and restore esp
+ // Return to 32bit
" movl $2f, %%edx\n"
" jmp transition32\n"
" .code32\n"
- "2:addl %3, %%esp\n"
+ "2:\n"
: "+a" (eax)
- : "r" (func), "r" (edx), "r" (stackseg)
+ : "r" (func), "r" (edx)
: "edx", "ecx", "cc", "memory");
- Call32Method = C32_SLOPPY;
return eax;
}