[SeaBIOS] [PATCH] stacks: Use macro wrappers for call32() and stack_hop_back()

Kevin O'Connor kevin at koconnor.net
Thu Oct 15 18:20:21 CEST 2015


The C code only uses _cfuncX_ prefixes for parameters to the call32(),
stack_hop_back(), and call32_params() functions.  It's simpler to use
macro wrappers around those functions which provide the required
prefix.

This also changes the parameter order of stack_hop() and
stack_hop_back() to use the more natural (func, params) ordering.

Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
 docs/Linking_overview.md | 14 +++-----------
 src/block.c              |  7 +++----
 src/clock.c              |  4 +---
 src/hw/usb.c             |  5 ++---
 src/mouse.c              |  3 +--
 src/romlayout.S          |  2 +-
 src/stacks.c             | 25 ++++++++++---------------
 src/stacks.h             | 25 ++++++++++++++++++++-----
 8 files changed, 41 insertions(+), 44 deletions(-)

diff --git a/docs/Linking_overview.md b/docs/Linking_overview.md
index 965e926..bcb8298 100644
--- a/docs/Linking_overview.md
+++ b/docs/Linking_overview.md
@@ -92,17 +92,9 @@ those situations where an address of a C function in another mode is
 required the build supports symbols with a special "\_cfuncX_"
 prefix. The layoutrom.py script detects these references and will emit
 a corresponding symbol definitions in the linker script that points to
-the C code of the specified mode. This is typically seen with code
-like:
-
-```
-extern void _cfunc32flat_process_op(void);
-return call32(_cfunc32flat_process_op, 0, 0);
-```
-
-In the above example, when the build finds the symbol
-"\_cfunc32flat_process_op" it will emit that symbol with the physical
-address of the 32bit "flat" version of the process_op() C function.
+the C code of the specified mode. The call32() and stack_hop_back()
+macros automatically add the required prefix for C code, but the
+prefixes need to be explicitly added in assembler code.
 
 Build garbage collection
 ------------------------
diff --git a/src/block.c b/src/block.c
index 97e05fa..1762e2a 100644
--- a/src/block.c
+++ b/src/block.c
@@ -525,9 +525,8 @@ process_op_both(struct disk_op_s *op)
         if (!MODESEGMENT)
             return DISK_RET_EPARAM;
         // In 16bit mode and driver not found - try in 32bit mode
-        extern void _cfunc32flat_process_op_32(void);
-        return call32(_cfunc32flat_process_op_32
-                      , (u32)MAKE_FLATPTR(GET_SEG(SS), op), DISK_RET_EPARAM);
+        return call32(process_op_32, MAKE_FLATPTR(GET_SEG(SS), op)
+                      , DISK_RET_EPARAM);
     }
 }
 
@@ -625,5 +624,5 @@ send_disk_op(struct disk_op_s *op)
     if (! CONFIG_DRIVES)
         return -1;
 
-    return stack_hop((u32)op, GET_SEG(SS), __send_disk_op);
+    return stack_hop(__send_disk_op, op, GET_SEG(SS));
 }
diff --git a/src/clock.c b/src/clock.c
index c73545b..e83e0f3 100644
--- a/src/clock.c
+++ b/src/clock.c
@@ -248,9 +248,7 @@ handle_1abb(struct bregs *regs)
         return;
 
     dprintf(DEBUG_tcg, "16: Calling tpm_interrupt_handler\n");
-    extern void _cfunc32flat_tpm_interrupt_handler32(void);
-    call32(_cfunc32flat_tpm_interrupt_handler32,
-           (u32)MAKE_FLATPTR(GET_SEG(SS), regs), 0);
+    call32(tpm_interrupt_handler32, MAKE_FLATPTR(GET_SEG(SS), regs), 0);
 }
 
 // Unsupported
diff --git a/src/hw/usb.c b/src/hw/usb.c
index 2d5c224..e46092c 100644
--- a/src/hw/usb.c
+++ b/src/hw/usb.c
@@ -79,9 +79,8 @@ usb_poll_intr(struct usb_pipe *pipe_fl, void *data)
     case USB_TYPE_EHCI:
         return ehci_poll_intr(pipe_fl, data);
     case USB_TYPE_XHCI: ;
