diff --git a/sys/kern_sig.pas b/sys/kern_sig.pas index 8a8eded8..63187947 100644 --- a/sys/kern_sig.pas +++ b/sys/kern_sig.pas @@ -76,11 +76,11 @@ implementation uses ntapi, systm, - md_psl, _umtx, kern_umtx, kern_time, - kern_thread; + kern_thread, + vm_machdep; const max_pending_per_proc=128; @@ -808,10 +808,18 @@ var __set:sigset_t; begin td:=curkthread; - if (td=nil) then Exit(EFAULT); + if (td=nil) then + begin + td^.td_retval[0]:=EFAULT; + Exit(0); + end; Result:=copyin(oset,@__set,sizeof(sigset_t)); - if (Result<>0) then Exit(EFAULT); + if (Result<>0) then + begin + td^.td_retval[0]:=EFAULT; + Exit(0); + end; Result:=kern_sigtimedwait(td,__set,@ksi,nil); if (Result<>0) then @@ -820,10 +828,13 @@ begin begin Result:=ERESTART; end; - Exit; + td^.td_retval[0]:=Result; + Exit(0); end; Result:=copyout(@ksi.ksi_info.si_signo,sig,sizeof(Integer)); + td^.td_retval[0]:=Result; + Result:=0; end; Function sys_sigtimedwait(oset:p_sigset_t;info:p_siginfo_t;timeout:ptimespec):Integer; @@ -834,28 +845,28 @@ var __set:sigset_t; begin td:=curkthread; - if (td=nil) then Exit(-EFAULT); + if (td=nil) then Exit(-1); if (timeout<>nil) then begin Result:=copyin(timeout,@ts,sizeof(timespec)); - if (Result<>0) then Exit(-EFAULT); + if (Result<>0) then Exit; timeout:=@ts; end; Result:=copyin(oset,@__set,sizeof(sigset_t)); - if (Result<>0) then Exit(-EFAULT); + if (Result<>0) then Exit; Result:=kern_sigtimedwait(td,__set,@ksi,timeout); - if (Result<>0) then Exit(-Result); + if (Result<>0) then Exit; if (info<>nil) then begin Result:=copyout(@ksi.ksi_info,info,sizeof(siginfo_t)); - if (Result<>0) then Exit(-EFAULT); + if (Result<>0) then Exit; end; - Result:=ksi.ksi_info.si_signo; + td^.td_retval[0]:=ksi.ksi_info.si_signo; end; Function sys_sigwaitinfo(oset:p_sigset_t;info:p_siginfo_t):Integer; @@ -865,48 +876,21 @@ var __set:sigset_t; begin td:=curkthread; - if (td=nil) then Exit(-EFAULT); + if (td=nil) then Exit(-1); Result:=copyin(oset,@__set,sizeof(sigset_t)); - if (Result<>0) then Exit(-EFAULT); + if (Result<>0) then Exit; Result:=kern_sigtimedwait(td,__set,@ksi,nil); - if (Result<>0) then Exit(-Result); + if (Result<>0) then Exit; if (info<>nil) then begin Result:=copyout(@ksi.ksi_info,info,sizeof(siginfo_t)); - if (Result<>0) then Exit(-EFAULT); + if (Result<>0) then Exit; end; - Result:=ksi.ksi_info.si_signo; -end; - -procedure cpu_set_syscall_retval(td:p_kthread;error:Integer); -begin - Case error of - 0:With td^.td_frame^ do - begin - tf_rax:=td^.td_retval[0]; - tf_rdx:=td^.td_retval[1]; - tf_rflags:=tf_rflags and (not PSL_C); - end; - ERESTART: - With td^.td_frame^ do - begin - //tf_err = size of syscall cmd - tf_rip:=tf_rip-td^.td_frame^.tf_err; - tf_r10:=tf_rcx; - //set_pcb_flags(td->td_pcb, PCB_FULL_IRET); - end; - EJUSTRETURN:; - else - With td^.td_frame^ do - begin - tf_rax:=error; - tf_rflags:=tf_rflags or PSL_C; - end; - end; + td^.td_retval[0]:=ksi.ksi_info.si_signo; end; function postsig(sig:Integer):Integer; forward; @@ -945,7 +929,8 @@ begin Result:=EJUSTRETURN; end; -//TODO check td_errno,td_oldsigmask,td_retval + + function postsig(sig:Integer):Integer; begin diff --git a/sys/kern_thread.pas b/sys/kern_thread.pas index 282c2e19..855656f9 100644 --- a/sys/kern_thread.pas +++ b/sys/kern_thread.pas @@ -227,6 +227,7 @@ implementation uses hamt, systm, + vm_machdep, kern_rwlock, kern_umtx, _umtx, @@ -285,10 +286,7 @@ begin data:=data+SizeOf(kthread); Result^.td_frame:=data; - data:=VirtualAlloc(nil,16*1024,MEM_COMMIT or MEM_RESERVE,PAGE_READWRITE); - - data:=data+16*1024; - Result^.td_kstack:=data; + cpu_thread_alloc(Result); //Result^.td_state:=TDS_INACTIVE; Result^.td_lend_user_pri:=PRI_MAX; @@ -298,14 +296,11 @@ begin end; procedure thread_free(td:p_kthread); -var - data:Pointer; + begin umtx_thread_fini(td); // - data:=td^.td_kstack; - data:=data-16*1024; - VirtualFree(data,0,MEM_RELEASE); + cpu_thread_free(td); // FreeMem(td); end; @@ -403,21 +398,6 @@ begin end; end; -function cpuset_setaffinity(td:p_kthread;new:Ptruint):Integer; -begin - td^.td_cpuset:=new; - Result:=NtSetInformationThread(td^.td_handle,ThreadAffinityMask,@new,SizeOf(Ptruint)); -end; - -procedure cpu_set_user_tls(td:p_kthread;base:Pointer); -var - ptls:PPointer; -begin - ptls:=td^.td_teb+$708; - - ptls^:=base; -end; - function BaseQueryInfo(td:p_kthread):Integer; var TBI:THREAD_BASIC_INFORMATION; @@ -817,22 +797,9 @@ begin td^.td_pri_class:=_class; end; -function sched_priority(td:p_kthread;prio:Integer):Integer; +function sched_priority(td:p_kthread;prio:Integer):Integer; inline; begin - td^.td_priority:=prio; - - Case prio of - 0..255:prio:= 16; - 256..496:prio:= 2; - 497..526:prio:= 1; - 527..556:prio:= 0; - 557..586:prio:=-1; - 587..767:prio:=-2; - else - prio:=-16; - end; - - Result:=NtSetInformationThread(td^.td_handle,ThreadBasePriority,@prio,SizeOf(Integer)); + Result:=cpu_set_priority(td,prio); end; procedure sched_prio(td:p_kthread;prio:Integer); inline; diff --git a/sys/test/project1.lpi b/sys/test/project1.lpi index 14b37a2e..f136d40c 100644 --- a/sys/test/project1.lpi +++ b/sys/test/project1.lpi @@ -85,6 +85,10 @@ + + + + diff --git a/sys/test/project1.lpr b/sys/test/project1.lpr index a4a9c958..c6208974 100644 --- a/sys/test/project1.lpr +++ b/sys/test/project1.lpr @@ -57,12 +57,12 @@ 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:=_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); diff --git a/sys/trap.pas b/sys/trap.pas index 1e46be11..f0396307 100644 --- a/sys/trap.pas +++ b/sys/trap.pas @@ -91,27 +91,40 @@ procedure fast_syscall; implementation +uses + vm_machdep; + type tsyscall=function(rdi,rsi,rdx,rcx,r8,r9:QWORD):Integer; procedure amd64_syscall; var + td:p_kthread; td_frame:p_trapframe; + error:Integer; 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); + + td:=curkthread; + td_frame:=td^.td_frame; + + error:=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); + + if ((td^.td_pflags and TDP_NERRNO)=0) then + begin + td^.td_errno:=error; + end; + + cpu_set_syscall_retval(td,error); end; procedure fast_syscall; assembler; nostackframe; -label - rip; asm //prolog (debugger) pushq %rbp @@ -129,15 +142,12 @@ asm 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) @@ -149,7 +159,17 @@ asm movqq $0,trapframe.tf_trapno(%rax) movqq $0,trapframe.tf_addr (%rax) movqq $1,trapframe.tf_flags (%rax) - movqq $0,trapframe.tf_err (%rax) + movqq $5,trapframe.tf_err (%rax) //sizeof(call $32) + + movqq (%rsp),%r11 //get prev rbp + movqq %r11,trapframe.tf_rbp(%rax) + + movqq %rsp,%r11 + lea 16(%r11),%r11 //get prev rsp + movqq %r11,trapframe.tf_rsp(%rax) + + movqq 8(%rsp),%r11 //get prev rip + movqq %r11,trapframe.tf_rip(%rax) movqq -16(%rsp),%r11 //get rax movqq %r11,trapframe.tf_rax(%rax) @@ -164,7 +184,6 @@ asm andq $-32,%rsp //align stack call amd64_syscall - rip: //Restore preserved registers. movqq %gs:(0x700),%rax //curkthread @@ -181,7 +200,6 @@ asm 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 @@ -190,6 +208,8 @@ asm movqq trapframe.tf_r15(%rax),%r15 movqq trapframe.tf_rsp(%rax),%rsp + lea -16(%rsp),%rsp //restore rsp + movqq trapframe.tf_rax(%rax),%rax //restore rax //epilog (debugger) diff --git a/sys/vm_machdep.pas b/sys/vm_machdep.pas new file mode 100644 index 00000000..fb61d6f6 --- /dev/null +++ b/sys/vm_machdep.pas @@ -0,0 +1,122 @@ +unit vm_machdep; + +{$mode ObjFPC}{$H+} + +interface + +uses + ntapi, + windows, + md_psl, + sys_kernel, + kern_thread; + +function cpu_thread_alloc(td:p_kthread):Integer; +function cpu_thread_free(td:p_kthread):Integer; +procedure cpu_set_syscall_retval(td:p_kthread;error:Integer); +function cpuset_setaffinity(td:p_kthread;new:Ptruint):Integer; +procedure cpu_set_user_tls(td:p_kthread;base:Pointer); +function cpu_set_priority(td:p_kthread;prio:Integer):Integer; + +implementation + +function cpu_thread_alloc(td:p_kthread):Integer; +var + data:Pointer; + size:ULONG_PTR; +begin + data:=nil; + size:=16*1024; + + Result:=NtAllocateVirtualMemory( + NtCurrentProcess, + @data, + 0, + @size, + MEM_COMMIT or MEM_RESERVE, + PAGE_READWRITE + ); + + data:=data+16*1024; + td^.td_kstack:=data; +end; + +function cpu_thread_free(td:p_kthread):Integer; +var + data:Pointer; + size:ULONG_PTR; +begin + data:=td^.td_kstack; + data:=data-16*1024; + size:=0; + + Result:=NtFreeVirtualMemory( + NtCurrentProcess, + @data, + @size, + MEM_RELEASE + ); +end; + +procedure cpu_set_syscall_retval(td:p_kthread;error:Integer); +begin + Case error of + 0:With td^.td_frame^ do + begin + tf_rax:=td^.td_retval[0]; + tf_rdx:=td^.td_retval[1]; + tf_rflags:=tf_rflags and (not PSL_C); + end; + ERESTART: + With td^.td_frame^ do + begin + //tf_err = size of syscall cmd + tf_rip:=tf_rip-td^.td_frame^.tf_err; + tf_r10:=tf_rcx; + //set_pcb_flags(td->td_pcb, PCB_FULL_IRET); + end; + EJUSTRETURN:; + else + With td^.td_frame^ do + begin + tf_rax:=error; + tf_rflags:=tf_rflags or PSL_C; + end; + end; +end; + +function cpuset_setaffinity(td:p_kthread;new:Ptruint):Integer; +begin + td^.td_cpuset:=new; + Result:=NtSetInformationThread(td^.td_handle,ThreadAffinityMask,@new,SizeOf(Ptruint)); +end; + +procedure cpu_set_user_tls(td:p_kthread;base:Pointer); +var + ptls:PPointer; +begin + ptls:=td^.td_teb+$708; + + ptls^:=base; +end; + +function cpu_set_priority(td:p_kthread;prio:Integer):Integer; +begin + td^.td_priority:=prio; + + Case prio of + 0..255:prio:= 16; + 256..496:prio:= 2; + 497..526:prio:= 1; + 527..556:prio:= 0; + 557..586:prio:=-1; + 587..767:prio:=-2; + else + prio:=-16; + end; + + Result:=NtSetInformationThread(td^.td_handle,ThreadBasePriority,@prio,SizeOf(Integer)); +end; + +end. +