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);