mirror of
https://github.com/red-prig/fpPS4.git
synced 2024-11-23 22:39:44 +00:00
+
This commit is contained in:
parent
57b2c9fa13
commit
1011843140
@ -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
368
kernel/mm_adr_name.pas
Normal 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.
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -1113,6 +1113,7 @@ begin
|
||||
|
||||
//
|
||||
ps4_sceKernelGetCompiledSdkVersion(@SDK_VERSION);
|
||||
_mem_init;
|
||||
end;
|
||||
|
||||
initialization
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user