#ifndef _MACHINE_PMAP_VAR_H_
#define _MACHINE_PMAP_VAR_H_
#include <machine/pte.h>
#define NPG_IN_PT1 (NB_IN_PT1 / PAGE_SIZE)
#define NPT2_IN_PG (PAGE_SIZE / NB_IN_PT2)
#define NPTE2_IN_PG (NPT2_IN_PG * NPTE2_IN_PT2)
#ifdef _KERNEL
#define PT2PG_SHIFT 2
#define PT2PG_MASK ((1 << PT2PG_SHIFT) - 1)
#define PT2TAB_ENTRIES (NPTE1_IN_PT1 / NPT2_IN_PG)
#define PT2TAB_SHIFT (PTE1_SHIFT + PT2PG_SHIFT)
#define PT2MAP_SIZE (NPTE1_IN_PT1 * NB_IN_PT2)
#define PT2MAP_SHIFT PTE2_SHIFT
extern pt1_entry_t *kern_pt1;
extern pt2_entry_t *kern_pt2tab;
extern pt2_entry_t *PT2MAP;
static __inline u_int
pte1_index(vm_offset_t va)
{
return (va >> PTE1_SHIFT);
}
static __inline pt1_entry_t *
pte1_ptr(pt1_entry_t *pt1, vm_offset_t va)
{
return (pt1 + pte1_index(va));
}
static __inline vm_offset_t
pte1_trunc(vm_offset_t va)
{
return (va & PTE1_FRAME);
}
static __inline vm_offset_t
pte1_roundup(vm_offset_t va)
{
return ((va + PTE1_OFFSET) & PTE1_FRAME);
}
static __inline void
pte1_sync(pt1_entry_t *pte1p)
{
dsb();
#ifndef PMAP_PTE_NOCACHE
if (!cpuinfo.coherent_walk)
dcache_wb_pou((vm_offset_t)pte1p, sizeof(*pte1p));
#endif
}
static __inline void
pte1_sync_range(pt1_entry_t *pte1p, vm_size_t size)
{
dsb();
#ifndef PMAP_PTE_NOCACHE
if (!cpuinfo.coherent_walk)
dcache_wb_pou((vm_offset_t)pte1p, size);
#endif
}
static __inline void
pte1_store(pt1_entry_t *pte1p, pt1_entry_t pte1)
{
dmb();
*pte1p = pte1;
pte1_sync(pte1p);
}
static __inline void
pte1_clear(pt1_entry_t *pte1p)
{
pte1_store(pte1p, 0);
}
static __inline void
pte1_clear_bit(pt1_entry_t *pte1p, uint32_t bit)
{
*pte1p &= ~bit;
pte1_sync(pte1p);
}
static __inline bool
pte1_is_link(pt1_entry_t pte1)
{
return ((pte1 & L1_TYPE_MASK) == L1_TYPE_C);
}
static __inline int
pte1_is_section(pt1_entry_t pte1)
{
return ((pte1 & L1_TYPE_MASK) == L1_TYPE_S);
}
static __inline bool
pte1_is_dirty(pt1_entry_t pte1)
{
return ((pte1 & (PTE1_NM | PTE1_RO)) == 0);
}
static __inline bool
pte1_is_global(pt1_entry_t pte1)
{
return ((pte1 & PTE1_NG) == 0);
}
static __inline bool
pte1_is_valid(pt1_entry_t pte1)
{
int l1_type;
l1_type = pte1 & L1_TYPE_MASK;
return ((l1_type == L1_TYPE_C) || (l1_type == L1_TYPE_S));
}
static __inline bool
pte1_is_wired(pt1_entry_t pte1)
{
return (pte1 & PTE1_W);
}
static __inline pt1_entry_t
pte1_load(pt1_entry_t *pte1p)
{
pt1_entry_t pte1;
pte1 = *pte1p;
return (pte1);
}
static __inline pt1_entry_t
pte1_load_clear(pt1_entry_t *pte1p)
{
pt1_entry_t opte1;
opte1 = *pte1p;
*pte1p = 0;
pte1_sync(pte1p);
return (opte1);
}
static __inline void
pte1_set_bit(pt1_entry_t *pte1p, uint32_t bit)
{
*pte1p |= bit;
pte1_sync(pte1p);
}
static __inline vm_paddr_t
pte1_pa(pt1_entry_t pte1)
{
return ((vm_paddr_t)(pte1 & PTE1_FRAME));
}
static __inline vm_paddr_t
pte1_link_pa(pt1_entry_t pte1)
{
return ((vm_paddr_t)(pte1 & L1_C_ADDR_MASK));
}
static __inline void
pte2_sync(pt2_entry_t *pte2p)
{
dsb();
#ifndef PMAP_PTE_NOCACHE
if (!cpuinfo.coherent_walk)
dcache_wb_pou((vm_offset_t)pte2p, sizeof(*pte2p));
#endif
}
static __inline void
pte2_sync_range(pt2_entry_t *pte2p, vm_size_t size)
{
dsb();
#ifndef PMAP_PTE_NOCACHE
if (!cpuinfo.coherent_walk)
dcache_wb_pou((vm_offset_t)pte2p, size);
#endif
}
static __inline void
pte2_store(pt2_entry_t *pte2p, pt2_entry_t pte2)
{
dmb();
*pte2p = pte2;
pte2_sync(pte2p);
}
static __inline void
pte2_clear(pt2_entry_t *pte2p)
{
pte2_store(pte2p, 0);
}
static __inline void
pte2_clear_bit(pt2_entry_t *pte2p, uint32_t bit)
{
*pte2p &= ~bit;
pte2_sync(pte2p);
}
static __inline bool
pte2_is_dirty(pt2_entry_t pte2)
{
return ((pte2 & (PTE2_NM | PTE2_RO)) == 0);
}
static __inline bool
pte2_is_global(pt2_entry_t pte2)
{
return ((pte2 & PTE2_NG) == 0);
}
static __inline bool
pte2_is_valid(pt2_entry_t pte2)
{
return (pte2 & PTE2_V);
}
static __inline bool
pte2_is_wired(pt2_entry_t pte2)
{
return (pte2 & PTE2_W);
}
static __inline pt2_entry_t
pte2_load(pt2_entry_t *pte2p)
{
pt2_entry_t pte2;
pte2 = *pte2p;
return (pte2);
}
static __inline pt2_entry_t
pte2_load_clear(pt2_entry_t *pte2p)
{
pt2_entry_t opte2;
opte2 = *pte2p;
*pte2p = 0;
pte2_sync(pte2p);
return (opte2);
}
static __inline void
pte2_set_bit(pt2_entry_t *pte2p, uint32_t bit)
{
*pte2p |= bit;
pte2_sync(pte2p);
}
static __inline void
pte2_set_wired(pt2_entry_t *pte2p, bool wired)
{
if (wired)
*pte2p |= PTE2_W;
else
*pte2p &= ~PTE2_W;
}
static __inline vm_paddr_t
pte2_pa(pt2_entry_t pte2)
{
return ((vm_paddr_t)(pte2 & PTE2_FRAME));
}
static __inline u_int
pte2_attr(pt2_entry_t pte2)
{
return ((u_int)(pte2 & PTE2_ATTR_MASK));
}
static __inline u_int
pt2tab_index(vm_offset_t va)
{
return (va >> PT2TAB_SHIFT);
}
static __inline pt2_entry_t *
pt2tab_entry(pt2_entry_t *pt2tab, vm_offset_t va)
{
return (pt2tab + pt2tab_index(va));
}
static __inline void
pt2tab_store(pt2_entry_t *pte2p, pt2_entry_t pte2)
{
pte2_store(pte2p,pte2);
}
static __inline pt2_entry_t
pt2tab_load(pt2_entry_t *pte2p)
{
return (pte2_load(pte2p));
}
static __inline pt2_entry_t
pt2tab_load_clear(pt2_entry_t *pte2p)
{
return (pte2_load_clear(pte2p));
}
static __inline u_int
pt2map_index(vm_offset_t va)
{
return (va >> PT2MAP_SHIFT);
}
static __inline pt2_entry_t *
pt2map_entry(vm_offset_t va)
{
return (PT2MAP + pt2map_index(va));
}
static __inline pt1_entry_t *
pmap_pte1(pmap_t pmap, vm_offset_t va)
{
return (pte1_ptr(pmap->pm_pt1, va));
}
static __inline pt1_entry_t *
kern_pte1(vm_offset_t va)
{
return (pte1_ptr(kern_pt1, va));
}
static __inline pt2_entry_t *
pmap_pt2tab_entry(pmap_t pmap, vm_offset_t va)
{
return (pt2tab_entry(pmap->pm_pt2tab, va));
}
static __inline pt2_entry_t *
kern_pt2tab_entry(vm_offset_t va)
{
return (pt2tab_entry(kern_pt2tab, va));
}
static __inline vm_page_t
pmap_pt2_page(pmap_t pmap, vm_offset_t va)
{
pt2_entry_t pte2;
pte2 = pte2_load(pmap_pt2tab_entry(pmap, va));
return (PHYS_TO_VM_PAGE(pte2 & PTE2_FRAME));
}
static __inline vm_page_t
kern_pt2_page(vm_offset_t va)
{
pt2_entry_t pte2;
pte2 = pte2_load(kern_pt2tab_entry(va));
return (PHYS_TO_VM_PAGE(pte2 & PTE2_FRAME));
}
#endif
#endif