From: Kevin O'Connor Date: Tue, 30 Sep 2014 03:59:47 +0000 (-0400) Subject: Track when entering via call32() and use the same mode for stack_hop_back() X-Git-Tag: rel-1.8.0~88 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=dcacfa08b2a26e9aac17c52d4015100935bbcb9a;p=seabios.git Track when entering via call32() and use the same mode for stack_hop_back() If 32bit mode is entered directly via transition32, then use a simple call16() when hopping back to 16bit mode. Use only call16big() during post and when entering 32bit mode via call32(). Signed-off-by: Kevin O'Connor --- diff --git a/src/stacks.c b/src/stacks.c index 5a2628a..b91b216 100644 --- a/src/stacks.c +++ b/src/stacks.c @@ -22,6 +22,8 @@ ****************************************************************/ u16 StackSeg VARLOW; +u8 Call32Method VARLOW; +#define C32_SLOPPY 1 // Call a 32bit SeaBIOS function from a 16bit SeaBIOS function. u32 VISIBLE16 @@ -45,6 +47,7 @@ call32(void *func, u32 eax, u32 errret) u16 oldstackseg = GET_LOW(StackSeg); SET_LOW(StackSeg, GET_SEG(SS)); + SET_LOW(Call32Method, C32_SLOPPY); u32 bkup_ss, bkup_esp; asm volatile( // Backup ss/esp / set esp to flat stack location @@ -71,6 +74,7 @@ call32(void *func, u32 eax, u32 errret) : "r" (func) : "ecx", "edx", "cc", "memory"); + SET_LOW(Call32Method, 0); SET_LOW(StackSeg, oldstackseg); // Restore gdt and fs/gs @@ -95,6 +99,7 @@ call16(u32 eax, u32 edx, void *func) return __call16(eax, edx, func - BUILD_BIOS_ADDR); } +// Call a 16bit SeaBIOS function in "big real" mode. static inline u32 call16big(u32 eax, u32 edx, void *func) { @@ -105,6 +110,28 @@ call16big(u32 eax, u32 edx, void *func) return __call16big(eax, edx, func - BUILD_BIOS_ADDR); } +// Jump back to 16bit mode while in 32bit mode from call32() +static u32 +call16_sloppy(u32 eax, u32 edx, void *func) +{ + Call32Method = 0; + u32 ret = call16big(eax, edx, func); + Call32Method = C32_SLOPPY; + return ret; +} + +// Call a 16bit SeaBIOS function, restoring the mode from last call32(). +static u32 +call16_back(u32 eax, u32 edx, void *func) +{ + ASSERT32FLAT(); + if (Call32Method == C32_SLOPPY) + return call16_sloppy(eax, edx, func); + if (in_post()) + return call16big(eax, edx, func); + return call16(eax, edx, func); +} + /**************************************************************** * Extra 16bit stack @@ -159,7 +186,7 @@ u32 stack_hop_back(u32 eax, u32 edx, void *func) { if (!MODESEGMENT) - return call16big(eax, edx, func); + return call16_back(eax, edx, func); if (!on_extra_stack()) return ((u32 (*)(u32, u32))func)(eax, edx); ASSERT16();