This commit is contained in:
Pavel 2023-08-09 14:39:14 +03:00
parent 415e6b9526
commit 704c9d4e87
17 changed files with 617 additions and 236 deletions

88
sys/dev/dev_gc.pas Normal file
View File

@ -0,0 +1,88 @@
unit dev_gc;
{$mode ObjFPC}{$H+}
{$CALLING SysV_ABI_CDecl}
interface
uses
kern_conf;
procedure gc_initialize();
implementation
uses
errno,
vm,
kern_thr,
trap;
Function gc_ioctl(dev:p_cdev;cmd:QWORD;data:Pointer;fflag:Integer):Integer;
begin
Result:=0;
Writeln('gc_ioctl(0x',HexStr(cmd,8),')');
case cmd of
0:;
else
begin
print_backtrace(stderr,Pointer(curkthread^.td_frame.tf_rip),Pointer(curkthread^.td_frame.tf_rbp),0);
Assert(False);
Result:=EINVAL;
end;
end;
end;
Function gc_mmap(dev:p_cdev;offset:vm_ooffset_t;paddr:p_vm_paddr_t;nprot:Integer;memattr:p_vm_memattr_t):Integer;
begin
print_backtrace(stderr,Pointer(curkthread^.td_frame.tf_rip),Pointer(curkthread^.td_frame.tf_rbp),0);
Assert(False);
Result:=0;
end;
{
int ret2;
int ret1;
GS_OFFSET *in_GS_OFFSET;
ret2 = sceSblACMgrHasUseHp3dPipeCapability(in_GS_OFFSET->td->td_ucred);
ret1 = 1;
if ((ret2 == 0) && (ret1 = 0x16, offset < 0x4000)) {
ret1 = 0;
*paddr = offset + *(long *)(*(long *)(dev + 0xa8) + 0x216c8);
*memattr = 0;
}
return ret1;
}
const
gc_cdevsw:t_cdevsw=(
d_version :D_VERSION;
d_flags :0;
d_name :'gc';
d_open :nil;
d_fdopen :nil;
d_close :nil;
d_read :nil;
d_write :nil;
d_ioctl :@gc_ioctl;
d_poll :nil;
d_mmap :@gc_mmap;
d_strategy :nil;
d_dump :nil;
d_kqfilter :nil;
d_purge :nil;
d_mmap_single:nil;
);
procedure gc_initialize();
begin
make_dev(@gc_cdevsw,0,0,0,&666,'gc',[]);
end;
end.

View File

