mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
e3fc81c59c
commit
2bdaf6010f
|
@ -634,7 +634,7 @@ begin
|
|||
end;
|
||||
|
||||
obj:=vm_pager_allocate(OBJT_DEVICE,cdev,PAGE_SIZE,$33,off);
|
||||
obj^.map_base:=Pointer(@dce_page)-PAGE_SIZE;
|
||||
obj^.un_pager.map_base:=Pointer(@dce_page)-PAGE_SIZE;
|
||||
|
||||
if (obj=nil) then
|
||||
begin
|
||||
|
|
|
@ -141,7 +141,7 @@ begin
|
|||
Exit(-1);
|
||||
end;
|
||||
|
||||
paddr^:=offset + QWORD(dmap^.vobj^.map_base);
|
||||
paddr^:=offset + QWORD(dmap^.vobj^.un_pager.map_base);
|
||||
memattr^:=0;
|
||||
end;
|
||||
|
||||
|
@ -246,7 +246,7 @@ begin
|
|||
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);
|
||||
obj^.un_pager.map_base:=Pointer(VM_MIN_GPU_ADDRESS);
|
||||
vm_object_reference(obj);
|
||||
//
|
||||
dmem_maps[i].dmem:=@kern_dmem.dmem;
|
||||
|
|
|
@ -130,7 +130,7 @@ begin
|
|||
end;
|
||||
|
||||
obj:=vm_pager_allocate(OBJT_DEVICE,cdev,PAGE_SIZE,nprot,offset^);
|
||||
obj^.map_base:=@gc_page;
|
||||
obj^.un_pager.map_base:=@gc_page;
|
||||
|
||||
if (obj=nil) then
|
||||
begin
|
||||
|
|
|
@ -53,12 +53,15 @@ type
|
|||
|
||||
const
|
||||
//SceLncAppType
|
||||
SCE_LNC_APP_TYPE_INVALID =-1;
|
||||
SCE_LNC_APP_TYPE_SHELL_UI= 1; //isSystemApp
|
||||
SCE_LNC_APP_TYPE_DAEMON = 2; //isSystemApp
|
||||
SCE_LNC_APP_TYPE_CDLG = 3; //isSystemApp
|
||||
SCE_LNC_APP_TYPE_MINI_APP= 4; //isSystemApp
|
||||
SCE_LNC_APP_TYPE_BIG_APP = 5;
|
||||
SCE_LNC_APP_TYPE_INVALID =-1;
|
||||
SCE_LNC_APP_TYPE_NULL = 0;
|
||||
SCE_LNC_APP_TYPE_SHELL_UI = 1; //isSystemApp
|
||||
SCE_LNC_APP_TYPE_DAEMON = 2; //isSystemApp
|
||||
SCE_LNC_APP_TYPE_CDLG = 3; //isSystemApp
|
||||
SCE_LNC_APP_TYPE_MINI_APP = 4; //isSystemApp
|
||||
SCE_LNC_APP_TYPE_BIG_APP = 5;
|
||||
SCE_LNC_APP_TYPE_SHELL_CORE= 6; //isSystemApp
|
||||
SCE_LNC_APP_TYPE_SHELL_APP = 7; //isSystemApp
|
||||
|
||||
//[preloadPrxFlags] -> sceSysmodulePreloadModuleForLibkernel
|
||||
//0x0000000004 libSceNet
|
||||
|
@ -108,7 +111,7 @@ type
|
|||
AppId :Integer; //4
|
||||
mmap_flags :Integer; //4
|
||||
attributeExe :Integer; //4
|
||||
AppType :Integer; //4 SceLncAppType
|
||||
attribute2 :Integer; //4
|
||||
CUSANAME :TCUSANAME; //10 titleId
|
||||
debug_level :Byte; //1
|
||||
slv_flags :Byte; //1 eLoadOptions
|
||||
|
|
|
@ -265,6 +265,8 @@ begin
|
|||
|
||||
if (err=0) then
|
||||
begin
|
||||
vm_object_reference(dmap.vobj);
|
||||
|
||||
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
|
||||
|
@ -272,6 +274,8 @@ begin
|
|||
addr^:=vaddr;
|
||||
end else
|
||||
begin
|
||||
vm_object_deallocate(dmap.vobj);
|
||||
//
|
||||
Result:=vm_mmap_to_errno(err);
|
||||
end;
|
||||
end;
|
||||
|
|
|
@ -1310,9 +1310,9 @@ begin
|
|||
if (error<>0) then goto exec_fail_dealloc;
|
||||
|
||||
//imgp^.obj:=imgp^.vp^.v_object;
|
||||
//if (imgp^.object<>nil) then
|
||||
//if (imgp^.obj<>nil) then
|
||||
//begin
|
||||
// vm_object_reference(imgp^.object);
|
||||
// vm_object_reference(imgp^.obj);
|
||||
//end;
|
||||
|
||||
error:=rtld_load_self(imgp);
|
||||
|
@ -1457,7 +1457,6 @@ begin
|
|||
begin
|
||||
g_appinfo.mmap_flags:=g_appinfo.mmap_flags or 2; //is_system ???
|
||||
end;
|
||||
g_appinfo.AppType:=SCE_LNC_APP_TYPE_BIG_APP;
|
||||
|
||||
//TODO load CUSANAME
|
||||
|
||||
|
|
|
@ -1084,11 +1084,15 @@ begin
|
|||
//remove prev if exist
|
||||
vm_map_delete(map,vaddr_lo,vaddr_hi,True);
|
||||
|
||||
vm_object_reference(imgp^.obj);
|
||||
|
||||
Result:=vm_map_insert(map,imgp^.obj,offset,vaddr_lo,vaddr_hi,VM_PROT_RW,prot or VM_PROT_RW,0,false);
|
||||
if (Result<>0) then
|
||||
begin
|
||||
vm_map_unlock(map);
|
||||
//
|
||||
vm_object_deallocate(imgp^.obj);
|
||||
//
|
||||
Writeln(StdErr,'[KERNEL] self_load_section: vm_map_insert failed ',id,', ',HexStr(vaddr,8));
|
||||
Exit(vm_mmap_to_errno(Result));
|
||||
end;
|
||||
|
|
|
@ -31,6 +31,9 @@ function md_reset (base:Pointer;size:QWORD;prot:Integer):Integer;
|
|||
function md_mmap (var base:Pointer;size:QWORD;prot:Integer):Integer;
|
||||
function md_unmap (base:Pointer;size:QWORD):Integer;
|
||||
|
||||
function md_file_mmap (handle:THandle;var base:Pointer;offset,size:QWORD;prot:Integer):Integer;
|
||||
function md_file_unmap(base:Pointer;size:QWORD):Integer;
|
||||
|
||||
const
|
||||
ICACHE=1; //Flush the instruction cache.
|
||||
DCACHE=2; //Write back to memory and invalidate the affected valid cache lines.
|
||||
|
@ -146,6 +149,65 @@ begin
|
|||
);
|
||||
end;
|
||||
|
||||
function md_file_mmap(handle:THandle;var base:Pointer;offset,size:QWORD;prot:Integer):Integer;
|
||||
var
|
||||
hSection:THandle;
|
||||
DesiredAccess:DWORD;
|
||||
CommitSize:ULONG_PTR;
|
||||
SectionOffset:ULONG_PTR;
|
||||
ViewSize:ULONG_PTR;
|
||||
begin
|
||||
|
||||
case prot of
|
||||
PAGE_READWRITE :DesiredAccess:=SECTION_MAP_READ or SECTION_MAP_WRITE;
|
||||
PAGE_EXECUTE :DesiredAccess:=SECTION_MAP_EXECUTE;
|
||||
PAGE_EXECUTE_READ :DesiredAccess:=SECTION_MAP_EXECUTE or SECTION_MAP_READ;
|
||||
PAGE_EXECUTE_READWRITE:DesiredAccess:=SECTION_MAP_EXECUTE or SECTION_MAP_READ or SECTION_MAP_WRITE;
|
||||
else
|
||||
DesiredAccess:=SECTION_MAP_READ;
|
||||
end;
|
||||
|
||||
hSection:=0;
|
||||
Result:=NtCreateSection(
|
||||
@hSection,
|
||||
DesiredAccess,
|
||||
nil,
|
||||
@size,
|
||||
prot,
|
||||
SEC_COMMIT,
|
||||
handle
|
||||
);
|
||||
|
||||
if (Result<>0) then Exit;
|
||||
|
||||
base:=md_alloc_page(base);
|
||||
|
||||
CommitSize :=md_up_page(size);
|
||||
SectionOffset:=offset and (not (MD_ALLOC_GRANULARITY-1));
|
||||
ViewSize :=CommitSize;
|
||||
|
||||
Result:=NtMapViewOfSection(hSection,
|
||||
NtCurrentProcess,
|
||||
@base,
|
||||
0,
|
||||
CommitSize,
|
||||
@SectionOffset,
|
||||
@ViewSize,
|
||||
ViewUnmap,
|
||||
0 {MEM_COMMIT},
|
||||
prot
|
||||
);
|
||||
|
||||
NtClose(hSection);
|
||||
end;
|
||||
|
||||
function md_file_unmap(base:Pointer;size:QWORD):Integer;
|
||||
begin
|
||||
base:=md_alloc_page(base);
|
||||
|
||||
Result:=NtUnmapViewOfSection(NtCurrentProcess,@base);
|
||||
end;
|
||||
|
||||
//
|
||||
|
||||
procedure md_cacheflush(addr:Pointer;nbytes,cache:Integer);
|
||||
|
|
|
@ -1313,6 +1313,8 @@ begin
|
|||
|
||||
Result:=md_update_dirent(THandle(vp^.v_un),de,nil);
|
||||
|
||||
vnode_pager_setsize(vp, de^.ufs_size);
|
||||
|
||||
sx_xunlock(@de^.ufs_md_lock);
|
||||
|
||||
if (Result<>0) then Exit;
|
||||
|
@ -2403,19 +2405,6 @@ begin
|
|||
Dec(uio^.uio_iovcnt);
|
||||
end;
|
||||
|
||||
if (Result=0) and (uio^.uio_rw=UIO_WRITE) then
|
||||
begin
|
||||
if not locked then
|
||||
begin
|
||||
sx_xlock(@de^.ufs_md_lock);
|
||||
end;
|
||||
|
||||
md_update_dirent(F,de,nil);
|
||||
|
||||
vnode_pager_setsize(vp, de^.ufs_size);
|
||||
|
||||
sx_xunlock(@de^.ufs_md_lock);
|
||||
end else
|
||||
if locked then
|
||||
begin
|
||||
sx_xunlock(@de^.ufs_md_lock);
|
||||
|
|
|
@ -8,7 +8,9 @@ interface
|
|||
uses
|
||||
vm,
|
||||
vmparam,
|
||||
sys_vm_object;
|
||||
sys_vm_object,
|
||||
vm_file,
|
||||
vnode;
|
||||
|
||||
const
|
||||
PAGE_MAP_COUNT =(QWORD(VM_MAXUSER_ADDRESS) shr PAGE_SHIFT);
|
||||
|
@ -329,6 +331,40 @@ const
|
|||
MD_PROT_RW //XWR
|
||||
);
|
||||
|
||||
function get_vnode_handle(obj:vm_object_t):THandle;
|
||||
var
|
||||
vp:p_vnode;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
vp:=obj^.handle;
|
||||
|
||||
if (vp<>nil) then
|
||||
begin
|
||||
VI_LOCK(vp);
|
||||
|
||||
Result:=THandle(vp^.v_un);
|
||||
|
||||
VI_UNLOCK(vp);
|
||||
end;
|
||||
end;
|
||||
|
||||
function vm_file_map_fixed(map :p_vm_file_map;
|
||||
offset:vm_ooffset_t;
|
||||
start :vm_offset_t;
|
||||
__end :vm_offset_t;
|
||||
base :Pointer;
|
||||
size :QWORD):Integer;
|
||||
var
|
||||
obj:p_vm_file_obj;
|
||||
begin
|
||||
vm_file_map_delete(map,start,__end);
|
||||
|
||||
obj:=vm_file_obj_allocate(base,size,@md_file_unmap);
|
||||
|
||||
Result:=vm_file_map_insert(map,obj,offset,start,__end);
|
||||
end;
|
||||
|
||||
{
|
||||
* Maps a sequence of resident pages belonging to the same object.
|
||||
* The sequence begins with the given page m_start. This page is
|
||||
|
@ -350,8 +386,10 @@ procedure pmap_enter_object(pmap :pmap_t;
|
|||
label
|
||||
_default;
|
||||
var
|
||||
fd:THandle;
|
||||
base:Pointer;
|
||||
size:QWORD;
|
||||
delta:QWORD;
|
||||
r:Integer;
|
||||
begin
|
||||
Writeln('pmap_enter_object:',HexStr(start,11),':',HexStr(__end,11),':',HexStr(prot,2));
|
||||
|
@ -371,12 +409,12 @@ begin
|
|||
end;
|
||||
OBJT_DEVICE:
|
||||
begin
|
||||
if (obj^.map_base=nil) then
|
||||
if (obj^.un_pager.map_base=nil) then
|
||||
begin
|
||||
goto _default;
|
||||
end;
|
||||
|
||||
base:=obj^.map_base+trunc_page(offset);
|
||||
base:=obj^.un_pager.map_base+trunc_page(offset);
|
||||
size:=trunc_page(__end-start);
|
||||
|
||||
if ((obj^.flags and OBJ_DMEM_EXT)<>0) then
|
||||
|
@ -386,6 +424,43 @@ begin
|
|||
r:=md_enter(base,size,MD_PROT_RWX);
|
||||
end;
|
||||
end;
|
||||
OBJT_VNODE:
|
||||
begin
|
||||
VM_OBJECT_LOCK(obj);
|
||||
|
||||
fd:=get_vnode_handle(obj);
|
||||
|
||||
if (fd<>0) then
|
||||
begin
|
||||
|
||||
delta :=offset and (MD_ALLOC_GRANULARITY-1);
|
||||
offset:=offset and (not (MD_ALLOC_GRANULARITY-1));
|
||||
|
||||
size:=delta+offset+(__end-start);
|
||||
|
||||
if (size>obj^.un_pager.vnp.vnp_size) then
|
||||
begin
|
||||
size:=obj^.un_pager.vnp.vnp_size;
|
||||
end;
|
||||
size:=size-offset;
|
||||
|
||||
base:=nil;
|
||||
r:=md_file_mmap(fd,base,offset,size,wprots[prot and VM_RWX]);
|
||||
|
||||
if (r=0) then
|
||||
begin
|
||||
r:=vm_file_map_fixed(@obj^.un_pager.vnp.file_map,
|
||||
delta,
|
||||
start,
|
||||
__end,
|
||||
base,
|
||||
size);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
VM_OBJECT_UNLOCK(obj);
|
||||
end;
|
||||
else
|
||||
begin
|
||||
Writeln('TODO:',vm_object_type(obj));
|
||||
|
@ -489,12 +564,12 @@ begin
|
|||
end;
|
||||
OBJT_DEVICE:
|
||||
begin
|
||||
if (obj^.map_base=nil) then
|
||||
if (obj^.un_pager.map_base=nil) then
|
||||
begin
|
||||
goto _default;
|
||||
end;
|
||||
|
||||
base:=obj^.map_base+trunc_page(offset);
|
||||
base:=obj^.un_pager.map_base+trunc_page(offset);
|
||||
size:=trunc_page(__end-start);
|
||||
|
||||
if ((obj^.flags and OBJ_DMEM_EXT)<>0) then
|
||||
|
@ -551,7 +626,7 @@ begin
|
|||
end;
|
||||
OBJT_DEVICE:
|
||||
begin
|
||||
if (obj^.map_base=nil) then
|
||||
if (obj^.un_pager.map_base=nil) then
|
||||
begin
|
||||
goto _default;
|
||||
end;
|
||||
|
@ -608,12 +683,12 @@ begin
|
|||
end;
|
||||
OBJT_DEVICE:
|
||||
begin
|
||||
if (obj^.map_base=nil) then
|
||||
if (obj^.un_pager.map_base=nil) then
|
||||
begin
|
||||
goto _default;
|
||||
end;
|
||||
|
||||
base:=obj^.map_base+trunc_page(offset);
|
||||
base:=obj^.un_pager.map_base+trunc_page(offset);
|
||||
size:=trunc_page(__end-start);
|
||||
|
||||
if ((obj^.flags and OBJ_DMEM_EXT)<>0) then
|
||||
|
|
|
@ -375,22 +375,18 @@ begin
|
|||
//fs guest host
|
||||
err:=vfs_mount_mkdir('ufs','/app0' ,'/' ,nil,0);
|
||||
err:=vfs_mount_mkdir('ufs','/system','/system',nil,0);
|
||||
|
||||
err:=vfs_unmount_rmdir('/app0' ,0);
|
||||
err:=vfs_unmount_rmdir('/system',0);
|
||||
|
||||
err:=vfs_mount_mkdir('ufs','/app0' ,'/' ,nil,0);
|
||||
err:=vfs_mount_mkdir('ufs','/system','/system',nil,0);
|
||||
err:=vfs_mount_mkdir('ufs','/data' ,'/data' ,nil,0);
|
||||
|
||||
//argv0:='/app0/basic-sample_debug.elf';
|
||||
//argv0:='/app0/simple.elf';
|
||||
//argv0:='/app0/videoout_basic.elf';
|
||||
argv0:='/app0/videoout_cursor.elf';
|
||||
argv0:='/app0/videoout_basic.elf';
|
||||
//argv0:='/app0/videoout_basic.bin';
|
||||
//argv0:='/app0/videoout_cursor.elf';
|
||||
|
||||
//argv0:='/app0/scene2.bin';
|
||||
//argv0:='/app0/basic_quad_debug.elf';
|
||||
|
||||
//argv0:='/app0/hello_world.bin';
|
||||
argv0:='/app0/hello_world8.bin';
|
||||
|
||||
err:=_execve(argv0,@argv0,nil);
|
||||
end;
|
||||
|
|
|
@ -1046,13 +1046,8 @@ begin
|
|||
Exit(0);
|
||||
end;
|
||||
|
||||
if (vp^.v_object<>nil) then
|
||||
begin
|
||||
vm_object_deallocate(vp^.v_object);
|
||||
vp^.v_object:=nil;
|
||||
end;
|
||||
|
||||
//Exit(bufobj_invalbuf(@vp^.v_bufobj, flags, slpflag, slptimeo));
|
||||
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ interface
|
|||
uses
|
||||
mqueue,
|
||||
vm,
|
||||
vmparam,
|
||||
vm_file,
|
||||
kern_mtx;
|
||||
|
||||
type
|
||||
|
@ -30,25 +32,27 @@ type
|
|||
|
||||
p_vm_object_t=^vm_object_t;
|
||||
vm_object_t=^t_vm_object;
|
||||
t_vm_object=packed record
|
||||
mtx :mtx;
|
||||
patchq :TAILQ_HEAD; // list of patches
|
||||
size :vm_pindex_t; // Object size
|
||||
generation :Integer; // generation ID
|
||||
ref_count :Integer; // How many refs??
|
||||
otype :objtype_t; // type of pager
|
||||
pg_color :Word;
|
||||
flags :Word; // see below
|
||||
handle :Pointer;
|
||||
paging_in_progress:Integer;
|
||||
map_base :Pointer;
|
||||
un_pager:packed record
|
||||
vnp:packed record
|
||||
t_vm_object=record
|
||||
mtx :mtx;
|
||||
patchq :TAILQ_HEAD; // list of patches
|
||||
size :vm_pindex_t; // Object size
|
||||
generation:Integer; // generation ID
|
||||
ref_count :Integer; // How many refs??
|
||||
otype :objtype_t; // type of pager
|
||||
pg_color :Word;
|
||||
flags :Word; // see below
|
||||
pip :Integer;
|
||||
handle :Pointer;
|
||||
un_pager :record
|
||||
map_base:Pointer;
|
||||
vnp:record
|
||||
file_map:vm_file_map;
|
||||
vnp_size:QWORD;
|
||||
writemappings:vm_ooffset_t;
|
||||
end;
|
||||
physhm:packed record
|
||||
mtype:Byte;
|
||||
physhm:record
|
||||
map_base:Pointer;
|
||||
mtype :Byte;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
@ -180,15 +184,29 @@ begin
|
|||
Result^.generation:=1;
|
||||
Result^.ref_count :=1;
|
||||
|
||||
if (t=OBJT_DEFAULT) then
|
||||
begin
|
||||
Result^.flags:=OBJ_ONEMAPPING;
|
||||
case t of
|
||||
OBJT_DEFAULT:
|
||||
begin
|
||||
Result^.flags:=OBJ_ONEMAPPING;
|
||||
end;
|
||||
OBJT_VNODE:
|
||||
begin
|
||||
vm_file_map_init(@Result^.un_pager.vnp.file_map,0,VM_MAXUSER_ADDRESS);
|
||||
end;
|
||||
else;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
procedure vm_object_destroy(obj:vm_object_t);
|
||||
begin
|
||||
mtx_destroy(obj^.mtx);
|
||||
|
||||
if (obj^.otype=OBJT_VNODE) then
|
||||
begin
|
||||
vm_file_map_free(@obj^.un_pager.vnp.file_map);
|
||||
end;
|
||||
|
||||
FreeMem(obj);
|
||||
end;
|
||||
|
||||
|
@ -216,7 +234,7 @@ begin
|
|||
if (obj=nil) then Exit;
|
||||
|
||||
VM_OBJECT_LOCK_ASSERT(obj);
|
||||
obj^.paging_in_progress:=obj^.paging_in_progress+i;
|
||||
obj^.pip:=obj^.pip+i;
|
||||
end;
|
||||
|
||||
procedure vm_object_pip_subtract(obj:vm_object_t;i:word);
|
||||
|
@ -224,7 +242,7 @@ begin
|
|||
if (obj=nil) then Exit;
|
||||
|
||||
VM_OBJECT_LOCK_ASSERT(obj);
|
||||
obj^.paging_in_progress:=obj^.paging_in_progress-i;
|
||||
obj^.pip:=obj^.pip-i;
|
||||
end;
|
||||
|
||||
function vm_object_type(obj:vm_object_t):obj_type;
|
||||
|
|
|
@ -0,0 +1,444 @@
|
|||
unit vm_file;
|
||||
|
||||
{$mode ObjFPC}{$H+}
|
||||
{$CALLING SysV_ABI_CDecl}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
vm,
|
||||
vmparam;
|
||||
|
||||
type
|
||||
t_uncb=function(base:Pointer;size:QWORD):Integer;
|
||||
|
||||
p_vm_file_obj=^vm_file_obj;
|
||||
vm_file_obj=packed record
|
||||
base:Pointer;
|
||||
size:QWORD;
|
||||
refs:QWORD;
|
||||
uncb:t_uncb;
|
||||
end;
|
||||
|
||||
pp_vm_file_entry=^p_vm_file_entry;
|
||||
p_vm_file_entry=^vm_file_entry;
|
||||
vm_file_entry=packed record
|
||||
prev :p_vm_file_entry;
|
||||
next :p_vm_file_entry;
|
||||
left :p_vm_file_entry;
|
||||
right :p_vm_file_entry;
|
||||
start :QWORD;
|
||||
__end :QWORD;
|
||||
offset:QWORD;
|
||||
obj :p_vm_file_obj;
|
||||
end;
|
||||
|
||||
p_vm_file_map=^vm_file_map;
|
||||
vm_file_map=packed object
|
||||
header :vm_file_entry;
|
||||
root :p_vm_file_entry;
|
||||
nentries:DWORD;
|
||||
pages :DWORD;
|
||||
property min_offset:QWORD read header.start write header.start;
|
||||
property max_offset:QWORD read header.__end write header.__end;
|
||||
end;
|
||||
|
||||
function vm_file_obj_allocate (base:Pointer;size:QWORD;uncb:t_uncb):p_vm_file_obj;
|
||||
procedure vm_file_obj_destroy (obj:p_vm_file_obj);
|
||||
procedure vm_file_obj_reference (obj:p_vm_file_obj);
|
||||
procedure vm_file_obj_deallocate(obj:p_vm_file_obj);
|
||||
|
||||
procedure vm_file_map_init(map:p_vm_file_map;min,max:QWORD);
|
||||
procedure vm_file_map_free(map:p_vm_file_map);
|
||||
|
||||
function vm_file_map_lookup_entry(
|
||||
map :p_vm_file_map;
|
||||
address:QWORD;
|
||||
entry :pp_vm_file_entry):Boolean;
|
||||
|
||||
function vm_file_map_insert(
|
||||
map :p_vm_file_map;
|
||||
obj :p_vm_file_obj;
|
||||
offset:QWORD;
|
||||
start :QWORD;
|
||||
__end :QWORD):Integer;
|
||||
|
||||
function vm_file_map_delete(map:p_vm_file_map;
|
||||
start:QWORD;
|
||||
__end:QWORD):Integer;
|
||||
|
||||
implementation
|
||||
|
||||
function OFF_TO_IDX(x:QWORD):DWORD; inline;
|
||||
begin
|
||||
Result:=QWORD(x) shr PAGE_SHIFT;
|
||||
end;
|
||||
|
||||
function vm_file_obj_allocate(base:Pointer;size:QWORD;uncb:t_uncb):p_vm_file_obj;
|
||||
begin
|
||||
Result:=AllocMem(SizeOf(vm_file_obj));
|
||||
|
||||
Result^.base:=base;
|
||||
Result^.size:=size;
|
||||
Result^.refs:=1;
|
||||
Result^.uncb:=uncb;
|
||||
end;
|
||||
|
||||
procedure vm_file_obj_destroy(obj:p_vm_file_obj);
|
||||
begin
|
||||
if (obj^.uncb<>nil) then
|
||||
begin
|
||||
obj^.uncb(obj^.base,obj^.size);
|
||||
end;
|
||||
|
||||
FreeMem(obj);
|
||||
end;
|
||||
|
||||
procedure vm_file_obj_reference(obj:p_vm_file_obj);
|
||||
begin
|
||||
if (obj=nil) then Exit;
|
||||
|
||||
System.InterlockedIncrement64(obj^.refs);
|
||||
end;
|
||||
|
||||
procedure vm_file_obj_deallocate(obj:p_vm_file_obj);
|
||||
begin
|
||||
if (obj=nil) then Exit;
|
||||
|
||||
if (System.InterlockedDecrement64(obj^.refs)=0) then
|
||||
begin
|
||||
vm_file_obj_destroy(obj);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure vm_file_map_init(map:p_vm_file_map;min,max:QWORD);
|
||||
begin
|
||||
map^.header.next:=@map^.header;
|
||||
map^.header.prev:=@map^.header;
|
||||
map^.min_offset :=min;
|
||||
map^.max_offset :=max;
|
||||
map^.root :=nil;
|
||||
map^.nentries :=0;
|
||||
map^.pages :=0;
|
||||
end;
|
||||
|
||||
procedure vm_file_map_free(map:p_vm_file_map);
|
||||
begin
|
||||
vm_file_map_delete(map,map^.min_offset,map^.max_offset);
|
||||
end;
|
||||
|
||||
procedure vm_file_entry_dispose(map:p_vm_file_map;entry:p_vm_file_entry); inline;
|
||||
begin
|
||||
vm_file_obj_deallocate(entry^.obj);
|
||||
FreeMem(entry);
|
||||
end;
|
||||
|
||||
function vm_file_entry_create(map:p_vm_file_map):p_vm_file_entry;
|
||||
var
|
||||
new_entry:p_vm_file_entry;
|
||||
begin
|
||||
new_entry:=AllocMem(SizeOf(vm_file_entry));
|
||||
Assert((new_entry<>nil),'vm_file_entry_create: kernel resources exhausted');
|
||||
Result:=new_entry;
|
||||
end;
|
||||
|
||||
function vm_file_entry_splay(addr:QWORD;root:p_vm_file_entry):p_vm_file_entry;
|
||||
var
|
||||
llist,rlist:p_vm_file_entry;
|
||||
ltree,rtree:p_vm_file_entry;
|
||||
y :p_vm_file_entry;
|
||||
begin
|
||||
if (root=nil) then Exit(root);
|
||||
|
||||
llist:=nil;
|
||||
rlist:=nil;
|
||||
repeat
|
||||
if (addr<root^.start) then
|
||||
begin
|
||||
y:=root^.left;
|
||||
if (y=nil) then break;
|
||||
if (addr<y^.start) and (y^.left<>nil) then
|
||||
begin
|
||||
root^.left:=y^.right;
|
||||
y^.right:=root;
|
||||
root:=y^.left;
|
||||
y^.left:=rlist;
|
||||
rlist:=y;
|
||||
end else
|
||||
begin
|
||||
root^.left:=rlist;
|
||||
rlist:=root;
|
||||
root:=y;
|
||||
end;
|
||||
end else
|
||||
if (addr>=root^.__end) then
|
||||
begin
|
||||
y:=root^.right;
|
||||
if (y=nil) then break;
|
||||
if (addr>=y^.__end) and (y^.right<>nil) then
|
||||
begin
|
||||
root^.right:=y^.left;
|
||||
y^.left:=root;
|
||||
root:=y^.right;
|
||||
y^.right:=llist;
|
||||
llist:=y;
|
||||
end else
|
||||
begin
|
||||
root^.right:=llist;
|
||||
llist:=root;
|
||||
root:=y;
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
break;
|
||||
end;
|
||||
until false;
|
||||
|
||||
ltree:=root^.left;
|
||||
while (llist<>nil) do
|
||||
begin
|
||||
y:=llist^.right;
|
||||
llist^.right:=ltree;
|
||||
ltree:=llist;
|
||||
llist:=y;
|
||||
end;
|
||||
|
||||
rtree:=root^.right;
|
||||
while (rlist<>nil) do
|
||||
begin
|
||||
y:=rlist^.left;
|
||||
rlist^.left:=rtree;
|
||||
rtree:=rlist;
|
||||
rlist:=y;
|
||||
end;
|
||||
|
||||
root^.left:=ltree;
|
||||
root^.right:=rtree;
|
||||
|
||||
Result:=(root);
|
||||
end;
|
||||
|
||||
procedure vm_file_map_entry_link(
|
||||
map :p_vm_file_map;
|
||||
after_where:p_vm_file_entry;
|
||||
entry :p_vm_file_entry);
|
||||
begin
|
||||
Inc(map^.nentries);
|
||||
|
||||
entry^.prev:=after_where;
|
||||
entry^.next:=after_where^.next;
|
||||
entry^.next^.prev:=entry;
|
||||
after_where^.next:=entry;
|
||||
|
||||
if (after_where<>@map^.header) then
|
||||
begin
|
||||
if (after_where<>map^.root) then
|
||||
begin
|
||||
vm_file_entry_splay(after_where^.start, map^.root);
|
||||
end;
|
||||
entry^.right:=after_where^.right;
|
||||
entry^.left:=after_where;
|
||||
after_where^.right:=nil;
|
||||
end else
|
||||
begin
|
||||
entry^.right:=map^.root;
|
||||
entry^.left:=nil;
|
||||
end;
|
||||
map^.root:=entry;
|
||||
end;
|
||||
|
||||
procedure vm_file_map_entry_unlink(
|
||||
map :p_vm_file_map;
|
||||
entry:p_vm_file_entry);
|
||||
var
|
||||
next,prev,root:p_vm_file_entry;
|
||||
begin
|
||||
if (entry<>map^.root) then
|
||||
begin
|
||||
vm_file_entry_splay(entry^.start, map^.root);
|
||||
end;
|
||||
if (entry^.left=nil) then
|
||||
begin
|
||||
root:=entry^.right;
|
||||
end else
|
||||
begin
|
||||
root:=vm_file_entry_splay(entry^.start, entry^.left);
|
||||
root^.right:=entry^.right;
|
||||
end;
|
||||
map^.root:=root;
|
||||
|
||||
prev:=entry^.prev;
|
||||
next:=entry^.next;
|
||||
next^.prev:=prev;
|
||||
prev^.next:=next;
|
||||
Dec(map^.nentries);
|
||||
end;
|
||||
|
||||
function vm_file_map_lookup_entry(
|
||||
map :p_vm_file_map;
|
||||
address:QWORD;
|
||||
entry :pp_vm_file_entry):Boolean;
|
||||
var
|
||||
cur:p_vm_file_entry;
|
||||
begin
|
||||
cur:=map^.root;
|
||||
if (cur=nil) then
|
||||
begin
|
||||
entry^:=@map^.header;
|
||||
end else
|
||||
if (address>=cur^.start) and (cur^.__end>address) then
|
||||
begin
|
||||
entry^:=cur;
|
||||
Exit(TRUE);
|
||||
end else
|
||||
begin
|
||||
cur:=vm_file_entry_splay(address,cur);
|
||||
map^.root:=cur;
|
||||
|
||||
if (address>=cur^.start) then
|
||||
begin
|
||||
entry^:=cur;
|
||||
if (cur^.__end>address) then
|
||||
begin
|
||||
Exit(TRUE);
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
entry^:=cur^.prev;
|
||||
end;
|
||||
end;
|
||||
Result:=(FALSE);
|
||||
end;
|
||||
|
||||
function vm_file_map_insert(
|
||||
map :p_vm_file_map;
|
||||
obj :p_vm_file_obj;
|
||||
offset:QWORD;
|
||||
start :QWORD;
|
||||
__end :QWORD):Integer;
|
||||
var
|
||||
new_entry :p_vm_file_entry;
|
||||
prev_entry:p_vm_file_entry;
|
||||
temp_entry:p_vm_file_entry;
|
||||
begin
|
||||
if (start>=__end) then
|
||||
begin
|
||||
Exit(KERN_INVALID_ADDRESS);
|
||||
end;
|
||||
|
||||
if vm_file_map_lookup_entry(map,start,@temp_entry) then
|
||||
begin
|
||||
Exit(KERN_NO_SPACE);
|
||||
end;
|
||||
|
||||
prev_entry:=temp_entry;
|
||||
|
||||
if (prev_entry^.next<>@map^.header) and
|
||||
(prev_entry^.next^.start<__end) then
|
||||
begin
|
||||
Exit(KERN_NO_SPACE);
|
||||
end;
|
||||
|
||||
new_entry:=vm_file_entry_create(map);
|
||||
new_entry^.start:=start;
|
||||
new_entry^.__end:=__end;
|
||||
|
||||
new_entry^.offset:=offset;
|
||||
new_entry^.obj :=obj;
|
||||
|
||||
vm_file_map_entry_link(map, prev_entry, new_entry);
|
||||
map^.pages:=map^.pages+OFF_TO_IDX(new_entry^.__end - new_entry^.start);
|
||||
end;
|
||||
|
||||
procedure vm_file_map_entry_delete(map:p_vm_file_map;entry:p_vm_file_entry);
|
||||
begin
|
||||
vm_file_map_entry_unlink(map, entry);
|
||||
|
||||
map^.pages:=map^.pages-OFF_TO_IDX(entry^.__end - entry^.start);
|
||||
|
||||
vm_file_entry_dispose(map,entry);
|
||||
end;
|
||||
|
||||
procedure _vm_map_clip_start(map:p_vm_file_map;entry:p_vm_file_entry;start:QWORD);
|
||||
var
|
||||
new_entry:p_vm_file_entry;
|
||||
begin
|
||||
new_entry:=vm_file_entry_create(map);
|
||||
new_entry^:=entry^;
|
||||
|
||||
new_entry^.__end:=start;
|
||||
entry^.offset:=entry^.offset + (start - entry^.start);
|
||||
entry^.start:=start;
|
||||
|
||||
vm_file_map_entry_link(map, entry^.prev, new_entry);
|
||||
|
||||
vm_file_obj_reference(new_entry^.obj);
|
||||
end;
|
||||
|
||||
procedure vm_map_clip_start(map:p_vm_file_map;entry:p_vm_file_entry;start:QWORD);
|
||||
begin
|
||||
if (start>entry^.start) then
|
||||
begin
|
||||
_vm_map_clip_start(map,entry,start);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure _vm_map_clip_end(map:p_vm_file_map;entry:p_vm_file_entry;__end:QWORD);
|
||||
var
|
||||
new_entry:p_vm_file_entry;
|
||||
begin
|
||||
new_entry:=vm_file_entry_create(map);
|
||||
new_entry^:=entry^;
|
||||
|
||||
new_entry^.start:=__end;
|
||||
entry^.__end:=__end;
|
||||
new_entry^.offset:=new_entry^.offset + (__end - entry^.start);
|
||||
|
||||
vm_file_map_entry_link(map, entry, new_entry);
|
||||
|
||||
vm_file_obj_reference(new_entry^.obj);
|
||||
end;
|
||||
|
||||
procedure vm_map_clip_end(map:p_vm_file_map;entry:p_vm_file_entry;__end:QWORD);
|
||||
begin
|
||||
if (__end<entry^.__end) then
|
||||
begin
|
||||
_vm_map_clip_end(map,entry,__end);
|
||||
end;
|
||||
end;
|
||||
|
||||
function vm_file_map_delete(map:p_vm_file_map;
|
||||
start:QWORD;
|
||||
__end:QWORD):Integer;
|
||||
var
|
||||
entry :p_vm_file_entry;
|
||||
first_entry:p_vm_file_entry;
|
||||
next :p_vm_file_entry;
|
||||
begin
|
||||
if (start=__end) then
|
||||
begin
|
||||
Exit(KERN_SUCCESS);
|
||||
end;
|
||||
|
||||
if (not vm_file_map_lookup_entry(map, start, @first_entry)) then
|
||||
begin
|
||||
entry:=first_entry^.next;
|
||||
end else
|
||||
begin
|
||||
entry:=first_entry;
|
||||
|
||||
vm_map_clip_start(map, entry, start);
|
||||
end;
|
||||
|
||||
while (entry<>@map^.header) and (entry^.start<__end) do
|
||||
begin
|
||||
vm_map_clip_end(map, entry, __end);
|
||||
next:=entry^.next;
|
||||
vm_file_map_entry_delete(map, entry);
|
||||
entry:=next;
|
||||
end;
|
||||
Result:=(KERN_SUCCESS);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
@ -1136,8 +1136,6 @@ charged:
|
|||
new_entry^.entry_id:=map^.entry_id;
|
||||
Inc(map^.entry_id);
|
||||
|
||||
vm_object_reference(obj);
|
||||
|
||||
Assert(not ENTRY_CHARGED(new_entry),'OVERCOMMIT: vm_map_insert leaks vm_map %p", new_entry');
|
||||
|
||||
{
|
||||
|
@ -2070,7 +2068,7 @@ var
|
|||
current:vm_map_entry_t;
|
||||
entry :vm_map_entry_t;
|
||||
size :vm_size_t;
|
||||
vm_obj :vm_object_t;
|
||||
obj :vm_object_t;
|
||||
offset :vm_ooffset_t;
|
||||
last_timestamp:DWORD;
|
||||
failed:Boolean;
|
||||
|
@ -2145,21 +2143,21 @@ begin
|
|||
begin
|
||||
size:=tsize;
|
||||
end;
|
||||
vm_obj:=tentry^.vm_obj;
|
||||
obj:=tentry^.vm_obj;
|
||||
offset:=tentry^.offset + (offset - tentry^.start);
|
||||
vm_map_unlock(smap);
|
||||
end else
|
||||
begin
|
||||
vm_obj:=current^.vm_obj;
|
||||
obj:=current^.vm_obj;
|
||||
end;
|
||||
|
||||
vm_object_reference(vm_obj);
|
||||
vm_object_reference(obj);
|
||||
last_timestamp:=map^.timestamp;
|
||||
vm_map_unlock(map);
|
||||
//if (not vm_object_sync(_object, offset, size, syncio, invalidate)) then
|
||||
// failed:=TRUE;
|
||||
start:=start+size;
|
||||
vm_object_deallocate(vm_obj);
|
||||
vm_object_deallocate(obj);
|
||||
vm_map_lock(map);
|
||||
if (last_timestamp=map^.timestamp) or
|
||||
(not vm_map_lookup_entry(map, start, @current)) then
|
||||
|
|
|
@ -511,7 +511,7 @@ begin
|
|||
|
||||
if (rv=KERN_SUCCESS) then
|
||||
begin
|
||||
//
|
||||
//vm_map_wire
|
||||
end else
|
||||
begin
|
||||
if (writecounted) then
|
||||
|
@ -521,6 +521,7 @@ begin
|
|||
|
||||
vm_object_deallocate(obj);
|
||||
end;
|
||||
|
||||
Exit(vm_mmap_to_errno(rv));
|
||||
end;
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ begin
|
|||
}
|
||||
vm_object_pip_wait(obj, 'objtrm');
|
||||
|
||||
Assert(obj^.paging_in_progress=0,'vm_object_terminate: pageout in progress');
|
||||
Assert(obj^.pip=0,'vm_object_terminate: pageout in progress');
|
||||
|
||||
vm_object_patch_remove(obj,0,0);
|
||||
|
||||
|
@ -235,8 +235,8 @@ begin
|
|||
if (obj=nil) then Exit;
|
||||
|
||||
VM_OBJECT_LOCK_ASSERT(obj);
|
||||
Dec(obj^.paging_in_progress);
|
||||
if ((obj^.flags and OBJ_PIPWNT)<>0) and (obj^.paging_in_progress=0) then
|
||||
Dec(obj^.pip);
|
||||
if ((obj^.flags and OBJ_PIPWNT)<>0) and (obj^.pip=0) then
|
||||
begin
|
||||
vm_object_clear_flag(obj, OBJ_PIPWNT);
|
||||
wakeup(obj);
|
||||
|
@ -248,8 +248,8 @@ begin
|
|||
if (obj=nil) then Exit;
|
||||
|
||||
VM_OBJECT_LOCK_ASSERT(obj);
|
||||
Dec(obj^.paging_in_progress,i);
|
||||
if ((obj^.flags and OBJ_PIPWNT)<>0) and (obj^.paging_in_progress=0) then
|
||||
Dec(obj^.pip,i);
|
||||
if ((obj^.flags and OBJ_PIPWNT)<>0) and (obj^.pip=0) then
|
||||
begin
|
||||
vm_object_clear_flag(obj, OBJ_PIPWNT);
|
||||
wakeup(obj);
|
||||
|
@ -261,7 +261,7 @@ begin
|
|||
if (obj=nil) then Exit;
|
||||
|
||||
VM_OBJECT_LOCK_ASSERT(obj);
|
||||
while (obj^.paging_in_progress<>0) do
|
||||
while (obj^.pip<>0) do
|
||||
begin
|
||||
obj^.flags:=obj^.flags or OBJ_PIPWNT;
|
||||
msleep(obj, VM_OBJECT_MTX(obj), PVM, waitid, 0);
|
||||
|
|
|
@ -187,11 +187,11 @@ begin
|
|||
* Dereference the reference we just created. This assumes
|
||||
* that the obj is associated with the vp.
|
||||
}
|
||||
//VM_OBJECT_LOCK(obj);
|
||||
// Dec(obj^.ref_count);
|
||||
//VM_OBJECT_UNLOCK(obj);
|
||||
VM_OBJECT_LOCK(obj);
|
||||
Dec(obj^.ref_count);
|
||||
VM_OBJECT_UNLOCK(obj);
|
||||
|
||||
//vrele(vp);
|
||||
vrele(vp);
|
||||
|
||||
Assert(vp^.v_object<>nil, 'vnode_create_vobject: nil obj');
|
||||
|
||||
|
|
Loading…
Reference in New Issue