-        extern void _cfunc32flat_xhci_poll_intr(void);
-        return call32_params(_cfunc32flat_xhci_poll_intr, (u32)pipe_fl
-                             , (u32)MAKE_FLATPTR(GET_SEG(SS), (u32)data), 0, -1);
+        return call32_params(xhci_poll_intr, pipe_fl
+                             , MAKE_FLATPTR(GET_SEG(SS), data), 0, -1);
     }
 }
 
diff --git a/src/mouse.c b/src/mouse.c
index 6d1f5b7..b7ad7c6 100644
--- a/src/mouse.c
+++ b/src/mouse.c
@@ -280,8 +280,7 @@ invoke_mouse_handler(void)
     if (!CONFIG_MOUSE)
         return;
     if (need_hop_back()) {
-        extern void _cfunc16_invoke_mouse_handler(void);
-        stack_hop_back(0, 0, _cfunc16_invoke_mouse_handler);
+        stack_hop_back(invoke_mouse_handler, 0, 0);
         return;
     }
     ASSERT16();
diff --git a/src/romlayout.S b/src/romlayout.S
index 7910806..7d65809 100644
--- a/src/romlayout.S
+++ b/src/romlayout.S
@@ -277,7 +277,7 @@ entry_pmm:
         movl $_cfunc32flat_handle_pmm, %eax // Setup: call32(handle_pmm, args, -1)
         leal PUSHBREGS_size+12(%esp, %ecx), %edx // %edx points to start of args
         movl $-1, %ecx
-        calll call32
+        calll __call32
         movw %ax, BREGS_eax(%esp)       // Modify %ax:%dx to return %eax
         shrl $16, %eax
         movw %ax, BREGS_edx(%esp)
diff --git a/src/stacks.c b/src/stacks.c
index 583b456..40bd4d3 100644
--- a/src/stacks.c
+++ b/src/stacks.c
@@ -242,7 +242,7 @@ call16_smm(u32 eax, u32 edx, void *func)
 
 // Call a 32bit SeaBIOS function from a 16bit SeaBIOS function.
 u32 VISIBLE16
