diff --git a/sys/kern_sig.pas b/sys/kern_sig.pas index 4a1569bd..eac38b1b 100644 --- a/sys/kern_sig.pas +++ b/sys/kern_sig.pas @@ -1,6 +1,7 @@ unit kern_sig; {$mode ObjFPC}{$H+} +{$CALLING SysV_ABI_CDecl} interface diff --git a/sys/signal.pas b/sys/signal.pas index bec481bd..aa3a2f25 100644 --- a/sys/signal.pas +++ b/sys/signal.pas @@ -91,6 +91,10 @@ const _MC_HASFPXSTATE=$4; _MC_FLAG_MASK =(_MC_HASSEGS or _MC_HASBASES or _MC_HASFPXSTATE); + TF_HASSEGS =$1; + TF_HASBASES =$2; + TF_HASFPXSTATE=$4; + type p_sigset_t=^sigset_t; sigset_t=packed record //16 diff --git a/sys/sys_umtx.pas b/sys/sys_umtx.pas index 62ef6f2a..36a969a3 100644 --- a/sys/sys_umtx.pas +++ b/sys/sys_umtx.pas @@ -8,8 +8,7 @@ interface uses sys_kernel, time, - _umtx, - kern_umtx; + _umtx; procedure umtx_init(var umtx:umtx); inline; function umtx_owner(var umtx:umtx):QWORD; inline; @@ -20,10 +19,16 @@ function umtx_unlock(var umtx:umtx;id:QWORD):Integer; inline; function umtx_wait(var umtx:umtx;id:QWORD;timeout:ptimespec):Integer; inline; function umtx_wake(var umtx:umtx;nr_wakeup:Integer):Integer; inline; -function sys_umtx_op(obj:Pointer;op:Integer;val:QWORD;uaddr1,uaddr2:Pointer):Integer; +function _umtx_lock(mtx:p_umtx):Integer; +function _umtx_unlock(mtx:p_umtx):Integer; +function _umtx_op(obj:Pointer;op:Integer;val:QWORD;uaddr1,uaddr2:Pointer):Integer; implementation +uses + kern_umtx, + trap; + procedure umtx_init(var umtx:umtx); inline; begin umtx.u_owner:=UMTX_UNOWNED; @@ -39,7 +44,7 @@ begin Result:=0; if (System.InterlockedCompareExchange64(umtx.u_owner,id,UMTX_UNOWNED)=0) then begin - Result:=_sys_umtx_lock(@umtx); + Result:=_umtx_lock(@umtx); end; end; @@ -57,7 +62,7 @@ begin Result:=0; if (System.InterlockedCompareExchange64(umtx.u_owner,id,UMTX_UNOWNED)=0) then begin - Result:=_sys_umtx_op(@umtx,UMTX_OP_LOCK,id,nil,timeout) + Result:=_umtx_op(@umtx,UMTX_OP_LOCK,id,nil,timeout) end; end; @@ -66,23 +71,36 @@ begin Result:=0; if (System.InterlockedCompareExchange64(umtx.u_owner,UMTX_UNOWNED,id)=0) then begin - Result:=_sys_umtx_unlock(@umtx); + Result:=_umtx_unlock(@umtx); end; end; function umtx_wait(var umtx:umtx;id:QWORD;timeout:ptimespec):Integer; inline; begin - Result:=_sys_umtx_op(@umtx,UMTX_OP_WAIT,id,nil,timeout) + Result:=_umtx_op(@umtx,UMTX_OP_WAIT,id,nil,timeout) end; function umtx_wake(var umtx:umtx;nr_wakeup:Integer):Integer; inline; begin - Result:=_sys_umtx_op(@umtx,UMTX_OP_WAKE,nr_wakeup,nil,nil); + Result:=_umtx_op(@umtx,UMTX_OP_WAKE,nr_wakeup,nil,nil); end; -function sys_umtx_op(obj:Pointer;op:Integer;val:QWORD;uaddr1,uaddr2:Pointer):Integer; -begin - Result:=_sys_umtx_op(obj,op,val,uaddr1,uaddr2); +function _umtx_lock(mtx:p_umtx):Integer; assembler; nostackframe; +asm + movq _sys_umtx_lock,%rax + call fast_syscall +end; + +function _umtx_unlock(mtx:p_umtx):Integer; assembler; nostackframe; +asm + movq _sys_umtx_unlock,%rax + call fast_syscall +end; + +function _umtx_op(obj:Pointer;op:Integer;val:QWORD;uaddr1,uaddr2:Pointer):Integer; assembler; nostackframe; +asm + movq _sys_umtx_op,%rax + call fast_syscall end; end. diff --git a/sys/test/project1.lpr b/sys/test/project1.lpr index f3c21ea0..ee0c9f85 100644 --- a/sys/test/project1.lpr +++ b/sys/test/project1.lpr @@ -57,16 +57,16 @@ begin repeat - Writeln('before: sptr:',HexStr(sptr)); - asm - Movq trap_test,%rax - call fast_syscall - end; - Writeln('after: sptr:',HexStr(sptr)); +//Writeln('before: sptr:',HexStr(sptr)); +//asm +// Movq trap_test,%rax +// call fast_syscall +//end; +//Writeln('after: sptr:',HexStr(sptr)); - //e:=sys_umtx_op(@mtx,{UMTX_OP_MUTEX_LOCK} UMTX_OP_LOCK,td.td_tid,nil,nil); - e:=sys_umtx_op(@mtx,UMTX_OP_MUTEX_LOCK,td^.td_tid,nil,nil); - //e:=sys_umtx_op(@rwl,UMTX_OP_RW_WRLOCK,0,nil,nil); + //e:=_umtx_op(@mtx,{UMTX_OP_MUTEX_LOCK} UMTX_OP_LOCK,td.td_tid,nil,nil); + //e:=_umtx_op(@mtx,UMTX_OP_MUTEX_LOCK,td^.td_tid,nil,nil); + e:=_umtx_op(@rwl,UMTX_OP_RW_WRLOCK,0,nil,nil); Writeln(' lock[',GetCurrentThreadId,'] ',e); //e:=_do_lock_normal(GetCurrentThreadId,@mtx,0,NT_INFINITE,0); @@ -74,11 +74,15 @@ begin //sleep(100); - //e:=sys_umtx_op(@mtx,{UMTX_OP_MUTEX_UNLOCK} UMTX_OP_UNLOCK,td.td_tid,nil,nil); - e:=sys_umtx_op(@mtx,UMTX_OP_MUTEX_UNLOCK,td^.td_tid,nil,nil); - //e:=sys_umtx_op(@rwl,UMTX_OP_RW_UNLOCK,0,nil,nil); + //Writeln('before: sptr:',HexStr(sptr)); + + //e:=_umtx_op(@mtx,{UMTX_OP_MUTEX_UNLOCK} UMTX_OP_UNLOCK,td.td_tid,nil,nil); + //e:=_umtx_op(@mtx,UMTX_OP_MUTEX_UNLOCK,td^.td_tid,nil,nil); + e:=_umtx_op(@rwl,UMTX_OP_RW_UNLOCK,0,nil,nil); Writeln('unlock[',GetCurrentThreadId,'] ',e); + //Writeln('after: sptr:',HexStr(sptr)); + //sleep(1000) //_umtx_obj_done(@mtx); diff --git a/sys/trap.pas b/sys/trap.pas index 2158f61f..1e46be11 100644 --- a/sys/trap.pas +++ b/sys/trap.pas @@ -1,6 +1,7 @@ unit trap; {$mode ObjFPC}{$H+} +{$CALLING SysV_ABI_CDecl} interface @@ -86,43 +87,57 @@ const 'DTrace pid return trap' // 32 T_DTRACE_RET ); -procedure fast_syscall; assembler; +procedure fast_syscall; implementation +type + tsyscall=function(rdi,rsi,rdx,rcx,r8,r9:QWORD):Integer; + +procedure amd64_syscall; +var + td_frame:p_trapframe; +begin + //Call directly to the address or make an ID table? + td_frame:=curkthread^.td_frame; + td_frame^.tf_rax:=tsyscall(td_frame^.tf_rax) + (td_frame^.tf_rdi, + td_frame^.tf_rsi, + td_frame^.tf_rdx, + td_frame^.tf_rcx, + td_frame^.tf_r8, + td_frame^.tf_r9); +end; procedure fast_syscall; assembler; nostackframe; +label + rip; asm - movq %rax,-16(%rsp) //save rax + //prolog (debugger) + pushq %rbp + movq %rsp,%rbp - movq %gs:(0x700),%rax //curkthread - movq kthread.td_frame(%rax),%rax //td_frame + movqq %rax,-16(%rsp) //save rax - movq %rdi,trapframe.tf_rdi(%rax) - movq %rsi,trapframe.tf_rsi(%rax) - movq %rdx,trapframe.tf_rdx(%rax) - movq %rcx,trapframe.tf_rcx(%rax) - movq %r8 ,trapframe.tf_r8 (%rax) - movq %r9 ,trapframe.tf_r9 (%rax) - movq %rbx,trapframe.tf_rbx(%rax) - movq %rbp,trapframe.tf_rbp(%rax) - movq %r10,trapframe.tf_r10(%rax) - movq %r11,trapframe.tf_r11(%rax) - movq %r12,trapframe.tf_r12(%rax) - movq %r13,trapframe.tf_r13(%rax) - movq %r14,trapframe.tf_r14(%rax) - movq %r15,trapframe.tf_r15(%rax) - movq %rsp,trapframe.tf_rsp(%rax) + movqq %gs:(0x700),%rax //curkthread + movqq kthread.td_frame(%rax),%rax //td_frame - movq -16(%rsp),%r11 //get rax - movq %r11,trapframe.tf_rax(%rax) - - pushfq //push FLAGS - pop %r11 //get FLAGS - movq %r11,trapframe.tf_rflags(%rax) - - movq (%rsp),%r11 //get caller addr - movq %r11,trapframe.tf_rip(%rax) + movqq %rdi,trapframe.tf_rdi(%rax) + movqq %rsi,trapframe.tf_rsi(%rax) + movqq %rdx,trapframe.tf_rdx(%rax) + movqq %rcx,trapframe.tf_rcx(%rax) + movqq %r8 ,trapframe.tf_r8 (%rax) + movqq %r9 ,trapframe.tf_r9 (%rax) + movqq %rbx,trapframe.tf_rbx(%rax) + movqq %rbp,trapframe.tf_rbp(%rax) + movqq %r10,trapframe.tf_r10(%rax) + movqq %r11,trapframe.tf_r11(%rax) + movqq %r12,trapframe.tf_r12(%rax) + movqq %r13,trapframe.tf_r13(%rax) + movqq %r14,trapframe.tf_r14(%rax) + movqq %r15,trapframe.tf_r15(%rax) + movqq %rsp,trapframe.tf_rsp(%rax) + movqq $rip,trapframe.tf_rip(%rax) //save caller addr movqw %fs,trapframe.tf_fs(%rax) movqw %gs,trapframe.tf_gs(%rax) @@ -131,40 +146,57 @@ asm movqw %cs,trapframe.tf_cs(%rax) movqw %ss,trapframe.tf_ss(%rax) - movq $0,trapframe.tf_trapno(%rax) - movq $0,trapframe.tf_addr (%rax) - movq $0,trapframe.tf_flags (%rax) - movq $0,trapframe.tf_err (%rax) + movqq $0,trapframe.tf_trapno(%rax) + movqq $0,trapframe.tf_addr (%rax) + movqq $1,trapframe.tf_flags (%rax) + movqq $0,trapframe.tf_err (%rax) - movq -16(%rsp),%rax //restore rax + movqq -16(%rsp),%r11 //get rax + movqq %r11,trapframe.tf_rax(%rax) - movq %gs:(0x700),%rsp //curkthread - movq kthread.td_kstack(%rsp),%rsp //td_kstack + pushfq //push FLAGS + popq %r11 //get FLAGS + movqq %r11,trapframe.tf_rflags(%rax) - push %r11 //rip callstack (debugger) + movqq %gs:(0x700),%rsp //curkthread + movqq kthread.td_kstack(%rsp),%rsp //td_kstack - call %rax //Call directly to the address or make an ID table? + andq $-32,%rsp //align stack + + call amd64_syscall + rip: //Restore preserved registers. - movq %gs:(0x700),%rax //curkthread - movq kthread.td_frame(%rax),%rax //td_frame + movqq %gs:(0x700),%rax //curkthread + movqq kthread.td_frame(%rax),%rax //td_frame - movq trapframe.tf_rflags(%rax),%r11 - push %r11 //set FLAGS - popfq //pop FLAGS + movqq trapframe.tf_rflags(%rax),%r11 + pushq %r11 //set FLAGS + popfq //pop FLAGS - movq trapframe.tf_rdi(%rax),%rdi - movq trapframe.tf_rsi(%rax),%rsi - movq trapframe.tf_rdx(%rax),%rdx - movq trapframe.tf_rsp(%rax),%rsp + movqq trapframe.tf_rdi(%rax),%rdi + movqq trapframe.tf_rsi(%rax),%rsi + movqq trapframe.tf_rdx(%rax),%rdx + movqq trapframe.tf_rcx(%rax),%rcx + movqq trapframe.tf_r8 (%rax),%r8 + movqq trapframe.tf_r9 (%rax),%r9 + movqq trapframe.tf_rbx(%rax),%rbx + movqq trapframe.tf_rbp(%rax),%rbp + movqq trapframe.tf_r10(%rax),%r10 + movqq trapframe.tf_r11(%rax),%r11 + movqq trapframe.tf_r12(%rax),%r12 + movqq trapframe.tf_r13(%rax),%r13 + movqq trapframe.tf_r14(%rax),%r14 + movqq trapframe.tf_r15(%rax),%r15 + movqq trapframe.tf_rsp(%rax),%rsp - //restore rip? - movq trapframe.tf_rip(%rax),%r11 - movq %r11,(%rsp) + movqq trapframe.tf_rax(%rax),%rax //restore rax - movq trapframe.tf_rsp(%rax),%rax //restore rax + //epilog (debugger) + popq %rbp end; +//testl $TDF_ASTPENDING | TDF_NEEDRESCHED,TD_FLAGS(%rax) //2: /* AST scheduled. */ //sti //movq %rsp,%rdi