diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2010-11-25 09:17:31 -0500 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2010-11-25 09:17:31 -0500 |
commit | af9629be3aeb3952ff432cf009394f10727ee0e8 (patch) | |
tree | 50cec3936fc2765dbe236c29d262cb46ae0ca5f6 | |
parent | 4057f9847e94147aaa9799b92ba4561506333a57 (diff) | |
download | seabios-af9629be3aeb3952ff432cf009394f10727ee0e8.tar.gz |
Enhance call32() to pass a parameter to called function.
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.
-rw-r--r-- | src/stacks.c | 18 | ||||
-rw-r--r-- | 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); } @@ -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); |