@ -5,12 +5,118 @@ unit kern_authinfo;
interface
uses
kern_rtld;
type
p_proc_type_info=^t_proc_type_info;
t_proc_type_info=packed record
size :QWORD;
bptype:DWORD;
pflags:DWORD;
end;
{$IF sizeof(t_proc_type_info)<>16}{$STOP sizeof(t_proc_type_info)<>16}{$ENDIF}
p_authinfo=^t_authinfo;
t_authinfo=packed record
app_type :QWORD;
app_flags :QWORD; //62 bit IsSystemProcess;61 bit IsGameProcess1;60 bit IsGameProcess2;
app_cap :QWORD;
unknow1 :array[0..1] of QWORD;
s_prog_attr:QWORD;
unknow2 :array[0..10] of QWORD;
end;
{$IF sizeof(t_authinfo)<>136}{$STOP sizeof(t_authinfo)<>136}{$ENDIF}
const
//eLoadOptions
LOAD_OPTIONS_DEFAULT =$0000;
LOAD_OPTIONS_LOAD_SUSPENDED =$0001;
LOAD_OPTIONS_USE_SYSTEM_LIBRARY_VERIFICATION =$0002;
LOAD_OPTIONS_SLV_MODE_WARN =$0004;
LOAD_OPTIONS_ARG_STACK_SIZE =$0008;
LOAD_OPTIONS_FULL_DEBUG_REQUIRED =$0010;
//mmap_flags
//bit 1 -> is_big_app
//bit 2 -> first find addr is (1 shl 33) ->
// _sceKernelMapFlexibleMemory
// _sceKernelMapDirectMemory
// sceKernelMapDirectMemory2
//excp_flags
//bit 1 -> use in [libkernel_exception] ->
// -> sceKernelInstallExceptionHandler
// -> sceKernelRemoveExceptionHandler
// -> sceKernelAddGpuExceptionEvent
// -> sceKernelDeleteGpuExceptionEvent
// -> sceKernelBacktraceSelf
//bit 2 -> sys_mdbg_service
type
TCUSANAME=array[0..9] of AnsiChar;
//[preload_lib] -> sceSysmodulePreloadModuleForLibkernel
//0x0000000004 libSceNet
//0x0000000008 libSceIpmi
//0x0000000010 libSceMbus
//0x0000000020 libSceRegMgr
//0x0000000040 libSceRtc
//0x0000000080 libSceAvSetting
//0x0000000100 libSceVideoOut
//0x0000000200 libSceGnmDriver
//0x0000000400 libSceAudioOut
//0x0000000800 libSceAudioIn
//0x0000001000 libSceAjm
//0x0000002000 libScePad
//0x0000004000 libSceCamera
//0x0000008000 libSceDbg
//0x0000010000 libSceNetCtl
//0x0000020000 libScettp
//0x0000040000 libSceSsl
//0x0000080000 libSceNpCommon
//0x0000100000 libSceNpManager
//0x0000200000 libSceNpWebApi
//0x0000400000 libSceSaveData
//0x0000800000 libSceSystemService
//0x0001000000 libSceUserService
//0x0002000000 libSceCommonDialog
//0x0004000000 libSceSysUtil
//0x0008000000 libScePerf
//0x0010000000 libSceWebKit2ForVideoService
//0x0020000000 libSceOrbisCompatForVideoService
//0x0040000000 libSceFios2,libc
//0x0080000000 libSceRazorCpu
//0x0100000000 libSceRazorCpu_debug
//0x1000000000 libSceHttp2
//0x2000000000 libSceNpGameIntent
//0x4000000000 libSceNpWebApi2
p_appinfo=^t_appinfo;
t_appinfo=packed record
AppId :Integer; //4
mmap_flags :Integer; //4
excp_flags :Integer; //4
AppType :Integer; //4 5?
CUSANAME :TCUSANAME; //10
debug_level:Byte; //1
slv_flags :Byte; //1 eLoadOptions
f_1c :Byte;
f_1d :Byte;
f_1e :Byte;
f_1f :Byte;
preload_lib:QWORD;
f_28 :Integer;
f_2c :Integer;
f_30 :Integer;
f_34 :Integer;
f_38 :QWORD;
f_40 :QWORD;
end;
{$IF sizeof(t_appinfo)<>72}{$STOP sizeof(t_appinfo)<>72}{$ENDIF}
var
g_authinfo:t_authinfo;
g_appinfo :t_appinfo;
function sys_get_proc_type_info(dst:Pointer):Integer;
function sys_get_authinfo(pid:Integer;info:Pointer):Integer;
implementation
@ -18,7 +124,79 @@ implementation
uses
errno,
systm,
md_proc;
md_proc,
kern_rtld;
function sceSblACMgrIsVideoplayerProcess(info:p_authinfo):Boolean;
begin
Result:=(info^.app_type + QWORD($c7ffffffefffffff)) < 2;
end;
function sceSblACMgrHasUseVideoServiceCapability(info:p_authinfo):Boolean;
begin
Result:=((info^.app_cap shr $39) and 1)<>0;
end;
function sceSblACMgrHasSceProgramAttribute(info:p_authinfo):Boolean;
var
sce_prog_attr:QWORD;
begin
sce_prog_attr:=info^.s_prog_attr;
if ((sce_prog_attr and $1000000)=0) then
begin
if ((sce_prog_attr and $2000000)<>0) then
begin
Exit(true);
end;
//sceSblRcMgrIsAllowULDebugger
if (((sce_prog_attr shr (3*8)) and 1)=0) then
begin
Exit(false);
end;
end;
//sceSblRcMgrIsSoftwagnerQafForAcmgr
Exit(false);
end;
function sys_get_proc_type_info(dst:Pointer):Integer;
var
info:t_proc_type_info;
begin
info:=Default(t_proc_type_info);
Result:=copyin(dst,@info.size,SizeOf(QWORD));
if (Result<>0) then Exit;
if (info.size<>SizeOf(t_proc_type_info)) then Exit(EINVAL);
info.bptype:=budget_ptype_caller;
if sceSblACMgrIsVideoplayerProcess(@g_authinfo) then
begin
info.pflags:=info.pflags or $04;
end;
if sceSblACMgrHasUseVideoServiceCapability(@g_authinfo) then
begin
info.pflags:=info.pflags or $10;
end;
if sceSblACMgrHasSceProgramAttribute(@g_authinfo) then
begin
info.pflags:=info.pflags or $80;
end;
//sceSblACMgrIsJitCompilerProcess() -> | 0x01
//sceSblACMgrIsJitApplicationProcess() -> | 0x02
//sceSblACMgrIsVideoplayerProcess() -> | 0x04
//sceSblACMgrIsDiskplayeruiProcess() -> | 0x08
//sceSblACMgrHasUseVideoServiceCapability() -> | 0x10
//sceSblACMgrIsWebcoreProcess() -> | 0x20
//is_libkernel_sys() -> | 0x40
//sceSblACMgrHasSceProgramAttribute() -> | 0x80
Result:=copyout(@info,dst,SizeOf(t_proc_type_info));
end;
function sys_get_authinfo(pid:Integer;info:Pointer):Integer;
var
@ -40,12 +218,12 @@ begin
// data:=g_authinfo;
//end else
begin
x:=g_authinfo.app_type_id;
x:=g_authinfo.app_type;
y:=x+QWORD($c7ffffffeffffffc);
if (y < $f) and (((QWORD($6001) shr (y and $3f)) and 1)<>0) then
begin
data.app_type_id:=x;
data.app_type:=x;
end;
data.app_flags:=g_authinfo.app_flags and QWORD($7000000000000000);

