This commit is contained in:
red-prig 2022-10-02 20:33:18 +03:00
parent 57b2c9fa13
commit 1011843140
5 changed files with 828 additions and 43 deletions

View File

@ -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 (Offset<Flo) or (Offset>Fhi) 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);

368
kernel/mm_adr_name.pas Normal file
View File

@ -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<TNameAdrNode,TNamedAdrAllcCompare>;
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.Offset<b.F.Offset);
end;
//
function Max(a,b:Pointer):Pointer; inline;
begin
if (a>b) 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)<cmp) then Exit;
C_BE:if (key.Offset<cmp) then Exit;
else
Exit;
end;
R:=rkey;
FAllcSet.erase(It);
Result:=True;
end;
//
procedure TNamedManager._Merge(key:TNameAdrNode);
var
rkey:TNameAdrNode;
begin
//prev union
repeat
rkey:=key;
rkey.F.Offset:=rkey.F.Offset-1; //hack
if not _FetchNode_m(M_LE or C_UP,key.Offset,rkey) then Break;
key.F.Size :=key.F.Size+(key.F.Offset-rkey.F.Offset); //hack
key.F.Offset:=rkey.F.Offset; //hack
until false;
//next union
repeat
rkey:=key;
rkey.F.Offset:=rkey.F.Offset+rkey.F.Size; //hack
if not _FetchNode_m(M_BE or C_DW,(key.Offset+key.Size),rkey) then Break;
key.F.Size :=key.F.Size+rkey.F.Size; //hack
until false;
_Insert(key);
end;
procedure TNamedManager._Devide(Offset:Pointer;Size:QWORD;var key:TNameAdrNode);
var
FOffset:Pointer;
FSize:QWORD;
FEndN,FEndO:Pointer;
begin
FOffset:=key.Offset;
FSize :=key.Size;
FEndN:=Offset +Size;
FEndO:=FOffset+FSize;
if (Offset>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.

View File

@ -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

View File

@ -1113,6 +1113,7 @@ begin
//
ps4_sceKernelGetCompiledSdkVersion(@SDK_VERSION);
_mem_init;
end;
initialization

View File

@ -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 (len<PHYSICAL_PAGE_SIZE) then Exit;
if not IsAlign(len,PHYSICAL_PAGE_SIZE) then Exit;
if not IsAlign(addr,PHYSICAL_PAGE_SIZE) then Exit;
_sig_lock;
rwlock_wrlock(PageMM.FLock); //rw
@ -1714,9 +1737,139 @@ begin
_sig_unlock;
end;
function __release_direct(Offset,Size:QWORD):Integer;
function _mprotect(addr:Pointer;len:size_t;prot:Integer):Integer;
var
tmp:Pointer;
begin
Result:=DirectManager.Release(Offset,Size);
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.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.