diff --git a/kernel/libthr/thr_umtx.pas b/kernel/libthr/thr_umtx.pas
index b573b76f..31022933 100644
--- a/kernel/libthr/thr_umtx.pas
+++ b/kernel/libthr/thr_umtx.pas
@@ -75,6 +75,11 @@ uses
errno,
thr_init;
+function TID(thr:p_pthread):Integer; inline;
+begin
+ Result:=thr^.tid;
+end;
+
function atomic_cmpset_acq_32(p:PDWORD;cmpval,newval:DWORD):DWORD; inline;
begin
Result:=System.InterlockedCompareExchange(p^,newval,cmpval);
diff --git a/sys/fs/ufs/md_vnops.pas b/sys/fs/ufs/md_vnops.pas
index 4a202bc8..4764fe39 100644
--- a/sys/fs/ufs/md_vnops.pas
+++ b/sys/fs/ufs/md_vnops.pas
@@ -122,7 +122,6 @@ uses
vstat,
vfs_subr,
subr_uio,
- kern_time,
kern_thr;
const
diff --git a/sys/kern/kern_sig.pas b/sys/kern/kern_sig.pas
index 4cdfa573..08c79ee0 100644
--- a/sys/kern/kern_sig.pas
+++ b/sys/kern/kern_sig.pas
@@ -10,8 +10,7 @@ uses
time,
signal,
signalvar,
- kern_thr,
- rtprio;
+ kern_thr;
const
SA_KILL =$01; // terminates process by default
@@ -113,8 +112,7 @@ uses
kern_exit,
kern_prot,
kern_synch,
- vm_machdep,
- md_thread,
+ md_context,
md_proc,
machdep,
sched_ule,
diff --git a/sys/kern/kern_synch.pas b/sys/kern/kern_synch.pas
index f1b7895f..97b9e72f 100644
--- a/sys/kern/kern_synch.pas
+++ b/sys/kern/kern_synch.pas
@@ -56,7 +56,7 @@ implementation
uses
kern_thread,
sched_ule,
- vm_machdep,
+ md_sleep,
rtprio;
function msleep(ident :Pointer;
diff --git a/sys/kern/kern_thread.pas b/sys/kern/kern_thread.pas
index 862ed8c1..d1e93160 100644
--- a/sys/kern/kern_thread.pas
+++ b/sys/kern/kern_thread.pas
@@ -84,7 +84,8 @@ implementation
uses
errno,
systm,
- vm_machdep,
+ md_sleep,
+ md_context,
machdep,
md_proc,
md_thread,
diff --git a/sys/kern/kern_umtx.pas b/sys/kern/kern_umtx.pas
index 43101c64..4081fef0 100644
--- a/sys/kern/kern_umtx.pas
+++ b/sys/kern/kern_umtx.pas
@@ -89,9 +89,8 @@ uses
HAMT,
errno,
systm,
- trap,
md_time,
- vm_machdep,
+ md_sleep,
kern_thread,
sched_ule;
@@ -1548,6 +1547,7 @@ begin
end else
begin
ets:=TIMESPEC_TO_UNIT(timeout);
+ tts:=ets;
cts:=0;
Result:=kern_clock_gettime_unit(clockid,@cts);
diff --git a/sys/kern/machdep.pas b/sys/kern/machdep.pas
index 23e22605..e6f28707 100644
--- a/sys/kern/machdep.pas
+++ b/sys/kern/machdep.pas
@@ -38,7 +38,8 @@ uses
systm,
md_psl,
kern_sig,
- trap;
+ trap,
+ md_context;
//clearing memory without AVX optimizations
procedure bzero(ptr:Pointer;size:ptrint);
@@ -207,15 +208,14 @@ begin
//xmm,ymm
if ((tp^.tf_flags and TF_HASFPXSTATE)<>0) then
begin
- get_fpcontext(td,mcp,@mcp^.mc_fpstate);
+ Result:=get_fpcontext(td,mcp,@mcp^.mc_fpstate);
end else
begin
- //get md
+ Result:=md_get_fpcontext(td,mcp,@mcp^.mc_fpstate);
end;
+ if (Result<>0) then Exit;
//xmm,ymm
- mcp^.mc_fpformat:=_MC_FPFMT_XMM;
-
mcp^.mc_fsbase:=ptruint(td^.pcb_fsbase);
mcp^.mc_gsbase:=ptruint(td^.pcb_gsbase);
diff --git a/sys/kern/md_sleep.pas b/sys/kern/md_sleep.pas
new file mode 100644
index 00000000..a6ccfc93
--- /dev/null
+++ b/sys/kern/md_sleep.pas
@@ -0,0 +1,119 @@
+unit md_sleep;
+
+{$mode ObjFPC}{$H+}
+{$CALLING SysV_ABI_CDecl}
+
+interface
+
+uses
+ ntapi,
+ windows,
+ kern_thr;
+
+function _umtxq_alloc:THandle;
+procedure _umtxq_free(h:THandle);
+function msleep_umtxq(h:THandle;timo:Int64):Integer; inline;
+function wakeup_umtxq(h:THandle):Integer; inline;
+
+function msleep_td(timo:Int64):Integer; inline;
+function wakeup_td(td:p_kthread):Integer; inline;
+procedure md_yield; inline;
+
+implementation
+
+uses
+ errno,
+ trap;
+
+function ntw2px(n:Integer):Integer; inline;
+begin
+ Case DWORD(n) of
+ STATUS_SUCCESS :Result:=0;
+ STATUS_ABANDONED :Result:=EPERM;
+ STATUS_ALERTED :Result:=EINTR;
+ STATUS_USER_APC :Result:=EINTR;
+ STATUS_TIMEOUT :Result:=ETIMEDOUT;
+ STATUS_ACCESS_VIOLATION:Result:=EFAULT;
+ else
+ Result:=EINVAL;
+ end;
+end;
+
+function ntd2px(n:Integer):Integer; inline;
+begin
+ Case DWORD(n) of
+ STATUS_SUCCESS :Result:=ETIMEDOUT;
+ STATUS_ABANDONED :Result:=EPERM;
+ STATUS_ALERTED :Result:=EINTR;
+ STATUS_USER_APC :Result:=EINTR;
+ STATUS_ACCESS_VIOLATION:Result:=EFAULT;
+ else
+ Result:=EINVAL;
+ end;
+end;
+
+function _umtxq_alloc:THandle;
+var
+ n:Integer;
+begin
+ Result:=0;
+ n:=NtCreateEvent(@Result,EVENT_ALL_ACCESS,nil,SynchronizationEvent,False);
+ Assert(n=0);
+end;
+
+procedure _umtxq_free(h:THandle);
+begin
+ NtClose(h);
+end;
+
+function msleep_umtxq(h:THandle;timo:Int64):Integer; inline;
+begin
+ if (timo=0) then
+ begin
+ timo:=NT_INFINITE;
+ end else
+ begin
+ timo:=-timo;
+ end;
+ sig_sta;
+ Result:=ntw2px(NtWaitForSingleObject(h,True,@timo));
+ sig_cla;
+end;
+
+function wakeup_umtxq(h:THandle):Integer; inline;
+begin
+ Result:=ntw2px(NtSetEvent(h,nil));
+end;
+
+function msleep_td(timo:Int64):Integer; inline;
+begin
+ if (timo=0) then
+ begin
+ timo:=NT_INFINITE;
+ end else
+ begin
+ timo:=-timo;
+ end;
+ sig_sta;
+ Result:=ntd2px(NtDelayExecution(True,@timo));
+ sig_cla;
+end;
+
+procedure _apc_null(dwParam:PTRUINT); stdcall;
+begin
+end;
+
+function wakeup_td(td:p_kthread):Integer; inline;
+begin
+ Result:=ntw2px(NtQueueApcThread(td^.td_handle,@_apc_null,nil,nil,0));
+end;
+
+procedure md_yield; inline;
+begin
+ NtYieldExecution;
+end;
+
+end.
+
+
+
diff --git a/sys/kern/sched_ule.pas b/sys/kern/sched_ule.pas
index 981c1a6b..8f1ea547 100644
--- a/sys/kern/sched_ule.pas
+++ b/sys/kern/sched_ule.pas
@@ -24,7 +24,7 @@ function setrunnable(td:p_kthread):Integer;
implementation
uses
- vm_machdep,
+ md_sleep,
md_thread;
procedure sched_fork_thread(td,childtd:p_kthread);
diff --git a/sys/kern/trap.pas b/sys/kern/trap.pas
index 486d5834..b66deb4e 100644
--- a/sys/kern/trap.pas
+++ b/sys/kern/trap.pas
@@ -117,7 +117,7 @@ implementation
uses
errno,
machdep,
- vm_machdep,
+ md_context,
kern_sig,
sysent;
diff --git a/sys/kern/vm_machdep.pas b/sys/kern/vm_machdep.pas
deleted file mode 100644
index 2c09de1e..00000000
--- a/sys/kern/vm_machdep.pas
+++ /dev/null
@@ -1,394 +0,0 @@
-unit vm_machdep;
-
-{$mode ObjFPC}{$H+}
-{$CALLING SysV_ABI_CDecl}
-
-interface
-
-uses
- ntapi,
- windows,
- md_psl,
- ucontext,
- trap,
- kern_thr;
-
-procedure ipi_sigreturn;
-function ipi_send_cpu(td:p_kthread):Integer;
-
-function _umtxq_alloc:THandle;
-procedure _umtxq_free(h:THandle);
-function msleep_umtxq(h:THandle;timo:Int64):Integer; inline;
-function wakeup_umtxq(h:THandle):Integer; inline;
-
-function msleep_td(timo:Int64):Integer; inline;
-function wakeup_td(td:p_kthread):Integer; inline;
-procedure md_yield; inline;
-
-implementation
-
-uses
- errno,
- systm,
- machdep,
- md_context,
- signal,
- kern_sig,
- md_thread;
-
-function ntw2px(n:Integer):Integer; inline;
-begin
- Case DWORD(n) of
- STATUS_SUCCESS :Result:=0;
- STATUS_ABANDONED :Result:=EPERM;
- STATUS_ALERTED :Result:=EINTR;
- STATUS_USER_APC :Result:=EINTR;
- STATUS_TIMEOUT :Result:=ETIMEDOUT;
- STATUS_ACCESS_VIOLATION:Result:=EFAULT;
- else
- Result:=EINVAL;
- end;
-end;
-
-function ntd2px(n:Integer):Integer; inline;
-begin
- Case DWORD(n) of
- STATUS_SUCCESS :Result:=ETIMEDOUT;
- STATUS_ABANDONED :Result:=EPERM;
- STATUS_ALERTED :Result:=EINTR;
- STATUS_USER_APC :Result:=EINTR;
- STATUS_ACCESS_VIOLATION:Result:=EFAULT;
- else
- Result:=EINVAL;
- end;
-end;
-
-function _umtxq_alloc:THandle;
-var
- n:Integer;
-begin
- Result:=0;
- n:=NtCreateEvent(@Result,EVENT_ALL_ACCESS,nil,SynchronizationEvent,False);
- Assert(n=0);
-end;
-
-procedure _umtxq_free(h:THandle);
-begin
- NtClose(h);
-end;
-
-function msleep_umtxq(h:THandle;timo:Int64):Integer; inline;
-begin
- if (timo=0) then
- begin
- timo:=NT_INFINITE;
- end else
- begin
- timo:=-timo;
- end;
- sig_sta;
- Result:=ntw2px(NtWaitForSingleObject(h,True,@timo));
- sig_cla;
-end;
-
-function wakeup_umtxq(h:THandle):Integer; inline;
-begin
- Result:=ntw2px(NtSetEvent(h,nil));
-end;
-
-function msleep_td(timo:Int64):Integer; inline;
-begin
- if (timo=0) then
- begin
- timo:=NT_INFINITE;
- end else
- begin
- timo:=-timo;
- end;
- sig_sta;
- Result:=ntd2px(NtDelayExecution(True,@timo));
- sig_cla;
-end;
-
-procedure _apc_null(dwParam:PTRUINT); stdcall;
-begin
-end;
-
-function wakeup_td(td:p_kthread):Integer; inline;
-begin
- Result:=ntw2px(NtQueueApcThread(td^.td_handle,@_apc_null,nil,nil,0));
-end;
-
-procedure md_yield; inline;
-begin
- NtYieldExecution;
-end;
-
-function cpu_get_iflag(td:p_kthread):PInteger; inline;
-begin
- Result:=@td^.td_teb^.iflag;
-end;
-
-function IS_SYSTEM_STACK(td:p_kthread;rsp:qword):Boolean; inline;
-begin
- Result:=(rsp<=QWORD(td^.td_kstack)) and (rsp>(QWORD(td^.td_kstack)-SYS_STACK_SIZE));
-end;
-
-function IS_SYSCALL(rip:qword):Boolean;
-var
- w:Word;
-begin
- Result:=False;
- if (rip<>0) then
- begin
- w:=0;
- NtReadVirtualMemory(NtCurrentProcess,@PWord(Rip)[-1],@w,SizeOf(Word),nil);
- Result:=(w=$050F);
- end;
-end;
-
-function get_top_mem_td(td:p_kthread;size,align:qword):Pointer;
-begin
- Result:=System.Align(td^.td_ksttop,align);
- if ((Result+size)>=SPtr) then Exit(nil);
-end;
-
-procedure ipi_sigreturn;
-var
- td:p_kthread;
- Context:PCONTEXT;
- regs:p_trapframe;
-begin
- td:=curkthread;
- regs:=td^.td_frame;
-
- if ((regs^.tf_flags and TF_HASFPXSTATE)<>0) then
- begin
- //xmm,ymm
- Context:=get_top_mem_td(td,GetContextSize(CONTEXT_ALLX),16);
- Assert(Context<>nil);
- Context:=InitializeContextExtended(Context,CONTEXT_ALLX);
- end else
- begin
- //simple
- Context:=get_top_mem_td(td,SizeOf(TCONTEXT),16);
- Assert(Context<>nil);
- Context^:=Default(TCONTEXT);
- Context^.ContextFlags:=CONTEXT_INTEGER or CONTEXT_CONTROL;
- end;
-
- Context^.Rdi:=regs^.tf_rdi;
- Context^.Rsi:=regs^.tf_rsi;
- Context^.Rdx:=regs^.tf_rdx;
- Context^.Rcx:=regs^.tf_rcx;
- Context^.R8 :=regs^.tf_r8 ;
- Context^.R9 :=regs^.tf_r9 ;
- Context^.Rax:=regs^.tf_rax;
- Context^.Rbx:=regs^.tf_rbx;
- Context^.Rbp:=regs^.tf_rbp;
- Context^.R10:=regs^.tf_r10;
- Context^.R11:=regs^.tf_r11;
- Context^.R12:=regs^.tf_r12;
- Context^.R13:=regs^.tf_r13;
- Context^.R14:=regs^.tf_r14;
- Context^.R15:=regs^.tf_r15;
-
- Context^.Rip :=regs^.tf_rip;
- Context^.EFlags:=regs^.tf_rflags;
- Context^.Rsp :=regs^.tf_rsp;
-
- Context^.SegGs:=KGDT64_R3_DATA or RPL_MASK;
- Context^.SegEs:=KGDT64_R3_DATA or RPL_MASK;
- Context^.SegDs:=KGDT64_R3_DATA or RPL_MASK;
- Context^.SegCs:=KGDT64_R3_CODE or RPL_MASK;
- Context^.SegSs:=KGDT64_R3_DATA or RPL_MASK;
- Context^.SegFs:=KGDT64_R3_CMTEB or RPL_MASK;
-
- //xmm,ymm
- if ((regs^.tf_flags and TF_HASFPXSTATE)<>0) then
- begin
- _set_fpcontext(Context,@td^.td_fpstate);
-
- regs^.tf_flags:=regs^.tf_flags and (not TF_HASFPXSTATE);
- end;
- //xmm,ymm
-
- NtContinue(Context,False);
-end;
-
-function ipi_send_cpu(td:p_kthread):Integer;
-label
- resume,
- tryagain;
-var
- td_handle:THandle;
- iflag :PInteger;
- Context :PCONTEXT;
- w:LARGE_INTEGER;
- sf:sigframe;
- sfp:p_sigframe;
- regs:p_trapframe;
- sp:QWORD;
- oonstack:Integer;
-begin
- Result :=0;
- td_handle:=td^.td_handle;
- iflag :=cpu_get_iflag(td);
-
- PROC_LOCK;
-
- tryagain:
-
- if (NtSuspendThread(td_handle,nil)<>STATUS_SUCCESS) then
- begin
- PROC_UNLOCK;
- Exit(ESRCH);
- end;
-
- w.QuadPart:=0;
- if (NtWaitForSingleObject(td_handle,False,@w)<>STATUS_TIMEOUT) then
- begin
- Result:=ESRCH;
- goto resume;
- end;
-
- if ((iflag^ and SIG_ALTERABLE)<>0) then //alterable?
- begin
- NtQueueApcThread(td_handle,@_apc_null,nil,nil,0);
- Result:=0;
- goto resume;
- end else
- if (iflag^<>0) then //locked?
- begin
- Result:=0;
- goto resume;
- end;
-
- Context:=get_top_mem_td(td,GetContextSize(CONTEXT_ALLX),16);
- Assert(Context<>nil);
- Context:=InitializeContextExtended(Context,CONTEXT_ALLX);
-
- if (NtGetContextThread(td_handle,Context)<>STATUS_SUCCESS) then
- begin
- Result:=ESRCH;
- goto resume;
- end;
-
- if IS_SYSTEM_STACK(td,Context^.Rsp) then //system?
- begin
- Result:=0;
- goto resume;
- end;
-
- if IS_SYSCALL(Context^.Rip) then //system call in code without blocking
- begin
- NtResumeThread(td_handle,nil);
- w.QuadPart:=-10000;
- NtDelayExecution(False,@w); //100ms
- goto tryagain;
- end;
-
- regs:=td^.td_frame;
- oonstack:=sigonstack(Context^.Rsp);
-
- // Save user context.
- sf:=Default(sigframe);
-
- sf.sf_uc.uc_sigmask:=td^.td_sigmask;
- sf.sf_uc.uc_stack :=td^.td_sigstk;
-
- if ((td^.td_pflags and TDP_ALTSTACK)<>0) then
- begin
- if (oonstack<>0) then
- begin
- sf.sf_uc.uc_stack.ss_flags:=SS_ONSTACK;
- end else
- begin
- sf.sf_uc.uc_stack.ss_flags:=0;
- end;
- end else
- begin
- sf.sf_uc.uc_stack.ss_flags:=SS_DISABLE;
- end;
-
- //copy frame
- regs^.tf_rdi:=Context^.Rdi;
- regs^.tf_rsi:=Context^.Rsi;
- regs^.tf_rdx:=Context^.Rdx;
- regs^.tf_rcx:=Context^.Rcx;
- regs^.tf_r8 :=Context^.R8 ;
- regs^.tf_r9 :=Context^.R9 ;
- regs^.tf_rax:=Context^.Rax;
- regs^.tf_rbx:=Context^.Rbx;
- regs^.tf_rbp:=Context^.Rbp;
- regs^.tf_r10:=Context^.R10;
- regs^.tf_r11:=Context^.R11;
- regs^.tf_r12:=Context^.R12;
- regs^.tf_r13:=Context^.R13;
- regs^.tf_r14:=Context^.R14;
- regs^.tf_r15:=Context^.R15;
-
- regs^.tf_rip :=Context^.Rip;
- regs^.tf_rflags:=Context^.EFlags;
- regs^.tf_rsp :=Context^.Rsp;
-
- regs^.tf_cs:=_ucodesel;
- regs^.tf_ds:=_udatasel;
- regs^.tf_ss:=_udatasel;
- regs^.tf_es:=_udatasel;
- regs^.tf_fs:=_ufssel;
- regs^.tf_gs:=_ugssel;
- regs^.tf_flags:=TF_HASSEGS;
- //copy frame
-
- sf.sf_uc.uc_mcontext.mc_onstack:=oonstack;
-
- Move(regs^,sf.sf_uc.uc_mcontext.mc_rdi,SizeOf(trapframe));
-
- sf.sf_uc.uc_mcontext.mc_len:=sizeof(mcontext_t);
-
- sf.sf_uc.uc_mcontext.mc_fsbase:=QWORD(td^.pcb_fsbase);
- sf.sf_uc.uc_mcontext.mc_gsbase:=QWORD(td^.pcb_gsbase);
-
- sf.sf_uc.uc_mcontext.mc_flags:=_MC_HASSEGS or _MC_HASBASES or _MC_HASFPXSTATE;
-
- //xmm,ymm
- _get_fpcontext(Context,@sf.sf_uc.uc_mcontext.mc_fpstate);
-
- sf.sf_uc.uc_mcontext.mc_fpformat:=_MC_FPFMT_XMM;
- sf.sf_uc.uc_mcontext.mc_ownedfp :=_MC_FPOWNED_FPU;
- //xmm,ymm
-
- sp:=QWORD(td^.td_kstack);
-
- sp:=sp-sizeof(sigframe);
-
- sfp:=p_sigframe(sp and (not $1F));
-
- if (copyout(@sf,sfp,sizeof(sigframe))<>0) then
- begin
- Result:=EFAULT;
- goto resume;
- end;
-
- Context^.Rsp:=QWORD(sfp);
- Context^.Rip:=QWORD(@sigipi);
- Context^.EFlags:=Context^.EFlags and (not (PSL_T or PSL_D));
-
- set_pcb_flags(td,PCB_FULL_IRET);
-
- if (NtSetContextThread(td_handle,Context)<>STATUS_SUCCESS) then
- begin
- Result:=ESRCH;
- goto resume;
- end;
-
- resume:
- NtResumeThread(td_handle,nil);
- PROC_UNLOCK;
-end;
-
-end.
-
-
-
diff --git a/sys/md_context.pas b/sys/md_context.pas
index 7f357569..2bff5408 100644
--- a/sys/md_context.pas
+++ b/sys/md_context.pas
@@ -7,9 +7,8 @@ interface
uses
Windows,
ntapi,
- signal,
ucontext,
- machdep;
+ kern_thr;
const
XSTATE_LEGACY_FLOATING_POINT=0;
@@ -81,8 +80,28 @@ procedure _set_fpcontext(dst:PCONTEXT;xstate:Pointer);
procedure _get_ucontext(src:PCONTEXT;dst:p_ucontext_t);
procedure _set_ucontext(dst:PCONTEXT;src:p_ucontext_t);
+function md_get_fpcontext(td:p_kthread;mcp:p_mcontext_t;xstate:Pointer):Integer;
+
+procedure ipi_sigreturn;
+function ipi_send_cpu(td:p_kthread):Integer;
+
implementation
+uses
+ errno,
+ systm,
+ trap,
+ md_psl,
+ signal,
+ kern_sig,
+ md_thread;
+
+const
+ _ucodesel=(8 shl 3) or 3;
+ _udatasel=(7 shl 3) or 3;
+ _ufssel =(2 shl 3) or 3;
+ _ugssel =(3 shl 3) or 3;
+
function GetEnabledXStateFeatures:QWORD; stdcall external 'kernel32';
function InitializeContext(
@@ -316,5 +335,298 @@ begin
end;
+function cpu_get_iflag(td:p_kthread):PInteger; inline;
+begin
+ Result:=@td^.td_teb^.iflag;
+end;
+
+function IS_SYSTEM_STACK(td:p_kthread;rsp:qword):Boolean; inline;
+begin
+ Result:=(rsp<=QWORD(td^.td_kstack)) and (rsp>(QWORD(td^.td_kstack)-SYS_STACK_SIZE));
+end;
+
+function IS_SYSCALL(rip:qword):Boolean;
+var
+ w:Word;
+begin
+ Result:=False;
+ if (rip<>0) then
+ begin
+ w:=0;
+ NtReadVirtualMemory(NtCurrentProcess,@PWord(Rip)[-1],@w,SizeOf(Word),nil);
+ Result:=(w=$050F);
+ end;
+end;
+
+function get_top_mem_td(td:p_kthread;size,align:qword):Pointer;
+begin
+ Result:=System.Align(td^.td_ksttop,align);
+ if ((Result+size)>=SPtr) then Exit(nil);
+end;
+
+procedure _apc_null(dwParam:PTRUINT); stdcall;
+begin
+end;
+
+function md_get_fpcontext(td:p_kthread;mcp:p_mcontext_t;xstate:Pointer):Integer;
+var
+ td_handle:THandle;
+ Context :PCONTEXT;
+begin
+ Result :=0;
+ td_handle:=td^.td_handle;
+
+ Context:=get_top_mem_td(td,GetContextSize(CONTEXT_XSTATE),16);
+ Assert(Context<>nil);
+ Context:=InitializeContextExtended(Context,CONTEXT_XSTATE);
+
+ if (NtGetContextThread(td_handle,Context)<>STATUS_SUCCESS) then
+ begin
+ Exit(ESRCH)
+ end;
+
+ //xmm,ymm
+ _get_fpcontext(Context,xstate);
+
+ mcp^.mc_fpformat:=_MC_FPFMT_XMM;
+ mcp^.mc_ownedfp :=_MC_FPOWNED_FPU;
+ //xmm,ymm
+end;
+
+procedure ipi_sigreturn;
+var
+ td:p_kthread;
+ Context:PCONTEXT;
+ regs:p_trapframe;
+begin
+ td:=curkthread;
+ regs:=td^.td_frame;
+
+ if ((regs^.tf_flags and TF_HASFPXSTATE)<>0) then
+ begin
+ //xmm,ymm
+ Context:=get_top_mem_td(td,GetContextSize(CONTEXT_ALLX),16);
+ Assert(Context<>nil);
+ Context:=InitializeContextExtended(Context,CONTEXT_ALLX);
+ end else
+ begin
+ //simple
+ Context:=get_top_mem_td(td,SizeOf(TCONTEXT),16);
+ Assert(Context<>nil);
+ Context^:=Default(TCONTEXT);
+ Context^.ContextFlags:=CONTEXT_INTEGER or CONTEXT_CONTROL;
+ end;
+
+ Context^.Rdi:=regs^.tf_rdi;
+ Context^.Rsi:=regs^.tf_rsi;
+ Context^.Rdx:=regs^.tf_rdx;
+ Context^.Rcx:=regs^.tf_rcx;
+ Context^.R8 :=regs^.tf_r8 ;
+ Context^.R9 :=regs^.tf_r9 ;
+ Context^.Rax:=regs^.tf_rax;
+ Context^.Rbx:=regs^.tf_rbx;
+ Context^.Rbp:=regs^.tf_rbp;
+ Context^.R10:=regs^.tf_r10;
+ Context^.R11:=regs^.tf_r11;
+ Context^.R12:=regs^.tf_r12;
+ Context^.R13:=regs^.tf_r13;
+ Context^.R14:=regs^.tf_r14;
+ Context^.R15:=regs^.tf_r15;
+
+ Context^.Rip :=regs^.tf_rip;
+ Context^.EFlags:=regs^.tf_rflags;
+ Context^.Rsp :=regs^.tf_rsp;
+
+ Context^.SegGs:=KGDT64_R3_DATA or RPL_MASK;
+ Context^.SegEs:=KGDT64_R3_DATA or RPL_MASK;
+ Context^.SegDs:=KGDT64_R3_DATA or RPL_MASK;
+ Context^.SegCs:=KGDT64_R3_CODE or RPL_MASK;
+ Context^.SegSs:=KGDT64_R3_DATA or RPL_MASK;
+ Context^.SegFs:=KGDT64_R3_CMTEB or RPL_MASK;
+
+ //xmm,ymm
+ if ((regs^.tf_flags and TF_HASFPXSTATE)<>0) then
+ begin
+ _set_fpcontext(Context,@td^.td_fpstate);
+
+ regs^.tf_flags:=regs^.tf_flags and (not TF_HASFPXSTATE);
+ end;
+ //xmm,ymm
+
+ NtContinue(Context,False);
+end;
+
+function ipi_send_cpu(td:p_kthread):Integer;
+label
+ resume,
+ tryagain;
+var
+ td_handle:THandle;
+ iflag :PInteger;
+ Context :PCONTEXT;
+ w:LARGE_INTEGER;
+ sf:sigframe;
+ sfp:p_sigframe;
+ regs:p_trapframe;
+ sp:QWORD;
+ oonstack:Integer;
+begin
+ Result :=0;
+ td_handle:=td^.td_handle;
+ iflag :=cpu_get_iflag(td);
+
+ PROC_LOCK;
+
+ tryagain:
+
+ if (NtSuspendThread(td_handle,nil)<>STATUS_SUCCESS) then
+ begin
+ PROC_UNLOCK;
+ Exit(ESRCH);
+ end;
+
+ w.QuadPart:=0;
+ if (NtWaitForSingleObject(td_handle,False,@w)<>STATUS_TIMEOUT) then
+ begin
+ Result:=ESRCH;
+ goto resume;
+ end;
+
+ if ((iflag^ and SIG_ALTERABLE)<>0) then //alterable?
+ begin
+ NtQueueApcThread(td_handle,@_apc_null,nil,nil,0);
+ Result:=0;
+ goto resume;
+ end else
+ if (iflag^<>0) then //locked?
+ begin
+ Result:=0;
+ goto resume;
+ end;
+
+ Context:=get_top_mem_td(td,GetContextSize(CONTEXT_ALLX),16);
+ Assert(Context<>nil);
+ Context:=InitializeContextExtended(Context,CONTEXT_ALLX);
+
+ if (NtGetContextThread(td_handle,Context)<>STATUS_SUCCESS) then
+ begin
+ Result:=ESRCH;
+ goto resume;
+ end;
+
+ if IS_SYSTEM_STACK(td,Context^.Rsp) then //system?
+ begin
+ Result:=0;
+ goto resume;
+ end;
+
+ if IS_SYSCALL(Context^.Rip) then //system call in code without blocking
+ begin
+ NtResumeThread(td_handle,nil);
+ w.QuadPart:=-10000;
+ NtDelayExecution(False,@w); //100ms
+ goto tryagain;
+ end;
+
+ regs:=td^.td_frame;
+ oonstack:=sigonstack(Context^.Rsp);
+
+ // Save user context.
+ sf:=Default(sigframe);
+
+ sf.sf_uc.uc_sigmask:=td^.td_sigmask;
+ sf.sf_uc.uc_stack :=td^.td_sigstk;
+
+ if ((td^.td_pflags and TDP_ALTSTACK)<>0) then
+ begin
+ if (oonstack<>0) then
+ begin
+ sf.sf_uc.uc_stack.ss_flags:=SS_ONSTACK;
+ end else
+ begin
+ sf.sf_uc.uc_stack.ss_flags:=0;
+ end;
+ end else
+ begin
+ sf.sf_uc.uc_stack.ss_flags:=SS_DISABLE;
+ end;
+
+ //copy frame
+ regs^.tf_rdi:=Context^.Rdi;
+ regs^.tf_rsi:=Context^.Rsi;
+ regs^.tf_rdx:=Context^.Rdx;
+ regs^.tf_rcx:=Context^.Rcx;
+ regs^.tf_r8 :=Context^.R8 ;
+ regs^.tf_r9 :=Context^.R9 ;
+ regs^.tf_rax:=Context^.Rax;
+ regs^.tf_rbx:=Context^.Rbx;
+ regs^.tf_rbp:=Context^.Rbp;
+ regs^.tf_r10:=Context^.R10;
+ regs^.tf_r11:=Context^.R11;
+ regs^.tf_r12:=Context^.R12;
+ regs^.tf_r13:=Context^.R13;
+ regs^.tf_r14:=Context^.R14;
+ regs^.tf_r15:=Context^.R15;
+
+ regs^.tf_rip :=Context^.Rip;
+ regs^.tf_rflags:=Context^.EFlags;
+ regs^.tf_rsp :=Context^.Rsp;
+
+ regs^.tf_cs:=_ucodesel;
+ regs^.tf_ds:=_udatasel;
+ regs^.tf_ss:=_udatasel;
+ regs^.tf_es:=_udatasel;
+ regs^.tf_fs:=_ufssel;
+ regs^.tf_gs:=_ugssel;
+ regs^.tf_flags:=TF_HASSEGS;
+ //copy frame
+
+ sf.sf_uc.uc_mcontext.mc_onstack:=oonstack;
+
+ Move(regs^,sf.sf_uc.uc_mcontext.mc_rdi,SizeOf(trapframe));
+
+ sf.sf_uc.uc_mcontext.mc_len:=sizeof(mcontext_t);
+
+ sf.sf_uc.uc_mcontext.mc_fsbase:=QWORD(td^.pcb_fsbase);
+ sf.sf_uc.uc_mcontext.mc_gsbase:=QWORD(td^.pcb_gsbase);
+
+ sf.sf_uc.uc_mcontext.mc_flags:=_MC_HASSEGS or _MC_HASBASES or _MC_HASFPXSTATE;
+
+ //xmm,ymm
+ _get_fpcontext(Context,@sf.sf_uc.uc_mcontext.mc_fpstate);
+
+ sf.sf_uc.uc_mcontext.mc_fpformat:=_MC_FPFMT_XMM;
+ sf.sf_uc.uc_mcontext.mc_ownedfp :=_MC_FPOWNED_FPU;
+ //xmm,ymm
+
+ sp:=QWORD(td^.td_kstack);
+
+ sp:=sp-sizeof(sigframe);
+
+ sfp:=p_sigframe(sp and (not $1F));
+
+ if (copyout(@sf,sfp,sizeof(sigframe))<>0) then
+ begin
+ Result:=EFAULT;
+ goto resume;
+ end;
+
+ Context^.Rsp:=QWORD(sfp);
+ Context^.Rip:=QWORD(@sigipi);
+ Context^.EFlags:=Context^.EFlags and (not (PSL_T or PSL_D));
+
+ set_pcb_flags(td,PCB_FULL_IRET);
+
+ if (NtSetContextThread(td_handle,Context)<>STATUS_SUCCESS) then
+ begin
+ Result:=ESRCH;
+ goto resume;
+ end;
+
+ resume:
+ NtResumeThread(td_handle,nil);
+ PROC_UNLOCK;
+end;
+
end.
diff --git a/sys/sys_machdep.pas b/sys/sys_machdep.pas
index baa634cc..3e84e8bb 100644
--- a/sys/sys_machdep.pas
+++ b/sys/sys_machdep.pas
@@ -57,6 +57,8 @@ var
iargs :t_i386_ioperm_args;
begin
Result:=0;
+ i386base:=0;
+ a64base :=0;
//read
case op of
diff --git a/sys/test/project1.lpi b/sys/test/project1.lpi
index 6215404c..285757cb 100644
--- a/sys/test/project1.lpi
+++ b/sys/test/project1.lpi
@@ -121,10 +121,6 @@
-
-
-
-
@@ -545,6 +541,10 @@
+
+
+
+
diff --git a/sys/test/project1.lpr b/sys/test/project1.lpr
index e0fcf78e..f7aa8661 100644
--- a/sys/test/project1.lpr
+++ b/sys/test/project1.lpr
@@ -80,7 +80,7 @@ uses
md_proc,
kern_ksched,
kern_uuid,
- kern_gpo,
+ kern_gpo, md_sleep,
sys_machdep;
var
diff --git a/sys/vfs/vfs_mountroot.pas b/sys/vfs/vfs_mountroot.pas
index 13aac80c..01cbb140 100644
--- a/sys/vfs/vfs_mountroot.pas
+++ b/sys/vfs/vfs_mountroot.pas
@@ -233,7 +233,7 @@ var
nd:t_nameidata;
mporoot,mpnroot:p_mount;
vp,vporoot,vpdevfs:p_vnode;
- fspath:PChar;
+ //fspath:PChar;
error:Integer;
begin
mpnroot:=TAILQ_NEXT(mpdevfs,@mpdevfs^.mnt_list);