Improve calling convention so it's more performance and doesn't mess up stack for vsprintf /stdargs
This commit is contained in:
parent
4f8191d8ff
commit
25dbadb1c0
|
@ -28,12 +28,7 @@
|
||||||
* Determine the correct system function implementation and call it.
|
* Determine the correct system function implementation and call it.
|
||||||
*/
|
*/
|
||||||
unsigned long syscall_dispatch(int32_t function, int32_t param0, int32_t param1, int32_t param2, int32_t param3, int32_t param4, int32_t param5) {
|
unsigned long syscall_dispatch(int32_t function, int32_t param0, int32_t param1, int32_t param2, int32_t param3, int32_t param4, int32_t param5) {
|
||||||
#ifdef KDEBUG
|
//TRACE7("DISPATCH(%lx,%ld,%ld,%ld,%ld,%ld,%ld)", function, param0, param1, param2, param3, param4, param5);
|
||||||
char buf[80];
|
|
||||||
sprintf(buf,"fn:0x%04x d1:%04x d2:0x%04x d3:0x%04x", (int)function, (int)param0, (int)param1, (int)param2);
|
|
||||||
DEBUG(buf);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (function & 0x00f0) {
|
switch (function & 0x00f0) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
/* Core System Calls */
|
/* Core System Calls */
|
||||||
|
|
|
@ -148,6 +148,7 @@ coldboot: move.w #$2700,SR ; Supervisor mode, disable all interrupts
|
||||||
lea ___STACK,sp
|
lea ___STACK,sp
|
||||||
bsr _int_disable_all
|
bsr _int_disable_all
|
||||||
|
|
||||||
|
|
||||||
lea ___BSSSTART,a0
|
lea ___BSSSTART,a0
|
||||||
move.l #___BSSSIZE,d0
|
move.l #___BSSSIZE,d0
|
||||||
beq callmain
|
beq callmain
|
||||||
|
@ -161,6 +162,8 @@ clrloop: ; We don't use clr.l because it's a read-modify-write operation
|
||||||
subq.l #4,d0
|
subq.l #4,d0
|
||||||
bpl.s clrloop
|
bpl.s clrloop
|
||||||
|
|
||||||
|
move.l #trap_save_area,trap_save_area
|
||||||
|
|
||||||
callmain: jsr ___main ; call __main to transfer to the C code
|
callmain: jsr ___main ; call __main to transfer to the C code
|
||||||
|
|
||||||
; endless loop; can be changed accordingly
|
; endless loop; can be changed accordingly
|
||||||
|
@ -379,40 +382,54 @@ panic_lock: bra panic_lock
|
||||||
; Function to make a system call based on the number of the system function:
|
; Function to make a system call based on the number of the system function:
|
||||||
; int32_t syscall(int32_t number, int32_t p0, int32_t p1, int32_t p2, int32_t p3, int32_t p4, int32_t p5)
|
; int32_t syscall(int32_t number, int32_t p0, int32_t p1, int32_t p2, int32_t p3, int32_t p4, int32_t p5)
|
||||||
;
|
;
|
||||||
|
xdef _trace
|
||||||
|
aze dc.b "return address: %p",0
|
||||||
|
even
|
||||||
|
|
||||||
_syscall:
|
_syscall:
|
||||||
movem.l d1-d7,-(sp) ; Save caller's registers
|
; Repush the parameters
|
||||||
move.l (56,sp),d6 ; Parameter 5 to D6
|
move.l 28(sp),-(sp)
|
||||||
move.l (52,sp),d5 ; Parameter 4 to D5
|
move.l 28(sp),-(sp)
|
||||||
move.l (48,sp),d4 ; Parameter 3 to D4
|
move.l 28(sp),-(sp)
|
||||||
move.l (44,sp),d3 ; Parameter 2 to D3
|
move.l 28(sp),-(sp)
|
||||||
move.l (40,sp),d2 ; Parameter 1 to D2
|
move.l 28(sp),-(sp)
|
||||||
move.l (36,sp),d1 ; Parameter 0 to D1
|
move.l 28(sp),-(sp)
|
||||||
move.l (32,sp),d0 ; Function number to D0 (32 = 4(PC)+7(regs)*4)
|
move.l 28(sp),-(sp)
|
||||||
|
trap #15 ; Call into the kernel
|
||||||
TRAP #15 ; Call into the kernel
|
lea 28(sp),sp
|
||||||
|
|
||||||
movem.l (sp)+,d1-d7 ; Restore caller's registers
|
|
||||||
rts
|
rts
|
||||||
|
|
||||||
;
|
;
|
||||||
; TRAP#15 handler... transfer control to the C dispatcher
|
; TRAP#15 handler... transfer control to the C dispatcher
|
||||||
;
|
;
|
||||||
h_trap_15:
|
h_trap_15:
|
||||||
cmpi.w #$43,d1 ; Is this a sys_proc_elevate call?
|
; Save sr, return address and non-scratch registers into our save area
|
||||||
beq.s h_trap_elev ; Yes, just handle it here
|
; TODO we should guard this if we want to allow system calls from interrupts.
|
||||||
|
move.l trap_save_area,a0
|
||||||
|
move.w (sp)+,d0 ; Status register
|
||||||
|
move.w d0,-(a0)
|
||||||
|
move.l (sp)+,-(a0) ; Return address
|
||||||
|
movem.l d2-d7/a2-a7,-(a0)
|
||||||
|
move.l a0,trap_save_area ; TODO should we check if we're beyond the end of that area ? As we'd be corrupting data.
|
||||||
|
|
||||||
|
; Fix stack if necessary so it points to the arguments for the dispatcher
|
||||||
|
btst #13,d0 ; Check supervisor bit from caller's status register to see if were we called from user mode
|
||||||
|
bne.s syscall_stack_set ; If yes, sp already points to the arguments
|
||||||
|
move.l usp,sp ; If not, the argument are on the user stack, so use it
|
||||||
|
syscall_stack_set:
|
||||||
|
|
||||||
move.l d6,-(sp) ; Push the parameters to the stack for the C call
|
cmpi.w #$43,(sp) ; Is this a sys_proc_elevate call?
|
||||||
move.l d5,-(sp)
|
beq.s h_trap_elev ; Yes, just handle it here
|
||||||
move.l d4,-(sp)
|
|
||||||
move.l d3,-(sp)
|
|
||||||
move.l d2,-(sp)
|
|
||||||
move.l d1,-(sp)
|
|
||||||
move.l d0,-(sp)
|
|
||||||
|
|
||||||
jsr _syscall_dispatch ; Call the C routine to do the dispatch
|
jsr _syscall_dispatch ; Call the C routine to do the dispatch
|
||||||
; Note: the C routine depends upon the register push order
|
|
||||||
|
|
||||||
adda.l #7*4,sp ; Remove parameters from the stack
|
; Restore context from our save area
|
||||||
|
move.l trap_save_area,a0
|
||||||
|
movem.l (a0)+,d2-d7/a2-a7
|
||||||
|
move.l (a0)+,-(sp) ; Return address
|
||||||
|
move.w (a0)+,-(sp) ; Status register
|
||||||
|
move.l a0,trap_save_area
|
||||||
|
|
||||||
rte ; Return to the caller
|
rte ; Return to the caller
|
||||||
|
|
||||||
h_trap_elev ori #$2000,(a7) ; Change the caller's privilege to supervisor
|
h_trap_elev ori #$2000,(a7) ; Change the caller's privilege to supervisor
|
||||||
|
@ -446,3 +463,9 @@ _restart_cli:
|
||||||
lea ___STACK,sp
|
lea ___STACK,sp
|
||||||
jsr _cli_rerepl
|
jsr _cli_rerepl
|
||||||
bra _restart_cli
|
bra _restart_cli
|
||||||
|
|
||||||
|
section BSS
|
||||||
|
|
||||||
|
TRAP_MAX_REENTRANCY EQU 4 ; Max number of reentrant calls to the trap handler
|
||||||
|
ds.b (6+12*4)*TRAP_MAX_REENTRANCY ; Each time we save status register .w and return address .l, so 6 bytes, + the saved registers (non-scratch) d2-d7/a2-a7 according to VBCC doc
|
||||||
|
trap_save_area: ds.l 1
|
||||||
|
|
Loading…
Reference in a new issue