diff --git a/sys/dev/dev_dce.pas b/sys/dev/dev_dce.pas index f7663ae6..d62b1356 100644 --- a/sys/dev/dev_dce.pas +++ b/sys/dev/dev_dce.pas @@ -6,12 +6,16 @@ unit dev_dce; interface uses + vm, + vmparam, kern_conf, sys_event; procedure dce_initialize(); var + dce_page:array[0..PAGE_SIZE-1] of Byte; + g_video_out_event_flip:t_knlist; implementation @@ -20,8 +24,6 @@ uses errno, systm, subr_backtrace, - vm, - vmparam, sys_vm_object, vm_pager, kern_event, @@ -584,7 +586,7 @@ var begin Result:=0; - if ($3ffffff < offset) then + if (offset > $3ffffff) then begin Exit(EINVAL); end; @@ -621,12 +623,18 @@ begin Exit(EINVAL); end; + if (off<>PAGE_SIZE) then + begin + Assert(false); + end; + if (nprot<>$33) then begin Exit(EACCES); end; obj:=vm_pager_allocate(OBJT_DEVICE,cdev,PAGE_SIZE,$33,off); + obj^.map_base:=Pointer(@dce_page)-PAGE_SIZE; if (obj=nil) then begin @@ -647,22 +655,23 @@ end; const dce_cdevsw:t_cdevsw=( - d_version :D_VERSION; - d_flags :0; - d_name :'dce'; - d_open :nil; - d_fdopen :nil; - d_close :nil; - d_read :nil; - d_write :nil; - d_ioctl :@dce_ioctl; - d_poll :nil; - d_mmap :@dce_mmap; - d_strategy :nil; - d_dump :nil; - d_kqfilter :@dce_kqfilter; - d_purge :nil; - d_mmap_single:@dce_mmap_single; + d_version :D_VERSION; + d_flags :0; + d_name :'dce'; + d_open :nil; + d_fdopen :nil; + d_close :nil; + d_read :nil; + d_write :nil; + d_ioctl :@dce_ioctl; + d_poll :nil; + d_mmap :@dce_mmap; + d_strategy :nil; + d_dump :nil; + d_kqfilter :@dce_kqfilter; + d_purge :nil; + d_mmap_single :@dce_mmap_single; + d_mmap_single2:nil; ); function filt_display_attach(kn:p_knote):Integer; diff --git a/sys/dev/dev_dipsw.pas b/sys/dev/dev_dipsw.pas index 77e7db5c..866565e2 100644 --- a/sys/dev/dev_dipsw.pas +++ b/sys/dev/dev_dipsw.pas @@ -41,22 +41,23 @@ end; const dipsw_cdevsw:t_cdevsw=( - d_version :D_VERSION; - d_flags :0; - d_name :'dipsw_dev'; - d_open :nil; - d_fdopen :nil; - d_close :nil; - d_read :nil; - d_write :nil; - d_ioctl :@dipsw_ioctl; - d_poll :nil; - d_mmap :nil; - d_strategy :nil; - d_dump :nil; - d_kqfilter :nil; - d_purge :nil; - d_mmap_single:nil; + d_version :D_VERSION; + d_flags :0; + d_name :'dipsw_dev'; + d_open :nil; + d_fdopen :nil; + d_close :nil; + d_read :nil; + d_write :nil; + d_ioctl :@dipsw_ioctl; + d_poll :nil; + d_mmap :nil; + d_strategy :nil; + d_dump :nil; + d_kqfilter :nil; + d_purge :nil; + d_mmap_single :nil; + d_mmap_single2:nil; ); procedure dipsw_init(); diff --git a/sys/dev/dev_dmem.pas b/sys/dev/dev_dmem.pas index 442b635e..7b0149df 100644 --- a/sys/dev/dev_dmem.pas +++ b/sys/dev/dev_dmem.pas @@ -17,9 +17,12 @@ uses vuio, subr_uio, vm, + vmparam, dmem_map, kern_dmem, sys_vm_object, + vm_pager, + kern_authinfo, subr_backtrace; type @@ -47,9 +50,13 @@ type end; Function dmem_ioctl(dev:p_cdev;cmd:QWORD;data:Pointer;fflag:Integer):Integer; +var + dmap:p_dmem_obj; begin Result:=0; + dmap:=dev^.si_drv1; + Writeln('dmem_ioctl("',dev^.si_name,'",0x',HexStr(cmd,8),',0x',HexStr(fflag,8),')'); case cmd of @@ -62,7 +69,7 @@ begin begin with PAvailableDirectMemorySize(data)^ do begin - Result:=dmem_map_query_available(@dmem,start,__end,align,start,osize); + Result:=dmem_map_query_available(dmap^.dmem,start,__end,align,start,osize); end; end; @@ -70,7 +77,7 @@ begin begin with PAllocateDirectMemory(data)^ do begin - Result:=dmem_map_alloc(@dmem,start,__end,len,align,mtype,start); + Result:=dmem_map_alloc(dmap^.dmem,start,__end,len,align,mtype,start); end; end; @@ -78,7 +85,7 @@ begin begin with PReleaseDirectMemory(data)^ do begin - Result:=dmem_map_release(@dmem,start,len,False); + Result:=dmem_map_release(dmap^.dmem,start,len,False); end; end; @@ -92,55 +99,127 @@ begin end; +function OFF_TO_IDX(x:QWORD):DWORD; inline; +begin + Result:=QWORD(x) shr PAGE_SHIFT; +end; + Function dmem_mmap(dev:p_cdev;offset:vm_ooffset_t;paddr:p_vm_paddr_t;nprot:Integer;memattr:p_vm_memattr_t):Integer; +var + dmap:p_dmem_obj; + entry:p_dmem_map_entry; + r:Boolean; begin Result:=0; + if is_sce_prog_attr_40_800000(@g_authinfo) then + begin + Exit(EPERM); + end; + + if is_sce_prog_attr_40_400000(@g_authinfo) then + begin + Exit(EPERM); + end; + Writeln('dmem_mmap("',dev^.si_name,'",0x',HexStr(offset,8),',0x',HexStr(paddr),',',nprot,')'); - print_backtrace_td(stderr); - Assert(False); + dmap:=dev^.si_drv1; + + entry:=nil; + + dmem_map_lock(dmap^.dmem); + + r:=dmem_map_lookup_entry(dmap^.dmem, + OFF_TO_IDX(offset), + @entry); + + dmem_map_unlock(dmap^.dmem); + + if not r then + begin + Exit(-1); + end; + + paddr^:=offset + QWORD(dmap^.vobj^.map_base); + memattr^:=0; end; -Function dmem_mmap_single2(dev:p_cdev;offset:p_vm_ooffset_t;size:vm_size_t;obj:p_vm_object_t;nprot:Integer):Integer; -//byte *maxprotp,uint *flagsp +Function dmem_mmap_single2(dev:p_cdev;offset:p_vm_ooffset_t;size:vm_size_t;obj:p_vm_object_t;nprot:Integer;maxprotp:p_vm_prot_t;flagsp:PInteger):Integer; begin - Result:=0; + if is_sce_prog_attr_40_800000(@g_authinfo) then + begin + Exit(EPERM); + end; + + if is_sce_prog_attr_40_400000(@g_authinfo) then + begin + Exit(EPERM); + end; + Writeln('dmem_mmap_single2("',dev^.si_name,'",0x',HexStr(offset^,8),',0x',HexStr(size,8),',',nprot,')'); print_backtrace_td(stderr); Assert(False); end; +Function dmem_open(dev:p_cdev;oflags,devtype:Integer):Integer; +begin + Result:=0; + + if is_sce_prog_attr_40_800000(@g_authinfo) then + begin + Exit(EPERM); + end; + + if is_sce_prog_attr_40_400000(@g_authinfo) then + begin + Exit(EPERM); + end; +end; + const dmem_cdevsw:t_cdevsw=( - d_version :D_VERSION; - d_flags :0; - d_name :'dmem'; - d_open :nil; - d_fdopen :nil; - d_close :nil; - d_read :nil; - d_write :nil; - d_ioctl :@dmem_ioctl; - d_poll :nil; - d_mmap :@dmem_mmap; - d_strategy :nil; - d_dump :nil; - d_kqfilter :nil; - d_purge :nil; - d_mmap_single:nil; + d_version :D_VERSION; + d_flags :0; + d_name :'dmem'; + d_open :@dmem_open; + d_fdopen :nil; + d_close :nil; + d_read :nil; + d_write :nil; + d_ioctl :@dmem_ioctl; + d_poll :nil; + d_mmap :@dmem_mmap; + d_strategy :nil; + d_dump :nil; + d_kqfilter :nil; + d_purge :nil; + d_mmap_single :nil; + d_mmap_single2:@dmem_mmap_single2; ); procedure dmemdev_init(); var + dev:p_cdev; + obj:vm_object_t; i:Integer; begin For i:=0 to 2 do begin - make_dev(@dmem_cdevsw,i,0,0,&777,'dmem%d',[i]); + dev:=make_dev(@dmem_cdevsw,i,0,0,&777,'dmem%d',[i]); + dev^.si_drv1:=@dmem_maps[i]; + // + obj:=vm_pager_allocate(OBJT_DEVICE,dev,0,0,0); + obj^.size:=$1400000; + obj^.flags:=obj^.flags or OBJ_DMEM_EXT; + obj^.map_base:=Pointer(VM_MIN_GPU_ADDRESS); + vm_object_reference(obj); + // + dmem_maps[i].dmem:=@kern_dmem.dmem; + dmem_maps[i].vobj:=obj; end; end; diff --git a/sys/dev/dev_gc.pas b/sys/dev/dev_gc.pas index 757516cd..c0966ebb 100644 --- a/sys/dev/dev_gc.pas +++ b/sys/dev/dev_gc.pas @@ -17,10 +17,13 @@ uses kern_authinfo, vm, vmparam, + sys_vm_object, + vm_pager, subr_backtrace; var - gc_mmap_ptr:Pointer=nil; + gc_page:array[0..PAGE_SIZE-1] of Byte; + gc_AreSubmitsAllowed:Integer=0; //0=true,1=false (0xfe0100000) type @@ -107,6 +110,38 @@ begin end; +Function gc_mmap_single(cdev:p_cdev;offset:p_vm_ooffset_t;size:vm_size_t;objp:p_vm_object_t;nprot:Integer):Integer; +var + obj:vm_object_t; +begin + if sceSblACMgrHasUseHp3dPipeCapability(@g_authinfo) then + begin + Exit(EINVAL); + end; + + if (offset^>=PAGE_SIZE) then + begin + Exit(EPERM); + end; + + if (size<>PAGE_SIZE) then + begin + Exit(EINVAL); + end; + + obj:=vm_pager_allocate(OBJT_DEVICE,cdev,PAGE_SIZE,nprot,offset^); + obj^.map_base:=@gc_page; + + if (obj=nil) then + begin + Exit(EINVAL); + end; + + objp^:=obj; + + Result:=0; +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 if sceSblACMgrHasUseHp3dPipeCapability(@g_authinfo) then @@ -119,7 +154,7 @@ begin Exit(EPERM); end; - paddr^:=offset + QWORD(gc_mmap_ptr); + paddr^:=offset + QWORD(@gc_page); memattr^:=0; Result:=0; @@ -127,28 +162,27 @@ end; 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; + 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 :@gc_mmap_single; + d_mmap_single2:nil; ); procedure gc_initialize(); begin - gc_mmap_ptr:=Pointer($fe0200000); - make_dev(@gc_cdevsw,0,0,0,&666,'gc',[]); end; diff --git a/sys/dev/dev_null.pas b/sys/dev/dev_null.pas index c2ac9e5e..67e78e16 100644 --- a/sys/dev/dev_null.pas +++ b/sys/dev/dev_null.pas @@ -40,41 +40,43 @@ Function zero_read(dev:p_cdev;uio:p_uio;ioflag:Integer):Integer; fo const null_cdevsw:t_cdevsw=( - d_version :D_VERSION; - d_flags :0; - d_name :'null'; - d_open :nil; - d_fdopen :nil; - d_close :nil; - d_read :d_read_t(@_nullop); - d_write :@null_write; - d_ioctl :@null_ioctl; - d_poll :nil; - d_mmap :nil; - d_strategy :nil; - d_dump :nil; - d_kqfilter :nil; - d_purge :nil; - d_mmap_single:nil; + d_version :D_VERSION; + d_flags :0; + d_name :'null'; + d_open :nil; + d_fdopen :nil; + d_close :nil; + d_read :d_read_t(@_nullop); + d_write :@null_write; + d_ioctl :@null_ioctl; + d_poll :nil; + d_mmap :nil; + d_strategy :nil; + d_dump :nil; + d_kqfilter :nil; + d_purge :nil; + d_mmap_single :nil; + d_mmap_single2:nil; ); zero_cdevsw:t_cdevsw=( - d_version :D_VERSION; - d_flags :D_MMAP_ANON; - d_name :'zero'; - d_open :nil; - d_fdopen :nil; - d_close :nil; - d_read :@zero_read; - d_write :@null_write; - d_ioctl :@zero_ioctl; - d_poll :nil; - d_mmap :nil; - d_strategy :nil; - d_dump :nil; - d_kqfilter :nil; - d_purge :nil; - d_mmap_single:nil; + d_version :D_VERSION; + d_flags :D_MMAP_ANON; + d_name :'zero'; + d_open :nil; + d_fdopen :nil; + d_close :nil; + d_read :@zero_read; + d_write :@null_write; + d_ioctl :@zero_ioctl; + d_poll :nil; + d_mmap :nil; + d_strategy :nil; + d_dump :nil; + d_kqfilter :nil; + d_purge :nil; + d_mmap_single :nil; + d_mmap_single2:nil; ); { ARGSUSED } diff --git a/sys/dev/dev_rng.pas b/sys/dev/dev_rng.pas index d9bae1ab..3385c2f4 100644 --- a/sys/dev/dev_rng.pas +++ b/sys/dev/dev_rng.pas @@ -39,22 +39,23 @@ end; const devw_rng:t_cdevsw=( - d_version :D_VERSION; - d_flags :0; - d_name :'rng'; - d_open :nil; - d_fdopen :nil; - d_close :nil; - d_read :nil; - d_write :nil; - d_ioctl :@rng_ioctl; - d_poll :nil; - d_mmap :nil; - d_strategy :nil; - d_dump :nil; - d_kqfilter :nil; - d_purge :nil; - d_mmap_single:nil; + d_version :D_VERSION; + d_flags :0; + d_name :'rng'; + d_open :nil; + d_fdopen :nil; + d_close :nil; + d_read :nil; + d_write :nil; + d_ioctl :@rng_ioctl; + d_poll :nil; + d_mmap :nil; + d_strategy :nil; + d_dump :nil; + d_kqfilter :nil; + d_purge :nil; + d_mmap_single :nil; + d_mmap_single2:nil; ); procedure rng_init(); diff --git a/sys/dev/dev_tty.pas b/sys/dev/dev_tty.pas index b0acb069..b529b86e 100644 --- a/sys/dev/dev_tty.pas +++ b/sys/dev/dev_tty.pas @@ -293,22 +293,23 @@ end; const ttydev_cdevsw:t_cdevsw=( - d_version :D_VERSION; - d_flags :D_TTY; - d_name :'ttydev'; - d_open :@ttydev_open; - d_fdopen :nil; - d_close :@ttydev_close; - d_read :@ttydev_read; - d_write :@ttydev_write; - d_ioctl :@ttydev_ioctl; - d_poll :@ttydev_poll; - d_mmap :@ttydev_mmap; - d_strategy :nil; - d_dump :nil; - d_kqfilter :@ttydev_kqfilter; - d_purge :nil; - d_mmap_single:nil; + d_version :D_VERSION; + d_flags :D_TTY; + d_name :'ttydev'; + d_open :@ttydev_open; + d_fdopen :nil; + d_close :@ttydev_close; + d_read :@ttydev_read; + d_write :@ttydev_write; + d_ioctl :@ttydev_ioctl; + d_poll :@ttydev_poll; + d_mmap :@ttydev_mmap; + d_strategy :nil; + d_dump :nil; + d_kqfilter :@ttydev_kqfilter; + d_purge :nil; + d_mmap_single :nil; + d_mmap_single2:nil; ); { @@ -328,22 +329,23 @@ end; const ttyconsdev_cdevsw:t_cdevsw=( - d_version :D_VERSION; - d_flags :D_TTY; - d_name :'ttyconsdev'; - d_open :@ttyconsdev_open; - d_fdopen :nil; - d_close :@ttydev_close; - d_read :@ttydev_read; - d_write :@ttyconsdev_write; - d_ioctl :@ttydev_ioctl; - d_poll :@ttydev_poll; - d_mmap :@ttydev_mmap; - d_strategy :nil; - d_dump :nil; - d_kqfilter :@ttydev_kqfilter; - d_purge :nil; - d_mmap_single:nil; + d_version :D_VERSION; + d_flags :D_TTY; + d_name :'ttyconsdev'; + d_open :@ttyconsdev_open; + d_fdopen :nil; + d_close :@ttydev_close; + d_read :@ttydev_read; + d_write :@ttyconsdev_write; + d_ioctl :@ttydev_ioctl; + d_poll :@ttydev_poll; + d_mmap :@ttydev_mmap; + d_strategy :nil; + d_dump :nil; + d_kqfilter :@ttydev_kqfilter; + d_purge :nil; + d_mmap_single :nil; + d_mmap_single2:nil; ); { diff --git a/sys/kern/kern_budget.pas b/sys/kern/kern_budget.pas index cc84fe2b..944b1828 100644 --- a/sys/kern/kern_budget.pas +++ b/sys/kern/kern_budget.pas @@ -9,11 +9,11 @@ uses vm, sys_vm_object; -procedure budget_enter_object(obj :vm_object_t; - len :vm_ooffset_t); +procedure budget_reserve(obj :vm_object_t; + len :vm_ooffset_t); -procedure budget_remove(obj :vm_object_t; - len :vm_ooffset_t); +procedure budget_release(obj :vm_object_t; + len :vm_ooffset_t); function get_mlock_avail():QWORD; function get_mlock_total():QWORD; @@ -36,10 +36,9 @@ uses var budget_total :QWORD=(448*1024*1024); budget_malloc:QWORD=0; - budget_dmem :QWORD=0; -procedure budget_enter_object(obj :vm_object_t; - len :vm_ooffset_t); +procedure budget_reserve(obj :vm_object_t; + len :vm_ooffset_t); label _inc_malloc; begin @@ -53,16 +52,10 @@ begin begin goto _inc_malloc; end; - - if (obj<>nil) then - if (obj^.otype=OBJT_PHYSHM) then - begin - System.InterlockedExchangeAdd64(budget_dmem,len); - end; end; -procedure budget_remove(obj :vm_object_t; - len :vm_ooffset_t); +procedure budget_release(obj :vm_object_t; + len :vm_ooffset_t); label _dec_malloc; begin @@ -76,12 +69,6 @@ begin begin goto _dec_malloc; end; - - if (obj<>nil) then - if (obj^.otype=OBJT_PHYSHM) then - begin - System.InterlockedExchangeAdd64(budget_dmem,-len); - end; end; function get_mlock_avail():QWORD; diff --git a/sys/kern/kern_dmem.pas b/sys/kern/kern_dmem.pas index 2d899630..09c7ac0f 100644 --- a/sys/kern/kern_dmem.pas +++ b/sys/kern/kern_dmem.pas @@ -63,11 +63,19 @@ type operation:Integer; end; +type + p_dmem_obj=^t_dmem_obj; + t_dmem_obj=record + dmem:p_dmem_map; + vobj:vm_object_t; + end; + var - dobj:vm_object_t; dmem:t_dmem_map; rmap:t_rmem_map; + dmem_maps:array[0..2] of t_dmem_obj; + procedure init_dmem_map; function sys_dmem_container(d_pool_id:Integer):Integer; @@ -127,9 +135,6 @@ procedure init_dmem_map; var vmap:vm_map_t; begin - dobj:=vm_object_allocate(OBJT_PHYSHM,OFF_TO_IDX(SCE_KERNEL_MAIN_DMEM_SIZE)); - dobj^.flags:=dobj^.flags or OBJ_DMEM_EXT or OBJ_NOSPLIT; - dmem_map_init(@dmem,0,SCE_KERNEL_MAIN_DMEM_SIZE); rmem_map_init(@rmap,0,SCE_KERNEL_MAIN_DMEM_SIZE); @@ -201,6 +206,8 @@ label _fixed, _rmap_insert; var + dmap:t_dmem_obj; + v_end:QWORD; faddr:QWORD; entry,next:vm_map_entry_t; @@ -218,6 +225,8 @@ begin Exit(EACCES); end; + dmap:=dmem_maps[default_pool_id]; + //eflags = flags & MAP_NO_COALESCE | 0x20000 | 0x80000 cow:=(flags and MAP_NO_COALESCE) or MAP_COW_UNK; @@ -247,11 +256,11 @@ begin begin _rmap_insert: - err:=dmem_map_set_mtype(@dmem,OFF_TO_IDX(phaddr),OFF_TO_IDX(phaddr+length),mtype); + err:=dmem_map_set_mtype(dmap.dmem,OFF_TO_IDX(phaddr),OFF_TO_IDX(phaddr+length),mtype); if (err=0) then begin - err:=vm_map_insert(map, dobj, phaddr, vaddr, v_end, prot, VM_PROT_ALL, cow, ((p_proc.p_dmem_aliasing and 3)<>0)); + err:=vm_map_insert(map, dmap.vobj, phaddr, vaddr, v_end, prot, VM_PROT_ALL, cow, ((p_proc.p_dmem_aliasing and 3)<>0)); if (err=0) then begin @@ -337,6 +346,16 @@ begin td:=curkthread; if (td=nil) then Exit(Pointer(-1)); + if is_sce_prog_attr_40_800000(@g_authinfo) then + begin + Exit(Pointer(EPERM)); + end; + + if is_sce_prog_attr_40_400000(@g_authinfo) then + begin + Exit(Pointer(EPERM)); + end; + if (default_pool_id<>1) then begin Exit(Pointer(EOPNOTSUPP)); @@ -465,7 +484,7 @@ end; function get_obj_mtype(obj:vm_map_object):Byte; begin - Result:=QWORD(obj^.un_pager.vnp.vnp_size); + Result:=obj^.un_pager.physhm.mtype; end; procedure dmem_vmo_get_type(map:vm_map_t; @@ -529,7 +548,7 @@ begin addr:=start; end; - ret:=dmem_map_get_mtype(@dmem,obj,addr + relofs,@d_start2,@d_end2,@d_mtype); + ret:=dmem_map_get_mtype(dmem_maps[default_pool_id].dmem,obj,addr + relofs,@d_start2,@d_end2,@d_mtype); if (ret<>0) then begin Assert(false,'dmem_vmo_get_type error %d'); diff --git a/sys/md/vm_pmap.pas b/sys/md/vm_pmap.pas index 013d2f20..e3a802be 100644 --- a/sys/md/vm_pmap.pas +++ b/sys/md/vm_pmap.pas @@ -347,6 +347,8 @@ procedure pmap_enter_object(pmap :pmap_t; start :vm_offset_t; __end :vm_offset_t; prot :vm_prot_t); +label + _default; var base:Pointer; size:QWORD; @@ -356,24 +358,33 @@ begin r:=0; case vm_object_type(obj) of - OBJT_DEVICE, // same? OBJT_SELF , // same? OBJT_DEFAULT: begin + _default: + base:=Pointer(trunc_page(start)); size:=trunc_page(__end-start); r:=md_enter(base,size,wprots[prot and VM_RWX]); end; - OBJT_PHYSHM: + OBJT_DEVICE: begin - base:=Pointer(trunc_page(offset))+VM_MIN_GPU_ADDRESS; + if (obj^.map_base=nil) then + begin + goto _default; + end; + + base:=obj^.map_base+trunc_page(offset); size:=trunc_page(__end-start); - Writeln('pmap_enter_gpuobj:',HexStr(QWORD(base),11),':',HexStr(QWORD(base)+size,11),':',HexStr(prot,2)); + if ((obj^.flags and OBJ_DMEM_EXT)<>0) then + begin + Writeln('pmap_enter_gpuobj:',HexStr(QWORD(base),11),':',HexStr(QWORD(base)+size,11),':',HexStr(prot,2)); - r:=md_enter(base,size,MD_PROT_RWX); + r:=md_enter(base,size,MD_PROT_RWX); + end; end; else begin @@ -454,6 +465,8 @@ procedure pmap_protect(pmap :pmap_t; start :vm_offset_t; __end :vm_offset_t; prot :vm_prot_t); +label + _default; var base:Pointer; size:QWORD; @@ -463,24 +476,33 @@ begin r:=0; case vm_object_type(obj) of - OBJT_DEVICE, // same? OBJT_SELF , // same? OBJT_DEFAULT: begin + _default: + base:=Pointer(trunc_page(start)); size:=trunc_page(__end-start); r:=md_protect(base,size,wprots[prot and VM_RWX]); end; - OBJT_PHYSHM: + OBJT_DEVICE: begin - base:=Pointer(trunc_page(offset))+VM_MIN_GPU_ADDRESS; + if (obj^.map_base=nil) then + begin + goto _default; + end; + + base:=obj^.map_base+trunc_page(offset); size:=trunc_page(__end-start); - Writeln('pmap_protect_gpuobj:',HexStr(QWORD(base),11),':',HexStr(QWORD(base)+size,11),':',HexStr(prot,2)); + if ((obj^.flags and OBJ_DMEM_EXT)<>0) then + begin + Writeln('pmap_protect_gpuobj:',HexStr(QWORD(base),11),':',HexStr(QWORD(base)+size,11),':',HexStr(prot,2)); - r:=md_protect(base,size,MD_PROT_RWX); + r:=md_protect(base,size,MD_PROT_RWX); + end; end; else begin @@ -505,6 +527,8 @@ procedure pmap_madv_free(pmap :pmap_t; start :vm_offset_t; __end :vm_offset_t; prot :vm_prot_t); +label + _default; var base:Pointer; size:QWORD; @@ -514,16 +538,25 @@ begin r:=0; case vm_object_type(obj) of - OBJT_DEVICE, // same? OBJT_SELF , // same? OBJT_DEFAULT: begin + _default: + base:=Pointer(trunc_page(start)); size:=trunc_page(__end-start); r:=md_reset(base,size,wprots[prot and VM_RWX]); end; + OBJT_DEVICE: + begin + if (obj^.map_base=nil) then + begin + goto _default; + end; + //ignore + end; OBJT_PHYSHM: begin //ignore @@ -549,6 +582,8 @@ procedure pmap_remove(pmap :pmap_t; start :vm_offset_t; __end :vm_offset_t; prot :vm_prot_t); +label + _default; var base:Pointer; size:QWORD; @@ -560,24 +595,33 @@ begin r:=0; case vm_object_type(obj) of - OBJT_DEVICE, // same? OBJT_SELF , // same? OBJT_DEFAULT: begin + _default: + base:=Pointer(trunc_page(start)); size:=trunc_page(__end-start); r:=md_remove(base,size); end; - OBJT_PHYSHM: + OBJT_DEVICE: begin - base:=Pointer(trunc_page(offset))+VM_MIN_GPU_ADDRESS; + if (obj^.map_base=nil) then + begin + goto _default; + end; + + base:=obj^.map_base+trunc_page(offset); size:=trunc_page(__end-start); - Writeln('pmap_remove_gpuobj:',HexStr(QWORD(base),11),':',HexStr(QWORD(base)+size,11),':',HexStr(prot,2)); + if ((obj^.flags and OBJ_DMEM_EXT)<>0) then + begin + Writeln('pmap_remove_gpuobj:',HexStr(QWORD(base),11),':',HexStr(QWORD(base)+size,11),':',HexStr(prot,2)); - r:=md_remove(base,size); + r:=md_remove(base,size); + end; end; else begin diff --git a/sys/vfs/kern_conf.pas b/sys/vfs/kern_conf.pas index 5492356a..5e6b68c9 100644 --- a/sys/vfs/kern_conf.pas +++ b/sys/vfs/kern_conf.pas @@ -70,19 +70,20 @@ type __si_namebuf :array[0..SPECNAMELEN] of AnsiChar; end; - d_open_t =Function (dev:p_cdev;oflags,devtype:Integer):Integer; - d_fdopen_t =Function (dev:p_cdev;oflags:Integer;fp:p_file):Integer; - d_close_t =Function (dev:p_cdev;fflag,devtype:Integer):Integer; - d_strategy_t =Procedure(bp:Pointer);//bio - d_ioctl_t =Function (dev:p_cdev;cmd:QWORD;data:Pointer;fflag:Integer):Integer; + d_open_t =Function (dev:p_cdev;oflags,devtype:Integer):Integer; + d_fdopen_t =Function (dev:p_cdev;oflags:Integer;fp:p_file):Integer; + d_close_t =Function (dev:p_cdev;fflag,devtype:Integer):Integer; + d_strategy_t =Procedure(bp:Pointer);//bio + d_ioctl_t =Function (dev:p_cdev;cmd:QWORD;data:Pointer;fflag:Integer):Integer; - d_read_t =Function (dev:p_cdev;uio:p_uio;ioflag:Integer):Integer; - d_write_t =Function (dev:p_cdev;uio:p_uio;ioflag:Integer):Integer; - d_poll_t =Function (dev:p_cdev;events:Integer):Integer; - d_kqfilter_t =Function (dev:p_cdev;kn:p_knote):Integer; - d_mmap_t =Function (dev:p_cdev;offset:vm_ooffset_t;paddr:p_vm_paddr_t;nprot:Integer;memattr:p_vm_memattr_t):Integer; - d_mmap_single_t=Function (cdev:p_cdev;offset:p_vm_ooffset_t;size:vm_size_t;obj:p_vm_object_t;nprot:Integer):Integer; - d_purge_t =Procedure(dev:p_cdev); + d_read_t =Function (dev:p_cdev;uio:p_uio;ioflag:Integer):Integer; + d_write_t =Function (dev:p_cdev;uio:p_uio;ioflag:Integer):Integer; + d_poll_t =Function (dev:p_cdev;events:Integer):Integer; + d_kqfilter_t =Function (dev:p_cdev;kn:p_knote):Integer; + d_mmap_t =Function (dev:p_cdev;offset:vm_ooffset_t;paddr:p_vm_paddr_t;nprot:Integer;memattr:p_vm_memattr_t):Integer; + d_mmap_single_t =Function (dev:p_cdev;offset:p_vm_ooffset_t;size:vm_size_t;obj:p_vm_object_t;nprot:Integer):Integer; + d_mmap_single2_t=Function (dev:p_cdev;offset:p_vm_ooffset_t;size:vm_size_t;obj:p_vm_object_t;nprot:Integer;maxprotp:p_vm_prot_t;flagsp:PInteger):Integer; + d_purge_t =Procedure(dev:p_cdev); dumper_t=Function( _priv:Pointer ; { Private to the driver. } @@ -133,24 +134,25 @@ type pp_cdevsw=^p_cdevsw; p_cdevsw=^t_cdevsw; t_cdevsw=packed record - d_version :Integer; - d_flags :DWORD; - d_name :PChar; - d_open :d_open_t; - d_fdopen :d_fdopen_t; - d_close :d_close_t; - d_read :d_read_t; - d_write :d_write_t; - d_ioctl :d_ioctl_t; - d_poll :d_poll_t; - d_mmap :d_mmap_t; - d_strategy :d_strategy_t; - d_dump :dumper_t; - d_kqfilter :d_kqfilter_t; - d_purge :d_purge_t; - d_mmap_single:d_mmap_single_t; + d_version :Integer; + d_flags :DWORD; + d_name :PChar; + d_open :d_open_t; + d_fdopen :d_fdopen_t; + d_close :d_close_t; + d_read :d_read_t; + d_write :d_write_t; + d_ioctl :d_ioctl_t; + d_poll :d_poll_t; + d_mmap :d_mmap_t; + d_strategy :d_strategy_t; + d_dump :dumper_t; + d_kqfilter :d_kqfilter_t; + d_purge :d_purge_t; + d_mmap_single :d_mmap_single_t; + d_mmap_single2:d_mmap_single2_t; - d_spare0:array[0..3] of Integer; + d_spare0:array[0..1] of Integer; d_spare1:array[0..2] of Pointer; { These fields should not be messed with by drivers } @@ -516,22 +518,23 @@ end; const dead_cdevsw:t_cdevsw=( - d_version :D_VERSION; - d_flags :0; - d_name :'dead'; - d_open :d_open_t(@_enxio); - d_fdopen :nil; - d_close :d_close_t(@_enxio); - d_read :d_read_t(@_enxio); - d_write :d_write_t(@_enxio); - d_ioctl :d_ioctl_t(@_enxio); - d_poll :d_poll_t(@_enodev); - d_mmap :d_mmap_t(@_enodev); - d_strategy :@dead_strategy; - d_dump :dumper_t(@_enxio); - d_kqfilter :d_kqfilter_t(@_enxio); - d_purge :nil; - d_mmap_single:d_mmap_single_t(@_enodev); + d_version :D_VERSION; + d_flags :0; + d_name :'dead'; + d_open :d_open_t(@_enxio); + d_fdopen :nil; + d_close :d_close_t(@_enxio); + d_read :d_read_t(@_enxio); + d_write :d_write_t(@_enxio); + d_ioctl :d_ioctl_t(@_enxio); + d_poll :d_poll_t(@_enodev); + d_mmap :d_mmap_t(@_enodev); + d_strategy :@dead_strategy; + d_dump :dumper_t(@_enxio); + d_kqfilter :d_kqfilter_t(@_enxio); + d_purge :nil; + d_mmap_single :d_mmap_single_t(@_enodev); + d_mmap_single2:d_mmap_single2_t(@_enodev); ); procedure no_strategy(bp:Pointer); @@ -733,6 +736,23 @@ begin Exit(retval); end; +Function giant_mmap_single2(dev:p_cdev;offset:p_vm_ooffset_t;size:vm_size_t;obj:p_vm_object_t;nprot:Integer;maxprotp:p_vm_prot_t;flagsp:PInteger):Integer; +var + dsw:p_cdevsw; + ref,retval:Integer; +begin + dsw:=dev_refthread(dev, @ref); + if (dsw=nil) then + begin + Exit(ENXIO); + end; + mtx_lock(VFS_Giant); + retval:=dsw^.d_gianttrick^.d_mmap_single2(dev, offset, size, obj, nprot, maxprotp, flagsp); + mtx_unlock(VFS_Giant); + dev_relthread(dev, ref); + Exit(retval); +end; + procedure notify(dev:p_cdev;ev:PChar;flags:Integer); const prefix:PChar='cdev='; @@ -844,17 +864,18 @@ begin if (devsw^.d_version<>D_VERSION_03) then begin Writeln('WARNING: Device driver has wrong version'); - devsw^.d_open :=d_open_t(@_enxio); - devsw^.d_close :=d_close_t(@_enxio); - devsw^.d_read :=d_read_t(@_enxio); - devsw^.d_write :=d_write_t(@_enxio); - devsw^.d_ioctl :=d_ioctl_t(@_enxio); - devsw^.d_poll :=d_poll_t(@_enodev); - devsw^.d_mmap :=d_mmap_t(@_enodev); - devsw^.d_mmap_single:=d_mmap_single_t(@_enodev); - devsw^.d_strategy :=@dead_strategy; - devsw^.d_dump :=dumper_t(@_enxio); - devsw^.d_kqfilter :=d_kqfilter_t(@_enxio); + devsw^.d_open :=d_open_t(@_enxio); + devsw^.d_close :=d_close_t(@_enxio); + devsw^.d_read :=d_read_t(@_enxio); + devsw^.d_write :=d_write_t(@_enxio); + devsw^.d_ioctl :=d_ioctl_t(@_enxio); + devsw^.d_poll :=d_poll_t(@_enodev); + devsw^.d_mmap :=d_mmap_t(@_enodev); + devsw^.d_mmap_single :=d_mmap_single_t(@_enodev); + devsw^.d_mmap_single2:=d_mmap_single2_t(@_enodev); + devsw^.d_strategy :=@dead_strategy; + devsw^.d_dump :=dumper_t(@_enxio); + devsw^.d_kqfilter :=d_kqfilter_t(@_enxio); end; if ((devsw^.d_flags and D_NEEDGIANT)<>0) then @@ -867,17 +888,18 @@ begin end; end; - FIXUP(@devsw^.d_open, @_nullop, @giant_open); - FIXUP(@devsw^.d_fdopen, nil, @giant_fdopen); - FIXUP(@devsw^.d_close, @_nullop, @giant_close); - FIXUP(@devsw^.d_read, @_enodev, @giant_read); - FIXUP(@devsw^.d_write, @_enodev, @giant_write); - FIXUP(@devsw^.d_ioctl, @_enodev, @giant_ioctl); - FIXUP(@devsw^.d_poll, @no_poll, @giant_poll); - FIXUP(@devsw^.d_mmap, @_enodev, @giant_mmap); - FIXUP(@devsw^.d_strategy, @no_strategy, @giant_strategy); - FIXUP(@devsw^.d_kqfilter, @_enodev, @giant_kqfilter); - FIXUP(@devsw^.d_mmap_single, @_enodev, @giant_mmap_single); + FIXUP(@devsw^.d_open, @_nullop, @giant_open); + FIXUP(@devsw^.d_fdopen, nil, @giant_fdopen); + FIXUP(@devsw^.d_close, @_nullop, @giant_close); + FIXUP(@devsw^.d_read, @_enodev, @giant_read); + FIXUP(@devsw^.d_write, @_enodev, @giant_write); + FIXUP(@devsw^.d_ioctl, @_enodev, @giant_ioctl); + FIXUP(@devsw^.d_poll, @no_poll, @giant_poll); + FIXUP(@devsw^.d_mmap, @_enodev, @giant_mmap); + FIXUP(@devsw^.d_strategy, @no_strategy, @giant_strategy); + FIXUP(@devsw^.d_kqfilter, @_enodev, @giant_kqfilter); + FIXUP(@devsw^.d_mmap_single, @_enodev, @giant_mmap_single); + FIXUP(@devsw^.d_mmap_single2, @_enodev, @giant_mmap_single2); if (devsw^.d_dump=nil) then devsw^.d_dump:=dumper_t(@_enodev); @@ -886,7 +908,10 @@ begin devsw^.d_flags:=devsw^.d_flags or D_INIT; if (dsw2<>nil) then + begin cdevsw_free_devlocked(dsw2); + end; + Exit(0); end; diff --git a/sys/vm/sys_vm_object.pas b/sys/vm/sys_vm_object.pas index b94747ee..cb4c9a09 100644 --- a/sys/vm/sys_vm_object.pas +++ b/sys/vm/sys_vm_object.pas @@ -43,11 +43,15 @@ type flags :Word; // see below handle :Pointer; paging_in_progress:Integer; + map_base :Pointer; un_pager:packed record vnp:packed record vnp_size:QWORD; writemappings:vm_ooffset_t; end; + physhm:packed record + mtype:Byte; + end; end; end; diff --git a/sys/vm/vm_map.pas b/sys/vm/vm_map.pas index 9a424b95..021063fa 100644 --- a/sys/vm/vm_map.pas +++ b/sys/vm/vm_map.pas @@ -936,11 +936,12 @@ var if (cow<>-1) then begin - budget_enter_object(obj,__end-start); + budget_reserve(obj,__end-start); if (obj<>nil) then begin - if ((obj^.flags and OBJ_DMEM_EXT2)<>0) or (obj^.otype=OBJT_PHYSHM) then + if ((obj^.flags and OBJ_DMEM_EXT2)<>0) or + (obj^.otype=OBJT_PHYSHM) then begin Result:=vm_object_rmap_insert(map,obj,start,__end,offset,alias); end; @@ -2362,13 +2363,14 @@ begin next:=entry^.next; - budget_remove(entry^.vm_obj, - entry^.__end-entry^.start); + budget_release(entry^.vm_obj, + entry^.__end-entry^.start); p_rem:=True; if (obj<>nil) then begin - if ((obj^.flags and (OBJ_DMEM_EXT or OBJ_DMEM_EXT2))<>0) or (obj^.otype=OBJT_PHYSHM) then + if ((obj^.flags and (OBJ_DMEM_EXT or OBJ_DMEM_EXT2))<>0) or + (obj^.otype=OBJT_PHYSHM) then begin Result:=vm_object_rmap_release(map, obj, diff --git a/sys/vm/vm_mmap.pas b/sys/vm/vm_mmap.pas index 5d77c07f..86994033 100644 --- a/sys/vm/vm_mmap.pas +++ b/sys/vm/vm_mmap.pas @@ -92,7 +92,7 @@ begin if ((dsw^.d_flags and D_MMAP_ANON)<>0) then begin dev_relthread(cdev, ref); - maxprotp^:=VM_PROT_ALL; + maxprotp^:=$33; flagsp^:=flagsp^ or MAP_ANON; Exit(0); end; @@ -111,20 +111,21 @@ 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_* - } + error:=dsw^.d_mmap_single2(cdev, foff, objsize, objp, prot, maxprotp, @flags); + + if (error<>ENODEV) then + begin + dev_relthread(cdev, ref); + flagsp^:=flags; + Exit(error); + end; + error:=dsw^.d_mmap_single(cdev, foff, objsize, objp, prot); dev_relthread(cdev, ref); @@ -400,7 +401,6 @@ begin begin error:=vm_mmap_cdev(size,prot,@maxprot,@flags,handle,@foff,@obj); end; - OBJT_SELF, //same as file OBJT_VNODE: begin error:=vm_mmap_vnode(size,prot,@maxprot,@flags,handle,@foff,@obj,@writecounted); @@ -419,6 +419,7 @@ begin end; end; + OBJT_SELF, //same as default OBJT_DEFAULT: begin if (handle=nil) then diff --git a/sys/vm/vm_pager.pas b/sys/vm/vm_pager.pas index 1f715988..1719b8a4 100644 --- a/sys/vm/vm_pager.pas +++ b/sys/vm/vm_pager.pas @@ -10,10 +10,10 @@ uses sys_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; + 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);