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:
parent
a1b4dd09d7
commit
b4cca861a2
|
@ -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
|
||||
------------------------
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
25
src/stacks.c
25
src/stacks.c
|
@ -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), ¶ms), errret);
|
||||
return call32(call32_params_helper, MAKE_FLATPTR(GET_SEG(SS), ¶ms)
|
||||
, errret);
|
||||
}
|
||||
|
|
25
src/stacks.h
25
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
|
||||
|
||||
|
|
Loading…
Reference in New Issue