mirror of
https://github.com/red-prig/fpPS4.git
synced 2024-10-07 11:43:21 +00:00
+
This commit is contained in:
parent
c9403e82f7
commit
1ddc84c58c
@ -8,7 +8,8 @@ uses
|
||||
Windows,
|
||||
Classes,
|
||||
SysUtils,
|
||||
g23tree;
|
||||
g23tree,
|
||||
sys_types;
|
||||
|
||||
{
|
||||
name node:
|
||||
@ -319,6 +320,12 @@ begin
|
||||
if (Size=0) then Exit(EINVAL);
|
||||
if (Offset<Flo) or (Offset>Fhi) then Exit(EINVAL);
|
||||
|
||||
FEndO:=AlignDw(Offset,PHYSICAL_PAGE_SIZE);
|
||||
Size:=Size+(Offset-FEndO);
|
||||
|
||||
Offset:=FEndO;
|
||||
Size:=AlignUp(Size,PHYSICAL_PAGE_SIZE);
|
||||
|
||||
name:=Default(TName);
|
||||
if (pname<>nil) then
|
||||
begin
|
||||
@ -351,6 +358,8 @@ begin
|
||||
|
||||
if (pname=nil) then Exit(EINVAL);
|
||||
|
||||
Offset:=AlignDw(Offset,PHYSICAL_PAGE_SIZE);
|
||||
|
||||
key:=Default(TNameAdrNode);
|
||||
key.Offset:=Offset;
|
||||
|
||||
|
@ -58,17 +58,21 @@ type
|
||||
Procedure SetSize(q:QWORD); inline;
|
||||
Function GetUsed:QWORD; inline;
|
||||
Procedure SetUsed(q:QWORD); inline;
|
||||
Function GetRsrv:QWORD; inline;
|
||||
Procedure SetRsrv(q:QWORD); inline;
|
||||
public
|
||||
F:bitpacked record
|
||||
Offset:bit28;
|
||||
Size :bit28;
|
||||
btype :bit8;
|
||||
rsrv :DWORD;
|
||||
used :DWORD;
|
||||
end;
|
||||
Handle:Pointer; //gpu
|
||||
property Offset:Pointer read GetOffset write SetOffset;
|
||||
property Size:QWORD read GetSize write SetSize;
|
||||
property Used:QWORD read GetUsed write SetUsed;
|
||||
property Rsrv:QWORD read GetRsrv write SetRsrv;
|
||||
function Commit(key:PVirtualAdrNode;prot:Integer):Integer;
|
||||
function Free(key:PVirtualAdrNode):Integer;
|
||||
function Reserved(key:PVirtualAdrNode):Integer;
|
||||
@ -119,6 +123,8 @@ type
|
||||
TDirectUnmapCb=function(Offset,Size:QWORD):Integer;
|
||||
TDirectMtypeCb=function(Offset,Size:QWORD;mtype:Integer):Integer;
|
||||
|
||||
TBlockCb=function(block:PVirtualAdrBlock):Integer;
|
||||
|
||||
TVirtualManager=class
|
||||
private
|
||||
type
|
||||
@ -145,6 +151,8 @@ type
|
||||
procedure _Devide(Offset:Pointer;Size:QWORD;var key:TVirtualAdrNode);
|
||||
function _UnmapDirect(Offset,Size:QWORD):Integer;
|
||||
function _MtypeDirect(Offset,Size:QWORD;mtype:Integer):Integer;
|
||||
function _CreateBlock(block:PVirtualAdrBlock):Integer;
|
||||
function _FreeBlock(block:PVirtualAdrBlock):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);
|
||||
@ -154,6 +162,9 @@ type
|
||||
OnDirectUnmapCb:TDirectUnmapCb;
|
||||
OnDirectMtypeCb:TDirectMtypeCb;
|
||||
|
||||
OnCreateBlockCb:TBlockCb;
|
||||
OnFreeBlockCb :TBlockCb;
|
||||
|
||||
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;
|
||||
|
||||
@ -233,6 +244,20 @@ begin
|
||||
Result^.F.btype :=btype;
|
||||
Result^.Offset :=FOffset;
|
||||
Result^.Size :=ASize;
|
||||
|
||||
case btype of
|
||||
BT_PRIV,
|
||||
BT_GPUM:
|
||||
begin
|
||||
Result^.Rsrv:=ASize;
|
||||
end;
|
||||
BT_FMAP:
|
||||
begin
|
||||
Result^.Used:=ASize;
|
||||
end;
|
||||
else;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
//
|
||||
@ -320,15 +345,41 @@ begin
|
||||
Assert(GetUsed=q);
|
||||
end;
|
||||
|
||||
Function TVirtualAdrBlock.GetRsrv:QWORD; inline;
|
||||
begin
|
||||
Result:=QWORD(F.rsrv) shl 12;
|
||||
end;
|
||||
|
||||
Procedure TVirtualAdrBlock.SetRsrv(q:QWORD); inline;
|
||||
begin
|
||||
F.rsrv:=DWORD(q shr 12);
|
||||
Assert(GetRsrv=q);
|
||||
end;
|
||||
|
||||
function TVirtualAdrBlock.Commit(key:PVirtualAdrNode;prot:Integer):Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
if (key=nil) then Exit;
|
||||
|
||||
if (key^.F.reserv=0) then
|
||||
Assert(key^.Offset >= Offset);
|
||||
Assert(key^.Offset+key^.Size >= Offset+Size);
|
||||
|
||||
if (key^.F.Free<>0) then //free->commit
|
||||
begin
|
||||
Assert((Used+key^.Size)<=Size);
|
||||
Used:=Used+key^.Size;
|
||||
|
||||
Used:=Used+key^.Size; //+
|
||||
end else
|
||||
if (key^.F.reserv<>0) then //reserved->commit
|
||||
begin
|
||||
Assert(Rsrv>=key^.Size);
|
||||
Assert((Used+key^.Size)<=Size);
|
||||
|
||||
Rsrv:=Rsrv-key^.Size; //-
|
||||
Used:=Used+key^.Size; //+
|
||||
end else
|
||||
begin
|
||||
Exit;
|
||||
end;
|
||||
|
||||
case F.btype of
|
||||
@ -343,17 +394,56 @@ begin
|
||||
end;
|
||||
else;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
function TVirtualAdrBlock.Free(key:PVirtualAdrNode):Integer;
|
||||
begin
|
||||
Assert(Used>=key^.Size);
|
||||
Used:=Used-key^.Size;
|
||||
Result:=0;
|
||||
if (key=nil) then Exit;
|
||||
if (key^.F.Free<>0) then Exit; //its free
|
||||
|
||||
Assert(key^.Offset >= Offset);
|
||||
Assert(key^.Offset+key^.Size >= Offset+Size);
|
||||
|
||||
if (key^.F.reserv<>0) then //reserved->free
|
||||
begin
|
||||
Assert(Rsrv>=key^.Size);
|
||||
|
||||
Rsrv:=Rsrv-key^.Size; //-
|
||||
end else
|
||||
begin //commit->free
|
||||
Assert(Used>=key^.Size);
|
||||
|
||||
Used:=Used-key^.Size; //-
|
||||
end;
|
||||
|
||||
Result:=_VirtualDecommit(Pointer(key^.Offset),key^.Size);
|
||||
end;
|
||||
|
||||
function TVirtualAdrBlock.Reserved(key:PVirtualAdrNode):Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
if (key=nil) then Exit;
|
||||
if (key^.F.reserv<>0) then Exit; //its reserved
|
||||
|
||||
Assert(key^.Offset >= Offset);
|
||||
Assert(key^.Offset+key^.Size >= Offset+Size);
|
||||
|
||||
if (key^.F.Free<>0) then //free->reserved
|
||||
begin
|
||||
Assert((Rsrv+key^.Size)<=Size);
|
||||
|
||||
Rsrv:=Rsrv+key^.Size; //+
|
||||
end else
|
||||
begin //commit->reserved
|
||||
Assert(Used>=key^.Size);
|
||||
Assert((Rsrv+key^.Size)<=Size);
|
||||
|
||||
Used:=Used-key^.Size; //-
|
||||
Rsrv:=Rsrv+key^.Size; //+
|
||||
end;
|
||||
|
||||
Result:=_VirtualDecommit(Pointer(key^.Offset),key^.Size);
|
||||
end;
|
||||
|
||||
@ -361,6 +451,10 @@ function TVirtualAdrBlock.Protect(key:PVirtualAdrNode;prot:Integer):Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
if (key=nil) then Exit;
|
||||
if (key^.F.Free<>0) then Exit; //its free
|
||||
|
||||
Assert(key^.Offset >= Offset);
|
||||
Assert(key^.Offset+key^.Size >= Offset+Size);
|
||||
|
||||
if (key^.F.prot<>prot) then
|
||||
begin
|
||||
@ -636,6 +730,18 @@ begin
|
||||
Result:=OnDirectMtypeCb(Offset,Size,mtype);
|
||||
end;
|
||||
|
||||
function TVirtualManager._CreateBlock(block:PVirtualAdrBlock):Integer;
|
||||
begin
|
||||
if (OnCreateBlockCb=nil) then Exit(0);
|
||||
Result:=OnCreateBlockCb(block);
|
||||
end;
|
||||
|
||||
function TVirtualManager._FreeBlock(block:PVirtualAdrBlock):Integer;
|
||||
begin
|
||||
if (OnFreeBlockCb=nil) then Exit(0);
|
||||
Result:=OnFreeBlockCb(block);
|
||||
end;
|
||||
|
||||
Function TVirtualManager._FindFreeOffset(ss:Pointer;Size,Align:QWORD;var AdrOut:Pointer):Integer;
|
||||
var
|
||||
It:TFreePoolNodeSet.Iterator;
|
||||
@ -1202,20 +1308,19 @@ begin
|
||||
begin
|
||||
if (key.block=nil) then
|
||||
begin
|
||||
|
||||
if (key.Offset>Offset) then
|
||||
begin
|
||||
FSize:=key.Offset-Offset;
|
||||
FSize:=Min(Size-FSize,key.Size);
|
||||
|
||||
key.block:=NewAdrBlock(key.Offset,FSize,prot,btype,fd,addr);
|
||||
end else
|
||||
begin
|
||||
FSize:=Offset-key.Offset;
|
||||
FSize:=Min(Size+FSize,key.Size);
|
||||
|
||||
key.block:=NewAdrBlock(key.Offset,FSize,prot,btype,fd,addr);
|
||||
end;
|
||||
|
||||
key.block:=NewAdrBlock(key.Offset,FSize,prot,btype,fd,addr);
|
||||
|
||||
if (key.block=nil) then
|
||||
begin
|
||||
_Merge(key); //undo
|
||||
@ -1223,6 +1328,9 @@ begin
|
||||
Exit(ENOSYS);
|
||||
end;
|
||||
|
||||
Result:=_CreateBlock(key.block);
|
||||
if (Result<>0) then Exit;
|
||||
|
||||
_set_block(key.block^.Offset,key.block^.Size,key.block);
|
||||
|
||||
if _addres then
|
||||
@ -1381,6 +1489,13 @@ var
|
||||
|
||||
begin
|
||||
Result:=0;
|
||||
if ((prot and $ffffffc8)<>0) then Exit(EINVAL);
|
||||
|
||||
FEndO:=AlignDw(Offset,PHYSICAL_PAGE_SIZE);
|
||||
Size:=Size+(Offset-FEndO);
|
||||
|
||||
Offset:=FEndO;
|
||||
Size:=AlignUp(Size,PHYSICAL_PAGE_SIZE);
|
||||
|
||||
repeat
|
||||
|
||||
@ -1486,6 +1601,13 @@ var
|
||||
|
||||
begin
|
||||
Result:=0;
|
||||
if ((prot and $ffffffc8)<>0) then Exit(EINVAL);
|
||||
|
||||
FEndO:=AlignDw(Offset,PHYSICAL_PAGE_SIZE);
|
||||
Size:=Size+(Offset-FEndO);
|
||||
|
||||
Offset:=FEndO;
|
||||
Size:=AlignUp(Size,PHYSICAL_PAGE_SIZE);
|
||||
|
||||
repeat
|
||||
|
||||
@ -1564,6 +1686,8 @@ var
|
||||
if (block^.Used=0) then
|
||||
begin
|
||||
|
||||
_FreeBlock(block);
|
||||
|
||||
if (block^.F.btype=BT_FMAP) then
|
||||
begin
|
||||
err:=_VirtualUnmap(Pointer(block^.Offset));
|
||||
@ -1584,6 +1708,8 @@ var
|
||||
|
||||
_set_block(block^.Offset,block^.Size,nil);
|
||||
FreeMem(block);
|
||||
|
||||
key.block:=nil;
|
||||
end;
|
||||
|
||||
//new save
|
||||
@ -1624,6 +1750,12 @@ begin
|
||||
if (Size=0) then Exit(EINVAL);
|
||||
if (Offset<Flo) or (Offset>Fhi) then Exit(EINVAL);
|
||||
|
||||
FEndO:=AlignDw(Offset,PHYSICAL_PAGE_SIZE);
|
||||
Size:=Size+(Offset-FEndO);
|
||||
|
||||
Offset:=FEndO;
|
||||
Size:=AlignUp(Size,PHYSICAL_PAGE_SIZE);
|
||||
|
||||
repeat
|
||||
|
||||
key:=Default(TVirtualAdrNode);
|
||||
|
@ -834,11 +834,6 @@ 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(MMLock); //rw
|
||||
|
||||
@ -854,19 +849,9 @@ begin
|
||||
end;
|
||||
|
||||
function _mprotect(addr:Pointer;len:size_t;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(MMLock); //rw
|
||||
|
||||
@ -877,19 +862,9 @@ begin
|
||||
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(MMLock); //rw
|
||||
|
||||
@ -996,20 +971,12 @@ begin
|
||||
end;
|
||||
|
||||
Function _sys_mname(addr:Pointer;len:QWORD;pname:PChar):Integer;
|
||||
var
|
||||
tmp:Pointer;
|
||||
begin
|
||||
Result:=EFAULT;
|
||||
|
||||
if (pname=nil) then Exit;
|
||||
if (StrLen(pname)>32) then Exit;
|
||||
|
||||
tmp:=AlignDw(addr,PHYSICAL_PAGE_SIZE);
|
||||
len:=len+(addr-tmp);
|
||||
|
||||
addr:=tmp;
|
||||
len:=AlignUp(len,PHYSICAL_PAGE_SIZE);
|
||||
|
||||
_sig_lock;
|
||||
rwlock_rdlock(MMLock); //r
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user