View File

@ -13,16 +13,12 @@ function sys_budget_get_ptype(pid:Integer):Integer;
function sys_budget_get_ptype_of_budget(key:Integer):Integer;
function sys_budget_getid():Integer;
function sys_get_proc_type_info(dst:Pointer):Integer;
implementation
uses
errno,
systm,
kern_thr,
md_proc,
kern_rtld;
md_proc;
function sys_budget_create(name:pchar;ptype:DWORD;unk_ptr1:Pointer;unk_count:DWORD;unk_ptr2:Pointer):Integer;
begin
@ -76,41 +72,6 @@ begin
Exit(ENOSYS); //sceSblACMgrIsSystemUcred
end;
type
p_proc_type_info=^t_proc_type_info;
t_proc_type_info=packed record
size :QWORD;
bptype:DWORD;
pflags:DWORD;
end;
{$IF sizeof(t_proc_type_info)<>16}{$STOP sizeof(t_proc_type_info)<>16}{$ENDIF}
function sys_get_proc_type_info(dst:Pointer):Integer;
var
info:t_proc_type_info;
begin
info:=Default(t_proc_type_info);
Result:=copyin(dst,@info.size,SizeOf(QWORD));
if (Result<>0) then Exit;
if (Result<>SizeOf(t_proc_type_info)) then Exit(EINVAL);
info.bptype:=budget_ptype_caller;
info.pflags:=0;
//sceSblACMgrIsJitCompilerProcess() -> | 0x01
//sceSblACMgrIsJitApplicationProcess() -> | 0x02
//sceSblACMgrIsVideoplayerProcess() -> | 0x04
//sceSblACMgrIsDiskplayeruiProcess() -> | 0x08
//sceSblACMgrHasUseVideoServiceCapability() -> | 0x10
//sceSblACMgrIsWebcoreProcess() -> | 0x20
//is_libkernel_sys() -> | 0x40
//sceSblACMgrHasSceProgramAttribute() -> | 0x80
Result:=copyout(@info,dst,SizeOf(t_proc_type_info));
end;
end.

View File

@ -533,7 +533,8 @@ begin
def :=@dynlibs_info.sym_zero;
defobj:=dynlibs_info.libprogram;
end else
if (where<>nil) then
if (where<>nil) and
(ELF64_ST_TYPE(ref^.st_info)<>STT_OBJECT) then
begin
stub:=vm_get_patch_link(refobj^.rel_data^.obj,where);

View File

@ -38,8 +38,9 @@ uses
vmparam,
vm_map,
vm_mmap,
vnamei,
vm_object,
vm_pager,
vnamei,
vfs_lookup,
vmount,
vfile,
@ -1096,7 +1097,11 @@ begin
if (Result<>0) then Exit;
imgp^.obj:=vm_object_allocate(OBJT_DEFAULT,OFF_TO_IDX(imgp^.max_addr-imgp^.min_addr));
imgp^.obj:=vm_pager_allocate(OBJT_SELF,
imgp^.vp,
imgp^.max_addr-imgp^.min_addr,
1,
0);
Result:=scan_load_sections(imgp,phdr,hdr^.e_phnum);
if (Result<>0) then
@ -1433,6 +1438,15 @@ begin
//copy authinfo
g_authinfo:=imgp^.authinfo;
//copy appinfo
g_appinfo.mmap_flags:=g_appinfo.mmap_flags or 1; //is_big_app ???
if (p_proc.p_sce_replay_exec<>0) then
begin
g_appinfo.mmap_flags:=g_appinfo.mmap_flags or 2; //is_system ???
end;
//TODO load CUSANAME
//init std tty
init_tty;

View File

@ -12,7 +12,8 @@ uses
vnode,
vm_object,
vuio,
elf64;
elf64,
kern_authinfo;
const
AT_NULL = 0; // Terminates the vector.
@ -84,17 +85,6 @@ type
entry :QWORD;
end;
p_authinfo=^t_authinfo;
t_authinfo=packed record
app_type_id:QWORD;
app_flags :QWORD; //62 bit IsSystemProcess;61 bit IsGameProcess1;60 bit IsGameProcess2;
app_cap :QWORD;
unknow1 :array[0..1] of QWORD;
s_prog_attr:QWORD;
unknow2 :array[0..10] of QWORD;
end;
{$IF sizeof(t_authinfo)<>136}{$STOP sizeof(t_authinfo)<>136}{$ENDIF}
p_image_params=^t_image_params;
t_image_params=packed record
vp :p_vnode;
@ -481,10 +471,10 @@ begin
(imgp^.image_self =nil) then
begin
case ExtractFileExt(imgp^.execpath) of
'.sprx','.prx' :imgp^.authinfo.app_type_id:=QWORD($3900000000000002);
'.sdll','.sexe':imgp^.authinfo.app_type_id:=QWORD($3901000000000001);
'.sprx','.prx' :imgp^.authinfo.app_type:=QWORD($3900000000000002);
'.sdll','.sexe':imgp^.authinfo.app_type:=QWORD($3901000000000001);
else
imgp^.authinfo.app_type_id:=QWORD($3100000000000001);
imgp^.authinfo.app_type:=QWORD($3100000000000001);
end;
Exit;
end;
@ -498,7 +488,7 @@ begin
authinfo:=Pointer(Pointer(imgp^.image_self)+s);
imgp^.authinfo.app_type_id:=authinfo^.AuthorityID;
imgp^.authinfo.app_type:=authinfo^.AuthorityID;
end;
function is_used_mode_2mb(phdr:p_elf64_phdr;is_dynlib,budget_ptype_caller:Integer):Boolean;

