aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2010-11-25 09:17:31 -0500
committerKevin O'Connor <kevin@koconnor.net>2010-11-25 09:17:31 -0500
commitaf9629be3aeb3952ff432cf009394f10727ee0e8 (patch)
tree50cec3936fc2765dbe236c29d262cb46ae0ca5f6
parent4057f9847e94147aaa9799b92ba4561506333a57 (diff)
downloadseabios-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.c18
-rw-r--r--src/util.h1
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);