stacks: Use macro wrappers for call32() and stack_hop_back()

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>
This commit is contained in:
Kevin O'Connor 2015-10-09 11:53:02 -04:00
parent a1b4dd09d7
commit b4cca861a2
8 changed files with 41 additions and 44 deletions

View File

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

View File

@ -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));
}

View File

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

View File

@ -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);
}
}

View File

@ -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();

View File

@ -248,7 +248,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)

View File

@ -229,7 +229,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))
@ -328,7 +328,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);
@ -361,7 +361,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);
@ -404,8 +404,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();
@ -599,8 +598,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)
@ -629,8 +627,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");
@ -735,9 +732,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);
}
@ -758,11 +754,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);
}

View File

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