/*===========================================================================* * pt_bind * *===========================================================================*/ PUBLIC int pt_bind(pt_t *pt, struct vmproc *who) { int slot, ispt; u32_t phys; void *pdes; /* Basic sanity checks. */ assert(who); assert(who->vm_flags & VMF_INUSE); assert(pt); assert(pagedir_pde >= 0); slot = who->vm_slot; assert(slot >= 0); assert(slot < ELEMENTS(vmproc)); assert(slot < I386_VM_PT_ENTRIES); phys = pt->pt_dir_phys & I386_VM_ADDR_MASK; assert(pt->pt_dir_phys == phys); /* Update "page directory pagetable." */ page_directories[slot] = phys | I386_VM_PRESENT|I386_VM_WRITE; /* This is where the PDE's will be visible to the kernel * in its address space. */ pdes = (void *) arch_map2vir(&vmproc[VMP_SYSTEM], pagedir_pde*I386_BIG_PAGE_SIZE + slot * I386_PAGE_SIZE); #if 0 printf("VM: slot %d endpoint %d has pde val 0x%lx at kernel address 0x%lx\n", slot, who->vm_endpoint, page_directories[slot], pdes); #endif /* Tell kernel about new page table root. */ return sys_vmctl_set_addrspace(who->vm_endpoint, pt ? pt->pt_dir_phys : 0, pt ? pdes : 0); }
/*===========================================================================* * pt_bind * *===========================================================================*/ int pt_bind(pt_t *pt, struct vmproc *who) { int procslot, pdeslot; u32_t phys; void *pdes; int pagedir_pde; int slots_per_pde; int pages_per_pagedir = ARCH_PAGEDIR_SIZE/VM_PAGE_SIZE; struct pdm *pdm; slots_per_pde = ARCH_VM_PT_ENTRIES / pages_per_pagedir; /* Basic sanity checks. */ assert(who); assert(who->vm_flags & VMF_INUSE); assert(pt); procslot = who->vm_slot; pdm = &pagedir_mappings[procslot/slots_per_pde]; pdeslot = procslot%slots_per_pde; pagedir_pde = pdm->pdeno; assert(pdeslot >= 0); assert(procslot < ELEMENTS(vmproc)); assert(pdeslot < ARCH_VM_PT_ENTRIES / pages_per_pagedir); assert(pagedir_pde >= 0); #if defined(__i386__) phys = pt->pt_dir_phys & ARCH_VM_ADDR_MASK; #elif defined(__arm__) phys = pt->pt_dir_phys & ARM_VM_PTE_MASK; #endif assert(pt->pt_dir_phys == phys); assert(!(pt->pt_dir_phys % ARCH_PAGEDIR_SIZE)); /* Update "page directory pagetable." */ #if defined(__i386__) pdm->page_directories[pdeslot] = phys | ARCH_VM_PDE_PRESENT|ARCH_VM_PTE_RW; #elif defined(__arm__) { int i; for (i = 0; i < pages_per_pagedir; i++) { pdm->page_directories[pdeslot*pages_per_pagedir+i] = (phys+i*VM_PAGE_SIZE) | ARCH_VM_PTE_PRESENT | ARCH_VM_PTE_RW | ARCH_VM_PTE_USER; //LSC FIXME } } #endif /* This is where the PDE's will be visible to the kernel * in its address space. */ pdes = (void *) (pagedir_pde*ARCH_BIG_PAGE_SIZE + #if defined(__i386__) pdeslot * VM_PAGE_SIZE); #elif defined(__arm__) pdeslot * ARCH_PAGEDIR_SIZE); #endif #if 0 printf("VM: slot %d endpoint %d has pde val 0x%lx at kernel address 0x%lx\n", slot, who->vm_endpoint, page_directories[slot], pdes); #endif /* Tell kernel about new page table root. */ return sys_vmctl_set_addrspace(who->vm_endpoint, pt->pt_dir_phys, pdes); }