mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
80d44546cd
commit
0932250ac4
|
@ -319,6 +319,36 @@ type
|
|||
addressHi:bit16; // < base address Hi of buffer
|
||||
end;
|
||||
|
||||
const
|
||||
SET_PRED_CLEAR =0;
|
||||
SET_PRED_ZPASS =1;
|
||||
SET_PRED_PRIMCOUNT=2;
|
||||
SET_PRED_MEM =3;
|
||||
|
||||
type
|
||||
PPM4CMDSETPREDICATION=^PM4CMDSETPREDICATION;
|
||||
PM4CMDSETPREDICATION=bitpacked record
|
||||
header :PM4_TYPE_3_HEADER;
|
||||
startAddressLo :bit32; // < start address low
|
||||
startAddrHi :bit8; // < start address hi
|
||||
predicationBoolean:bit1; // < predication boolean
|
||||
reserved1 :bit3;
|
||||
hint :bit1; // < hint
|
||||
// < (only valid for Zpass/Occlusion Predicate)
|
||||
reserved2 :bit3;
|
||||
predOp :bit3; // < predicate operation
|
||||
reserved3 :bit12;
|
||||
continueBit :bit1; // < continue set predication
|
||||
end;
|
||||
|
||||
PPM4CMDDRAWPREAMBLE=^PM4CMDDRAWPREAMBLE;
|
||||
PM4CMDDRAWPREAMBLE=bitpacked record
|
||||
header :PM4_TYPE_3_HEADER;
|
||||
control1 :TVGT_PRIMITIVE_TYPE; //< writes to VGT_PRIMITIVE_TYPE reg
|
||||
control2 :TIA_MULTI_VGT_PARAM; //< writes to IA_MULTI_VGT_PARAM reg
|
||||
control3 :TVGT_LS_HS_CONFIG; //< writes to VGT_LS_HS_CONFIG reg
|
||||
end;
|
||||
|
||||
// WRITE_DATA DST_SEL and ENGINE definitions
|
||||
const
|
||||
WRITE_DATA_DST_SEL_REGISTER =0;
|
||||
|
|
|
@ -635,7 +635,7 @@ begin
|
|||
cfg.hOutput:=FAddHandle;
|
||||
cfg.hError :=FAddHandle;
|
||||
|
||||
cfg.fork_proc:=False;
|
||||
cfg.fork_proc:=True;
|
||||
|
||||
if Item.FLock then Exit;
|
||||
|
||||
|
|
|
@ -165,22 +165,52 @@ begin
|
|||
|
||||
end;
|
||||
|
||||
function revbinstr(val:int64;cnt:byte):shortstring;
|
||||
var
|
||||
i:Integer;
|
||||
begin
|
||||
Result[0]:=AnsiChar(cnt);
|
||||
for i:=1 to cnt do
|
||||
begin
|
||||
Result[i]:=AnsiChar(48+val and 1);
|
||||
val:=val shr 1;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure onContextControl(Body:PPM4CMDCONTEXTCONTROL);
|
||||
begin
|
||||
Writeln(' loadControl =b',BinStr(DWORD(Body^.loadControl ),32));
|
||||
Writeln(' shadowEnable=b',BinStr(DWORD(Body^.shadowEnable),32));
|
||||
Writeln(' loadControl =b',revbinstr(DWORD(Body^.loadControl ),32));
|
||||
Writeln(' shadowEnable=b',revbinstr(DWORD(Body^.shadowEnable),32));
|
||||
end;
|
||||
|
||||
procedure onSetBase(Body:PPM4CMDDRAWSETBASE);
|
||||
var
|
||||
addr:QWORD;
|
||||
begin
|
||||
addr:=Body^.addressLo or Body^.addressHi;
|
||||
addr:=Body^.addressLo or (Body^.addressHi shl 32);
|
||||
|
||||
Writeln(' baseIndex=0x',HexStr(Body^.baseIndex,4));
|
||||
Writeln(' address =0x',HexStr(addr,16));
|
||||
end;
|
||||
|
||||
procedure onSetPredication(Body:PPM4CMDSETPREDICATION);
|
||||
var
|
||||
addr:QWORD;
|
||||
begin
|
||||
addr:=Body^.startAddressLo or (Body^.startAddrHi shl 32);
|
||||
|
||||
Writeln(' startAddress=0x',HexStr(addr,16));
|
||||
Writeln(' pred =',Body^.predicationBoolean);
|
||||
Writeln(' hint =',Body^.hint);
|
||||
Writeln(' predOp =',Body^.predOp);
|
||||
Writeln(' continueBit =',Body^.continueBit);
|
||||
end;
|
||||
|
||||
procedure onDrawPreamble(Body:PPM4CMDDRAWPREAMBLE);
|
||||
begin
|
||||
//Writeln;
|
||||
end;
|
||||
|
||||
procedure onSetShReg(Body:PPM4CMDSETDATA);
|
||||
begin
|
||||
Writeln(' 0x',HexStr(SH_REG_BASE+Body^.REG_OFFSET,4),'..',
|
||||
|
@ -240,8 +270,8 @@ begin
|
|||
IT_PFP_SYNC_ME :;
|
||||
|
||||
IT_SET_BASE :onSetBase(buff);
|
||||
IT_DRAW_PREAMBLE :;
|
||||
IT_SET_PREDICATION :;
|
||||
IT_DRAW_PREAMBLE :onDrawPreamble(buff);
|
||||
IT_SET_PREDICATION :onSetPredication(buff);
|
||||
|
||||
else;
|
||||
end;
|
||||
|
|
|
@ -383,7 +383,7 @@ var
|
|||
),
|
||||
(//[65]
|
||||
sy_narg:3;
|
||||
sy_call:nil;
|
||||
sy_call:@sys_msync;
|
||||
sy_name:'sys_msync'
|
||||
),
|
||||
(//[66]
|
||||
|
@ -1443,7 +1443,7 @@ var
|
|||
),
|
||||
(//[277]
|
||||
sy_narg:3;
|
||||
sy_call:nil;
|
||||
sy_call:@sys_msync;
|
||||
sy_name:'sys_msync'
|
||||
),
|
||||
(//[278]
|
||||
|
|
|
@ -45,6 +45,7 @@ function readlink(path,buf:PChar;count:QWORD):Integer;
|
|||
function _execve(fname:pchar;argv,envv:ppchar):Integer;
|
||||
function umask(newmask:Integer):Integer;
|
||||
function chroot(path:PChar):Integer;
|
||||
function msync(addr:Pointer;len:QWORD;flags:Integer):Integer;
|
||||
function munmap(addr:Pointer;len:QWORD):Integer;
|
||||
function mprotect(addr:Pointer;len:QWORD;prot:Integer):Integer;
|
||||
function madvise(addr:Pointer;len:QWORD;behav:Integer):Integer;
|
||||
|
@ -525,6 +526,13 @@ asm
|
|||
jmp cerror
|
||||
end;
|
||||
|
||||
function msync(addr:Pointer;len:QWORD;flags:Integer):Integer; assembler; nostackframe;
|
||||
asm
|
||||
movq $65,%rax
|
||||
call fast_syscall
|
||||
jmp cerror
|
||||
end;
|
||||
|
||||
function munmap(addr:Pointer;len:QWORD):Integer; assembler; nostackframe;
|
||||
asm
|
||||
movq $73,%rax
|
||||
|
|
|
@ -225,6 +225,12 @@ function vm_map_madvise(map :vm_map_t;
|
|||
__end:vm_offset_t;
|
||||
behav:Integer):Integer;
|
||||
|
||||
function vm_map_sync(map :vm_map_t;
|
||||
start :vm_offset_t;
|
||||
__end :vm_offset_t;
|
||||
syncio :Boolean;
|
||||
invalidate:Boolean):Integer;
|
||||
|
||||
function vm_map_find(map :vm_map_t;
|
||||
vm_obj :vm_object_t;
|
||||
offset :vm_ooffset_t;
|
||||
|
@ -257,7 +263,7 @@ function vm_map_stack(map :vm_map_t;
|
|||
function vm_map_growstack(map:vm_map_t;addr:vm_offset_t):Integer;
|
||||
function vmspace_exec(minuser,maxuser:vm_offset_t):Integer;
|
||||
|
||||
procedure vm_map_lock(map:vm_map_t);
|
||||
procedure vm_map_lock(map:vm_map_t;tm:Boolean=True);
|
||||
function vm_map_trylock(map:vm_map_t):Boolean;
|
||||
procedure vm_map_unlock(map:vm_map_t);
|
||||
|
||||
|
@ -277,6 +283,7 @@ procedure vminit; //SYSINIT
|
|||
implementation
|
||||
|
||||
uses
|
||||
md_map,
|
||||
kern_proc,
|
||||
rmem_map,
|
||||
kern_budget;
|
||||
|
@ -398,10 +405,13 @@ begin
|
|||
Result:=vm;
|
||||
end;
|
||||
|
||||
procedure vm_map_lock(map:vm_map_t);
|
||||
procedure vm_map_lock(map:vm_map_t;tm:Boolean=True);
|
||||
begin
|
||||
mtx_lock(map^.lock);
|
||||
Inc(map^.timestamp);
|
||||
if tm then
|
||||
begin
|
||||
Inc(map^.timestamp);
|
||||
end;
|
||||
end;
|
||||
|
||||
function vm_map_trylock(map:vm_map_t):Boolean;
|
||||
|
@ -2088,9 +2098,9 @@ end;
|
|||
*
|
||||
* Returns an error if any part of the specified range is not mapped.
|
||||
}
|
||||
function vm_map_sync(map :vm_map_t;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
function vm_map_sync(map :vm_map_t;
|
||||
start :vm_offset_t;
|
||||
__end :vm_offset_t;
|
||||
syncio :Boolean;
|
||||
invalidate:Boolean):Integer;
|
||||
var
|
||||
|
@ -2118,12 +2128,20 @@ begin
|
|||
start:=entry^.start;
|
||||
__end:=entry^.__end;
|
||||
end;
|
||||
|
||||
{
|
||||
* Make a first pass to check for user-wired memory and holes.
|
||||
}
|
||||
current:=entry;
|
||||
while (current<>@map^.header) and (current^.start<__end) do
|
||||
begin
|
||||
if invalidate and
|
||||
((current^.eflags and MAP_ENTRY_USER_WIRED)<>0) then
|
||||
begin
|
||||
vm_map_unlock(map);
|
||||
Exit(KERN_INVALID_ARGUMENT);
|
||||
end;
|
||||
|
||||
if (__end>current^.__end) and
|
||||
((current^.next=@map^.header) or
|
||||
(current^.__end<>current^.next^.start)) then
|
||||
|
@ -2137,8 +2155,10 @@ begin
|
|||
|
||||
if invalidate then
|
||||
begin
|
||||
//
|
||||
md_cacheflush(Pointer(start),__end-start,ICACHE or DCACHE);
|
||||
//pmap_remove(map^.pmap, start, end);
|
||||
end;
|
||||
|
||||
failed:=FALSE;
|
||||
|
||||
{
|
||||
|
@ -2183,11 +2203,16 @@ begin
|
|||
vm_object_reference(obj);
|
||||
last_timestamp:=map^.timestamp;
|
||||
vm_map_unlock(map);
|
||||
//if (not vm_object_sync(_object, offset, size, syncio, invalidate)) then
|
||||
// failed:=TRUE;
|
||||
|
||||
if (not vm_object_sync(obj, offset, size, syncio, invalidate)) then
|
||||
begin
|
||||
failed:=TRUE;
|
||||
end;
|
||||
|
||||
start:=start+size;
|
||||
vm_object_deallocate(obj);
|
||||
vm_map_lock(map);
|
||||
|
||||
vm_map_lock(map,False);
|
||||
if (last_timestamp=map^.timestamp) or
|
||||
(not vm_map_lookup_entry(map, start, @current)) then
|
||||
begin
|
||||
|
|
|
@ -28,6 +28,7 @@ type
|
|||
pos :QWORD):Pointer;
|
||||
|
||||
function sys_munmap(addr:Pointer;len:QWORD):Integer;
|
||||
function sys_msync(addr:Pointer;len:QWORD;flags:Integer):Integer;
|
||||
function sys_mprotect(addr:Pointer;len:QWORD;prot:Integer):Integer;
|
||||
function sys_madvise(addr:Pointer;len:QWORD;behav:Integer):Integer;
|
||||
function sys_mname(addr:Pointer;len:QWORD;name:PChar):Integer;
|
||||
|
@ -842,6 +843,50 @@ begin
|
|||
Exit(0);
|
||||
end;
|
||||
|
||||
function sys_msync(addr:Pointer;len:QWORD;flags:Integer):Integer;
|
||||
var
|
||||
map:vm_map_t;
|
||||
_addr:vm_offset_t;
|
||||
pageoff:vm_size_t;
|
||||
begin
|
||||
_addr:=vm_offset_t(addr);
|
||||
|
||||
pageoff:=(_addr and PAGE_MASK);
|
||||
_addr:=_addr-pageoff;
|
||||
len:=len+pageoff;
|
||||
|
||||
len:=round_page(len);
|
||||
|
||||
if ((_addr + len) < _addr) then
|
||||
begin
|
||||
Exit(EINVAL);
|
||||
end;
|
||||
|
||||
if ((flags and (MS_ASYNC or MS_INVALIDATE))=(MS_ASYNC or MS_INVALIDATE)) then
|
||||
begin
|
||||
Exit(EINVAL);
|
||||
end;
|
||||
|
||||
map:=p_proc.p_vmspace;
|
||||
|
||||
// Clean the pages and interpret the Exit value.
|
||||
Result:=vm_map_sync(map,
|
||||
_addr,
|
||||
_addr + len,
|
||||
(flags and MS_ASYNC)=0,
|
||||
(flags and MS_INVALIDATE)<>0);
|
||||
|
||||
case Result of
|
||||
KERN_SUCCESS :Result:=0;
|
||||
KERN_INVALID_ADDRESS :Result:=ENOMEM;
|
||||
KERN_INVALID_ARGUMENT:Result:=EBUSY;
|
||||
KERN_FAILURE :Result:=EIO;
|
||||
else
|
||||
Result:=EINVAL;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
function sys_mprotect(addr:Pointer;len:QWORD;prot:Integer):Integer;
|
||||
var
|
||||
size,pageoff:vm_size_t;
|
||||
|
|
|
@ -39,6 +39,12 @@ procedure vm_object_madvise(pmap :Pointer;
|
|||
__end :vm_offset_t;
|
||||
advise:Integer);
|
||||
|
||||
function vm_object_sync(obj :vm_object_t;
|
||||
offset :vm_ooffset_t;
|
||||
size :vm_size_t;
|
||||
syncio :Boolean;
|
||||
invalidate:Boolean):Boolean;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
|
@ -504,6 +510,114 @@ begin
|
|||
VM_OBJECT_UNLOCK(obj);
|
||||
end;
|
||||
|
||||
{
|
||||
* Note that there is absolutely no sense in writing out
|
||||
* anonymous objects, so we track down the vnode object
|
||||
* to write out.
|
||||
* We invalidate (remove) all pages from the address space
|
||||
* for semantic correctness.
|
||||
*
|
||||
* If the backing object is a device object with unmanaged pages, then any
|
||||
* mappings to the specified range of pages must be removed before this
|
||||
* function is called.
|
||||
*
|
||||
* Note: certain anonymous maps, such as MAP_NOSYNC maps,
|
||||
* may start out with a nil object.
|
||||
}
|
||||
function vm_object_sync(obj :vm_object_t;
|
||||
offset :vm_ooffset_t;
|
||||
size :vm_size_t;
|
||||
syncio :Boolean;
|
||||
invalidate:Boolean):Boolean;
|
||||
var
|
||||
vp:p_vnode;
|
||||
mp:p_mount;
|
||||
error,flags:Integer;
|
||||
vfslocked:Integer;
|
||||
fsync_after:Boolean;
|
||||
res:Boolean;
|
||||
begin
|
||||
if (obj=nil) then Exit(TRUE);
|
||||
|
||||
res:=TRUE;
|
||||
error:=0;
|
||||
VM_OBJECT_LOCK(obj);
|
||||
|
||||
{
|
||||
* Flush pages if writing is allowed, invalidate them
|
||||
* if invalidation requested. Pages undergoing I/O
|
||||
* will be ignored by vm_object_page_remove().
|
||||
*
|
||||
* We cannot lock the vnode and then wait for paging
|
||||
* to complete without deadlocking against vm_fault.
|
||||
* Instead we simply call vm_object_page_remove() and
|
||||
* allow it to block internally on a page-by-page
|
||||
* basis when it encounters pages undergoing async
|
||||
* I/O.
|
||||
}
|
||||
if (obj^.otype=OBJT_VNODE) and
|
||||
((obj^.flags and OBJ_MIGHTBEDIRTY)<>0) then
|
||||
begin
|
||||
vp:=obj^.handle;
|
||||
VM_OBJECT_UNLOCK(obj);
|
||||
vn_start_write(vp, @mp, V_WAIT);
|
||||
vfslocked:=VFS_LOCK_GIANT(vp^.v_mount);
|
||||
vn_lock(vp, LK_EXCLUSIVE or LK_RETRY);
|
||||
|
||||
if (syncio) and
|
||||
(not invalidate) and
|
||||
(offset=0) and
|
||||
(OFF_TO_IDX(size)=obj^.size) then
|
||||
begin
|
||||
{
|
||||
* If syncing the whole mapping of the file,
|
||||
* it is faster to schedule all the writes in
|
||||
* async mode, also allowing the clustering,
|
||||
* and then wait for i/o to complete.
|
||||
}
|
||||
flags:=0;
|
||||
fsync_after:=TRUE;
|
||||
end else
|
||||
begin
|
||||
flags:=0;
|
||||
|
||||
if (syncio or invalidate) then
|
||||
begin
|
||||
flags:=flags or OBJPC_SYNC;
|
||||
end;
|
||||
|
||||
if (invalidate) then
|
||||
begin
|
||||
flags:=flags or (OBJPC_SYNC or OBJPC_INVAL);
|
||||
end;
|
||||
|
||||
fsync_after:=FALSE;
|
||||
end;
|
||||
|
||||
VM_OBJECT_LOCK(obj);
|
||||
res:=vm_object_page_clean(obj, offset, offset + size, flags);
|
||||
VM_OBJECT_UNLOCK(obj);
|
||||
|
||||
if (fsync_after) then
|
||||
begin
|
||||
error:=VOP_FSYNC(vp, MNT_WAIT);
|
||||
end;
|
||||
|
||||
VOP_UNLOCK(vp, 0);
|
||||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
vn_finished_write(mp);
|
||||
|
||||
if (error<>0) then
|
||||
begin
|
||||
res:=FALSE;
|
||||
end;
|
||||
|
||||
VM_OBJECT_LOCK(obj);
|
||||
end;
|
||||
|
||||
VM_OBJECT_UNLOCK(obj);
|
||||
Exit(res);
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue