mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
b817a72d01
commit
cbb844782b
|
@ -31,6 +31,7 @@ uses
|
|||
|
||||
//internal libs
|
||||
ps4_libSceSystemService,
|
||||
ps4_libSceUserService,
|
||||
ps4_libSceIpmi,
|
||||
ps4_libSceDialogs,
|
||||
ps4_libSceAvSetting
|
||||
|
|
|
@ -73,6 +73,8 @@ const
|
|||
ThreadSetTlsArrayAddress = 15;
|
||||
ThreadIsIoPending = 16;
|
||||
ThreadHideFromDebugger = 17;
|
||||
ThreadNameInformation = 38;
|
||||
ThreadSystemThreadInformation = 40;
|
||||
|
||||
//ProcessInformationClass
|
||||
ProcessBasicInformation=0;
|
||||
|
@ -155,6 +157,8 @@ const
|
|||
MEM_COALESCE_PLACEHOLDERS=$01;
|
||||
MEM_PRESERVE_PLACEHOLDER =$02;
|
||||
|
||||
MEM_RESET_UNDO=$1000000;
|
||||
|
||||
OBJ_INHERIT =$00000002;
|
||||
OBJ_PERMANENT =$00000010;
|
||||
OBJ_EXCLUSIVE =$00000020;
|
||||
|
|
|
@ -20,7 +20,8 @@ uses
|
|||
vm_pmap,
|
||||
sys_vm_object,
|
||||
vm_pager,
|
||||
subr_backtrace;
|
||||
subr_backtrace,
|
||||
bittype;
|
||||
|
||||
var
|
||||
gc_page:Pointer;
|
||||
|
@ -43,6 +44,49 @@ type
|
|||
param3:DWORD;
|
||||
end;
|
||||
|
||||
p_Submit=^t_Submit;
|
||||
t_Submit=packed record
|
||||
arg0 :DWORD;
|
||||
count:DWORD;
|
||||
cmds :PQWORD;
|
||||
end;
|
||||
|
||||
function PM4_TYPE(token:DWORD):Byte; inline;
|
||||
begin
|
||||
Result:=(token shr 30) and 3;
|
||||
end;
|
||||
|
||||
function PM4_LENGTH_DW(token:DWORD):WORD; inline;
|
||||
begin
|
||||
Result:=((token shr 16) and $3FFF) + 2;
|
||||
end;
|
||||
|
||||
type
|
||||
PPM4_TYPE_3_HEADER=^PM4_TYPE_3_HEADER;
|
||||
PM4_TYPE_3_HEADER=bitpacked record
|
||||
predicate:bit1; //1
|
||||
shaderType:bit1; //1
|
||||
reserved:bit6; //6
|
||||
opcode:Byte; //8
|
||||
count:bit14; //14
|
||||
_type:bit2; //2
|
||||
end;
|
||||
|
||||
PPM4CMDINDIRECTBUFFER=^PM4CMDINDIRECTBUFFER;
|
||||
PM4CMDINDIRECTBUFFER=bitpacked record
|
||||
ibBaseLo :DWORD; ///< Indirect buffer base address, must be 4 byte aligned
|
||||
ibBaseHi32 :DWORD; ///< Indirect buffer base address
|
||||
//
|
||||
ibSize :bit20; ///< Indirect buffer size
|
||||
chain :bit1; ///< set to chain to IB allocations
|
||||
offLoadPolling:bit1;
|
||||
volatile__CI :bit1;
|
||||
valid :bit1;
|
||||
vmid :bit4; ///< Virtual memory domain ID for command buffer
|
||||
cachePolicy :bit2;
|
||||
reserved1 :bit2;
|
||||
end;
|
||||
|
||||
Function gc_ioctl(dev:p_cdev;cmd:QWORD;data:Pointer;fflag:Integer):Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
|
@ -79,6 +123,7 @@ begin
|
|||
end;
|
||||
$C008811B: //sceGnmAreSubmitsAllowed
|
||||
begin
|
||||
//ret1 = mmap_addr(0xfe0100000,0x4000,1,(ulong *)&paddr,&local_50);
|
||||
PPointer(data)^:=@gc_AreSubmitsAllowed;
|
||||
end;
|
||||
|
||||
|
@ -98,7 +143,32 @@ begin
|
|||
$C0048114: //sceGnmFlushGarlic
|
||||
begin
|
||||
Writeln('sceGnmFlushGarlic');
|
||||
end
|
||||
end;
|
||||
|
||||
$C0108102: //submit
|
||||
begin
|
||||
Writeln(p_Submit(data)^.arg0);
|
||||
Writeln(p_Submit(data)^.count);
|
||||
Writeln(HexStr(p_Submit(data)^.cmds));
|
||||
|
||||
//IT_INDIRECT_BUFFER_CNST = $00000033; ccb
|
||||
//IT_COND_INDIRECT_BUFFER = $0000003f; dcb
|
||||
|
||||
//opcode 0x33 0x3F
|
||||
//if ((op != L'\xc0023300') && (op != L'\xc0023f00')) {
|
||||
// printf("## %s: invalid opcode = 0x%08x\n","gc_insert_indirect_buffer");
|
||||
// ret1 = 0x804c0010;
|
||||
// goto LAB_ffffffff826bd78b;
|
||||
//}
|
||||
//if ((_buffer[1] & 0xfffff00000000) == 0) {
|
||||
// printf("## %s: invalid ib_size = 0x%05x\n","gc_insert_indirect_buffer",0);
|
||||
// ret1 = 0x804c0011;
|
||||
// goto LAB_ffffffff826bd78b;
|
||||
//}
|
||||
|
||||
|
||||
Assert(False);
|
||||
end;
|
||||
|
||||
|
||||
else
|
||||
|
|
|
@ -1422,21 +1422,7 @@ begin
|
|||
Move(p_proc.p_comm, td^.td_name, sizeof(td^.td_name));
|
||||
KernSetThreadDebugName(td,'ps4:');
|
||||
|
||||
{
|
||||
* mark as execed, wakeup the process that vforked (if any) and tell
|
||||
* it that it now has its own resources back
|
||||
}
|
||||
p_proc.p_flag:=p_proc.p_flag or P_EXEC;
|
||||
|
||||
{
|
||||
* Notify others that we exec'd, and clear the P_INEXEC flag
|
||||
* as we're now a bona fide freshly-execed process.
|
||||
}
|
||||
KNOTE_LOCKED(@p_proc.p_klist, NOTE_EXEC);
|
||||
p_proc.p_flag:=p_proc.p_flag and (not P_INEXEC);
|
||||
|
||||
{ clear 'fork but no exec' flag, as we _are_ execing }
|
||||
//p^.p_acflag:= and ~AFORK;
|
||||
PROC_UNLOCK();
|
||||
|
||||
{
|
||||
* Free any previous argument cache and replace it with
|
||||
|
@ -1446,8 +1432,6 @@ begin
|
|||
p_proc.p_args:=newargs;
|
||||
newargs:=nil;
|
||||
|
||||
PROC_UNLOCK();
|
||||
|
||||
dynlib_proc_initialize_step3(imgp);
|
||||
|
||||
if (dynlibs_info.libkernel=nil) then
|
||||
|
@ -1456,6 +1440,26 @@ begin
|
|||
goto exec_fail_dealloc;
|
||||
end;
|
||||
|
||||
PROC_LOCK();
|
||||
|
||||
{
|
||||
* mark as execed, wakeup the process that vforked (if any) and tell
|
||||
* it that it now has its own resources back
|
||||
}
|
||||
p_proc.p_flag:=p_proc.p_flag or P_EXEC;
|
||||
|
||||
{
|
||||
* Notify others that we exec'd, and clear the P_INEXEC flag
|
||||
* as we're now a bona fide freshly-execed process.
|
||||
}
|
||||
KNOTE_LOCKED(@p_proc.p_klist, NOTE_EXEC);
|
||||
p_proc.p_flag:=p_proc.p_flag and (not P_INEXEC);
|
||||
|
||||
{ clear 'fork but no exec' flag, as we _are_ execing }
|
||||
//p^.p_acflag:= and ~AFORK;
|
||||
|
||||
PROC_UNLOCK();
|
||||
|
||||
vms:=p_proc.p_vmspace;
|
||||
|
||||
{ Set values passed into the program in registers. }
|
||||
|
@ -1556,6 +1560,13 @@ done2:
|
|||
VFS_UNLOCK_GIANT(vfslocked);
|
||||
exec_free_args(args);
|
||||
|
||||
if (error<>0) then
|
||||
begin
|
||||
// sorry, no more process anymore. exit gracefully
|
||||
//exit1(td, W_EXITCODE(0, SIGABRT));
|
||||
// NOT REACHED
|
||||
end;
|
||||
|
||||
Exit(error);
|
||||
end;
|
||||
|
||||
|
|
|
@ -325,13 +325,17 @@ end;
|
|||
|
||||
procedure KernSetThreadDebugName(newtd:p_kthread;prefix:PChar);
|
||||
var
|
||||
td:p_kthread;
|
||||
backup:array[0..1] of QWORD;
|
||||
//td:p_kthread;
|
||||
//backup:array[0..1] of QWORD;
|
||||
name:shortstring;
|
||||
begin
|
||||
name:=shortstring(prefix)+shortstring(newtd^.td_name);
|
||||
|
||||
cpu_thread_set_name(newtd,name);
|
||||
|
||||
{
|
||||
td:=curkthread;
|
||||
|
||||
if (td<>nil) then
|
||||
begin
|
||||
//prevent bullshit in ntdll:__chkstk
|
||||
|
@ -349,6 +353,7 @@ begin
|
|||
PQWORD(td^.td_kstack.stack)[-1]:=backup[0];
|
||||
PQWORD(td^.td_kstack.stack)[-2]:=backup[1];
|
||||
end;
|
||||
}
|
||||
end;
|
||||
|
||||
procedure before_start(td:p_kthread);
|
||||
|
|
|
@ -327,7 +327,7 @@ begin
|
|||
Writeln(stderr,_get_msg(Msg),' (',FName,', line ',LineNo,').');
|
||||
print_backtrace(stderr,Get_pc_addr,get_frame,2);
|
||||
|
||||
sleep(-1);
|
||||
//sleep(-1);
|
||||
|
||||
if IsDebuggerPresent then
|
||||
Raise EAssertionFailed.
|
||||
|
@ -340,6 +340,8 @@ begin
|
|||
// int3
|
||||
//end;
|
||||
|
||||
sleep(-1);
|
||||
|
||||
md_halt(217);
|
||||
end;
|
||||
|
||||
|
|
|
@ -47,7 +47,9 @@ function md_memfd_open (var hMem:THandle;hFile:THandle):Integer;
|
|||
function md_memfd_close (hMem:THandle):Integer;
|
||||
|
||||
function md_protect(base:Pointer;size:QWORD;prot:Integer):Integer;
|
||||
function md_reset (base:Pointer;size:QWORD;prot:Integer):Integer;
|
||||
|
||||
function md_dontneed(base:Pointer;size:QWORD):Integer;
|
||||
function md_activate(base:Pointer;size:QWORD):Integer;
|
||||
|
||||
function md_mmap (var base:Pointer;size:QWORD;prot:Integer):Integer;
|
||||
function md_unmap (base:Pointer;size:QWORD):Integer;
|
||||
|
@ -212,7 +214,7 @@ begin
|
|||
);
|
||||
end;
|
||||
|
||||
function md_reset(base:Pointer;size:QWORD;prot:Integer):Integer;
|
||||
function md_dontneed(base:Pointer;size:QWORD):Integer;
|
||||
begin
|
||||
Result:=NtAllocateVirtualMemory(
|
||||
NtCurrentProcess,
|
||||
|
@ -220,7 +222,19 @@ begin
|
|||
0,
|
||||
@size,
|
||||
MEM_RESET,
|
||||
prot
|
||||
PAGE_NOACCESS
|
||||
);
|
||||
end;
|
||||
|
||||
function md_activate(base:Pointer;size:QWORD):Integer;
|
||||
begin
|
||||
Result:=NtAllocateVirtualMemory(
|
||||
NtCurrentProcess,
|
||||
@base,
|
||||
0,
|
||||
@size,
|
||||
MEM_RESET_UNDO,
|
||||
PAGE_NOACCESS
|
||||
);
|
||||
end;
|
||||
|
||||
|
|
|
@ -8,7 +8,8 @@ interface
|
|||
uses
|
||||
ntapi,
|
||||
windows,
|
||||
kern_thr;
|
||||
kern_thr,
|
||||
sysutils;
|
||||
|
||||
Const
|
||||
SYS_STACK_RSRV=64*1024;
|
||||
|
@ -32,6 +33,8 @@ function cpu_thread_finished(td:p_kthread):Boolean;
|
|||
function cpuset_setaffinity(td:p_kthread;new:Ptruint):Integer;
|
||||
function cpu_set_priority(td:p_kthread;prio:Integer):Integer;
|
||||
|
||||
function cpu_thread_set_name(td:p_kthread;const name:shortstring):Integer;
|
||||
|
||||
procedure seh_wrapper_before(td:p_kthread;var func:Pointer);
|
||||
procedure seh_wrapper_after (td:p_kthread;func:Pointer);
|
||||
|
||||
|
@ -320,6 +323,27 @@ begin
|
|||
Result:=NtSetInformationThread(td^.td_handle,ThreadBasePriority,@prio,SizeOf(Integer));
|
||||
end;
|
||||
|
||||
function cpu_thread_set_name(td:p_kthread;const name:shortstring):Integer;
|
||||
var
|
||||
W:array[0..255] of WideChar;
|
||||
UNAME:UNICODE_STRING;
|
||||
L:DWORD;
|
||||
begin
|
||||
Result:=0;
|
||||
if (td=nil) then Exit;
|
||||
if (td^.td_handle=0) or (td^.td_handle=THandle(-1)) then Exit;
|
||||
|
||||
L:=Utf8ToUnicode(@W,length(W),@name[1],length(name));
|
||||
|
||||
W:=UTF8Decode(name);
|
||||
|
||||
UNAME.Length :=L*SizeOf(WideChar);
|
||||
UNAME.MaximumLength:=UNAME.Length;
|
||||
UNAME.Buffer :=@W;
|
||||
|
||||
Result:=NtSetInformationThread(td^.td_handle,ThreadNameInformation,@UNAME,SizeOf(UNAME));
|
||||
end;
|
||||
|
||||
procedure main_wrapper; assembler; nostackframe;
|
||||
asm
|
||||
subq $40, %rsp
|
||||
|
|
|
@ -92,24 +92,20 @@ procedure pmap_enter_object(pmap :pmap_t;
|
|||
|
||||
procedure pmap_protect(pmap :pmap_t;
|
||||
obj :vm_object_t;
|
||||
offset:vm_ooffset_t;
|
||||
start :vm_offset_t;
|
||||
__end :vm_offset_t;
|
||||
prot :vm_prot_t);
|
||||
|
||||
procedure pmap_madv_free(pmap :pmap_t;
|
||||
obj :vm_object_t;
|
||||
offset:vm_ooffset_t;
|
||||
start :vm_offset_t;
|
||||
__end :vm_offset_t;
|
||||
prot :vm_prot_t);
|
||||
procedure pmap_madvise(pmap :pmap_t;
|
||||
obj :vm_object_t;
|
||||
start :vm_offset_t;
|
||||
__end :vm_offset_t;
|
||||
advise:Integer);
|
||||
|
||||
procedure pmap_remove(pmap :pmap_t;
|
||||
obj :vm_object_t;
|
||||
offset:vm_ooffset_t;
|
||||
start :vm_offset_t;
|
||||
__end :vm_offset_t;
|
||||
prot :vm_prot_t);
|
||||
__end :vm_offset_t);
|
||||
|
||||
implementation
|
||||
|
||||
|
@ -760,14 +756,11 @@ end;
|
|||
|
||||
procedure pmap_protect(pmap :pmap_t;
|
||||
obj :vm_object_t;
|
||||
offset:vm_ooffset_t;
|
||||
start :vm_offset_t;
|
||||
__end :vm_offset_t;
|
||||
prot :vm_prot_t);
|
||||
label
|
||||
_default;
|
||||
var
|
||||
size:QWORD;
|
||||
begin
|
||||
Writeln('pmap_protect:',HexStr(start,11),':',HexStr(__end,11),':prot:',HexStr(prot,2));
|
||||
|
||||
|
@ -816,19 +809,18 @@ begin
|
|||
pmap_mark(start,__end,prot and VM_RWX);
|
||||
end;
|
||||
|
||||
procedure pmap_madv_free(pmap :pmap_t;
|
||||
obj :vm_object_t;
|
||||
offset:vm_ooffset_t;
|
||||
start :vm_offset_t;
|
||||
__end :vm_offset_t;
|
||||
prot :vm_prot_t);
|
||||
procedure pmap_madvise(pmap :pmap_t;
|
||||
obj :vm_object_t;
|
||||
start :vm_offset_t;
|
||||
__end :vm_offset_t;
|
||||
advise:Integer);
|
||||
label
|
||||
_default;
|
||||
var
|
||||
size:QWORD;
|
||||
r:Integer;
|
||||
begin
|
||||
Writeln('pmap_madv_free:',HexStr(start,11),':',HexStr(__end,11),':',HexStr(prot,2));
|
||||
Writeln('pmap_madv_free:',HexStr(start,11),':',HexStr(__end,11),':',HexStr(advise,2));
|
||||
|
||||
r:=0;
|
||||
case vm_object_type(obj) of
|
||||
|
@ -840,7 +832,7 @@ begin
|
|||
|
||||
size:=(__end-start);
|
||||
|
||||
r:=md_reset(Pointer(start),size,wprots[prot and VM_RWX]);
|
||||
r:=md_dontneed(Pointer(start),size);
|
||||
end;
|
||||
OBJT_DEVICE:
|
||||
begin
|
||||
|
@ -875,16 +867,14 @@ end;
|
|||
|
||||
procedure pmap_remove(pmap :pmap_t;
|
||||
obj :vm_object_t;
|
||||
offset:vm_ooffset_t;
|
||||
start :vm_offset_t;
|
||||
__end :vm_offset_t;
|
||||
prot :vm_prot_t);
|
||||
__end :vm_offset_t);
|
||||
label
|
||||
_default;
|
||||
var
|
||||
r:Integer;
|
||||
begin
|
||||
Writeln('pmap_remove:',HexStr(start,11),':',HexStr(__end,11),':',HexStr(prot,2));
|
||||
Writeln('pmap_remove:',HexStr(start,11),':',HexStr(__end,11));
|
||||
|
||||
pmap_unmark(start,__end);
|
||||
|
||||
|
@ -910,10 +900,10 @@ begin
|
|||
|
||||
if ((obj^.flags and OBJ_DMEM_EXT)<>0) then
|
||||
begin
|
||||
Writeln('pmap_remove_gpuobj:',HexStr(start,11),':',HexStr(__end,11),':',HexStr(prot,2));
|
||||
Writeln('pmap_remove_gpuobj:',HexStr(start,11),':',HexStr(__end,11));
|
||||
end else
|
||||
begin
|
||||
Writeln('pmap_remove_devobj:',HexStr(start,11),':',HexStr(__end,11),':',HexStr(prot,2));
|
||||
Writeln('pmap_remove_devobj:',HexStr(start,11),':',HexStr(__end,11));
|
||||
end;
|
||||
|
||||
goto _default;
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
unit ps4_libSceUserService;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
{$CALLING SysV_ABI_CDecl}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
subr_dynlib,
|
||||
atomic,
|
||||
Classes,
|
||||
SysUtils;
|
||||
|
||||
const
|
||||
SCE_USER_SERVICE_MAX_LOGIN_USERS=4;
|
||||
SCE_USER_SERVICE_USER_ID_INVALID=Integer($FFFFFFFF);
|
||||
|
||||
type
|
||||
PUserServiceInitializeParams=^TUserServiceInitializeParams;
|
||||
TUserServiceInitializeParams=packed record
|
||||
priority:DWORD;
|
||||
end;
|
||||
|
||||
PUserServiceLoginUserIdList=^TUserServiceLoginUserIdList;
|
||||
TUserServiceLoginUserIdList=packed record
|
||||
userId:array[0..SCE_USER_SERVICE_MAX_LOGIN_USERS-1] of Integer;
|
||||
end;
|
||||
|
||||
const
|
||||
//SceUserServiceEventType
|
||||
SCE_USER_SERVICE_EVENT_TYPE_LOGIN =0;
|
||||
SCE_USER_SERVICE_EVENT_TYPE_LOGOUT =1;
|
||||
|
||||
type
|
||||
pSceUserServiceEvent=^SceUserServiceEvent;
|
||||
SceUserServiceEvent=packed record
|
||||
eventType:Integer; //SceUserServiceEventType
|
||||
userId:Integer; //SceUserServiceUserId
|
||||
end;
|
||||
|
||||
TUserServiceEventCallback=procedure(event:pSceUserServiceEvent;arg:Pointer);
|
||||
|
||||
implementation
|
||||
|
||||
const
|
||||
SCE_USER_SERVICE_ERROR_NOT_INITIALIZED =-2137653246; //0x80960002
|
||||
SCE_USER_SERVICE_ERROR_INVALID_ARGUMENT=-2137653243; //0x80960005
|
||||
SCE_USER_SERVICE_ERROR_NO_EVENT =-2137653241; //0x80960007
|
||||
SCE_USER_SERVICE_ERROR_BUFFER_TOO_SHORT=-2137653238; //0x8096000A
|
||||
|
||||
function ps4_sceUserServiceInitialize(params:PUserServiceInitializeParams):Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceUserServiceInitialize2(threadPriority:Integer;cpuAffinityMask:qword):Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceUserServiceTerminate:Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceUserServiceGetLoginUserIdList(List:PUserServiceLoginUserIdList):Integer;
|
||||
var
|
||||
i:Integer;
|
||||
begin
|
||||
Result:=-1;
|
||||
if (List=nil) then Exit;
|
||||
List^.userId[0]:=1;
|
||||
For i:=1 to SCE_USER_SERVICE_MAX_LOGIN_USERS-1 do
|
||||
List^.userId[i]:=SCE_USER_SERVICE_USER_ID_INVALID;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceUserServiceGetInitialUser(pUserId:PInteger):Integer;
|
||||
begin
|
||||
if (pUserId=nil) then Exit(SCE_USER_SERVICE_ERROR_INVALID_ARGUMENT);
|
||||
pUserId^:=1;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceUserServiceGetUserName(userId:Integer;userName:PChar;size:size_t):Integer;
|
||||
Const
|
||||
cuser:PChar='user'#0;
|
||||
begin
|
||||
if (userName=nil) then Exit(SCE_USER_SERVICE_ERROR_INVALID_ARGUMENT);
|
||||
if (size<Length(cuser)) then Exit(SCE_USER_SERVICE_ERROR_BUFFER_TOO_SHORT);
|
||||
Move(cuser^,userName^,Length(cuser));
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function ps4_sceUserServiceRegisterEventCallback(func:TUserServiceEventCallback;arg:Pointer):Integer;
|
||||
begin
|
||||
Writeln('sceUserServiceRegisterEventCallback:',HexStr(func));
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
var
|
||||
login_event:Integer=0;
|
||||
|
||||
function ps4_sceUserServiceGetEvent(event:pSceUserServiceEvent):Integer;
|
||||
begin
|
||||
if (event=nil) then Exit(SCE_USER_SERVICE_ERROR_INVALID_ARGUMENT);
|
||||
|
||||
if not CAS(login_event,0,1) then
|
||||
begin
|
||||
Result:=SCE_USER_SERVICE_ERROR_NO_EVENT;
|
||||
end else
|
||||
begin
|
||||
|
||||
event^:=Default(SceUserServiceEvent);
|
||||
event^.eventType:=SCE_USER_SERVICE_EVENT_TYPE_LOGIN;
|
||||
event^.userId :=1;
|
||||
|
||||
Result:=0;
|
||||
end;
|
||||
end;
|
||||
|
||||
const
|
||||
//SceUserServiceUserColor
|
||||
SCE_USER_SERVICE_USER_COLOR_BLUE =0;
|
||||
SCE_USER_SERVICE_USER_COLOR_RED =1;
|
||||
SCE_USER_SERVICE_USER_COLOR_GREEN=2;
|
||||
SCE_USER_SERVICE_USER_COLOR_PINK =3;
|
||||
|
||||
function ps4_sceUserServiceGetUserColor(userId:Integer;
|
||||
color:pInteger //SceUserServiceUserColor
|
||||
):Integer;
|
||||
begin
|
||||
if (color=nil) then Exit(SCE_USER_SERVICE_ERROR_INVALID_ARGUMENT);
|
||||
color^:=SCE_USER_SERVICE_USER_COLOR_BLUE;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function Load_libSceUserService(name:pchar):p_lib_info;
|
||||
var
|
||||
lib:TLIBRARY;
|
||||
begin
|
||||
Result:=obj_new_int('libSceUserService');
|
||||
|
||||
lib:=Result^.add_lib('libSceUserService');
|
||||
lib.set_proc($8F760CBB531534DA,@ps4_sceUserServiceInitialize);
|
||||
lib.set_proc($6B3FF447A7AF899D,@ps4_sceUserServiceInitialize2);
|
||||
lib.set_proc($6F01634BE6D7F660,@ps4_sceUserServiceTerminate);
|
||||
lib.set_proc($7CF87298A36F2BF0,@ps4_sceUserServiceGetLoginUserIdList);
|
||||
lib.set_proc($09D5A9D281D61ABD,@ps4_sceUserServiceGetInitialUser);
|
||||
lib.set_proc($D71C5C3221AED9FA,@ps4_sceUserServiceGetUserName);
|
||||
lib.set_proc($C87D7B43A356B558,@ps4_sceUserServiceGetEvent);
|
||||
lib.set_proc($954A2AC1342EE06A,@ps4_sceUserServiceGetUserColor);
|
||||
|
||||
lib:=Result^.add_lib('libSceUserServiceForNpToolkit');
|
||||
|
||||
lib.set_proc($C2E23B73B50D9340,@ps4_sceUserServiceRegisterEventCallback);
|
||||
end;
|
||||
|
||||
var
|
||||
stub:t_int_file;
|
||||
|
||||
initialization
|
||||
reg_int_file(stub,'libSceUserService.prx',@Load_libSceUserService);
|
||||
|
||||
end.
|
||||
|
|
@ -1785,7 +1785,6 @@ begin
|
|||
begin
|
||||
pmap_protect(map^.pmap,
|
||||
current^.vm_obj,
|
||||
current^.offset,
|
||||
current^.start,
|
||||
current^.__end,
|
||||
current^.protection and MASK(current));
|
||||
|
@ -1921,6 +1920,7 @@ begin
|
|||
end;
|
||||
else;
|
||||
end;
|
||||
|
||||
vm_map_simplify_entry(map, current);
|
||||
|
||||
current:=current^.next;
|
||||
|
@ -1967,30 +1967,15 @@ begin
|
|||
continue;
|
||||
end;
|
||||
|
||||
//vm_object_madvise(current^.vm_obj, pstart, p__end, behav);
|
||||
vm_object_madvise(map^.pmap,
|
||||
current^.vm_obj,
|
||||
useStart,
|
||||
useStart+ptoa(pend-pstart),
|
||||
behav);
|
||||
|
||||
if (current^.vm_obj=nil) then
|
||||
if (behav=MADV_WILLNEED) then
|
||||
begin
|
||||
Case behav of
|
||||
MADV_WILLNEED:
|
||||
begin
|
||||
pmap_enter_object(map^.pmap,
|
||||
current^.vm_obj,
|
||||
ptoa(pstart),
|
||||
useStart,
|
||||
useStart+ptoa(pend-pstart),
|
||||
current^.protection);
|
||||
end;
|
||||
MADV_FREE:
|
||||
begin
|
||||
pmap_madv_free(map^.pmap,
|
||||
current^.vm_obj,
|
||||
ptoa(pstart),
|
||||
useStart,
|
||||
useStart+ptoa(pend-pstart),
|
||||
current^.protection);
|
||||
end;
|
||||
end;
|
||||
//re enter?
|
||||
end;
|
||||
|
||||
current:=current^.next;
|
||||
|
@ -2399,10 +2384,8 @@ begin
|
|||
begin
|
||||
pmap_remove(map^.pmap,
|
||||
entry^.vm_obj,
|
||||
entry^.offset,
|
||||
entry^.start,
|
||||
entry^.__end,
|
||||
entry^.protection);
|
||||
entry^.__end);
|
||||
|
||||
end;
|
||||
|
||||
|
|
|
@ -81,6 +81,11 @@ procedure vm_nt_map_protect(map:p_vm_nt_map;
|
|||
__end:vm_offset_t;
|
||||
prot :Integer);
|
||||
|
||||
procedure vm_nt_map_madvise(map:p_vm_nt_map;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
advise:Integer);
|
||||
|
||||
procedure vm_nt_entry_deallocate(entry:p_vm_nt_entry);
|
||||
|
||||
implementation
|
||||
|
@ -124,6 +129,7 @@ var
|
|||
r:Integer;
|
||||
begin
|
||||
if ((obj^.flags and NT_FILE_FREE)<>0) then
|
||||
if (obj^.hfile<>0) then
|
||||
begin
|
||||
r:=md_memfd_close(obj^.hfile);
|
||||
if (r<>0) then
|
||||
|
@ -281,15 +287,18 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
r:=md_file_mmap_ex(entry^.obj^.hfile,
|
||||
Pointer(entry^.start),
|
||||
entry^.offset,
|
||||
entry^.size, //unaligned size
|
||||
MD_PROT_RW);
|
||||
if (r<>0) then
|
||||
if (entry^.obj^.hfile<>0) then
|
||||
begin
|
||||
Writeln('failed md_file_mmap_ex(',HexStr(entry^.start,11),',',HexStr(entry^.start+size,11),'):0x',HexStr(r,8));
|
||||
Assert(false,'vm_map');
|
||||
r:=md_file_mmap_ex(entry^.obj^.hfile,
|
||||
Pointer(entry^.start),
|
||||
entry^.offset,
|
||||
entry^.size, //unaligned size
|
||||
MD_PROT_RW);
|
||||
if (r<>0) then
|
||||
begin
|
||||
Writeln('failed md_file_mmap_ex(',HexStr(entry^.start,11),',',HexStr(entry^.start+size,11),'):0x',HexStr(r,8));
|
||||
Assert(false,'vm_map');
|
||||
end;
|
||||
end;
|
||||
|
||||
if (prot<>MD_PROT_RW) then
|
||||
|
@ -384,11 +393,15 @@ begin
|
|||
if (p^.start<>0) and
|
||||
(p^.start<>p^.__end) then
|
||||
begin
|
||||
r:=md_file_unmap_ex(Pointer(p^.start));
|
||||
if (r<>0) then
|
||||
//
|
||||
if (stat.obj^.hfile<>0) then
|
||||
begin
|
||||
Writeln('failed md_file_unmap_ex(',HexStr(p^.start,11),',',HexStr(p^.__end,11),'):0x',HexStr(r,8));
|
||||
Assert(false,'vm_remap');
|
||||
r:=md_file_unmap_ex(Pointer(p^.start));
|
||||
if (r<>0) then
|
||||
begin
|
||||
Writeln('failed md_file_unmap_ex(',HexStr(p^.start,11),',',HexStr(p^.__end,11),'):0x',HexStr(r,8));
|
||||
Assert(false,'vm_remap');
|
||||
end;
|
||||
end;
|
||||
//
|
||||
//Writeln('md_file_unmap_ex(',HexStr(p^.start,11),',',HexStr(p^.__end,11),'):0x',HexStr(r,8));
|
||||
|
@ -440,6 +453,7 @@ begin
|
|||
begin
|
||||
//map new
|
||||
if (ets[i]^.obj<>nil) then
|
||||
if (stat.obj^.hfile<>0) then
|
||||
begin
|
||||
r:=md_file_mmap_ex(stat.obj^.hfile,
|
||||
Pointer(ets[i]^.start),
|
||||
|
@ -482,6 +496,7 @@ var
|
|||
r:Integer;
|
||||
begin
|
||||
if (entry^.obj<>nil) then
|
||||
if (entry^.obj^.hfile<>0) then
|
||||
begin
|
||||
r:=md_file_unmap_ex(Pointer(entry^.start));
|
||||
if (r<>0) then
|
||||
|
@ -1066,6 +1081,55 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure vm_nt_map_madvise(map:p_vm_nt_map;
|
||||
start:vm_offset_t;
|
||||
__end:vm_offset_t;
|
||||
advise:Integer);
|
||||
var
|
||||
entry:p_vm_nt_entry;
|
||||
base,size:vm_size_t;
|
||||
r:Integer;
|
||||
begin
|
||||
if (start=__end) then Exit;
|
||||
|
||||
if (not vm_nt_map_lookup_entry(map, start, @entry)) then
|
||||
begin
|
||||
entry:=entry^.next;
|
||||
end else
|
||||
begin
|
||||
entry:=entry;
|
||||
end;
|
||||
|
||||
while (entry<>@map^.header) and (entry^.start<__end) do
|
||||
begin
|
||||
base:=entry^.start;
|
||||
size:=entry^.__end;
|
||||
|
||||
if (base<start) then
|
||||
begin
|
||||
base:=start;
|
||||
end;
|
||||
|
||||
if (size>__end) then
|
||||
begin
|
||||
size:=__end;
|
||||
end;
|
||||
|
||||
size:=size-base;
|
||||
|
||||
case advise of
|
||||
MADV_WILLNEED:r:=md_dontneed(Pointer(base),size);
|
||||
MADV_DONTNEED,
|
||||
MADV_FREE :r:=md_activate(Pointer(base),size);
|
||||
else;
|
||||
end;
|
||||
|
||||
//ignore errors
|
||||
|
||||
entry:=entry^.next;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
@ -33,10 +33,17 @@ function vm_object_coalesce(prev_object:vm_object_t;
|
|||
next_size :vm_ooffset_t;
|
||||
reserved :Boolean):Boolean;
|
||||
|
||||
procedure vm_object_madvise(pmap :Pointer;
|
||||
obj :vm_object_t;
|
||||
start :vm_offset_t;
|
||||
__end :vm_offset_t;
|
||||
advise:Integer);
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
vmparam,
|
||||
vm_pmap,
|
||||
vnode,
|
||||
vnode_if,
|
||||
vmount,
|
||||
|
@ -409,5 +416,96 @@ begin
|
|||
Result:=(TRUE);
|
||||
end;
|
||||
|
||||
{
|
||||
vm_object_madvise:
|
||||
|
||||
Implements the madvise function at the object/page level.
|
||||
|
||||
MADV_WILLNEED (any object)
|
||||
|
||||
Activate the specified pages if they are resident.
|
||||
|
||||
MADV_DONTNEED (any object)
|
||||
|
||||
Deactivate the specified pages if they are resident.
|
||||
|
||||
MADV_FREE (OBJT_DEFAULT/OBJT_SWAP objects,
|
||||
OBJ_ONEMAPPING only)
|
||||
|
||||
Deactivate and clean the specified pages if they are
|
||||
resident. This permits the process to reuse the pages
|
||||
without faulting or the kernel to reclaim the pages
|
||||
without I/O.
|
||||
}
|
||||
procedure vm_object_madvise(pmap :Pointer;
|
||||
obj :vm_object_t;
|
||||
start :vm_offset_t;
|
||||
__end :vm_offset_t;
|
||||
advise:Integer);
|
||||
label
|
||||
unlock_tobject;
|
||||
begin
|
||||
if (obj=nil) then
|
||||
begin
|
||||
|
||||
case advise of
|
||||
MADV_WILLNEED,
|
||||
MADV_DONTNEED,
|
||||
MADV_FREE :
|
||||
begin
|
||||
pmap_madvise(pmap,
|
||||
obj,
|
||||
start,
|
||||
__end,
|
||||
advise);
|
||||
end
|
||||
else;
|
||||
end;
|
||||
|
||||
Exit;
|
||||
end;
|
||||
|
||||
VM_OBJECT_LOCK(obj);
|
||||
|
||||
{
|
||||
* MADV_FREE only operates on OBJT_DEFAULT or OBJT_SWAP pages
|
||||
* and those pages must be OBJ_ONEMAPPING.
|
||||
}
|
||||
if (advise=MADV_FREE) then
|
||||
begin
|
||||
if ((obj^.otype<>OBJT_DEFAULT) and
|
||||
(obj^.otype<>OBJT_SELF) and //
|
||||
(obj^.otype<>OBJT_SWAP)) or
|
||||
((obj^.flags and OBJ_ONEMAPPING)=0) then
|
||||
begin
|
||||
goto unlock_tobject;
|
||||
end;
|
||||
end else
|
||||
if (obj^.otype=OBJT_PHYS) then
|
||||
begin
|
||||
goto unlock_tobject;
|
||||
end;
|
||||
|
||||
case advise of
|
||||
MADV_WILLNEED,
|
||||
MADV_DONTNEED,
|
||||
MADV_FREE :
|
||||
begin
|
||||
pmap_madvise(pmap,
|
||||
obj,
|
||||
start,
|
||||
__end,
|
||||
advise);
|
||||
end
|
||||
else;
|
||||
end;
|
||||
|
||||
unlock_tobject:
|
||||
VM_OBJECT_UNLOCK(obj);
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
end.
|
||||
|
||||
|
|
Loading…
Reference in New Issue