View File

@ -15,8 +15,6 @@ const
m_first_chunk=2;
m_last__chunk=4;
segment_size =64*1024;
type
p_stub_chunk=^stub_chunk;
stub_chunk=packed record
@ -40,6 +38,7 @@ uses
hamt,
kern_rwlock,
vm,
vmparam,
vm_map,
vm_mmap,
vm_object;
@ -50,32 +49,51 @@ var
chunk_lock :Pointer=nil;
function alloc_segment(start:Pointer):p_stub_chunk;
function AlignUp(addr:PtrUInt;alignment:PtrUInt):PtrUInt; inline;
var
tmp:PtrUInt;
begin
if (alignment=0) then Exit(addr);
tmp:=addr+PtrUInt(alignment-1);
Result:=tmp-(tmp mod alignment)
end;
function alloc_segment(start,size:QWORD):p_stub_chunk;
var
map:vm_map_t;
err:Integer;
begin
Result:=nil;
size:=AlignUp(size+SizeOf(stub_chunk),PAGE_SIZE);
map:=@g_vmspace.vm_map;
if (start=0) then
begin
start:=SCE_REPLAY_EXEC_START;
end;
err:=vm_mmap2(map,
@start,
segment_size,
size,
VM_PROT_RWX,
VM_PROT_RWX,
MAP_ANON or MAP_PRIVATE or (16 shl MAP_ALIGNMENT_BIT),
MAP_ANON or MAP_PRIVATE,
OBJT_DEFAULT,
nil,
0);
if (err<>0) then Exit;
Result:=start;
vm_map_set_name(map,start,size,'#patch');
Result:=Pointer(start);
Result^.head :=m_header;
Result^.flags :=m_free__chunk or m_first_chunk or m_last__chunk;
Result^.prev_size :=0;
Result^.curr_size :=segment_size;
Result^.curr_size :=size;
Result^.refs :=0;
Result^.link.tqe_next:=nil;
Result^.link.tqe_prev:=nil;
@ -88,25 +106,15 @@ begin
map:=@g_vmspace.vm_map;
vm_map_lock (map);
vm_map_delete(map, qword(chunk), qword(chunk) + segment_size);
vm_map_delete(map, qword(chunk), qword(chunk) + chunk^.curr_size);
vm_map_unlock(map);
end;
function AlignUp(addr:PtrUInt;alignment:PtrUInt):PtrUInt; inline;
var
tmp:PtrUInt;
begin
if (alignment=0) then Exit(addr);
tmp:=addr+PtrUInt(alignment-1);
Result:=tmp-(tmp mod alignment)
end;
procedure fix_next_size(chunk:p_stub_chunk);
var
next:p_stub_chunk;
begin
if (chunk^.curr_size<segment_size) and
((chunk^.flags and m_last__chunk)=0) then
if ((chunk^.flags and m_last__chunk)=0) then
begin
next:=Pointer(chunk)+chunk^.curr_size;
next^.prev_size:=chunk^.curr_size;
@ -175,8 +183,7 @@ begin
end;
end;
if (chunk^.curr_size<segment_size) and
((chunk^.flags and m_last__chunk)=0) then
if ((chunk^.flags and m_last__chunk)=0) then
begin
next:=Pointer(chunk)+chunk^.curr_size;
if ((next^.flags and m_free__chunk)<>0) then
@ -230,15 +237,13 @@ function p_alloc(vaddr:Pointer;size:Integer):p_stub_chunk;
var
chunk:p_stub_chunk;
begin
Assert(size<=(segment_size-SizeOf(stub_chunk)),'p_alloc to big');
rw_wlock(chunk_lock);
chunk:=find_free_chunk(vaddr,size);
if (chunk=nil) then
begin
chunk:=alloc_segment(vaddr);
chunk:=alloc_segment(QWORD(vaddr),size);
Assert(chunk<>nil,'p_alloc NOMEM');
end;
@ -271,8 +276,7 @@ begin
merge_chunk(chunk);
if (chunk^.curr_size>=segment_size) and
((chunk^.flags and (m_first_chunk or m_last__chunk))=(m_first_chunk or m_last__chunk)) then
if ((chunk^.flags and (m_first_chunk or m_last__chunk))=(m_first_chunk or m_last__chunk)) then
begin
free_segment(chunk);
end else

