diff --git a/chip/ps4_videodrv.pas b/chip/ps4_videodrv.pas index f1b7eaa1..2d70e46f 100644 --- a/chip/ps4_videodrv.pas +++ b/chip/ps4_videodrv.pas @@ -316,6 +316,26 @@ begin end; end; +const + GpuCoreClockFrequency=800000000; + +function GetGpuTickCount:QWORD; +var + pc,pf:QWORD; + DW0,DW1:QWORD; +begin + pc:=0; + pf:=1; + NtQueryPerformanceCounter(@pc,@pf); + + //DW0*GF/pf + SHL_32* DW1*GF/pf + + DW0:=(DWORD(pc shr 00)*GpuCoreClockFrequency) div pf; + DW1:=(DWORD(pc shr 32)*GpuCoreClockFrequency) div pf; + + Result:=DW0+(DW1 shl 32); +end; + Function me_eop(node:pvMeEopInfo):Boolean; begin Result:=True; @@ -326,7 +346,7 @@ begin kEventWriteSource32BitsImmediate :PDWORD(node^.adr)^:=PDWORD(@node^.data)^; kEventWriteSource64BitsImmediate :PQWORD(node^.adr)^:=PQWORD(@node^.data)^; kEventWriteSourceGlobalClockCounter , - kEventWriteSourceGpuCoreClockCounter:PQWORD(node^.adr)^:=GetTickCount64*1000; + kEventWriteSourceGpuCoreClockCounter:PQWORD(node^.adr)^:=GetGpuTickCount; else Assert(False); end; diff --git a/kernel/mm_adr_direct.pas b/kernel/mm_adr_direct.pas index 70ed8ae6..beaeb72a 100644 --- a/kernel/mm_adr_direct.pas +++ b/kernel/mm_adr_direct.pas @@ -97,7 +97,7 @@ type Function CheckedAlloc(Offset,Size:QWORD):Integer; Function CheckedMMap(Offset,Size:QWORD):Integer; Function CheckedRelease(Offset,Size:QWORD):Integer; - Function Release(Offset,Size:QWORD):Integer; + Function Release(Offset,Size:QWORD;inher:Boolean):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; @@ -659,7 +659,7 @@ begin end; end; -Function TDirectManager.Release(Offset,Size:QWORD):Integer; +Function TDirectManager.Release(Offset,Size:QWORD;inher:Boolean):Integer; var key:TDirectAdrNode; FEndN,FEndO:QWORD; @@ -703,12 +703,13 @@ var if (FEndO>=FEndN) then Exit(True); FSize:=FEndO-Offset; + Assert(FSize<>0); Offset:=Offset+FSize; Size :=Size -FSize; end; - function _skip:Boolean; inline; + function _skip:Boolean; //inline; begin Result:=False; @@ -718,6 +719,7 @@ var if (FEndO>=FEndN) then Exit(True); FSize:=FEndO-Offset; + Assert(FSize<>0); Offset:=Offset+FSize; Size :=Size -FSize; @@ -736,7 +738,13 @@ begin if _fetch then begin - Result:=_UnmapVirtual(key.addr,key.Size); + if inher then + begin + Result:=0; + end else + begin + Result:=_UnmapVirtual(key.addr,key.Size); + end; if (Result<>0) then begin @@ -810,13 +818,14 @@ var if (FEndO>=FEndN) then Exit(True); FSize:=FEndO-Offset; + Assert(FSize<>0); addr :=ia(addr,FSize); Offset:=Offset+FSize; Size :=Size -FSize; end; - function _skip:Boolean; inline; + function _skip:Boolean; //inline; begin Result:=False; @@ -826,6 +835,7 @@ var if (FEndO>=FEndN) then Exit(True); FSize:=FEndO-Offset; + Assert(FSize<>0); addr :=ia(addr,FSize); Offset:=Offset+FSize; @@ -904,12 +914,13 @@ var if (FEndO>=FEndN) then Exit(True); FSize:=FEndO-Offset; + Assert(FSize<>0); Offset:=Offset+FSize; Size :=Size -FSize; end; - function _skip:Boolean; inline; + function _skip:Boolean; //inline; begin Result:=False; @@ -919,6 +930,7 @@ var if (FEndO>=FEndN) then Exit(True); FSize:=FEndO-Offset; + Assert(FSize<>0); Offset:=Offset+FSize; Size :=Size -FSize; diff --git a/kernel/mm_adr_name.pas b/kernel/mm_adr_name.pas index cdce9887..9bbb5c73 100644 --- a/kernel/mm_adr_name.pas +++ b/kernel/mm_adr_name.pas @@ -315,6 +315,7 @@ var if (FEndO>=FEndN) then Exit(True); FSize:=FEndO-Offset; + Assert(FSize<>0); Offset:=Offset+FSize; Size :=Size -FSize; diff --git a/kernel/mm_adr_virtual.pas b/kernel/mm_adr_virtual.pas index 795fc70a..9e1139c4 100644 --- a/kernel/mm_adr_virtual.pas +++ b/kernel/mm_adr_virtual.pas @@ -187,6 +187,7 @@ type Function TryGetMapBlockByAddr(Offset:Pointer;var block:PVirtualAdrBlock):Boolean; + procedure Test; procedure Print; end; @@ -427,15 +428,17 @@ begin Assert(Used>=key^.Size); Used:=Used-key^.Size; //- + + //// + if not _iswrite(key^.F.prot) then + begin + _VirtualProtect(Pointer(key^.Offset),key^.Size,PROT_READ or PROT_WRITE); + end; + FillChar(key^.Offset^,key^.Size,0); + + Result:=_VirtualProtect(Pointer(key^.Offset),key^.Size,0); end; - if not _iswrite(key^.F.prot) then - begin - _VirtualProtect(Pointer(key^.Offset),key^.Size,PROT_READ or PROT_WRITE); - end; - FillChar(key^.Offset^,key^.Size,0); - - Result:=_VirtualProtect(Pointer(key^.Offset),key^.Size,0); //Result:=_VirtualDecommit(Pointer(key^.Offset),key^.Size); end; @@ -979,6 +982,7 @@ var if (FEndO>=FEndN) then Exit(True); FSize:=FEndO-Offset; + Assert(FSize<>0); Offset:=Offset+FSize; Size :=Size -FSize; @@ -1000,6 +1004,7 @@ begin end; until false; + end; procedure TVirtualManager._mmap_addr(Offset:Pointer;Size,addr:QWORD;direct:Boolean); @@ -1050,6 +1055,7 @@ var if (FEndO>=FEndN) then Exit(True); FSize:=FEndO-Offset; + Assert(FSize<>0); addr :=addr +FSize; Offset:=Offset+FSize; @@ -1072,6 +1078,7 @@ begin end; until false; + end; procedure TVirtualManager._mmap_sys(Offset:Pointer;Size:QWORD); @@ -1123,12 +1130,13 @@ var if (FEndO>=FEndN) then Exit(True); FSize:=FEndO-Offset; + Assert(FSize<>0); Offset:=Offset+FSize; Size :=Size -FSize; end; - function _skip:Boolean; inline; + function _skip:Boolean; //inline; begin Result:=False; @@ -1138,6 +1146,7 @@ var if (FEndO>=FEndN) then Exit(True); FSize:=FEndO-Offset; + Assert(FSize<>0); Offset:=Offset+FSize; Size :=Size -FSize; @@ -1170,6 +1179,8 @@ begin end; until false; + + //Test; end; Function TVirtualManager.check_fixed(Offset:Pointer;Size:QWORD;flags,fd:Integer):Integer; @@ -1316,6 +1327,7 @@ var if (FEndO>=FEndN) then Exit(True); FSize:=FEndO-Offset; + Assert(FSize<>0); addr :=ia(_addres,addr,FSize); Offset:=Offset+FSize; @@ -1351,6 +1363,7 @@ var if (FEndO>=FEndN) then Exit(True); FSize:=FEndO-Offset; + Assert(FSize<>0); addr :=ia(_addres,addr,FSize); Offset:=Offset+FSize; @@ -1403,6 +1416,8 @@ begin Result:=check_fixed(Offset,Size,flags,fd); if (Result<>0) then Exit; + //Test; + repeat key:=Default(TVirtualAdrNode); @@ -1436,7 +1451,11 @@ begin end; Result:=_CreateBlock(key.block); - if (Result<>0) then Exit; + if (Result<>0) then + begin + _Merge(key); //undo + Exit; + end; _set_block(key.block^.Offset,key.block^.Size,key.block,_reserv); @@ -1530,6 +1549,8 @@ begin until false; + //Test; + if (Result=0) then begin AdrOut:=start; @@ -1588,12 +1609,13 @@ var if (FEndO>=FEndN) then Exit(True); FSize:=FEndO-Offset; + Assert(FSize<>0); Offset:=Offset+FSize; Size :=Size -FSize; end; - function _skip:Boolean; inline; + function _skip:Boolean; //inline; begin Result:=False; @@ -1603,6 +1625,7 @@ var if (FEndO>=FEndN) then Exit(True); FSize:=FEndO-Offset; + Assert(FSize<>0); Offset:=Offset+FSize; Size :=Size -FSize; @@ -1621,6 +1644,8 @@ begin Offset:=FEndO; Size:=AlignUp(Size,PHYSICAL_PAGE_SIZE); + //Test; + repeat key:=Default(TVirtualAdrNode); @@ -1644,6 +1669,8 @@ begin end; until false; + + //Test; end; Function TVirtualManager.Mtypeprotect(Offset:Pointer;Size:QWORD;mtype,prot:Integer):Integer; @@ -1703,12 +1730,13 @@ var if (FEndO>=FEndN) then Exit(True); FSize:=FEndO-Offset; + Assert(FSize<>0); Offset:=Offset+FSize; Size :=Size -FSize; end; - function _skip:Boolean; inline; + function _skip:Boolean; //inline; begin Result:=False; @@ -1718,6 +1746,7 @@ var if (FEndO>=FEndN) then Exit(True); FSize:=FEndO-Offset; + Assert(FSize<>0); Offset:=Offset+FSize; Size :=Size -FSize; @@ -1736,6 +1765,8 @@ begin Offset:=FEndO; Size:=AlignUp(Size,PHYSICAL_PAGE_SIZE); + //Test; + repeat key:=Default(TVirtualAdrNode); @@ -1759,6 +1790,8 @@ begin end; until false; + + //Test; end; Function TVirtualManager.Release(Offset:Pointer;Size:QWORD):Integer; @@ -1852,12 +1885,13 @@ var if (FEndO>=FEndN) then Exit(True); FSize:=FEndO-Offset; + Assert(FSize<>0); Offset:=Offset+FSize; Size :=Size -FSize; end; - function _skip:Boolean; inline; + function _skip:Boolean; //inline; begin Result:=False; @@ -1867,6 +1901,7 @@ var if (FEndO>=FEndN) then Exit(True); FSize:=FEndO-Offset; + Assert(FSize<>0); Offset:=Offset+FSize; Size :=Size -FSize; @@ -1883,6 +1918,8 @@ begin Offset:=FEndO; Size:=AlignUp(Size,PHYSICAL_PAGE_SIZE); + //Test; + repeat key:=Default(TVirtualAdrNode); @@ -1920,6 +1957,8 @@ begin end; until false; + + //Test; end; Function TVirtualManager.Query(Offset:Pointer;next:Boolean;var ROut:TVirtualAdrNode):Integer; @@ -1929,6 +1968,8 @@ var begin Result:=0; + //Test; + if (Offset>Fhi) then Exit(EINVAL); Offset:=AlignDw(Offset,PHYSICAL_PAGE_SIZE); @@ -1978,6 +2019,8 @@ var begin Result:=0; + //Test; + if (Offset>Fhi) then Exit(EINVAL); Offset:=AlignDw(Offset,PHYSICAL_PAGE_SIZE); @@ -2060,6 +2103,35 @@ begin end; end; +procedure TVirtualManager.Test; +var + prev,curr:Pointer; + key:TVirtualAdrNode; + It:TAllcPoolNodeSet.Iterator; +begin + prev:=nil; + + It:=FAllcSet.cbegin; + While (It.Item<>nil) do + begin + key:=It.Item^; + + if (prev<>nil) then + begin + curr:=key.Offset; + if (curr<>prev) then + begin + Writeln(HexStr(prev),':',HexStr(curr)); + Assert(false); + end; + end; + + prev:=key.Offset+key.Size; + + It.Next; + end; +end; + procedure TVirtualManager.Print; var key:TVirtualAdrNode; diff --git a/kernel/ps4_map_mm.pas b/kernel/ps4_map_mm.pas index e24eaf00..2f3b5bbd 100644 --- a/kernel/ps4_map_mm.pas +++ b/kernel/ps4_map_mm.pas @@ -592,6 +592,10 @@ begin rwlock_rdlock(MMLock); //r Result:=DirectManager.CheckedRelease(start,len); + if (Result=0) then + begin + Result:=DirectManager.Release(start,len,False); + end; rwlock_unlock(MMLock); _sig_unlock; @@ -607,7 +611,7 @@ begin _sig_lock; rwlock_wrlock(MMLock); //rw - Result:=DirectManager.Release(start,len); + Result:=DirectManager.Release(start,len,False); rwlock_unlock(MMLock); _sig_unlock; @@ -733,6 +737,7 @@ begin if (Result<>0) then begin + Result:=_sceKernelCheckedReleaseDirectMemory(start,len); Writeln(StdErr,'[WARN]:sceKernelCheckedReleaseDirectMemory:',Result); end; _set_errno(Result); @@ -870,7 +875,7 @@ end; function __release_direct(Offset,Size:QWORD):Integer; begin - Result:=DirectManager.Release(Offset,Size); + Result:=DirectManager.Release(Offset,Size,True); end; function __mtype_direct(Offset,Size:QWORD;mtype:Integer):Integer; diff --git a/src/ps4_libscegnmdriver.pas b/src/ps4_libscegnmdriver.pas index 84b7a98f..ffcdaa63 100644 --- a/src/ps4_libscegnmdriver.pas +++ b/src/ps4_libscegnmdriver.pas @@ -1756,7 +1756,6 @@ begin Result:=kWorkloadStatusInvalidPointer; end; - function ps4_sceGnmEndWorkload(workload:QWORD):Integer; SysV_ABI_CDecl; begin if (workload<>0) then @@ -1765,6 +1764,11 @@ begin end; end; +function ps4_sceGnmGetGpuCoreClockFrequency:QWORD; SysV_ABI_CDecl; +begin + Result:=800000000; +end; + const //EqEventType kEqEventCompute0RelMem = $00; ///< ReleaseMem event from the compute pipe 0. @@ -1925,6 +1929,8 @@ begin lib^.set_proc($8A1C6B6ECA122967,@ps4_sceGnmBeginWorkload); lib^.set_proc($15ADF1EF938E2D10,@ps4_sceGnmEndWorkload); + lib^.set_proc($170BE1FBE9BD2102,@ps4_sceGnmGetGpuCoreClockFrequency); + //nop nid:libSceGnmDriver:DBDA0ABCA5F3119A:sceGnmMapComputeQueue end;