Support passing a parameter to the 32bit function, as well as returning the result of the function back to the 16bit code.
Also, make call32 available outside of stacks.c. --- src/stacks.c | 18 +++++++++--------- src/util.h | 1 + 2 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/src/stacks.c b/src/stacks.c index a68d37c..c77ba1f 100644 --- a/src/stacks.c +++ b/src/stacks.c @@ -37,14 +37,14 @@ static inline void lgdt(struct descloc_s *desc) { }
// Call a 32bit SeaBIOS function from a 16bit SeaBIOS function. -static inline int -call32(void *func) +u32 +call32(void *func, u32 eax, u32 errret) { ASSERT16(); u32 cr0 = getcr0(); if (cr0 & CR0_PE) // Called in 16bit protected mode?! - return -1; + return errret;
// Backup cmos index register and disable nmi u8 cmosindex = inb(PORT_CMOS_INDEX); @@ -63,13 +63,13 @@ call32(void *func) " movl %%esp, %1\n" " shll $4, %0\n" " addl %0, %%esp\n" - " movl %%ss, %0\n" + " shrl $4, %0\n"
// Transition to 32bit mode, call func, return to 16bit " movl $(" __stringify(BUILD_BIOS_ADDR) " + 1f), %%edx\n" " jmp transition32\n" " .code32\n" - "1:calll *%2\n" + "1:calll *%3\n" " movl $2f, %%edx\n" " jmp transition16big\n"
@@ -78,9 +78,9 @@ call32(void *func) "2:movl %0, %%ds\n" " movl %0, %%ss\n" " movl %1, %%esp\n" - : "=&r" (bkup_ss), "=&r" (bkup_esp) + : "=&r" (bkup_ss), "=&r" (bkup_esp), "+a" (eax) : "r" (func) - : "eax", "ecx", "edx", "cc", "memory"); + : "ecx", "edx", "cc", "memory");
// Restore gdt and fs/gs lgdt(&gdt); @@ -90,7 +90,7 @@ call32(void *func) // Restore cmos index register outb(cmosindex, PORT_CMOS_INDEX); inb(PORT_CMOS_DATA); - return 0; + return eax; }
// 16bit trampoline for enabling irqs from 32bit mode. @@ -393,5 +393,5 @@ check_preempt(void) || GET_FLATPTR(MainThread.next) == &MainThread) return;
- call32(yield_preempt); + call32(yield_preempt, 0, 0); } diff --git a/src/util.h b/src/util.h index 18ab814..e513e84 100644 --- a/src/util.h +++ b/src/util.h @@ -211,6 +211,7 @@ char *strtcpy(char *dest, const char *src, size_t len); int get_keystroke(int msec);
// stacks.c +u32 call32(void *func, u32 eax, u32 errret); inline u32 stack_hop(u32 eax, u32 edx, void *func); extern struct thread_info MainThread; struct thread_info *getCurThread(void);