View File

@ -161,6 +161,7 @@ uses
kern_thr,
kern_sx,
time,
kern_authinfo,
md_arc4random,
md_proc;
@ -349,65 +350,11 @@ begin
Result:=SYSCTL_OUT(req,@data,len);
end;
const
//eLoadOptions
LOAD_OPTIONS_DEFAULT =$0000;
LOAD_OPTIONS_LOAD_SUSPENDED =$0001;
LOAD_OPTIONS_USE_SYSTEM_LIBRARY_VERIFICATION =$0002;
LOAD_OPTIONS_SLV_MODE_WARN =$0004;
LOAD_OPTIONS_ARG_STACK_SIZE =$0008;
LOAD_OPTIONS_FULL_DEBUG_REQUIRED =$0010;
//mmap_flags
//bit 1 -> is_big_app
//bit 2 -> first find addr is (1 shl 33) ->
// _sceKernelMapFlexibleMemory
// _sceKernelMapDirectMemory
// sceKernelMapDirectMemory2
//excp_flags
//bit 1 -> use in [libkernel_exception] ->
// -> sceKernelInstallExceptionHandler
// -> sceKernelRemoveExceptionHandler
// -> sceKernelAddGpuExceptionEvent
// -> sceKernelDeleteGpuExceptionEvent
// -> sceKernelBacktraceSelf
//bit 2 -> sys_mdbg_service
type
TCUSANAME=array[0..9] of AnsiChar;
PSCE_APP_ENV=^TSCE_APP_ENV;
TSCE_APP_ENV=packed record
AppId :Integer; //4
mmap_flags :Integer; //4
excp_flags :Integer; //4
AppType :Integer; //4 5?
CUSANAME :TCUSANAME; //10
debug_level:Byte; //1
slv_flags :Byte; //1 eLoadOptions
f_1c :Byte;
f_1d :Byte;
f_1e :Byte;
f_1f :Byte;
f_20 :QWORD;
f_28 :Integer;
f_2c :Integer;
f_30 :Integer;
f_34 :Integer;
f_38 :QWORD;
f_40 :QWORD;
end;
{$IF sizeof(TSCE_APP_ENV)<>72}{$STOP sizeof(TSCE_APP_ENV)<>72}{$ENDIF}
var
G_APPINFO:TSCE_APP_ENV;
function sysctl_kern_proc_appinfo(oidp:p_sysctl_oid;arg1:Pointer;arg2:ptrint;req:p_sysctl_req):Integer;
var
pid:Integer;
APPINFO:TSCE_APP_ENV;
flags:Integer;
appinfo:t_appinfo;
begin
if (req^.oldlen > 72) then Exit(EINVAL);
@ -415,27 +362,19 @@ begin
if (pid<>g_pid) then Exit(EINVAL);
//G_APPINFO.mmap_flags:=G_APPINFO.mmap_flags or 1;
if (p_proc.p_sce_replay_exec<>0) then
begin
G_APPINFO.mmap_flags:=G_APPINFO.mmap_flags or 2;
end;
//sceSblACMgrIsSystemUcred()!=0 -> any proc
//sceSblACMgrIsSystemUcred()==0 -> cur proc
Result:=SYSCTL_OUT(req,@G_APPINFO,SizeOf(TSCE_APP_ENV));
Result:=SYSCTL_OUT(req,@g_appinfo,SizeOf(t_appinfo));
if (Result=0) and (req^.newlen=SizeOf(TSCE_APP_ENV)) then
if (Result=0) and (req^.newlen=SizeOf(t_appinfo)) then
begin
Result:=SYSCTL_IN(req,@APPINFO,SizeOf(TSCE_APP_ENV));
Result:=SYSCTL_IN(req,@appinfo,SizeOf(t_appinfo));
if (Result=0) then
begin
G_APPINFO:=APPINFO;
if (p_proc.p_sce_replay_exec<>0) then
begin
G_APPINFO.mmap_flags:=G_APPINFO.mmap_flags or 2;
end;
flags:=g_appinfo.mmap_flags;
g_appinfo:=appinfo;
g_appinfo.mmap_flags:=g_appinfo.mmap_flags or (flags and 2)
end;
end;

View File

@ -357,6 +357,7 @@ uses
vm_map,
vm_mmap,
vm_object,
vm_pager,
vuio,
vstat,
vfcntl,
@ -2045,7 +2046,11 @@ begin
new^.tls_init_addr :=new^.tls_init_addr +delta;
new^.eh_frame_hdr_addr:=new^.eh_frame_hdr_addr+delta;
imgp^.obj:=vm_object_allocate(OBJT_SELF,OFF_TO_IDX(imgp^.max_addr-imgp^.min_addr));
imgp^.obj:=vm_pager_allocate(OBJT_SELF,
imgp^.vp,
imgp^.max_addr-imgp^.min_addr,
1,
0);
error:=dynlib_load_sections(imgp,new,phdr,hdr^.e_phnum,delta);
if (error<>0) then
@ -2675,6 +2680,8 @@ begin
Result^.internal:=1;
Result^.loaded:=1;
Writeln(' preload_prx_internal:',path);
//
Exit;
end;

