diff --git a/kernel/mm_adr_name.pas b/kernel/mm_adr_name.pas index 839f6957..18ec4eeb 100644 --- a/kernel/mm_adr_name.pas +++ b/kernel/mm_adr_name.pas @@ -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 (OffsetFhi) 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; diff --git a/kernel/mm_adr_virtual.pas b/kernel/mm_adr_virtual.pas index 5c2c512f..4d18b157 100644 --- a/kernel/mm_adr_virtual.pas +++ b/kernel/mm_adr_virtual.pas @@ -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 (OffsetFhi) 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); diff --git a/kernel/ps4_map_mm.pas b/kernel/ps4_map_mm.pas index 70a0da74..2e7714f6 100644 --- a/kernel/ps4_map_mm.pas +++ b/kernel/ps4_map_mm.pas @@ -834,11 +834,6 @@ 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(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