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 --- src/stacks.c | 86 +++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 47 insertions(+), 39 deletions(-)
diff --git a/src/stacks.c b/src/stacks.c index 82d1c5c..2a7be06 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; }