-call32(void *func, u32 eax, u32 errret)
+__call32(void *func, u32 eax, u32 errret)
 {
     ASSERT16();
     if (CONFIG_CALL32_SMM && GET_GLOBAL(HaveSmmCall32))
@@ -341,7 +341,7 @@ on_extra_stack(void)
 
 // Switch to the extra stack and call a function.
 u32
-stack_hop(u32 eax, u32 edx, void *func)
+__stack_hop(u32 eax, u32 edx, void *func)
 {
     if (on_extra_stack())
         return ((u32 (*)(u32, u32))func)(eax, edx);
@@ -374,7 +374,7 @@ stack_hop(u32 eax, u32 edx, void *func)
 
 // Switch back to original caller's stack and call a function.
 u32
-stack_hop_back(u32 eax, u32 edx, void *func)
+__stack_hop_back(u32 eax, u32 edx, void *func)
 {
     if (!MODESEGMENT)
         return call16(eax, edx, func);
@@ -417,8 +417,7 @@ void VISIBLE16
 _farcall16(struct bregs *callregs, u16 callregseg)
 {
     if (need_hop_back()) {
-        extern void _cfunc16__farcall16(void);
-        stack_hop_back((u32)callregs, callregseg, _cfunc16__farcall16);
+        stack_hop_back(_farcall16, callregs, callregseg);
         return;
     }
     ASSERT16();
@@ -612,8 +611,7 @@ check_irqs(void)
         return;
     }
     if (need_hop_back()) {
-        extern void _cfunc16_check_irqs(void);
-        stack_hop_back(0, 0, _cfunc16_check_irqs);
+        stack_hop_back(check_irqs, 0, 0);
         return;
     }
     if (MODE16)
@@ -642,8 +640,7 @@ void VISIBLE16
 wait_irq(void)
 {
     if (need_hop_back()) {
-        extern void _cfunc16_wait_irq(void);
-        stack_hop_back(0, 0, _cfunc16_wait_irq);
+        stack_hop_back(wait_irq, 0, 0);
         return;
     }
     asm volatile("sti ; hlt ; cli ; cld": : :"memory");
@@ -748,9 +745,8 @@ yield_preempt(void)
 void
 check_preempt(void)
 {
-    extern void _cfunc32flat_yield_preempt(void);
     if (CONFIG_THREADS && GET_GLOBAL(CanPreempt) && have_threads())
-        call32(_cfunc32flat_yield_preempt, 0, 0);
+        call32(yield_preempt, 0, 0);
 }
 
 
@@ -771,11 +767,10 @@ call32_params_helper(struct call32_params_s *params)
 }
 
 u32
-call32_params(void *func, u32 eax, u32 edx, u32 ecx, u32 errret)
+__call32_params(void *func, u32 eax, u32 edx, u32 ecx, u32 errret)
 {
     ASSERT16();
     struct call32_params_s params = {func, eax, edx, ecx};
-    extern void _cfunc32flat_call32_params_helper(void);
-    return call32(_cfunc32flat_call32_params_helper
-                  , (u32)MAKE_FLATPTR(GET_SEG(SS), &params), errret);
+    return call32(call32_params_helper, MAKE_FLATPTR(GET_SEG(SS), &params)
+                  , errret);
 }
diff --git a/src/stacks.h b/src/stacks.h
index a3b031c..c71bdc8 100644
--- a/src/stacks.h
+++ b/src/stacks.h
@@ -10,17 +10,27 @@
 
 // stacks.c
 extern int HaveSmmCall32;
-u32 call32(void *func, u32 eax, u32 errret);
+u32 __call32(void *func, u32 eax, u32 errret);
+#define call32(func, eax, errret) ({                            \
+        extern void _cfunc32flat_ ##func (void);                \
+        __call32( _cfunc32flat_ ##func , (u32)(eax), (errret)); \
+    })
 extern u8 ExtraStack[], *StackPos;
-u32 stack_hop(u32 eax, u32 edx, void *func);
-u32 stack_hop_back(u32 eax, u32 edx, void *func);
+u32 __stack_hop(u32 eax, u32 edx, void *func);
+#define stack_hop(func, eax, edx)               \
+    __stack_hop((u32)(eax), (u32)(edx), (func))
+u32 __stack_hop_back(u32 eax, u32 edx, void *func);
+#define stack_hop_back(func, eax, edx) ({                               \
+        extern void _cfunc16_ ##func (void);                            \
+        __stack_hop_back((u32)(eax), (u32)(edx), _cfunc16_ ##func );    \
+    })
 int on_extra_stack(void);
 struct bregs;
 void farcall16(struct bregs *callregs);
 void farcall16big(struct bregs *callregs);
 void __call16_int(struct bregs *callregs, u16 offset);
 #define call16_int(nr, callregs) do {                           \
-        extern void irq_trampoline_ ##nr ();                    \
+        extern void irq_trampoline_ ##nr (void);                \
         __call16_int((callregs), (u32)&irq_trampoline_ ##nr );  \
     } while (0)
 void reset(void);
@@ -39,7 +49,12 @@ void start_preempt(void);
 void finish_preempt(void);
 int wait_preempt(void);
 void check_preempt(void);
-u32 call32_params(void *func, u32 eax, u32 edx, u32 ecx, u32 errret);
+u32 __call32_params(void *func, u32 eax, u32 edx, u32 ecx, u32 errret);
+#define call32_params(func, eax, edx, ecx, errret) ({                   \
+        extern void _cfunc32flat_ ##func (void);                        \
+        __call32_params( _cfunc32flat_ ##func , (u32)(eax), (u32)(edx)  \
+                        , (u32)(ecx), (errret));                        \
+    })
 
 // Inline functions
 
-- 
2.4.3




More information about the SeaBIOS mailing list