summaryrefslogtreecommitdiffstats
path: root/sys/powerpc
diff options
context:
space:
mode:
authorjhibbits <jhibbits@FreeBSD.org>2016-01-19 03:07:25 +0000
committerjhibbits <jhibbits@FreeBSD.org>2016-01-19 03:07:25 +0000
commit730341be8a56c9ab6d81cb4c4edd37af0f2d61cb (patch)
tree29dee9f2d7962043e035604a070d001df1c1e047 /sys/powerpc
parent09fb369fc5164b2baaba44740ab7379c43306071 (diff)
downloadFreeBSD-src-730341be8a56c9ab6d81cb4c4edd37af0f2d61cb.zip
FreeBSD-src-730341be8a56c9ab6d81cb4c4edd37af0f2d61cb.tar.gz
Hide most of the PTE initialization and management.
By confining the page table management to a handful of functions it'll be easier to modify the page table scheme without affecting other functions. This will be necessary when 64-bit support is added, and page tables become much larger.
Diffstat (limited to 'sys/powerpc')
-rw-r--r--sys/powerpc/booke/pmap.c76
1 files changed, 46 insertions, 30 deletions
diff --git a/sys/powerpc/booke/pmap.c b/sys/powerpc/booke/pmap.c
index bb1a7b5..67a2500 100644
--- a/sys/powerpc/booke/pmap.c
+++ b/sys/powerpc/booke/pmap.c
@@ -242,6 +242,8 @@ static vm_paddr_t pte_vatopa(mmu_t, pmap_t, vm_offset_t);
static pte_t *pte_find(mmu_t, pmap_t, vm_offset_t);
static int pte_enter(mmu_t, pmap_t, vm_page_t, vm_offset_t, uint32_t, boolean_t);
static int pte_remove(mmu_t, pmap_t, vm_offset_t, uint8_t);
+static void kernel_pte_alloc(vm_offset_t data_end, vm_offset_t addr,
+ vm_offset_t pdir);
static pv_entry_t pv_alloc(void);
static void pv_free(pv_entry_t);
@@ -507,6 +509,10 @@ tlb1_get_tlbconf(void)
tlb1_entries = tlb1_cfg & TLBCFG_NENTRY_MASK;
}
+/**************************************************************************/
+/* Page table related */
+/**************************************************************************/
+
/* Initialize pool of kva ptbl buffers. */
static void
ptbl_init(void)
@@ -1014,6 +1020,33 @@ pte_find(mmu_t mmu, pmap_t pmap, vm_offset_t va)
return (NULL);
}
+/* Set up kernel page tables. */
+static void
+kernel_pte_alloc(vm_offset_t data_end, vm_offset_t addr, vm_offset_t pdir)
+{
+ int i;
+ vm_offset_t va;
+ pte_t *pte;
+
+ /* Initialize kernel pdir */
+ for (i = 0; i < kernel_ptbls; i++)
+ kernel_pmap->pm_pdir[kptbl_min + i] =
+ (pte_t *)(pdir + (i * PAGE_SIZE * PTBL_PAGES));
+
+ /*
+ * Fill in PTEs covering kernel code and data. They are not required
+ * for address translation, as this area is covered by static TLB1
+ * entries, but for pte_vatopa() to work correctly with kernel area
+ * addresses.
+ */
+ for (va = addr; va < data_end; va += PAGE_SIZE) {
+ pte = &(kernel_pmap->pm_pdir[PDIR_IDX(va)][PTBL_IDX(va)]);
+ pte->rpn = kernload + (va - kernstart);
+ pte->flags = PTE_M | PTE_SR | PTE_SW | PTE_SX | PTE_WIRED |
+ PTE_VALID;
+ }
+}
+
/**************************************************************************/
/* PMAP related */
/**************************************************************************/
@@ -1031,10 +1064,9 @@ mmu_booke_bootstrap(mmu_t mmu, vm_offset_t start, vm_offset_t kernelend)
vm_paddr_t physsz, hwphyssz;
u_int phys_avail_count;
vm_size_t kstack0_sz;
- vm_offset_t kernel_pdir, kstack0, va;
+ vm_offset_t kernel_pdir, kstack0;
vm_paddr_t kstack0_phys;
void *dpcpu;
- pte_t *pte;
debugf("mmu_booke_bootstrap: entered\n");
@@ -1287,11 +1319,7 @@ mmu_booke_bootstrap(mmu_t mmu, vm_offset_t start, vm_offset_t kernelend)
debugf("kernel pdir range: 0x%08x - 0x%08x\n",
kptbl_min * PDIR_SIZE, (kptbl_min + kernel_ptbls) * PDIR_SIZE - 1);
- /* Initialize kernel pdir */
- for (i = 0; i < kernel_ptbls; i++)
- kernel_pmap->pm_pdir[kptbl_min + i] =
- (pte_t *)(kernel_pdir + (i * PAGE_SIZE * PTBL_PAGES));
-
+ kernel_pte_alloc(data_end, kernstart, kernel_pdir);
for (i = 0; i < MAXCPU; i++) {
kernel_pmap->pm_tid[i] = TID_KERNEL;
@@ -1299,18 +1327,6 @@ mmu_booke_bootstrap(mmu_t mmu, vm_offset_t start, vm_offset_t kernelend)
tidbusy[i][TID_KERNEL] = kernel_pmap;
}
- /*
- * Fill in PTEs covering kernel code and data. They are not required
- * for address translation, as this area is covered by static TLB1
- * entries, but for pte_vatopa() to work correctly with kernel area
- * addresses.
- */
- for (va = kernstart; va < data_end; va += PAGE_SIZE) {
- pte = &(kernel_pmap->pm_pdir[PDIR_IDX(va)][PTBL_IDX(va)]);
- pte->rpn = kernload + (va - kernstart);
- pte->flags = PTE_M | PTE_SR | PTE_SW | PTE_SX | PTE_WIRED |
- PTE_VALID;
- }
/* Mark kernel_pmap active on all CPUs */
CPU_FILL(&kernel_pmap->pm_active);
@@ -1502,8 +1518,6 @@ mmu_booke_kenter(mmu_t mmu, vm_offset_t va, vm_paddr_t pa)
static void
mmu_booke_kenter_attr(mmu_t mmu, vm_offset_t va, vm_paddr_t pa, vm_memattr_t ma)
{
- unsigned int pdir_idx = PDIR_IDX(va);
- unsigned int ptbl_idx = PTBL_IDX(va);
uint32_t flags;
pte_t *pte;
@@ -1513,7 +1527,7 @@ mmu_booke_kenter_attr(mmu_t mmu, vm_offset_t va, vm_paddr_t pa, vm_memattr_t ma)
flags = PTE_SR | PTE_SW | PTE_SX | PTE_WIRED | PTE_VALID;
flags |= tlb_calc_wimg(pa, ma);
- pte = &(kernel_pmap->pm_pdir[pdir_idx][ptbl_idx]);
+ pte = pte_find(mmu, kernel_pmap, va);
mtx_lock_spin(&tlbivax_mutex);
tlb_miss_lock();
@@ -1548,17 +1562,15 @@ mmu_booke_kenter_attr(mmu_t mmu, vm_offset_t va, vm_paddr_t pa, vm_memattr_t ma)
static void
mmu_booke_kremove(mmu_t mmu, vm_offset_t va)
{
- unsigned int pdir_idx = PDIR_IDX(va);
- unsigned int ptbl_idx = PTBL_IDX(va);
pte_t *pte;
-// CTR2(KTR_PMAP,("%s: s (va = 0x%08x)\n", __func__, va));
+ CTR2(KTR_PMAP,"%s: s (va = 0x%08x)\n", __func__, va);
KASSERT(((va >= VM_MIN_KERNEL_ADDRESS) &&
(va <= VM_MAX_KERNEL_ADDRESS)),
("mmu_booke_kremove: invalid va"));
- pte = &(kernel_pmap->pm_pdir[pdir_idx][ptbl_idx]);
+ pte = pte_find(mmu, kernel_pmap, va);
if (!PTE_ISVALID(pte)) {
@@ -2333,7 +2345,7 @@ mmu_booke_quick_enter_page(mmu_t mmu, vm_page_t m)
critical_enter();
qaddr = PCPU_GET(qmap_addr);
- pte = &(kernel_pmap->pm_pdir[PDIR_IDX(qaddr)][PTBL_IDX(qaddr)]);
+ pte = pte_find(mmu, kernel_pmap, qaddr);
KASSERT(pte->flags == 0, ("mmu_booke_quick_enter_page: PTE busy"));
@@ -2360,7 +2372,7 @@ mmu_booke_quick_remove_page(mmu_t mmu, vm_offset_t addr)
{
pte_t *pte;
- pte = &(kernel_pmap->pm_pdir[PDIR_IDX(addr)][PTBL_IDX(addr)]);
+ pte = pte_find(mmu, kernel_pmap, addr);
KASSERT(PCPU_GET(qmap_addr) == addr,
("mmu_booke_quick_remove_page: invalid address"));
@@ -2832,8 +2844,8 @@ mmu_booke_mapdev_attr(mmu_t mmu, vm_paddr_t pa, vm_size_t size, vm_memattr_t ma)
} while (va % sz != 0);
}
if (bootverbose)
- printf("Wiring VA=%x to PA=%llx (size=%x), "
- "using TLB1[%d]\n", va, pa, sz, tlb1_idx);
+ printf("Wiring VA=%lx to PA=%jx (size=%lx), "
+ "using TLB1[%d]\n", va, (uintmax_t)pa, sz, tlb1_idx);
tlb1_set_entry(va, pa, sz, tlb_calc_wimg(pa, ma));
size -= sz;
pa += sz;
@@ -3237,7 +3249,11 @@ tlb1_mapin_region(vm_offset_t va, vm_paddr_t pa, vm_size_t size)
}
mapped = (va - base);
+#ifdef __powerpc64__
+ printf("mapped size 0x%016lx (wasted space 0x%16lx)\n",
+#else
printf("mapped size 0x%08x (wasted space 0x%08x)\n",
+#endif
mapped, mapped - size);
return (mapped);
}
OpenPOWER on IntegriCloud