[SeaBIOS] [PATCH 04/12] Update stack_hop_back() to jump to 16bit mode if called in 32bit mode.

Kevin O'Connor kevin at koconnor.net
Tue Sep 30 20:38:38 CEST 2014


Also, update callers to rely on this feature.

Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
 src/mouse.c  |  8 ++++++--
 src/stacks.c | 31 +++++++++++++------------------
 src/stacks.h |  2 +-
 3 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/src/mouse.c b/src/mouse.c
index 466f55a..6d1f5b7 100644
--- a/src/mouse.c
+++ b/src/mouse.c
@@ -274,13 +274,17 @@ handle_15c2(struct bregs *regs)
     }
 }
 
-static void
+void VISIBLE16
 invoke_mouse_handler(void)
 {
+    if (!CONFIG_MOUSE)
+        return;
     if (need_hop_back()) {
-        stack_hop_back(0, 0, invoke_mouse_handler);
+        extern void _cfunc16_invoke_mouse_handler(void);
+        stack_hop_back(0, 0, _cfunc16_invoke_mouse_handler);
         return;
     }
+    ASSERT16();
     u16 ebda_seg = get_ebda_seg();
     u16 status = GET_EBDA(ebda_seg, mouse_data[0]);
     u16 X      = GET_EBDA(ebda_seg, mouse_data[1]);
diff --git a/src/stacks.c b/src/stacks.c
index 4fd70a7..5a2628a 100644
--- a/src/stacks.c
+++ b/src/stacks.c
@@ -158,6 +158,8 @@ stack_hop(u32 eax, u32 edx, void *func)
 u32
 stack_hop_back(u32 eax, u32 edx, void *func)
 {
+    if (!MODESEGMENT)
+        return call16big(eax, edx, func);
     if (!on_extra_stack())
         return ((u32 (*)(u32, u32))func)(eax, edx);
     ASSERT16();
@@ -196,11 +198,12 @@ stack_hop_back(u32 eax, u32 edx, void *func)
 void VISIBLE16
 _farcall16(struct bregs *callregs, u16 callregseg)
 {
-    ASSERT16();
     if (need_hop_back()) {
-        stack_hop_back((u32)callregs, callregseg, _farcall16);
+        extern void _cfunc16__farcall16(void);
+        stack_hop_back((u32)callregs, callregseg, _cfunc16__farcall16);
         return;
     }
+    ASSERT16();
     asm volatile(
         "calll __farcall16\n"
         : "+a" (callregs), "+m" (*callregs), "+d" (callregseg)
@@ -385,7 +388,8 @@ void VISIBLE16
 check_irqs(void)
 {
     if (need_hop_back()) {
-        stack_hop_back(0, 0, check_irqs);
+        extern void _cfunc16_check_irqs(void);
+        stack_hop_back(0, 0, _cfunc16_check_irqs);
         return;
     }
     asm volatile("sti ; nop ; rep ; nop ; cli ; cld" : : :"memory");
@@ -395,19 +399,14 @@ check_irqs(void)
 void
 yield(void)
 {
-    if (MODESEGMENT) {
+    if (MODESEGMENT || !CONFIG_THREADS) {
         check_irqs();
         return;
     }
-    extern void _cfunc16_check_irqs(void);
-    if (!CONFIG_THREADS) {
-        call16big(0, 0, _cfunc16_check_irqs);
-        return;
-    }
     struct thread_info *cur = getCurThread();
     if (cur == &MainThread)
         // Permit irqs to fire
-        call16big(0, 0, _cfunc16_check_irqs);
+        check_irqs();
 
     // Switch to the next thread
     switch_next(cur);
@@ -417,7 +416,8 @@ void VISIBLE16
 wait_irq(void)
 {
     if (need_hop_back()) {
-        stack_hop_back(0, 0, wait_irq);
+        extern void _cfunc16_wait_irq(void);
+        stack_hop_back(0, 0, _cfunc16_wait_irq);
         return;
     }
     asm volatile("sti ; hlt ; cli ; cld": : :"memory");
@@ -427,17 +427,12 @@ wait_irq(void)
 void
 yield_toirq(void)
 {
-    if (MODESEGMENT) {
-        wait_irq();
-        return;
-    }
-    if (have_threads()) {
+    if (!MODESEGMENT && have_threads()) {
         // Threads still active - do a yield instead.
         yield();
         return;
     }
-    extern void _cfunc16_wait_irq(void);
-    call16big(0, 0, _cfunc16_wait_irq);
+    wait_irq();
 }
 
 // Wait for all threads (other than the main thread) to complete.
diff --git a/src/stacks.h b/src/stacks.h
index 265b404..cbc5f4f 100644
--- a/src/stacks.h
+++ b/src/stacks.h
@@ -42,7 +42,7 @@ u32 call32_params(void *func, u32 eax, u32 edx, u32 ecx, u32 errret);
 static inline int
 need_hop_back(void)
 {
-    return on_extra_stack();
+    return !MODESEGMENT || on_extra_stack();
 }
 
 #endif // stacks.h
-- 
1.9.3




More information about the SeaBIOS mailing list