kernel/arm/pmap.c
/*
 * Unmaps a segment from the address space pointed to by pmap.
 */
Unmaps a segment from the address space pointed to by pmap.
Unmaps a segment from the address space pointed to by pmap .
int PmapRemove(struct AddressSpace *as, vm_addr va) {
  struct Pmap *pmap;
  uint32_t *pt, *phys_pt;
  int pde_idx, pte_idx;
  vm_addr current_paddr;
  struct Pageframe *pf;
  struct Pageframe *ptpf;
  struct PmapVPTE *vpte;
  struct PmapVPTE *vpte_base;
  if (va == 0) {
    return -EFAULT;
  }
  pmap = &as->pmap;
  pde_idx = (va & L1_ADDR_BITS) >> L1_IDX_SHIFT;
  if ((pmap->l1_table[pde_idx] & L1_TYPE_MASK) == L1_TYPE_INV) {
    return -EINVAL;
  }
  phys_pt = (uint32_t *)(pmap->l1_table[pde_idx] & L1_C_ADDR_MASK);
  pt = (uint32_t *)PmapPaToVa((vm_addr)phys_pt);
  pte_idx = (va & L2_ADDR_BITS) >> L2_IDX_SHIFT;
  current_paddr = pt[pte_idx] & L2_ADDR_MASK;
  vpte_base = (struct PmapVPTE *)((uint8_t *)pt + VPTE_TABLE_OFFS);
  vpte = vpte_base + pte_idx;
  if ((pt[pte_idx] & L2_TYPE_MASK) == L2_TYPE_INV) {
    return -EINVAL;
  }
  if ((vpte->flags & VPTE_PHYS) == 0) {
    pf = PmapPaToPf(current_paddr);
    LIST_REM_ENTRY(&pf->pmap_pageframe.vpte_list, vpte, link);
  }
  vpte->flags = 0;
  pt[pte_idx] = L2_TYPE_INV;
  ptpf = PmapVaToPf((vm_addr)pt);
  ptpf->reference_cnt--;
  if (ptpf->reference_cnt == 0) {
    PmapFreePageTable(pt);
    pmap->l1_table[pde_idx] = L1_TYPE_INV;
  }
  return 0;
}
int PmapRemove ( struct AddressSpace * as , vm_addr va ) { struct Pmap * pmap ; uint32_t * pt , * phys_pt ; int pde_idx , pte_idx ; vm_addr current_paddr ; struct Pageframe * pf ; struct Pageframe * ptpf ; struct PmapVPTE * vpte ; struct PmapVPTE * vpte_base ; if ( va == 0 ) { return - EFAULT ; } pmap = & as -> pmap ; pde_idx = ( va & L1_ADDR_BITS ) >> L1_IDX_SHIFT ; if ( ( pmap -> l1_table [ pde_idx ] & L1_TYPE_MASK ) == L1_TYPE_INV ) { return - EINVAL ; } phys_pt = ( uint32_t * ) ( pmap -> l1_table [ pde_idx ] & L1_C_ADDR_MASK ) ; pt = ( uint32_t * ) PmapPaToVa ( ( vm_addr ) phys_pt ) ; pte_idx = ( va & L2_ADDR_BITS ) >> L2_IDX_SHIFT ; current_paddr = pt [ pte_idx ] & L2_ADDR_MASK ; vpte_base = ( struct PmapVPTE * ) ( ( uint8_t * ) pt + VPTE_TABLE_OFFS ) ; vpte = vpte_base + pte_idx ; if ( ( pt [ pte_idx ] & L2_TYPE_MASK ) == L2_TYPE_INV ) { return - EINVAL ; } if ( ( vpte -> flags & VPTE_PHYS ) == 0 ) { pf = PmapPaToPf ( current_paddr ) ; LIST_REM_ENTRY ( & pf -> pmap_pageframe . vpte_list , vpte , link ) ; } vpte -> flags = 0 ; pt [ pte_idx ] = L2_TYPE_INV ; ptpf = PmapVaToPf ( ( vm_addr ) pt ) ; ptpf -> reference_cnt -- ; if ( ptpf -> reference_cnt == 0 ) { PmapFreePageTable ( pt ) ; pmap -> l1_table [ pde_idx ] = L1_TYPE_INV ; } return 0 ; }
Unmaps a segment from the address space pointed to by pmap.
Unmaps a segment from the address space pointed to by pmap .
// TODO : Check user base user ceiling // Unmap any existing mapping, then map either anon or phys mem