kernel/arm/pmap.c
/*
 * 4k page tables,  1k real PTEs,  3k virtual-page linked list and flags (packed
 * 12 bytes)
 */
4k page tables,  1k real PTEs,  3k virtual-page linked list and flags (packed
12 bytes)
4k page tables 1k real PTEs 3k virtual - page linked list and flags ( packed 12 bytes )
int PmapEnter(struct AddressSpace *as, vm_addr addr, vm_addr paddr,
              bits32_t flags) {
  struct Pmap *pmap;
  uint32_t *pt, *phys_pt;
  int pde_idx, pte_idx;
  uint32_t pa_bits;
  struct Pageframe *pf;
  struct Pageframe *ptpf;
  struct PmapVPTE *vpte;
  struct PmapVPTE *vpte_base;
  if (addr == 0) {
    return -EFAULT;
  }
  pa_bits = PmapCalcPABits(flags);
  pmap = &as->pmap;
  pde_idx = (addr & L1_ADDR_BITS) >> L1_IDX_SHIFT;
  if ((pmap->l1_table[pde_idx] & L1_TYPE_MASK) == L1_TYPE_INV) {
    if ((pt = PmapAllocPageTable()) == NULL) {
      return -ENOMEM;
    }
    phys_pt = (uint32_t *)PmapVaToPa((vm_addr)pt);
    pmap->l1_table[pde_idx] = (uint32_t)phys_pt | L1_TYPE_C;
  } else {
    phys_pt = (uint32_t *)(pmap->l1_table[pde_idx] & L1_C_ADDR_MASK);
    pt = (uint32_t *)PmapPaToVa((vm_addr)phys_pt);
  }
  pte_idx = (addr & L2_ADDR_BITS) >> L2_IDX_SHIFT;
  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) {
    PmapFreePageTable(pt);
    pmap->l1_table[pde_idx] = L1_TYPE_INV;
    return -EINVAL;
  }
  if ((flags & MEM_MASK) != MEM_PHYS) {
    pf = &pageframe_table[paddr / PAGE_SIZE];
    vpte->flags = flags;
    LIST_ADD_HEAD(&pf->pmap_pageframe.vpte_list, vpte, link);
    pt[pte_idx] = paddr | pa_bits;
  } else {
    vpte->flags = flags;
    pt[pte_idx] = paddr | pa_bits;
  }
  ptpf = PmapVaToPf((vm_addr)pt);
  ptpf->reference_cnt++;
  return 0;
}
int PmapEnter ( struct AddressSpace * as , vm_addr addr , vm_addr paddr , bits32_t flags ) { struct Pmap * pmap ; uint32_t * pt , * phys_pt ; int pde_idx , pte_idx ; uint32_t pa_bits ; struct Pageframe * pf ; struct Pageframe * ptpf ; struct PmapVPTE * vpte ; struct PmapVPTE * vpte_base ; if ( addr == 0 ) { return - EFAULT ; } pa_bits = PmapCalcPABits ( flags ) ; pmap = & as -> pmap ; pde_idx = ( addr & L1_ADDR_BITS ) >> L1_IDX_SHIFT ; if ( ( pmap -> l1_table [ pde_idx ] & L1_TYPE_MASK ) == L1_TYPE_INV ) { if ( ( pt = PmapAllocPageTable ( ) ) == NULL ) { return - ENOMEM ; } phys_pt = ( uint32_t * ) PmapVaToPa ( ( vm_addr ) pt ) ; pmap -> l1_table [ pde_idx ] = ( uint32_t ) phys_pt | L1_TYPE_C ; } else { phys_pt = ( uint32_t * ) ( pmap -> l1_table [ pde_idx ] & L1_C_ADDR_MASK ) ; pt = ( uint32_t * ) PmapPaToVa ( ( vm_addr ) phys_pt ) ; } pte_idx = ( addr & L2_ADDR_BITS ) >> L2_IDX_SHIFT ; 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 ) { PmapFreePageTable ( pt ) ; pmap -> l1_table [ pde_idx ] = L1_TYPE_INV ; return - EINVAL ; } if ( ( flags & MEM_MASK ) != MEM_PHYS ) { pf = & pageframe_table [ paddr / PAGE_SIZE ] ; vpte -> flags = flags ; LIST_ADD_HEAD ( & pf -> pmap_pageframe . vpte_list , vpte , link ) ; pt [ pte_idx ] = paddr | pa_bits ; } else { vpte -> flags = flags ; pt [ pte_idx ] = paddr | pa_bits ; } ptpf = PmapVaToPf ( ( vm_addr ) pt ) ; ptpf -> reference_cnt ++ ; return 0 ; }
4k page tables,  1k real PTEs,  3k virtual-page linked list and flags (packed
 12 bytes)
4k page tables 1k real PTEs 3k virtual - page linked list and flags ( packed 12 bytes )