Hi,
the diff below moves l1_ttable into struct pmap, the XXX does
mention maybe using a pool too, but for a struct of three fields w/one
of them being the _link, i don't think it would make _any_ sense, just
like the current list of L1 tables, when there is exactly one
L1table per pmap, i left pmap_alloc_l1 and pmap_free_l1 almost as is,
wrongly named now and so on for the minimal diff, but imo. those should
be inlined in pmap_create() and pmap_destroy() fwiw..
Less moving parts, can't hurt.
Just testing the diff below on cubieboard2&wandboard atm.,
loaded both w/enough make builds to keep 'em busy for the night.
-Artturi
diff --git a/sys/arch/arm/arm/pmap7.c b/sys/arch/arm/arm/pmap7.c
index f99ee582e00..92adbb53196 100644
--- a/sys/arch/arm/arm/pmap7.c
+++ b/sys/arch/arm/arm/pmap7.c
@@ -282,21 +282,12 @@ boolean_t pmap_initialized;
/*
* Metadata for L1 translation tables.
*/
-struct l1_ttable {
- /* Entry on the L1 Table list */
- TAILQ_ENTRY(l1_ttable) l1_link;
-
- /* Physical address of this L1 page table */
- paddr_t l1_physaddr;
-
- /* KVA of this L1 page table */
- pd_entry_t *l1_kva;
-};
+TAILQ_HEAD(, pmap) pm_list; /* A list of all pmaps */
/*
* Convert a virtual address into its L1 table index. That is, the
* index used to locate the L2 descriptor table pointer in an L1 table.
- * This is basically used to index l1->l1_kva[].
+ * This is basically used to index pm_l1kva[].
*
* Each L2 descriptor table represents 1MB of VA space.
*/
@@ -308,11 +299,6 @@ struct l1_ttable {
pd_entry_t l1_c_pxn;
/*
- * A list of all L1 tables
- */
-TAILQ_HEAD(, l1_ttable) l1_list;
-
-/*
* The l2_dtable tracks L2_BUCKET_SIZE worth of L1 slots.
*
* This is normally 16MB worth L2 page descriptors for any given pmap.
@@ -404,7 +390,7 @@ void pmap_clearbit(struct vm_page *, u_int);
void pmap_clean_page(struct vm_page *);
void pmap_page_remove(struct vm_page *);
-void pmap_init_l1(struct l1_ttable *, pd_entry_t *);
+void pmap_init_l1(pmap_t, pd_entry_t *);
vaddr_t kernel_pt_lookup(paddr_t);
@@ -615,7 +601,6 @@ uint nl1;
void
pmap_alloc_l1(pmap_t pm)
{
- struct l1_ttable *l1;
struct pglist plist;
struct vm_page *m;
pd_entry_t *pl1pt;
@@ -625,8 +610,6 @@ pmap_alloc_l1(pmap_t pm)
#ifdef PMAP_DEBUG
printf("%s: %d\n", __func__, ++nl1);
#endif
- /* XXX use a pool? or move to inside struct pmap? */
- l1 = malloc(sizeof(*l1), M_VMPMAP, M_WAITOK);
/* Allocate a L1 page table */
for (;;) {
@@ -654,9 +637,7 @@ printf("%s: %d\n", __func__, ++nl1);
m = TAILQ_NEXT(m, pageq);
}
- pmap_init_l1(l1, pl1pt);
-
- pm->pm_l1 = l1;
+ pmap_init_l1(pm, pl1pt);
}
/*
@@ -666,7 +647,6 @@ printf("%s: %d\n", __func__, ++nl1);
void
pmap_free_l1(pmap_t pm)
{
- struct l1_ttable *l1 = pm->pm_l1;
struct pglist mlist;
struct vm_page *pg;
struct l2_bucket *l2b;
@@ -674,12 +654,11 @@ pmap_free_l1(pmap_t pm)
vaddr_t va;
uint npg;
- pm->pm_l1 = NULL;
- TAILQ_REMOVE(&l1_list, l1, l1_link);
+ TAILQ_REMOVE(&pm_list, pm, pm_link);
/* free backing pages */
TAILQ_INIT(&mlist);
- va = (vaddr_t)l1->l1_kva;
+ va = (vaddr_t)pm->pm_l1kva;
for (npg = atop(L1_TABLE_SIZE); npg != 0; npg--) {
l2b = pmap_get_l2_bucket(pmap_kernel(), va);
ptep = &l2b->l2b_kva[l2pte_index(va)];
@@ -687,13 +666,11 @@ pmap_free_l1(pmap_t pm)
TAILQ_INSERT_TAIL(&mlist, pg, pageq);
va += PAGE_SIZE;
}
- pmap_kremove((vaddr_t)l1->l1_kva, L1_TABLE_SIZE);
+ pmap_kremove((vaddr_t)pm->pm_l1kva, L1_TABLE_SIZE);
uvm_pglistfree(&mlist);
/* free backing va */
- uvm_km_free(kernel_map, (vaddr_t)l1->l1_kva, L1_TABLE_SIZE);
-
- free(l1, M_VMPMAP, 0);
+ uvm_km_free(kernel_map, (vaddr_t)pm->pm_l1kva, L1_TABLE_SIZE);
}
/*
@@ -830,7 +807,7 @@ pmap_free_l2_bucket(pmap_t pm, struct l2_bucket *l2b, u_int
count)
ptep = l2b->l2b_kva;
l2b->l2b_kva = NULL;
- pl1pd = &pm->pm_l1->l1_kva[l1idx];
+ pl1pd = &pm->pm_l1kva[l1idx];
/*
* Invalidate the L1 slot.
@@ -1257,7 +1234,7 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_t pa, vm_prot_t
prot, int flags)
*/
pd_entry_t *pl1pd, l1pd;
- pl1pd = &pm->pm_l1->l1_kva[L1_IDX(va)];
+ pl1pd = &pm->pm_l1kva[L1_IDX(va)];
l1pd = L1_C_PROTO | l2b->l2b_phys | l1_c_pxn;
if (*pl1pd != l1pd) {
*pl1pd = l1pd;
@@ -1479,7 +1456,7 @@ pmap_extract(pmap_t pm, vaddr_t va, paddr_t *pap)
l1idx = L1_IDX(va);
- pl1pd = &pm->pm_l1->l1_kva[l1idx];
+ pl1pd = &pm->pm_l1kva[l1idx];
l1pd = *pl1pd;
if (l1pte_section_p(l1pd)) {
@@ -2089,7 +2066,7 @@ vaddr_t
pmap_growkernel(vaddr_t maxkvaddr)
{
pmap_t kpm = pmap_kernel();
- struct l1_ttable *l1;
+ pmap_t pm;
struct l2_bucket *l2b;
pd_entry_t *pl1pd;
int s;
@@ -2116,8 +2093,8 @@ pmap_growkernel(vaddr_t maxkvaddr)
KDASSERT(l2b != NULL);
/* Distribute new L1 entry to all other L1s */
- TAILQ_FOREACH(l1, &l1_list, l1_link) {
- pl1pd = &l1->l1_kva[L1_IDX(pmap_curmaxkvaddr)];
+ TAILQ_FOREACH(pm, &pm_list, pm_link) {
+ pl1pd = &pm->pm_l1kva[L1_IDX(pmap_curmaxkvaddr)];
*pl1pd = L1_C_PROTO | l2b->l2b_phys;
PTE_SYNC(pl1pd);
}
@@ -2167,8 +2144,8 @@ vector_page_setprot(int prot)
void
pmap_set_pcb_pagedir(pmap_t pm, struct pcb *pcb)
{
- KDASSERT(pm->pm_l1);
- pcb->pcb_pagedir = pm->pm_l1->l1_physaddr;
+ KDASSERT(pm);
+ pcb->pcb_pagedir = pm->pm_l1pa;
}
/*
@@ -2194,11 +2171,11 @@ pmap_get_pde_pte(pmap_t pm, vaddr_t va, pd_entry_t
**pdp, pt_entry_t **ptp)
pt_entry_t *ptep;
u_short l1idx;
- if (pm->pm_l1 == NULL)
+ if (pm == NULL)
return (FALSE);
l1idx = L1_IDX(va);
- *pdp = pl1pd = &pm->pm_l1->l1_kva[l1idx];
+ *pdp = pl1pd = &pm->pm_l1kva[l1idx];
l1pd = *pl1pd;
if (l1pte_section_p(l1pd)) {
@@ -2219,21 +2196,20 @@ pmap_get_pde_pte(pmap_t pm, vaddr_t va, pd_entry_t
**pdp, pt_entry_t **ptp)
/************************ Bootstrapping routines ****************************/
void
-pmap_init_l1(struct l1_ttable *l1, pd_entry_t *l1pt)
+pmap_init_l1(pmap_t pm, pd_entry_t *l1pt)
{
- l1->l1_kva = l1pt;
+ pm->pm_l1kva = l1pt;
/*
* Copy the kernel's L1 entries to each new L1.
*/
if (pmap_initialized)
- memcpy(l1pt, pmap_kernel()->pm_l1->l1_kva, L1_TABLE_SIZE);
+ memcpy(l1pt, pmap_kernel()->pm_l1kva, L1_TABLE_SIZE);
- if (pmap_extract(pmap_kernel(), (vaddr_t)l1pt,
- &l1->l1_physaddr) == FALSE)
+ if (pmap_extract(pmap_kernel(), (vaddr_t)l1pt, &pm->pm_l1pa) == FALSE)
panic("pmap_init_l1: can't get PA of L1 at %p", l1pt);
- TAILQ_INSERT_TAIL(&l1_list, l1, l1_link);
+ TAILQ_INSERT_TAIL(&pm_list, pm, pm_link);
}
/*
@@ -2256,14 +2232,13 @@ pmap_init_l1(struct l1_ttable *l1, pd_entry_t *l1pt)
*/
#define PMAP_STATIC_L2_SIZE 16
void
-pmap_bootstrap(pd_entry_t *kernel_l1pt, vaddr_t vstart, vaddr_t vend)
+pmap_bootstrap(pv_addr_t *kl1pd, vaddr_t vstart, vaddr_t vend)
{
- static struct l1_ttable static_l1;
static struct l2_dtable static_l2[PMAP_STATIC_L2_SIZE];
- struct l1_ttable *l1 = &static_l1;
struct l2_dtable *l2;
struct l2_bucket *l2b;
pmap_t pm = pmap_kernel();
+ pd_entry_t *kernel_l1pt = (pd_entry_t *)kl1pd->pv_va;
pd_entry_t pde;
pt_entry_t *ptep;
paddr_t pa;
@@ -2273,8 +2248,11 @@ pmap_bootstrap(pd_entry_t *kernel_l1pt, vaddr_t vstart,
vaddr_t vend)
/*
* Initialise the kernel pmap object
*/
- pm->pm_l1 = l1;
pm->pm_refs = 1;
+ pm->pm_l1kva = (pd_entry_t *)kl1pd->pv_va;
+ TAILQ_INIT(&pm_list);
+ pm->pm_l1pa = kl1pd->pv_pa;
+ TAILQ_INSERT_TAIL(&pm_list, pm, pm_link);
/*
* Scan the L1 translation table created by initarm() and create
@@ -2373,12 +2351,6 @@ pmap_bootstrap(pd_entry_t *kernel_l1pt, vaddr_t vstart,
vaddr_t vend)
&pmap_kernel_l2dtable_kva, NULL);
/*
- * We can now initialise the first L1's metadata.
- */
- TAILQ_INIT(&l1_list);
- pmap_init_l1(l1, kernel_l1pt);
-
- /*
* Initialize the pmap pool.
*/
pool_init(&pmap_pmap_pool, sizeof(struct pmap), 0, IPL_NONE, 0,
diff --git a/sys/arch/arm/include/pmap.h b/sys/arch/arm/include/pmap.h
index 83c3395f710..a0815530601 100644
--- a/sys/arch/arm/include/pmap.h
+++ b/sys/arch/arm/include/pmap.h
@@ -121,7 +121,6 @@
#ifndef _LOCORE
-struct l1_ttable;
struct l2_dtable;
/*
@@ -171,7 +170,9 @@ struct pmap_devmap {
struct pmap {
u_int8_t pm_domain;
boolean_t pm_remove_all;
- struct l1_ttable *pm_l1;
+ TAILQ_ENTRY(pmap) pm_link; /* Entry on the pmap list */
+ pd_entry_t *pm_l1kva; /* KVA of this L1 TTable */
+ paddr_t pm_l1pa; /* PA of this L1 TTable */
union pmap_cache_state pm_cstate;
u_int pm_refs;
struct l2_dtable *pm_l2[L2_SIZE];
@@ -260,7 +261,7 @@ void pmap_uncache_page(paddr_t, vaddr_t);
#define PMAP_GROWKERNEL /* turn on pmap_growkernel interface */
/* Functions we use internally. */
-void pmap_bootstrap(pd_entry_t *, vaddr_t, vaddr_t);
+void pmap_bootstrap(pv_addr_t *, vaddr_t, vaddr_t);
int pmap_fault_fixup(pmap_t, vaddr_t, vm_prot_t, int);
boolean_t pmap_get_pde_pte(pmap_t, vaddr_t, pd_entry_t **, pt_entry_t **);
diff --git a/sys/arch/armv7/armv7/armv7_machdep.c
b/sys/arch/armv7/armv7/armv7_machdep.c
index aa1c549b29b..afeb21f7b13 100644
--- a/sys/arch/armv7/armv7/armv7_machdep.c
+++ b/sys/arch/armv7/armv7/armv7_machdep.c
@@ -767,7 +767,7 @@ initarm(void *arg0, void *arg1, void *arg2, paddr_t
loadaddr)
#ifdef VERBOSE_INIT_ARM
printf("pmap ");
#endif
- pmap_bootstrap((pd_entry_t *)kernel_l1pt.pv_va, KERNEL_VM_BASE,
+ pmap_bootstrap(&kernel_l1pt, KERNEL_VM_BASE,
KERNEL_VM_BASE + KERNEL_VM_SIZE);
vector_page_setprot(PROT_READ | PROT_EXEC);