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(a)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), ¶ms), errret);
+ return call32(call32_params_helper, MAKE_FLATPTR(GET_SEG(SS), ¶ms)
+ , 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