View File

@ -44,7 +44,8 @@ uses
dev_tty,
dev_dmem,
dev_dipsw,
dev_rng;
dev_rng,
dev_gc;
var
daemon_thr:p_kthread;
@ -81,6 +82,7 @@ begin
dmemdev_init();
dipsw_init();
rng_init();
gc_initialize();
end;
//Manual order of lazy initialization

View File

@ -229,7 +229,7 @@ function budget_get_ptype(pid:Integer):Integer;
function __sys_get_proc_type_info(dst:Pointer):Integer;
function thr_get_name(id:DWORD;pname:PChar):Integer;
function set_gpo(uiBits:DWORD):Integer;
function ipmimgr_call(op,arg:Integer;res:PInteger;params:Pointer;paramsSize:QWORD):Integer;
function ipmimgr_call(op,kid:Integer;res:PInteger;params:Pointer;paramsSize:QWORD):Integer;
function get_gpo(pbits:PByte):Integer;
function thr_suspend_ucontext(tid:Integer):Integer;
function thr_resume_ucontext(tid:Integer):Integer;
@ -1807,7 +1807,7 @@ asm
jmp cerror
end;
function ipmimgr_call(op,arg:Integer;res:PInteger;params:Pointer;paramsSize:QWORD):Integer; assembler; nostackframe;
function ipmimgr_call(op,kid:Integer;res:PInteger;params:Pointer;paramsSize:QWORD):Integer; assembler; nostackframe;
asm
movq $622,%rax
call fast_syscall

View File

@ -670,6 +670,14 @@
<IsPartOfProject Value="True"/>
<UnitName Value="ps4_libSceIpmi"/>
</Unit>
<Unit>
<Filename Value="..\dev\dev_gc.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
<Unit>
<Filename Value="..\vm\vm_pager.pas"/>
<IsPartOfProject Value="True"/>
</Unit>
</Units>
</ProjectOptions>
<CompilerOptions>

View File

@ -99,10 +99,10 @@ uses
kern_dmem,
kern_bnet,
uipc_syscalls,
kern_ipmimgr{,
kern_ipmimgr,
ps4_libSceSystemService,
ps4_libSceIpmi,
ps4_libSceDialogs};
ps4_libSceDialogs;
const
PAGE_MAP_COUNT=(qword(VM_MAXUSER_ADDRESS) shr PAGE_SHIFT);
@ -366,6 +366,8 @@ begin
//readln;
argv0:='/app0/basic-sample_debug.elf';
argv0:='/app0/simple.elf';
//argv0:='/app0/videoout_basic.elf';
err:=_execve(argv0,@argv0,nil);
end;

View File

@ -129,8 +129,7 @@ uses
errno,
time,
md_time,
trap,
kern_dlsym;
trap;
type
pSceSystemServiceDisplaySafeAreaInfo=^SceSystemServiceDisplaySafeAreaInfo;
@ -419,23 +418,6 @@ begin
Result:=0;
end;
type
t_sceSysmoduleLoadModuleInternal=function(id:DWORD):DWORD;
procedure init();
var
ptr:t_sceSysmoduleLoadModuleInternal;
begin
ptr:=nil;
name_dlsym('libSceSysmodule','sceSysmoduleLoadModuleInternal',@ptr);
if (ptr<>nil) then
begin
ptr($80000052);
end;
Writeln('init');
end;
//
function Load_libSceSystemService(name:pchar):p_lib_info;
@ -444,8 +426,6 @@ var
begin
Result:=obj_new_int('libSceSystemService');
Result^.init_proc_addr:=@init;
lib:=Result^.add_lib('libSceSystemService');
lib.set_proc($7D9A38F2E9FB2CAE,@ps4_sceSystemServiceParamGetInt);
lib.set_proc($4AC0BF9BF4BD2530,@ps4_sceSystemServiceParamGetString);

View File

