diff --git a/chip/pm4_ring.pas b/chip/pm4_ring.pas index d787f25a..59231e97 100644 --- a/chip/pm4_ring.pas +++ b/chip/pm4_ring.pas @@ -371,7 +371,7 @@ begin base_dmem_addr:=get_dmem_ptr(ringBaseAddress); offset:=QWORD(readPtrAddress) and PAGE_MASK; - base :=Pointer(QWORD(readPtrAddress) and (not PAGE_MASK)); + base :=Pointer(QWORD(readPtrAddress) and QWORD(not PAGE_MASK)); read_mirr_addr:=mirror_map(base,PAGE_SIZE); @@ -399,7 +399,7 @@ var begin hqd^:=Default(t_gc_hqd); - base:=Pointer(QWORD(hqd^.read_mirr_addr) and (not PAGE_MASK)); + base:=Pointer(QWORD(hqd^.read_mirr_addr) and QWORD(not PAGE_MASK)); mirror_unmap(base,PAGE_SIZE); diff --git a/sys/dev/dev_sce_zlib.pas b/sys/dev/dev_sce_zlib.pas index 30453ae0..647c746e 100644 --- a/sys/dev/dev_sce_zlib.pas +++ b/sys/dev/dev_sce_zlib.pas @@ -6,6 +6,7 @@ unit dev_sce_zlib; interface uses + vmparam, sys_conf, sys_event; @@ -170,8 +171,8 @@ begin if (data^.length=0) or (data^.buffer=nil) then Exit(EINVAL); - buffer_lo:=QWORD(data^.buffer) and QWORD($ffffffffffffc000); - buffer_hi:=(QWORD(data^.buffer) + data^.length + $3fff) and QWORD($ffffffffffffc000); + buffer_lo:=QWORD(data^.buffer) and QWORD(not PAGE_MASK); + buffer_hi:=(QWORD(data^.buffer) + data^.length + PAGE_MASK) and QWORD(not PAGE_MASK); map:=p_proc.p_vmspace; diff --git a/sys/dev/display_soft.pas b/sys/dev/display_soft.pas index 9a49ac88..2930d4eb 100644 --- a/sys/dev/display_soft.pas +++ b/sys/dev/display_soft.pas @@ -325,9 +325,9 @@ var base:Pointer; begin mask:=QWORD(orig) and PAGE_MASK; - size:=(size+mask+PAGE_MASK) and (not PAGE_MASK); + size:=(size+mask+PAGE_MASK) and QWORD(not PAGE_MASK); - base:=vm_mmap.mirror_map(Pointer(QWORD(orig) and (not PAGE_MASK)),size); + base:=vm_mmap.mirror_map(Pointer(QWORD(orig) and QWORD(not PAGE_MASK)),size); Result.orig:=orig; Result.mirr:=base+mask; diff --git a/sys/init_sysent.pas b/sys/init_sysent.pas index b1162dd3..bb8ed252 100644 --- a/sys/init_sysent.pas +++ b/sys/init_sysent.pas @@ -2799,7 +2799,7 @@ var ), (//[548] sy_narg:5; - sy_call:nil; + sy_call:@sys_batch_map; sy_name:'sys_batch_map' ), (//[549] diff --git a/sys/jit/kern_jit_dynamic.pas b/sys/jit/kern_jit_dynamic.pas index cae0dc5e..90670702 100644 --- a/sys/jit/kern_jit_dynamic.pas +++ b/sys/jit/kern_jit_dynamic.pas @@ -206,7 +206,7 @@ procedure pick(var ctx:t_jit_context2;preload:Pointer); external name 'kern_jit_ function scan_up_exc(addr:QWORD):QWORD; begin - addr:=(addr+PAGE_MASK) and (not PAGE_MASK); + addr:=(addr+PAGE_MASK) and QWORD(not PAGE_MASK); while is_guest_addr(addr) do begin @@ -224,7 +224,7 @@ end; function scan_dw_exc(addr:QWORD):QWORD; begin - addr:=addr and (not PAGE_MASK); + addr:=addr and QWORD(not PAGE_MASK); while is_guest_addr(addr) do begin diff --git a/sys/kern/kern_dmem.pas b/sys/kern/kern_dmem.pas index e4920bc4..34580e42 100644 --- a/sys/kern/kern_dmem.pas +++ b/sys/kern/kern_dmem.pas @@ -44,26 +44,6 @@ type align:array[0..6] of Byte; end; -const - //SceKernelMapEntryOperation - SCE_KERNEL_MAP_OP_MAP_DIRECT =0; - SCE_KERNEL_MAP_OP_UNMAP =1; - SCE_KERNEL_MAP_OP_PROTECT =2; - SCE_KERNEL_MAP_OP_MAP_FLEXIBLE=3; - SCE_KERNEL_MAP_OP_TYPE_PROTECT=4; - -type - pSceKernelBatchMapEntry=^SceKernelBatchMapEntry; - SceKernelBatchMapEntry=packed record - start:Pointer; - offset:QWORD; - length:QWORD; - protection:Byte; - mtype:Byte; - pad1:Word; - operation:Integer; - end; - type p_dmem_obj=^t_dmem_obj; t_dmem_obj=record @@ -156,9 +136,6 @@ begin rmap.tmap:=@vmap^.pmap^.tr_map; end; -const - default_pool_id=1; - function sys_dmem_container(d_pool_id:Integer):Integer; var td:p_kthread; @@ -166,7 +143,7 @@ begin td:=curkthread; if (td=nil) then Exit(-1); - td^.td_retval[0]:=default_pool_id; + td^.td_retval[0]:=p_proc.p_pool_id; Result:=0; if (d_pool_id<>-1) then @@ -244,7 +221,7 @@ begin Exit(EACCES); end; - dmap:=dmem_maps[default_pool_id]; + dmap:=dmem_maps[p_proc.p_pool_id]; //entry->eflags = flags & 0x400000 | 0x20000 | 0x80000 //0x400000 -> MAP_ENTRY_NO_COALESCE -> MAP_NO_COALESCE @@ -404,7 +381,7 @@ begin Exit(Pointer(EPERM)); end; - if (default_pool_id<>1) then + if (p_proc.p_pool_id<>1) then begin Exit(Pointer(EOPNOTSUPP)); end; @@ -646,7 +623,7 @@ begin addr:=start; end; - ret:=dmem_map_get_mtype(dmem_maps[default_pool_id].dmem, + ret:=dmem_map_get_mtype(dmem_maps[p_proc.p_pool_id].dmem, obj, addr + (entry^.offset - start), //send not transformed offset @d_start2,@d_end2, diff --git a/sys/kern/kern_proc.pas b/sys/kern/kern_proc.pas index c657a76d..285fa10f 100644 --- a/sys/kern/kern_proc.pas +++ b/sys/kern/kern_proc.pas @@ -23,47 +23,55 @@ type ar_args :AnsiChar; // Arguments. end; -var - p_proc:record - p_mtx:mtx; +type + t_proc=object + var + p_mtx:mtx; - p_pid:Integer; + p_pid:Integer; - p_flag :Integer; - p_osrel:Integer; + p_flag :Integer; + p_osrel:Integer; - p_sdk_version:Integer; + p_sdk_version:Integer; - p_sysent:p_sysentvec; + p_sysent:p_sysentvec; - p_libkernel_start_addr:Pointer; - p_libkernel___end_addr:Pointer; + p_libkernel_start_addr:Pointer; + p_libkernel___end_addr:Pointer; - p_ptc:Int64; - p_guest_ptc:PInt64; + p_ptc :Int64; + p_guest_ptc:PInt64; - p_nsignals:Int64; - p_nvcsw :Int64; - p_nivcsw :Int64; + p_nsignals:Int64; + p_nvcsw :Int64; + p_nivcsw :Int64; - p_comm :array[0..MAXCOMLEN] of AnsiChar; - p_prog_name :array[0..1023] of AnsiChar; - p_randomized_path:array[0..7] of AnsiChar; + p_comm :array[0..MAXCOMLEN] of AnsiChar; + p_prog_name :array[0..1023] of AnsiChar; + p_randomized_path:array[0..7] of AnsiChar; - p_sigqueue :sigqueue_t; //Sigs not delivered to a td. - p_pendingcnt :Integer; //how many signals are pending + p_sigqueue :sigqueue_t; //Sigs not delivered to a td. + p_pendingcnt :Integer; //how many signals are pending - p_klist:t_knlist; + p_klist:t_knlist; - p_args:p_pargs; + p_args:p_pargs; - p_vmspace:Pointer; + p_vmspace:Pointer; + + p_budget_ptype :Integer; + p_dmem_aliasing:Integer; + p_vm_container :Integer; + + const + p_pool_id=1; - p_budget_ptype :Integer; - p_dmem_aliasing:Integer; - p_vm_container :Integer; end; +var + p_proc:t_proc; + function pargs_alloc(len:Integer):p_pargs; procedure pargs_free(pa:p_pargs); procedure pargs_hold(pa:p_pargs); @@ -138,7 +146,7 @@ begin p_proc.p_randomized_path:='system'; - p_proc.p_ptc:=rdtsc(); + p_proc.p_ptc :=rdtsc(); p_proc.p_guest_ptc:=nil; end; diff --git a/sys/kern/subr_dynlib.pas b/sys/kern/subr_dynlib.pas index 069e5040..cc00d0af 100644 --- a/sys/kern/subr_dynlib.pas +++ b/sys/kern/subr_dynlib.pas @@ -2460,8 +2460,8 @@ begin end else if (p_proc.p_sdk_version < $1700000) then begin - p_start:=Pointer(QWORD(dst) and (not PAGE_MASK)); - p___end:=Pointer((QWORD(dst)+size+PAGE_MASK) and (not PAGE_MASK)); + p_start:=Pointer(QWORD(dst) and QWORD(not PAGE_MASK)); + p___end:=Pointer((QWORD(dst)+size+PAGE_MASK) and QWORD(not PAGE_MASK)); offset:=QWORD(dst) and PAGE_MASK; p_size:=QWORD(p___end)-QWORD(p_start); diff --git a/sys/syscalls.pas b/sys/syscalls.pas index 16443c73..cb65ec49 100644 --- a/sys/syscalls.pas +++ b/sys/syscalls.pas @@ -205,6 +205,7 @@ function evf_set(key:Integer;bitPattern:QWORD):Integer; function evf_clear(key:Integer;bitPattern:QWORD):Integer; function evf_cancel(key:Integer;setPattern:QWORD;pNumWait:PInteger):Integer; function query_memory_protection(addr:Pointer;info:Pointer):Integer; +function batch_map(fd:Integer;flags:DWORD;entries:Pointer;numberOfEntries:Integer;numberOfEntriesOut:PInteger):Integer; function osem_create(name:PChar;attr:DWORD;initCount,maxCount:Integer):Integer; function osem_delete(key:Integer):Integer; function __sys_osem_open(name:PChar):Integer; @@ -1657,6 +1658,13 @@ asm jmp cerror end; +function batch_map(fd:Integer;flags:DWORD;entries:Pointer;numberOfEntries:Integer;numberOfEntriesOut:PInteger):Integer; assembler; nostackframe; +asm + movq $548,%rax + call fast_syscall + jmp cerror +end; + function osem_create(name:PChar;attr:DWORD;initCount,maxCount:Integer):Integer; assembler; nostackframe; asm movq $549,%rax diff --git a/sys/vm/vm.pas b/sys/vm/vm.pas index a36f3382..94a5624d 100644 --- a/sys/vm/vm.pas +++ b/sys/vm/vm.pas @@ -139,12 +139,12 @@ end; function round_page(x:QWORD):QWORD; inline; begin - Result:=(x+PAGE_MASK) and (not PAGE_MASK); + Result:=(x+PAGE_MASK) and QWORD(not PAGE_MASK); end; function trunc_page(x:QWORD):QWORD; inline; begin - Result:=x and (not PAGE_MASK); + Result:=x and QWORD(not PAGE_MASK); end; function roundup(addr:QWORD;alignment:QWORD):QWORD; inline; diff --git a/sys/vm/vm_mmap.pas b/sys/vm/vm_mmap.pas index 1862c5fd..4967e173 100644 --- a/sys/vm/vm_mmap.pas +++ b/sys/vm/vm_mmap.pas @@ -36,6 +36,13 @@ function sys_mtypeprotect(addr:Pointer;len:QWORD;mtype,prot:Integer):Integer; function sys_madvise(addr:Pointer;len:QWORD;behav:Integer):Integer; function sys_mname(addr:Pointer;len:QWORD;name:PChar):Integer; function sys_query_memory_protection(addr:Pointer;info:Pointer):Integer; + +function sys_batch_map(fd :Integer; + flags :DWORD; + entries :Pointer; + numberOfEntries :Integer; + numberOfEntriesOut:PInteger):Integer; + function sys_get_page_table_stats(vm_container,cpu_gpu:Integer;p_total,p_available:PInteger):Integer; function vm_mmap_to_errno(rv:Integer):Integer; inline; @@ -66,6 +73,7 @@ uses kern_proc, vmparam, vm_pmap, + kern_dmem, sys_resource, kern_resource, kern_mtx, @@ -1098,17 +1106,16 @@ end; function sys_mtypeprotect(addr:Pointer;len:QWORD;mtype,prot:Integer):Integer; var - size,pageoff:vm_size_t; + __end_u:QWORD; + __end_a:QWORD; begin - size:=len; - pageoff:=(vm_size_t(addr) and PAGE_MASK); - addr:=addr-pageoff; - size:=size+pageoff; - size:=round_page(size); + __end_u:=QWORD(addr) + len; + __end_a:=(__end_u + PAGE_MASK) and QWORD(not PAGE_MASK); - if (addr + size < addr) or - (DWORD(mtype) >= 11) or + if (__end_u < QWORD(addr)) or + (__end_a < __end_u) or + (DWORD(mtype) > 10) or ((prot and $c8) <> 0) then begin Exit(EINVAL); @@ -1116,7 +1123,7 @@ begin prot:=((Byte(prot) shr 1) and 1) or Byte(prot); - Result:=vm_map_type_protect(p_proc.p_vmspace, QWORD(addr), QWORD(addr) + size, mtype, prot); + Result:=vm_map_type_protect(p_proc.p_vmspace, QWORD(addr) and QWORD(not PAGE_MASK), __end_a, mtype, prot); case Result of KERN_SUCCESS :Result:=0; @@ -1255,6 +1262,205 @@ begin end; end; +const + SCE_KERNEL_MAP_OP_MAP_DIRECT =0; + SCE_KERNEL_MAP_OP_UNMAP =1; + SCE_KERNEL_MAP_OP_PROTECT =2; + SCE_KERNEL_MAP_OP_MAP_FLEXIBLE=3; + SCE_KERNEL_MAP_OP_TYPE_PROTECT=4; + +type + PSceKernelBatchMapEntry=^SceKernelBatchMapEntry; + SceKernelBatchMapEntry=packed record + start :Pointer; + offset :QWORD; + length :QWORD; + protection:Byte; + mtype :Byte; + pad :WORD; + operation :Integer; + end; + {$IF sizeof(SceKernelBatchMapEntry)<>32}{$STOP sizeof(SceKernelBatchMapEntry)<>32}{$ENDIF} + +function sys_batch_map(fd :Integer; + flags :DWORD; + entries :Pointer; + numberOfEntries :Integer; + numberOfEntriesOut:PInteger):Integer; +var + i,num_out:Integer; + + node:SceKernelBatchMapEntry; + + __end:QWORD; +begin + Result:=0; + + if (numberOfEntries <= -1) then + begin + if (numberOfEntriesOut<>nil) then + begin + suword32(PDWORD(numberOfEntriesOut)^,0); + end; + Exit(EINVAL); + end; + + if ((flags and $e0bffb6f) <> 0) then + begin + Exit(EINVAL); + end; + + if (numberOfEntries < 1) then + begin + Result :=0; + num_out:=0; + end else + begin + num_out:=0; + + node:=Default(SceKernelBatchMapEntry); + + For i:=0 to numberOfEntries-1 do + begin + + Result:=copyin(@PSceKernelBatchMapEntry(entries)[i],@node,SizeOf(node)); + if (Result<>0) then Break; + + case node.operation of + + SCE_KERNEL_MAP_OP_MAP_DIRECT: + begin + + if (p_proc.p_pool_id <> 1) or + ((g_appinfo.mmap_flags and 2) <> 0) or + ((flags and MAP_STACK) <> 0) or + (p_proc.p_sdk_version < $2500000) then + begin + + if ((QWORD(node.start) and PAGE_MASK) = 0) and + ((node.length and PAGE_MASK) = 0) and + ((node.offset and QWORD($8000000000003fff)) = 0) and + ((node.protection and $C8) = 0) then + begin + + Result:=Integer(sys_mmap(node.start, + node.length, + node.protection, + flags or MAP_SHARED, + fd, + node.offset)); + + end else + begin + Result:=EINVAL; + Break; + end; + + end else + begin + + Result:=Integer(sys_mmap_dmem(node.start, + node.length, + DWORD(-1), + node.protection, + flags, + node.offset)); + + end; + + end; //SCE_KERNEL_MAP_OP_MAP_DIRECT + + SCE_KERNEL_MAP_OP_UNMAP: + begin + + if ((QWORD(node.start) and PAGE_MASK) <> 0) or + ((node.length and PAGE_MASK) <> 0) then + begin + Result:=EINVAL; + Break; + end; + + Result:=sys_munmap(node.start,node.length); + + end; //SCE_KERNEL_MAP_OP_UNMAP + + SCE_KERNEL_MAP_OP_PROTECT: + begin + + __end:=QWORD(node.start) + ((node.length + PAGE_MASK) and QWORD(not PAGE_MASK)); + + if ((QWORD(node.start) and PAGE_MASK) <> 0) or + ((node.length and PAGE_MASK) <> 0) or + ((node.protection and $c8) <> 0) or + (__end < QWORD(node.start)) then + begin + Result:=EINVAL; + Break; + end; + + Result:=sys_mprotect(node.start,node.length,node.protection); + + end; //SCE_KERNEL_MAP_OP_PROTECT + + SCE_KERNEL_MAP_OP_MAP_FLEXIBLE: + begin + + if ((QWORD(node.start) and PAGE_MASK) <> 0) or + ((node.length and PAGE_MASK) <> 0) or + ((node.protection and $c8) <> 0) then + begin + Result:=EINVAL; + Break; + end; + + Result:=Integer(sys_mmap(node.start, + node.length, + node.protection, + flags or MAP_ANON, + -1, + 0)); + + end; //SCE_KERNEL_MAP_OP_MAP_FLEXIBLE + + SCE_KERNEL_MAP_OP_TYPE_PROTECT: + begin + + __end:=QWORD(node.start) + node.length; + + if (__end < QWORD(node.start)) or + (((__end + PAGE_MASK) and QWORD(not PAGE_MASK)) < __end) or + (DWORD(node.mtype) > 10) or + ((node.protection and $c8) <> 0) then + begin + Result:=EINVAL; + Break; + end; + + Result:=sys_mtypeprotect(node.start,node.length,node.mtype,node.protection); + + end; //SCE_KERNEL_MAP_OP_TYPE_PROTECT + + else + begin + Result:=EINVAL; + Break; + end; + end; //case + + if (Result<>0) then Break; + + end; //For + + + end; + + if (numberOfEntriesOut<>nil) then + begin + suword32(PDWORD(numberOfEntriesOut)^,num_out); + end; + +end; + function sys_get_page_table_stats(vm_container,cpu_gpu:Integer;p_total,p_available:PInteger):Integer; begin Exit(ENOENT); //devkit_parameter(0)=0