From 10118431403ba389835554cb6abd90c7285f0661 Mon Sep 17 00:00:00 2001 From: red-prig Date: Sun, 2 Oct 2022 20:33:18 +0300 Subject: [PATCH] + --- kernel/mm_adr_direct.pas | 92 ++++++++++ kernel/mm_adr_name.pas | 368 ++++++++++++++++++++++++++++++++++++++ kernel/mm_adr_virtual.pas | 212 ++++++++++++++++++---- kernel/ps4_libkernel.pas | 1 + kernel/ps4_map_mm.pas | 198 +++++++++++++++++++- 5 files changed, 828 insertions(+), 43 deletions(-) create mode 100644 kernel/mm_adr_name.pas diff --git a/kernel/mm_adr_direct.pas b/kernel/mm_adr_direct.pas index 026febde..72bb3d42 100644 --- a/kernel/mm_adr_direct.pas +++ b/kernel/mm_adr_direct.pas @@ -97,6 +97,7 @@ type Function CheckedRelease(Offset,Size:QWORD):Integer; Function Release(Offset,Size:QWORD):Integer; Function mmap_addr(Offset,Size:QWORD;addr:Pointer;mtype:Integer=-1):Integer; + Function mmap_type(Offset,Size:QWORD;mtype:Integer):Integer; Function unmap_addr(Offset,Size:QWORD):Integer; procedure Print; @@ -822,6 +823,97 @@ begin until false; end; +Function TDirectManager.mmap_type(Offset,Size:QWORD;mtype:Integer):Integer; +var + key:TDirectAdrNode; + FEndN,FEndO:QWORD; + FSize:QWORD; + + function _fetch:Boolean; + begin + Result:=False; + + if _FetchNode_m(M_LE or C_LE,Offset,key) then + begin + FEndN:=Offset+Size; + FEndO:=key.Offset+key.Size; + + _Devide(Offset,Size,key); + + Result:=True; + end else + if _FetchNode_m(M_BE or C_BE,Offset,key) then + begin + FEndN:=Offset+Size; + FEndO:=key.Offset+key.Size; + + _Devide(key.Offset,FEndN-key.Offset,key); + + Result:=True; + end; + end; + + function _map:Boolean; + begin + Result:=False; + + //new save + key.F.mtype:=mtype; + _Merge(key); + + if (FEndO>=FEndN) then Exit(True); + + FSize:=FEndO-Offset; + + Offset:=Offset+FSize; + Size :=Size -FSize; + end; + + function _skip:Boolean; inline; + begin + Result:=False; + + FEndN:=Offset+Size; + FEndO:=key.Offset+key.Size; + + if (FEndO>=FEndN) then Exit(True); + + FSize:=FEndO-Offset; + + Offset:=Offset+FSize; + Size :=Size -FSize; + end; + +begin + Result:=0; + if (Size=0) then Exit(EINVAL); + if (OffsetFhi) then Exit(EINVAL); + + repeat + + key:=Default(TDirectAdrNode); + key.IsFree:=False; + key.Offset:=Offset; + + if _fetch then + begin + if _map then Exit; + end else + if _Find_m(M_LE,key) then + begin + if _skip then Break; + end else + if _Find_m(M_BE,key) then + begin + if _skip then Break; + end else + begin + Break; + end; + + until false; +end; + Function TDirectManager.unmap_addr(Offset,Size:QWORD):Integer; begin Result:=mmap_addr(Offset,Size,nil); diff --git a/kernel/mm_adr_name.pas b/kernel/mm_adr_name.pas new file mode 100644 index 00000000..66863120 --- /dev/null +++ b/kernel/mm_adr_name.pas @@ -0,0 +1,368 @@ +unit mm_adr_name; + +{$mode ObjFPC}{$H+} + +interface + +uses + Windows, + Classes, + SysUtils, + g23tree; + +{ + name node: + [ + offset 12..39:28 + size 12..39:28 + + name[32] + ] + +} + +type + TName=array[0..31] of AnsiChar; + + TNameAdrNode=packed object + private + Function GetOffset:Pointer; inline; + Procedure SetOffset(q:Pointer); inline; + Function GetSize:QWORD; inline; + Procedure SetSize(q:QWORD); inline; + public + F:bitpacked record + Offset:DWORD; + Size :DWORD; + end; + name:TName; + property Offset:Pointer read GetOffset write SetOffset; + property Size:QWORD read GetSize write SetSize; + Function cmp_merge(const n:TNameAdrNode):Boolean; + end; + +type + TNamedAdrAllcCompare=object + function c(const a,b:TNameAdrNode):Integer; static; + end; + + TNamedManager=class + private + type + TAllcPoolNodeSet=specialize T23treeSet; + + var + Flo,Fhi:Pointer; + + FAllcSet:TAllcPoolNodeSet; + public + property lo:Pointer read Flo; + property hi:Pointer read Fhi; + + Constructor Create(_lo,_hi:QWORD); + private + procedure _Insert(const key:TNameAdrNode); + Function _FetchNode_m(mode:Byte;cmp:Pointer;var R:TNameAdrNode):Boolean; + + procedure _Merge(key:TNameAdrNode); + procedure _Devide(Offset:Pointer;Size:QWORD;var key:TNameAdrNode); + public + Function Mname(Offset:Pointer;Size:QWORD;pname:PChar):Integer; + Function Query(Offset:Pointer;pname:PChar):Integer; + end; + +implementation + +const + EINVAL=22; + +// + +function TNamedAdrAllcCompare.c(const a,b:TNameAdrNode):Integer; +begin + //1 FOffset + Result:=Integer(a.F.Offset>b.F.Offset)-Integer(a.F.Offsetb) then Result:=a else Result:=b; +end; + +// + +Function TNameAdrNode.GetOffset:Pointer; inline; +begin + Result:=Pointer(QWORD(F.Offset) shl 12); +end; + +Procedure TNameAdrNode.SetOffset(q:Pointer); inline; +begin + F.Offset:=DWORD(QWORD(q) shr 12); + Assert(GetOffset=q); +end; + +Function TNameAdrNode.GetSize:QWORD; inline; +begin + Result:=QWORD(F.Size) shl 12; +end; + +Procedure TNameAdrNode.SetSize(q:QWORD); inline; +begin + F.Size:=DWORD(q shr 12); + Assert(GetSize=q); +end; + +Function TNameAdrNode.cmp_merge(const n:TNameAdrNode):Boolean; +begin + Result:=False; + if (CompareChar0(name,n.name,SizeOf(TName))<>0) then Exit; + Result:=True; +end; + +/// + +Constructor TNamedManager.Create(_lo,_hi:QWORD); +var + key:TNameAdrNode; +begin + Assert(_lo<_hi); + + Flo:=Pointer(_lo); + Fhi:=Pointer(_hi); + + key:=Default(TNameAdrNode); + key.Offset:=Pointer(_lo); + key.Size :=(_hi-_lo+1); + + _Insert(key); +end; + +procedure TNamedManager._Insert(const key:TNameAdrNode); +begin + FAllcSet.Insert(key); +end; + +const + M_LE=0; + M_BE=1; + + C_UP=2; + C_DW=4; + + C_LE=6; + C_BE=8; + +Function TNamedManager._FetchNode_m(mode:Byte;cmp:Pointer;var R:TNameAdrNode):Boolean; +var + It:TAllcPoolNodeSet.Iterator; + key,rkey:TNameAdrNode; +begin + Result:=false; + + key:=R; + + Case (mode and 1) of + M_LE:It:=FAllcSet.find_le(key); + M_BE:It:=FAllcSet.find_be(key); + else + Exit; + end; + + if (It.Item=nil) then Exit; + + rkey:=It.Item^; + + Case (mode and (not 1)) of + C_UP: + begin + if not rkey.cmp_merge(key) then Exit; + if ((rkey.Offset+rkey.Size)<>cmp) then Exit; + end; + C_DW: + begin + if not rkey.cmp_merge(key) then Exit; + if (rkey.Offset <>cmp ) then Exit; + end; + + C_LE:if ((rkey.Offset+rkey.Size)FOffset) then //prev save + begin + key.Size:=Offset-FOffset; + _Merge(key); + end; + + if (FEndO>FEndN) then //next save + begin + key.Offset:=FEndN; + key.Size :=FEndO-FEndN; + + _Merge(key); + end else + if (FEndO<>FEndN) then //tunc size + begin + Size:=FEndO-Offset; + end; + + //new save + key.Offset :=Offset; + key.Size :=Size; +end; + +Function TNamedManager.Mname(Offset:Pointer;Size:QWORD;pname:PChar):Integer; +var + key:TNameAdrNode; + FEndN,FEndO:Pointer; + FSize:QWORD; + name:TName; + + function _fetch:Boolean; + begin + Result:=False; + + if _FetchNode_m(M_LE or C_LE,Offset,key) then + begin + FEndN:=Offset+Size; + FEndO:=key.Offset+key.Size; + + _Devide(Offset,Size,key); + + Result:=True; + end else + if _FetchNode_m(M_BE or C_BE,Offset,key) then + begin + FEndN:=Offset+Size; + FEndO:=key.Offset+key.Size; + + _Devide(key.Offset,FEndN-key.Offset,key); + + Result:=True; + end; + end; + + function _map:Boolean; + begin + Result:=False; + + //new save + key.name:=name; + _Merge(key); + + if (FEndO>=FEndN) then Exit(True); + + FSize:=FEndO-Offset; + + Offset:=Offset+FSize; + Size :=Size -FSize; + end; + +begin + Result:=0; + + name:=Default(TName); + if (pname<>nil) then + begin + MoveChar0(pname^,name,SizeOf(TName)); + end; + + repeat + + key:=Default(TNameAdrNode); + key.Offset:=Offset; + + if _fetch then + begin + if _map then Break; + end else + begin + Result:=EINVAL; + Break; + end; + + until false; +end; + +Function TNamedManager.Query(Offset:Pointer;pname:PChar):Integer; +var + It:TAllcPoolNodeSet.Iterator; + key:TNameAdrNode; +begin + Result:=0; + + if (pname=nil) then Exit(EINVAL); + + key:=Default(TNameAdrNode); + key.Offset:=Offset; + + It:=FAllcSet.find_le(key); + + if (It.Item=nil) then Exit(EINVAL); + + key:=It.Item^; + + MoveChar0(key.name,pname^,SizeOf(TName)); +end; + +initialization + +end. + + + + diff --git a/kernel/mm_adr_virtual.pas b/kernel/mm_adr_virtual.pas index 4179d19b..ac6ce8ab 100644 --- a/kernel/mm_adr_virtual.pas +++ b/kernel/mm_adr_virtual.pas @@ -118,6 +118,7 @@ type end; TDirectUnmapCb=function(Offset,Size:QWORD):Integer; + TDirectMtypeCb=function(Offset,Size:QWORD;mtype:Integer):Integer; TVirtualManager=class private @@ -137,26 +138,32 @@ type Constructor Create(_lo,_hi:QWORD); private procedure _Insert(const key:TVirtualAdrNode); - Function _FetchFree_s(ss:Pointer;Size,Align:QWORD;var R:TVirtualAdrNode):Boolean; Function _FetchNode_m(mode:Byte;cmp:Pointer;var R:TVirtualAdrNode):Boolean; Function _Find_m(mode:Byte;var R:TVirtualAdrNode):Boolean; procedure _Merge(key:TVirtualAdrNode); procedure _Devide(Offset:Pointer;Size:QWORD;var key:TVirtualAdrNode); function _UnmapDirect(Offset,Size:QWORD):Integer; + function _MtypeDirect(Offset,Size:QWORD;mtype:Integer):Integer; Function _FindFreeOffset(ss:Pointer;Size,Align:QWORD;var AdrOut:Pointer):Integer; procedure _set_block(Offset:Pointer;Size:QWORD;block:PVirtualAdrBlock); procedure _mmap_addr(Offset:Pointer;Size,addr:QWORD;direct:Boolean); public var OnDirectUnmapCb:TDirectUnmapCb; + OnDirectMtypeCb:TDirectMtypeCb; Function check_fixed(Offset:Pointer;Size:QWORD;flags:Byte;fd:Integer):Integer; Function mmap(Offset:Pointer;Size,Align:QWORD;prot,flags:Byte;fd:Integer;addr:QWORD;var AdrOut:Pointer):Integer; - procedure Protect(Offset:Pointer;Size:QWORD;prot:Integer); + Function Protect(Offset:Pointer;Size:QWORD;prot:Integer):Integer; + Function Mtypeprotect(Offset:Pointer;Size:QWORD;mtype,prot:Integer):Integer; + Function Release(Offset:Pointer;Size:QWORD):Integer; + Function Query(Offset:Pointer;next:Boolean;var ROut:TVirtualAdrNode):Integer; + Function QueryProt(Offset:Pointer;var ROut:TVirtualAdrNode):Integer; + procedure Print; end; @@ -393,6 +400,7 @@ begin if (F.direct<>n.F.direct) then Exit; if (F.stack <>n.F.stack ) then Exit; if (F.polled<>n.F.polled) then Exit; + if (F.mapped<>n.F.mapped) then Exit; if (block <>n.block ) then Exit; Result:=True; end; @@ -428,32 +436,6 @@ begin FAllcSet.Insert(key); end; -//free: [Size] |[Offset] -Function TVirtualManager._FetchFree_s(ss:Pointer;Size,Align:QWORD;var R:TVirtualAdrNode):Boolean; -var - It:TFreePoolNodeSet.Iterator; - key:TVirtualAdrNode; - Offset:Pointer; -begin - Result:=false; - key:=Default(TVirtualAdrNode); - key.Offset:=ss; - key.Size :=Size; - It:=FFreeSet.find_be(key); - if (It.Item=nil) then Exit; - repeat - key:=It.Item^; - Offset:=System.Align(Max(key.Offset,ss),Align); - if (Offset+Size)<=(key.Offset+key.Size) then - begin - R:=key; - FAllcSet.delete(key); - FFreeSet.erase(It); - Exit(True); - end; - until not It.Next; -end; - const M_LE=0; M_BE=1; @@ -491,7 +473,7 @@ begin if (rkey.IsFree<>key.IsFree) then Exit; end; - Case (mode and (not 1)) of + Case (mode and (not 3)) of C_UP: begin if not rkey.cmp_merge(key) then Exit; @@ -616,6 +598,13 @@ begin Result:=OnDirectUnmapCb(Offset,Size); end; +function TVirtualManager._MtypeDirect(Offset,Size:QWORD;mtype:Integer):Integer; +begin + if (Size=0) then Exit(0); + if (OnDirectMtypeCb=nil) then Exit(EINVAL); + Result:=OnDirectMtypeCb(Offset,Size,mtype); +end; + Function TVirtualManager._FindFreeOffset(ss:Pointer;Size,Align:QWORD;var AdrOut:Pointer):Integer; var It:TFreePoolNodeSet.Iterator; @@ -1113,7 +1102,7 @@ begin end; end; -procedure TVirtualManager.Protect(Offset:Pointer;Size:QWORD;prot:Integer); +Function TVirtualManager.Protect(Offset:Pointer;Size:QWORD;prot:Integer):Integer; var key:TVirtualAdrNode; FEndN,FEndO:Pointer; @@ -1148,12 +1137,15 @@ var Result:=False; //new save - if (key.block=nil) then + if (key.F.reserv=0) then begin - key.F.prot:=prot; - end else - begin - key.block^.Protect(@key,prot); + if (key.block=nil) then + begin + key.F.prot:=prot; + end else + begin + key.block^.Protect(@key,prot); + end; end; _Merge(key); @@ -1182,6 +1174,110 @@ var end; begin + Result:=0; + + repeat + + key:=Default(TVirtualAdrNode); + key.Offset:=Offset; + + if _fetch then + begin + if _map then Break; + end else + if _Find_m(M_LE,key) then + begin + if _skip then Break; + end else + if _Find_m(M_BE,key) then + begin + if _skip then Break; + end else + begin + Break; + end; + + until false; +end; + +Function TVirtualManager.Mtypeprotect(Offset:Pointer;Size:QWORD;mtype,prot:Integer):Integer; +var + key:TVirtualAdrNode; + FEndN,FEndO:Pointer; + FSize:QWORD; + + function _fetch:Boolean; + begin + Result:=False; + + if _FetchNode_m(M_LE or C_FR or C_LE,Offset,key) then + begin + FEndN:=Offset+Size; + FEndO:=key.Offset+key.Size; + + _Devide(Offset,Size,key); + + Result:=True; + end else + if _FetchNode_m(M_BE or C_FR or C_BE,Offset,key) then + begin + FEndN:=Offset+Size; + FEndO:=key.Offset+key.Size; + + _Devide(key.Offset,FEndN-key.Offset,key); + + Result:=True; + end; + end; + + function _map:Boolean; + begin + Result:=False; + + if (key.F.direct<>0) then + begin + _MtypeDirect(key.addr,key.Size,mtype); + end; + + //new save + if (key.F.reserv=0) then + begin + if (key.block=nil) then + begin + key.F.prot:=prot; + end else + begin + key.block^.Protect(@key,prot); + end; + end; + + _Merge(key); + + if (FEndO>=FEndN) then Exit(True); + + FSize:=FEndO-Offset; + + Offset:=Offset+FSize; + Size :=Size -FSize; + end; + + function _skip:Boolean; inline; + begin + Result:=False; + + FEndN:=Offset+Size; + FEndO:=key.Offset+key.Size; + + if (FEndO>=FEndN) then Exit(True); + + FSize:=FEndO-Offset; + + Offset:=Offset+FSize; + Size :=Size -FSize; + end; + +begin + Result:=0; repeat @@ -1349,6 +1445,52 @@ begin until false; end; +Function TVirtualManager.Query(Offset:Pointer;next:Boolean;var ROut:TVirtualAdrNode):Integer; +var + It:TAllcPoolNodeSet.Iterator; + key:TVirtualAdrNode; +begin + Result:=0; + key:=Default(TVirtualAdrNode); + key.Offset:=Offset; + + if next then + begin + It:=FAllcSet.find_be(key); + end else + begin + It:=FAllcSet.find(key); + end; + + if (It.Item=nil) then Exit(EINVAL); + + key:=It.Item^; + + if key.IsFree then Exit(EACCES); + + ROut:=key; +end; + +Function TVirtualManager.QueryProt(Offset:Pointer;var ROut:TVirtualAdrNode):Integer; +var + It:TAllcPoolNodeSet.Iterator; + key:TVirtualAdrNode; +begin + Result:=0; + key:=Default(TVirtualAdrNode); + key.Offset:=Offset; + + It:=FAllcSet.find_le(key); + + if (It.Item=nil) then Exit(EINVAL); + + key:=It.Item^; + + if key.IsFree then Exit(EACCES); + + ROut:=key; +end; + function _alloc_str(var key:TVirtualAdrNode):RawByteString; begin if (key.F.Free<>0) then diff --git a/kernel/ps4_libkernel.pas b/kernel/ps4_libkernel.pas index fca37e68..d7471c63 100644 --- a/kernel/ps4_libkernel.pas +++ b/kernel/ps4_libkernel.pas @@ -1113,6 +1113,7 @@ begin // ps4_sceKernelGetCompiledSdkVersion(@SDK_VERSION); + _mem_init; end; initialization diff --git a/kernel/ps4_map_mm.pas b/kernel/ps4_map_mm.pas index 55d1f5ec..7a2fbbe7 100644 --- a/kernel/ps4_map_mm.pas +++ b/kernel/ps4_map_mm.pas @@ -12,7 +12,7 @@ uses mmap, mm_adr_direct, mm_adr_virtual, - mm_adr_pool, + mm_adr_name, Classes, SysUtils; @@ -179,9 +179,15 @@ Function TryGetGpuMemBlockByAddr(addr:Pointer;var block:TGpuMemBlock):Boolean; Procedure RegistredStack; Procedure UnRegistredStack; +var + SceKernelFlexibleMemorySize:QWORD=0; + +Procedure _mem_init; + implementation uses + ps4_program, sys_kernel, sys_signal; @@ -1703,8 +1709,25 @@ begin Result:=VirtualManager.Release(addr,len); end; +function __release_direct(Offset,Size:QWORD):Integer; +begin + Result:=DirectManager.Release(Offset,Size); +end; + +function __mtype_direct(Offset,Size:QWORD;mtype:Integer):Integer; +begin + Result:=DirectManager.mmap_type(Offset,Size,mtype); +end; + function _munmap(addr:Pointer;len:size_t):Integer; begin + Result:=EINVAL; + + if (len0) then Exit; + + tmp:=AlignDw(addr,PHYSICAL_PAGE_SIZE); + len:=len+(addr-tmp); + + addr:=tmp; + len:=AlignUp(len,PHYSICAL_PAGE_SIZE); + + _sig_lock; + rwlock_wrlock(PageMM.FLock); //rw + + Result:=VirtualManager.Protect(addr,len,prot); + + rwlock_unlock(PageMM.FLock); + _sig_unlock; +end; + +function _sys_mtypeprotect(addr:Pointer;len:size_t;mtype,prot:Integer):Integer; +var + tmp:Pointer; +begin + Result:=EINVAL; + + if ((prot and $ffffffc8)<>0) then Exit; + + tmp:=AlignDw(addr,PHYSICAL_PAGE_SIZE); + len:=len+(addr-tmp); + + addr:=tmp; + len:=AlignUp(len,PHYSICAL_PAGE_SIZE); + + _sig_lock; + rwlock_wrlock(PageMM.FLock); //rw + + Result:=VirtualManager.Mtypeprotect(addr,len,mtype,prot); + + rwlock_unlock(PageMM.FLock); + _sig_unlock; +end; + +function _sys_query_memory_protection(addr:Pointer; + pStart,pEnd:PPointer; + pProt:PInteger):Integer; +var + ROut:TVirtualAdrNode; +begin + Result:=0; + + addr:=AlignDw(addr,PHYSICAL_PAGE_SIZE); + + ROut:=Default(TVirtualAdrNode); + + _sig_lock; + rwlock_rdlock(PageMM.FLock); //r + + Result:=VirtualManager.QueryProt(addr,ROut); + + rwlock_unlock(PageMM.FLock); + _sig_unlock; + + if (Result<>0) then + begin + if (pStart<>nil) then + begin + pStart^:=ROut.Offset; + end; + + if (pEnd<>nil) then + begin + pEnd ^:=ROut.Offset+ROut.Size; + end; + + if (pProt<>nil) then + begin + pProt ^:=ROut.F.prot; + end; + end; +end; + +function _sys_virtual_query(addr:Pointer; + flags:Integer; + info:pSceKernelVirtualQueryInfo; + infoSize:QWORD):Integer; +var + VOut:TVirtualAdrNode; + DOut:TDirectAdrNode; + Committed:Boolean; +begin + Result:=EFAULT; + + if (info=nil) then Exit; + if (infoSize<>SizeOf(SceKernelVirtualQueryInfo)) then Exit; + + addr:=AlignDw(addr,PHYSICAL_PAGE_SIZE); + + VOut:=Default(TVirtualAdrNode); + DOut:=Default(TDirectAdrNode); + + _sig_lock; + rwlock_rdlock(PageMM.FLock); //r + + Result:=VirtualManager.Query(addr,(flags=SCE_KERNEL_VQ_FIND_NEXT),VOut); + + if (Result<>0) and (VOut.F.direct=1) then + begin + Result:=DirectManager.QueryMType(VOut.addr,DOut); + end; + + rwlock_unlock(PageMM.FLock); + _sig_unlock; + + if (Result<>0) then + begin + Committed:=(VOut.F.Free=0) and (VOut.F.reserv=0); + info^:=Default(SceKernelVirtualQueryInfo); + info^.pstart :=VOut.Offset; + info^.pend :=VOut.Offset+VOut.Size; + info^.offset :=VOut.addr; + info^.protection :=VOut.F.prot; + info^.memoryType :=DOut.F.mtype; + info^.bits.isFlexibleMemory:=Byte((VOut.F.direct=0) and Committed); + info^.bits.isDirectMemory :=VOut.F.direct; + info^.bits.isStack :=VOut.F.stack; + info^.bits.isPooledMemory :=VOut.F.polled; + info^.bits.isCommitted :=Byte(Committed); + //info^.name:array[0..SCE_KERNEL_VIRTUAL_RANGE_NAME_SIZE-1] of AnsiChar; + end; end; function _sceKernelMapFlexibleMemory( @@ -1753,8 +1906,12 @@ begin end; Result:=__mmap(addr,length,0,prots,flags or MAP_ANON,-1,0,addr); + _set_errno(Result); - if (Result=0) then + if (Result<>0) then + begin + Result:=px2sce(Result); + end else begin virtualAddrDest^:=addr; Result:=0; @@ -1795,8 +1952,12 @@ begin end; Result:=__mmap(addr,length,alignment,0,flags or MAP_VOID or MAP_SHARED,-1,0,addr); + _set_errno(Result); - if (Result=0) then + if (Result<>0) then + begin + Result:=px2sce(Result); + end else begin virtualAddrDest^:=addr; Result:=0; @@ -1830,8 +1991,12 @@ begin if not IsAlign(addr,LOGICAL_PAGE_SIZE) then Exit; Result:=__sys_mmap_dmem(addr,length,alignment,mtype,prots,flags,physicalAddr,addr); + _set_errno(Result); - if (Result=0) then + if (Result<>0) then + begin + Result:=px2sce(Result); + end else begin virtualAddrDest^:=addr; Result:=0; @@ -1890,15 +2055,18 @@ begin end; Result:=__mmap(addr,length,alignment,prots,_flags or MAP_SHARED,0,physicalAddr,addr); + _set_errno(Result); - if (Result=0) then + if (Result<>0) then + begin + Result:=px2sce(Result); + end else begin virtualAddrDest^:=addr; Result:=0; end; end; - //// //// @@ -2233,11 +2401,25 @@ begin _sig_unlock; end; +Procedure _mem_init; +var + p:PQWORD; +begin + SceKernelFlexibleMemorySize:=(448*1024*1024); + p:=GetSceKernelFlexibleMemorySize; + if (p<>nil) then + begin + SceKernelFlexibleMemorySize:=p^; + end; +end; + initialization DirectManager :=TDirectManager .Create; DirectManager .OnMemoryUnmapCb:=@__munmap; + VirtualManager:=TVirtualManager.Create($400000,$3FFFFFFFF); VirtualManager.OnDirectUnmapCb:=@__release_direct; + VirtualManager.OnDirectMtypeCb:=@__mtype_direct; PageMM.init; end.