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@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