@ -63,7 +63,92 @@ uses
vfcntl,
vnode,
vfs_subr,
vnode_if;
vnode_if,
kern_conf,
vm_pager;
function vm_mmap_cdev(objsize :vm_size_t;
prot :vm_prot_t;
maxprotp :p_vm_prot_t;
flagsp :PInteger;
cdev :p_cdev;
foff :p_vm_ooffset_t;
objp :p_vm_object_t):Integer;
var
obj:vm_object_t;
dsw:p_cdevsw;
error,flags,ref:Integer;
begin
flags:=flagsp^;
dsw:=dev_refthread(cdev, @ref);
if (dsw=nil) then
begin
Exit(ENXIO);
end;
if ((dsw^.d_flags and D_MMAP_ANON)<>0) then
begin
dev_relthread(cdev, ref);
maxprotp^:=VM_PROT_ALL;
flagsp^:=flagsp^ or MAP_ANON;
Exit(0);
end;
{
* cdevs do not provide private mappings of any kind.
}
if ((maxprotp^ and VM_PROT_WRITE)=0) and
((prot and VM_PROT_WRITE)<>0) then
begin
dev_relthread(cdev, ref);
Exit(EACCES);
end;
if ((flags and (MAP_PRIVATE{ or MAP_COPY}))<>0) then
begin
dev_relthread(cdev, ref);
Exit(EINVAL);
end;
{
* Force device mappings to be shared.
}
flags:=flags or MAP_SHARED;
{
* First, try d_mmap_single(). If that is not implemented
* (returns ENODEV), fall back to using the device pager.
* Note that d_mmap_single() must return a reference to the
* object (it needs to bump the reference count of the object
* it returns somehow).
*
* XXX assumes VM_PROT_*=PROT_*
}
if (dsw^.d_mmap_single=nil) then
begin
error:=ENODEV;
end else
begin
error:=dsw^.d_mmap_single(cdev, foff, objsize, objp, prot);
end;
dev_relthread(cdev, ref);
if (error<>ENODEV) then
begin
Exit(error);
end;
obj:=vm_pager_allocate(OBJT_DEVICE, cdev, objsize, prot, foff^);
if (obj=nil) then
begin
Exit(EINVAL);
end;
objp^:=obj;
flagsp^:=flags;
Exit(0);
end;
function vm_mmap_vnode(objsize :vm_size_t;
prot :vm_prot_t;
@ -74,6 +159,7 @@ function vm_mmap_vnode(objsize :vm_size_t;
objp :p_vm_object_t;
writecounted:PBoolean):Integer;
label
mark_atime,
done;
var
va:t_vattr;
@ -100,44 +186,58 @@ begin
flags:=flagsp^;
obj:=nil;
obj:=vp^.v_object;
if (vp^.v_type=VREG) then
begin
{
* Get the proper underlying object
}
if (obj=nil) then
begin
error:=EINVAL;
goto done;
end;
if (obj^.handle<>vp) then
begin
vput(vp);
vp:=obj^.handle;
{
* Bypass filesystems obey the mpsafety of the
* underlying fs.
}
error:=vget(vp, locktype);
if (error<>0) then
begin
VFS_UNLOCK_GIANT(vfslocked);
Exit(error);
end;
end;
if (locktype=LK_EXCLUSIVE) then
begin
writecounted^:=TRUE;
//vnode_pager_update_writecount(obj, 0, objsize);
end;
end else
begin
error:=EINVAL;
goto done;
case vp^.v_type of
VREG:
begin
{
* Get the proper underlying object
}
if (obj=nil) then
begin
error:=EINVAL;
goto done;
end;
if (obj^.handle<>vp) then
begin
vput(vp);
vp:=obj^.handle;
{
* Bypass filesystems obey the mpsafety of the
* underlying fs.
}
error:=vget(vp, locktype);
if (error<>0) then
begin
VFS_UNLOCK_GIANT(vfslocked);
Exit(error);
end;
end;
if (locktype=LK_EXCLUSIVE) then
begin
writecounted^:=TRUE;
//vnode_pager_update_writecount(obj, 0, objsize);
end;
end;
VCHR:
begin
error:=vm_mmap_cdev(objsize, prot, maxprotp, flagsp, vp^.v_rdev, foffp, objp);
if (error=0) then goto mark_atime;
goto done;
end
else
begin
error:=EINVAL;
goto done;
end;
end;
error:=VOP_GETATTR(vp, @va);
if (error<>0) then
begin
goto done;
end;
if ((flags and MAP_SHARED)<>0) then
begin
@ -161,7 +261,7 @@ begin
begin
flags:=flags or MAP_NOSYNC;
end;
//obj:=vm_pager_allocate(OBJT_VNODE, vp, objsize, prot, foff, cred);
obj:=vm_pager_allocate(OBJT_VNODE, vp, objsize, prot, foff);
if (obj=nil) then
begin
error:=ENOMEM;
@ -170,6 +270,7 @@ begin
objp^:=obj;
flagsp^:=flags;
mark_atime:
vfs_mark_atime(vp);
done:
@ -183,6 +284,29 @@ done:
Result:=(error);
end;
function vm_mmap_shm(objsize :vm_size_t;
prot :vm_prot_t;
maxprotp :p_vm_prot_t;
flagsp :PInteger;
shmfd :Pointer; //shmfd
foff :p_vm_ooffset_t;
objp :p_vm_object_t):Integer;
var
error:Integer;
begin
if ((flagsp^ and MAP_SHARED)<>0) and
((maxprotp^ and VM_PROT_WRITE)=0) and
((prot and VM_PROT_WRITE)<>0) then
begin
Exit(EACCES);
end;
//error:=shm_mmap(shmfd, objsize, foff, objp);
error:=EOPNOTSUPP;
Exit(error);
end;
function vm_mmap_to_errno(rv:Integer):Integer; inline;
begin
Case rv of
@ -224,7 +348,7 @@ begin
size:=round_page(size);
if (g_vmspace.vm_map.size + size) > lim_cur(RLIMIT_VMEM) then
if (map^.size + size) > lim_cur(RLIMIT_VMEM) then
begin
Exit(ENOMEM);
end;
@ -246,9 +370,17 @@ begin
writecounted:=False;
Case handle_type of
OBJT_DEVICE:
begin
error:=vm_mmap_cdev(size,prot,@maxprot,@flags,handle,@foff,@vm_obj);
end;
OBJT_VNODE:
begin
error:=vm_mmap_vnode(size,prot,@maxprot,@flags, handle,@foff,@vm_obj,@writecounted);
error:=vm_mmap_vnode(size,prot,@maxprot,@flags,handle,@foff,@vm_obj,@writecounted);
end;
OBJT_SWAP:
begin
error:=vm_mmap_shm(size,prot,@maxprot,@flags,handle,@foff,@vm_obj);
end;
OBJT_DEFAULT:
begin
@ -260,11 +392,11 @@ begin
error:=EINVAL;
end;
end;
else
error:=EINVAL;
end;
else
error:=EINVAL;
end;
if (error<>0) then Exit(error);
if (error<>0) then Exit(error);
if ((flags and MAP_ANON)<>0) then
begin
@ -478,10 +610,11 @@ begin
Result:=fget_mmap(_fd,rights,@cap_maxprot,@fp);
if (Result<>0) then goto _done;
if (fp^.f_type=DTYPE_SHM) then
begin
handle:=fp^.f_data;
//handle_type:=OBJT_SWAP;
handle_type:=OBJT_SWAP;
maxprot:=VM_PROT_NONE;
// FREAD should always be set.
@ -601,10 +734,8 @@ begin
Exit(EINVAL);
end;
vm_map_lock(@g_vmspace.vm_map);
vm_map_lock (@g_vmspace.vm_map);
vm_map_delete(@g_vmspace.vm_map, qword(addr), qword(addr) + size);
vm_map_unlock(@g_vmspace.vm_map);
// vm_map_delete returns nothing but KERN_SUCCESS anyway

View File

@ -117,6 +117,7 @@ uses
vmparam,
vnode,
vfs_subr,
vm_pager,
vm_patch_link;
function IDX_TO_OFF(x:DWORD):QWORD; inline;
@ -193,9 +194,6 @@ end;
procedure vm_object_destroy(obj:vm_object_t);
begin
Case obj^.otype of
OBJT_DEFAULT:;
end;
mtx_destroy(obj^.mtx);
FreeMem(obj);
end;
@ -255,6 +253,7 @@ begin
Assert(obj^.ref_count=0,'vm_object_terminate: obj with references');
vm_pager_deallocate(obj);
VM_OBJECT_UNLOCK(obj);
vm_object_destroy(obj);

77
sys/vm/vm_pager.pas Normal file
View File

@ -0,0 +1,77 @@
unit vm_pager;
{$mode ObjFPC}{$H+}
{$CALLING SysV_ABI_CDecl}
interface
uses
vm,
vm_object;
function vm_pager_allocate(otype:objtype_t;
handle:Pointer;
size:vm_ooffset_t;
prot:vm_prot_t;
off:vm_ooffset_t):vm_object_t;
procedure vm_pager_deallocate(obj:vm_object_t);
implementation
uses
vmparam;
function OFF_TO_IDX(x:QWORD):DWORD; inline;
begin
Result:=QWORD(x) shr PAGE_SHIFT;
end;
function vm_pager_allocate(otype:objtype_t;
handle:Pointer;
size:vm_ooffset_t;
prot:vm_prot_t;
off:vm_ooffset_t):vm_object_t;
begin
case otype of
OBJT_DEFAULT :Result:=vm_object_allocate(otype,OFF_TO_IDX(size));
//OBJT_SWAP :;
//OBJT_VNODE :;
//OBJT_DEVICE :;
//OBJT_PHYS :;
//OBJT_DEAD :;
//OBJT_SG :;
//OBJT_JITSHM :;
OBJT_SELF :Result:=vm_object_allocate(otype,OFF_TO_IDX(size));
//OBJT_TRCMEM :;
//OBJT_PHYSHM :;
//OBJT_BLOCKPOOL:;
else
Assert(False);
end;
end;
procedure vm_pager_deallocate(obj:vm_object_t);
begin
if (obj=nil) then Exit;
case obj^.otype of
OBJT_DEFAULT :;
OBJT_SWAP :;
OBJT_VNODE :;
OBJT_DEVICE :;
OBJT_PHYS :;
OBJT_DEAD :;
OBJT_SG :;
OBJT_JITSHM :;
OBJT_SELF :;
OBJT_TRCMEM :;
OBJT_PHYSHM :;
OBJT_BLOCKPOOL:;
else;
end;
end;
end.