Index: arm/arm/pmap.c =================================================================== RCS file: /cognet/ncvs/src/sys/arm/arm/pmap.c,v retrieving revision 1.36.2.2 diff -u -p -r1.36.2.2 pmap.c --- arm/arm/pmap.c 23 Jun 2006 17:41:02 -0000 1.36.2.2 +++ arm/arm/pmap.c 19 Jul 2006 20:23:46 -0000 @@ -198,6 +198,8 @@ extern struct pv_addr systempage; static void pmap_free_pv_entry (pv_entry_t); static pv_entry_t pmap_get_pv_entry(void); +static void pmap_enter_locked(pmap_t, vm_offset_t, vm_page_t, + vm_prot_t, boolean_t, int); static void pmap_vac_me_harder(struct vm_page *, pmap_t, vm_offset_t); static void pmap_vac_me_kpmap(struct vm_page *, pmap_t, @@ -269,9 +271,6 @@ void (*pmap_zero_page_func)(vm_paddr_t, */ union pmap_cache_state *pmap_cache_state; -LIST_HEAD(pmaplist, pmap); -struct pmaplist allpmaps; - /* static pt_entry_t *msgbufmap;*/ struct msgbuf *msgbufp = 0; @@ -373,7 +372,7 @@ struct l2_dtable { * L2 allocation. */ #define pmap_alloc_l2_dtable() \ - (void*)uma_zalloc(l2table_zone, M_NOWAIT) + (void*)uma_zalloc(l2table_zone, M_NOWAIT|M_USE_RESERVE) #define pmap_free_l2_dtable(l2) \ uma_zfree(l2table_zone, l2) @@ -399,11 +398,6 @@ int pmap_needs_pte_sync; */ #define PV_BEEN_REFD(f) (((f) & PVF_REF) != 0) -/* - * Data for the pv entry allocation mechanism - */ -#define MINPV 2048 - #ifndef PMAP_SHPGPERPROC #define PMAP_SHPGPERPROC 200 #endif @@ -417,9 +411,8 @@ static vm_offset_t pmap_kernel_l2dtable_ static vm_offset_t pmap_kernel_l2ptp_kva; static vm_paddr_t pmap_kernel_l2ptp_phys; static struct vm_object pvzone_obj; -static struct vm_object l2zone_obj; static int pv_entry_count=0, pv_entry_max=0, pv_entry_high_water=0; -int pmap_pagedaemon_waken = 0; +int pmap_pagedaemon_waken; /* * This list exists for the benefit of pmap_map_chunk(). It keeps track @@ -461,14 +454,8 @@ kernel_pt_lookup(vm_paddr_t pa) struct pv_addr *pv; SLIST_FOREACH(pv, &kernel_pt_list, pv_list) { -#ifndef ARM32_NEW_VM_LAYOUT - if (pv->pv_pa == (pa & ~PAGE_MASK)) { - return (pv->pv_va | (pa & PAGE_MASK)); - } -#else if (pv->pv_pa == pa) return (pv->pv_va); -#endif } return (0); } @@ -720,21 +707,12 @@ xscale_setup_minidata(vm_offset_t l1pt, for (; size != 0; va += L2_S_SIZE, pa += L2_S_SIZE, size -= L2_S_SIZE) { -#ifndef ARM32_NEW_VM_LAYOUT - pte = (pt_entry_t *) - kernel_pt_lookup(pde[va >> L1_S_SHIFT] & L2_S_FRAME); -#else pte = (pt_entry_t *) kernel_pt_lookup( pde[L1_IDX(va)] & L1_C_ADDR_MASK); -#endif if (pte == NULL) panic("xscale_setup_minidata: can't find L2 table for " "VA 0x%08x", (u_int32_t) va); -#ifndef ARM32_NEW_VM_LAYOUT - pte[(va >> PAGE_SHIFT) & 0x3ff] = -#else pte[l2pte_index(va)] = -#endif L2_S_PROTO | pa | L2_S_PROT(PTE_KERNEL, VM_PROT_READ) | L2_C | L2_XSCALE_T_TEX(TEX_XSCALE_X); } @@ -919,6 +897,7 @@ pmap_alloc_l2_bucket(pmap_t pm, vm_offse l1idx = L1_IDX(va); + PMAP_ASSERT_LOCKED(pm); mtx_assert(&vm_page_queue_mtx, MA_OWNED); if ((l2 = pm->pm_l2[L2_IDX(l1idx)]) == NULL) { /* @@ -927,16 +906,21 @@ pmap_alloc_l2_bucket(pmap_t pm, vm_offse * Need to allocate a new l2_dtable. */ again_l2table: + PMAP_UNLOCK(pm); vm_page_unlock_queues(); if ((l2 = pmap_alloc_l2_dtable()) == NULL) { vm_page_lock_queues(); + PMAP_LOCK(pm); return (NULL); } vm_page_lock_queues(); + PMAP_LOCK(pm); if (pm->pm_l2[L2_IDX(l1idx)] != NULL) { + PMAP_UNLOCK(pm); vm_page_unlock_queues(); uma_zfree(l2table_zone, l2); vm_page_lock_queues(); + PMAP_LOCK(pm); l2 = pm->pm_l2[L2_IDX(l1idx)]; if (l2 == NULL) goto again_l2table; @@ -952,28 +936,32 @@ again_l2table: pm->pm_l2[L2_IDX(l1idx)] = l2; } } - + l2b = &l2->l2_bucket[L2_BUCKET(l1idx)]; - + /* * Fetch pointer to the L2 page table associated with the address. */ if (l2b->l2b_kva == NULL) { pt_entry_t *ptep; - + /* * No L2 page table has been allocated. Chances are, this * is because we just allocated the l2_dtable, above. */ again_ptep: + PMAP_UNLOCK(pm); vm_page_unlock_queues(); - ptep = (void*)uma_zalloc(l2zone, M_NOWAIT); + ptep = (void*)uma_zalloc(l2zone, M_NOWAIT|M_USE_RESERVE); vm_page_lock_queues(); + PMAP_LOCK(pm); if (l2b->l2b_kva != 0) { /* We lost the race. */ + PMAP_UNLOCK(pm); vm_page_unlock_queues(); uma_zfree(l2zone, ptep); vm_page_lock_queues(); + PMAP_LOCK(pm); if (l2b->l2b_kva == 0) goto again_ptep; return (l2b); @@ -991,13 +979,13 @@ again_ptep: } return (NULL); } - + l2->l2_occupancy++; l2b->l2b_kva = ptep; l2b->l2b_l1idx = l1idx; } - - return (l2b); + + return (l2b); } static PMAP_INLINE void @@ -1239,18 +1227,19 @@ pmap_dcache_wbinv_all(pmap_t pm) cpu_dcache_wbinv_all(); } -/* - * this routine defines the region(s) of memory that should - * not be tested for the modified bit. - */ + /* + * this routine defines the region(s) of memory that should + * not be tested for the modified bit. + */ static PMAP_INLINE int pmap_track_modified(vm_offset_t va) { - if ((va < kmi.clean_sva) || (va >= kmi.clean_eva)) - return 1; - else - return 0; + if ((va < kmi.clean_sva) || (va >= kmi.clean_eva)) + return 1; + else + return 0; } + /* * PTE_SYNC_CURRENT: * @@ -1329,6 +1318,7 @@ pmap_vac_me_harder(struct vm_page *pg, p { int nattr; + mtx_assert(&vm_page_queue_mtx, MA_OWNED); nattr = pmap_get_vac_flags(pg); if (nattr < 0) { @@ -1559,10 +1549,8 @@ pmap_clearbit(struct vm_page *pg, u_int vm_offset_t va; u_int oflags; int count = 0; -#if 0 - PMAP_HEAD_TO_MAP_LOCK(); - simple_lock(&pg->mdpage.pvh_slock); -#endif + + mtx_assert(&vm_page_queue_mtx, MA_OWNED); /* * Clear saved attributes (modify, reference) @@ -1570,10 +1558,6 @@ pmap_clearbit(struct vm_page *pg, u_int pg->md.pvh_attrs &= ~(maskbits & (PVF_MOD | PVF_REF)); if (TAILQ_EMPTY(&pg->md.pv_list)) { -#if 0 - simple_unlock(&pg->mdpage.pvh_slock); - PMAP_HEAD_TO_MAP_UNLOCK(); -#endif return (0); } @@ -1586,9 +1570,7 @@ pmap_clearbit(struct vm_page *pg, u_int oflags = pv->pv_flags; pv->pv_flags &= ~maskbits; -#if 0 - pmap_acquire_pmap_lock(pm); -#endif + PMAP_LOCK(pm); l2b = pmap_get_l2_bucket(pm, va); @@ -1707,16 +1689,10 @@ pmap_clearbit(struct vm_page *pg, u_int pmap_tlb_flushD_SE(pm, pv->pv_va); } -#if 0 - pmap_release_pmap_lock(pm); -#endif + PMAP_UNLOCK(pm); } -#if 0 - simple_unlock(&pg->mdpage.pvh_slock); - PMAP_HEAD_TO_MAP_UNLOCK(); -#endif if (maskbits & PVF_WRITE) vm_page_flag_clear(pg, PG_WRITEABLE); return (count); @@ -1745,14 +1721,12 @@ pmap_enter_pv(struct vm_page *pg, struct vm_offset_t va, u_int flags) { - + mtx_assert(&vm_page_queue_mtx, MA_OWNED); + PMAP_ASSERT_LOCKED(pm); pve->pv_pmap = pm; pve->pv_va = va; pve->pv_flags = flags; -#if 0 - mtx_lock(&pg->md.pvh_mtx); -#endif TAILQ_INSERT_HEAD(&pg->md.pv_list, pve, pv_list); TAILQ_INSERT_HEAD(&pm->pm_pvlist, pve, pv_plist); pg->md.pvh_attrs |= flags & (PVF_REF | PVF_MOD); @@ -1767,9 +1741,6 @@ pmap_enter_pv(struct vm_page *pg, struct else pg->md.uro_mappings++; pg->md.pv_list_count++; -#if 0 - mtx_unlock(&pg->md.pvh_mtx); -#endif if (pve->pv_flags & PVF_WIRED) ++pm->pm_stats.wired_count; vm_page_flag_set(pg, PG_REFERENCED); @@ -1786,6 +1757,7 @@ pmap_find_pv(struct vm_page *pg, pmap_t { struct pv_entry *pv; + mtx_assert(&vm_page_queue_mtx, MA_OWNED); TAILQ_FOREACH(pv, &pg->md.pv_list, pv_list) if (pm == pv->pv_pmap && va == pv->pv_va) break; @@ -1828,6 +1800,8 @@ static void pmap_nuke_pv(struct vm_page *pg, pmap_t pm, struct pv_entry *pve) { + mtx_assert(&vm_page_queue_mtx, MA_OWNED); + PMAP_ASSERT_LOCKED(pm); TAILQ_REMOVE(&pg->md.pv_list, pve, pv_list); TAILQ_REMOVE(&pm->pm_pvlist, pve, pv_plist); if (pve->pv_flags & PVF_WIRED) @@ -1863,6 +1837,7 @@ pmap_remove_pv(struct vm_page *pg, pmap_ { struct pv_entry *pve; + mtx_assert(&vm_page_queue_mtx, MA_OWNED); pve = TAILQ_FIRST(&pg->md.pv_list); while (pve) { @@ -1894,6 +1869,8 @@ pmap_modify_pv(struct vm_page *pg, pmap_ struct pv_entry *npv; u_int flags, oflags; + PMAP_ASSERT_LOCKED(pm); + mtx_assert(&vm_page_queue_mtx, MA_OWNED); if ((npv = pmap_find_pv(pg, pm, va)) == NULL) return (0); @@ -1959,6 +1936,9 @@ pmap_pinit0(struct pmap *pmap) dprintf("pmap_pinit0: pmap = %08x, pm_pdir = %08x\n", (u_int32_t) pmap, (u_int32_t) pmap->pm_pdir); bcopy(kernel_pmap, pmap, sizeof(*pmap)); + bzero(&pmap->pm_mtx, sizeof(pmap->pm_mtx)); + bzero(&pmap->pm_mtx, sizeof(pmap->pm_mtx)); + PMAP_LOCK_INIT(pmap); } /* @@ -1980,6 +1960,7 @@ pmap_page_init(vm_page_t m) void pmap_init(void) { + int shpgperproc = PMAP_SHPGPERPROC; PDEBUG(1, printf("pmap_init: phys_start = %08x\n")); @@ -1988,12 +1969,23 @@ pmap_init(void) */ pvzone = uma_zcreate("PV ENTRY", sizeof (struct pv_entry), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM | UMA_ZONE_NOFREE); - uma_prealloc(pvzone, MINPV); /* * Now it is safe to enable pv_table recording. */ PDEBUG(1, printf("pmap_init: done!\n")); + TUNABLE_INT_FETCH("vm.pmap.shpgperproc", &shpgperproc); + + pv_entry_max = shpgperproc * maxproc + vm_page_array_size; + pv_entry_high_water = 9 * (pv_entry_max / 10); + l2zone = uma_zcreate("L2 Table", L2_TABLE_SIZE_REAL, pmap_l2ptp_ctor, + NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM | UMA_ZONE_NOFREE); + l2table_zone = uma_zcreate("L2 Table", sizeof(struct l2_dtable), + NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, + UMA_ZONE_VM | UMA_ZONE_NOFREE); + + uma_zone_set_obj(pvzone, &pvzone_obj, pv_entry_max); + } int @@ -2007,11 +1999,9 @@ pmap_fault_fixup(pmap_t pm, vm_offset_t u_int l1idx; int rv = 0; -#if 0 - PMAP_MAP_TO_HEAD_LOCK(); - pmap_acquire_pmap_lock(pm); -#endif l1idx = L1_IDX(va); + vm_page_lock_queues(); + PMAP_LOCK(pm); /* * If there is no l2_dtable for this address, then the process @@ -2105,18 +2095,13 @@ pmap_fault_fixup(pmap_t pm, vm_offset_t struct vm_page *pg; /* Extract the physical address of the page */ - vm_page_lock_queues(); - if ((pg = PHYS_TO_VM_PAGE(pa)) == NULL) { - vm_page_unlock_queues(); + if ((pg = PHYS_TO_VM_PAGE(pa)) == NULL) goto out; - } /* Get the current flags for this page. */ pv = pmap_find_pv(pg, pm, va); - if (pv == NULL) { - vm_page_unlock_queues(); + if (pv == NULL) goto out; - } pg->md.pvh_attrs |= PVF_REF; pv->pv_flags |= PVF_REF; @@ -2125,7 +2110,6 @@ pmap_fault_fixup(pmap_t pm, vm_offset_t *ptep = (pte & ~L2_TYPE_MASK) | L2_S_PROTO; PTE_SYNC(ptep); rv = 1; - vm_page_unlock_queues(); } /* @@ -2216,22 +2200,14 @@ pmap_fault_fixup(pmap_t pm, vm_offset_t rv = 1; out: -#if 0 - pmap_release_pmap_lock(pm); - PMAP_MAP_TO_HEAD_UNLOCK(); -#endif + vm_page_unlock_queues(); + PMAP_UNLOCK(pm); return (rv); } -/* - * Initialize the address space (zone) for the pv_entries. Set a - * high water mark so that the system can recover from excessive - * numbers of pv entries. - */ void -pmap_init2() +pmap_init2(void) { - int shpgperproc = PMAP_SHPGPERPROC; struct l2_bucket *l2b; struct l1_ttable *l1; pd_entry_t *pl1pt; @@ -2239,21 +2215,6 @@ pmap_init2() vm_offset_t va, eva; u_int loop, needed; - TUNABLE_INT_FETCH("vm.pmap.shpgperproc", &shpgperproc); - - pv_entry_max = shpgperproc * maxproc + vm_page_array_size; - pv_entry_high_water = 9 * (pv_entry_max / 10); - l2zone = uma_zcreate("L2 Table", L2_TABLE_SIZE_REAL, pmap_l2ptp_ctor, - NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM | UMA_ZONE_NOFREE); - uma_prealloc(l2zone, 4096); - l2table_zone = uma_zcreate("L2 Table", sizeof(struct l2_dtable), - NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, - UMA_ZONE_VM | UMA_ZONE_NOFREE); - uma_prealloc(l2table_zone, 1024); - - uma_zone_set_obj(pvzone, &pvzone_obj, pv_entry_max); - uma_zone_set_obj(l2zone, &l2zone_obj, pv_entry_max); - needed = (maxproc / PMAP_DOMAINS) + ((maxproc % PMAP_DOMAINS) ? 1 : 0); needed -= 1; l1 = malloc(sizeof(*l1) * needed, M_VMPMAP, M_WAITOK); @@ -2317,7 +2278,6 @@ pmap_activate(struct thread *td) { pmap_t pm; struct pcb *pcb; - int s; pm = vmspace_pmap(td->td_proc->p_vmspace); pcb = td->td_pcb; @@ -2361,8 +2321,6 @@ pmap_activate(struct thread *td) cpu_domains(pcb->pcb_dacr); cpu_setttb(pcb->pcb_pagedir); - - splx(s); } critical_exit(); } @@ -2560,11 +2518,10 @@ pmap_bootstrap(vm_offset_t firstaddr, vm cpu_tlb_flushID(); cpu_cpwait(); + PMAP_LOCK_INIT(kernel_pmap); kernel_pmap->pm_active = -1; kernel_pmap->pm_domain = PMAP_DOMAIN_KERNEL; - LIST_INIT(&allpmaps); TAILQ_INIT(&kernel_pmap->pm_pvlist); - LIST_INSERT_HEAD(&allpmaps, kernel_pmap, pm_list); /* * Reserve some special page table entries/VA space for temporary @@ -2599,7 +2556,8 @@ pmap_bootstrap(vm_offset_t firstaddr, vm virtual_end = lastaddr; kernel_vm_end = pmap_curmaxkvaddr; arm_nocache_startaddr = lastaddr; - mtx_init(&cmtx, "TMP mappins mtx", NULL, MTX_DEF); + mtx_init(&cmtx, "TMP mappings mtx", NULL, MTX_DEF); + #ifdef ARM_USE_SMALL_ALLOC mtx_init(&smallalloc_mtx, "Small alloc page list", NULL, MTX_DEF); alloc_firstaddr = alloc_curaddr = arm_nocache_startaddr + @@ -2624,7 +2582,6 @@ pmap_release(pmap_t pmap) pmap_idcache_wbinv_all(pmap); pmap_tlb_flushID(pmap); cpu_cpwait(); - LIST_REMOVE(pmap, pm_list); if (vector_page < KERNBASE) { struct pcb *curpcb = PCPU_GET(curpcb); pcb = thread0.td_pcb; @@ -2653,6 +2610,7 @@ pmap_release(pmap_t pmap) } pmap_free_l1(pmap); + PMAP_LOCK_DESTROY(pmap); dprintf("pmap_release()\n"); } @@ -2763,7 +2721,6 @@ pmap_grow_l2_bucket(pmap_t pm, vm_offset return (NULL); PTE_SYNC_RANGE(ptep, PAGE_SIZE / sizeof(pt_entry_t)); } - memset(ptep, 0, L2_TABLE_SIZE_REAL); l2->l2_occupancy++; l2b->l2b_kva = ptep; @@ -2793,7 +2750,6 @@ void pmap_growkernel(vm_offset_t addr) { pmap_t kpm = pmap_kernel(); - int s; if (addr <= pmap_curmaxkvaddr) return; /* we are OK */ @@ -2802,8 +2758,6 @@ pmap_growkernel(vm_offset_t addr) * whoops! we need to add kernel PTPs */ - s = splhigh(); /* to be safe */ - /* Map 1MB at a time */ for (; pmap_curmaxkvaddr < addr; pmap_curmaxkvaddr += L1_S_SIZE) pmap_grow_l2_bucket(kpm, pmap_curmaxkvaddr); @@ -2863,6 +2817,7 @@ pmap_remove_pages(pmap_t pmap, vm_offset pt_entry_t *pt; vm_page_lock_queues(); + PMAP_LOCK(pmap); for (pv = TAILQ_FIRST(&pmap->pm_pvlist); pv; pv = npv) { if (pv->pv_va >= eva || pv->pv_va < sva) { npv = TAILQ_NEXT(pv, pv_plist); @@ -2882,12 +2837,15 @@ pmap_remove_pages(pmap_t pmap, vm_offset PTE_SYNC(pt); npv = TAILQ_NEXT(pv, pv_plist); pmap_nuke_pv(m, pmap, pv); + if (TAILQ_EMPTY(&m->md.pv_list)) + vm_page_flag_clear(m, PG_WRITEABLE); pmap_free_pv_entry(pv); } vm_page_unlock_queues(); cpu_idcache_wbinv_all(); cpu_tlb_flushID(); cpu_cpwait(); + PMAP_UNLOCK(pmap); } @@ -2965,6 +2923,7 @@ pmap_kenter(vm_offset_t va, vm_paddr_t p void pmap_kenter_nocache(vm_offset_t va, vm_paddr_t pa) { + pmap_kenter_internal(va, pa, 0); } @@ -3037,15 +2996,23 @@ pmap_map(vm_offset_t *virt, vm_offset_t } static void -pmap_wb_page(vm_page_t m, boolean_t do_inv) +pmap_wb_page(vm_page_t m) { struct pv_entry *pv; TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) - pmap_dcache_wb_range(pv->pv_pmap, pv->pv_va, PAGE_SIZE, do_inv, + pmap_dcache_wb_range(pv->pv_pmap, pv->pv_va, PAGE_SIZE, FALSE, (pv->pv_flags & PVF_WRITE) == 0); } +static void +pmap_inv_page(vm_page_t m) +{ + struct pv_entry *pv; + + TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) + pmap_dcache_wb_range(pv->pv_pmap, pv->pv_va, PAGE_SIZE, TRUE, TRUE); +} /* * Add a list of wired pages to the kva * this routine is only used for temporary @@ -3060,7 +3027,7 @@ pmap_qenter(vm_offset_t va, vm_page_t *m int i; for (i = 0; i < count; i++) { - pmap_wb_page(m[i], TRUE); + pmap_wb_page(m[i]); pmap_kenter_internal(va, VM_PAGE_TO_PHYS(m[i]), KENTER_CACHE); va += PAGE_SIZE; @@ -3081,7 +3048,7 @@ pmap_qremove(vm_offset_t va, int count) for (i = 0; i < count; i++) { pa = vtophys(va); if (pa) { - pmap_wb_page(PHYS_TO_VM_PAGE(pa), TRUE); + pmap_inv_page(PHYS_TO_VM_PAGE(pa)); pmap_kremove(va); } va += PAGE_SIZE; @@ -3213,6 +3180,7 @@ pmap_remove_all(vm_page_t m) if (flush == FALSE && (pv->pv_pmap == curpm || pv->pv_pmap == pmap_kernel())) flush = TRUE; + PMAP_LOCK(pv->pv_pmap); l2b = pmap_get_l2_bucket(pv->pv_pmap, pv->pv_va); KASSERT(l2b != NULL, ("No l2 bucket")); ptep = &l2b->l2b_kva[l2pte_index(pv->pv_va)]; @@ -3225,6 +3193,7 @@ pmap_remove_all(vm_page_t m) pv->pv_pmap->pm_stats.resident_count--; flags |= pv->pv_flags; pmap_nuke_pv(m, pv->pv_pmap, pv); + PMAP_UNLOCK(pv->pv_pmap); pmap_free_pv_entry(pv); } @@ -3234,6 +3203,7 @@ pmap_remove_all(vm_page_t m) else pmap_tlb_flushD(curpm); } + vm_page_flag_clear(m, PG_WRITEABLE); } @@ -3251,9 +3221,7 @@ pmap_protect(pmap_t pm, vm_offset_t sva, int flush; if ((prot & VM_PROT_READ) == 0) { - mtx_lock(&Giant); pmap_remove(pm, sva, eva); - mtx_unlock(&Giant); return; } @@ -3265,7 +3233,8 @@ pmap_protect(pmap_t pm, vm_offset_t sva, return; } - mtx_lock(&Giant); + vm_page_lock_queues(); + PMAP_LOCK(pm); /* * OK, at this point, we know we're doing write-protect operation. @@ -3276,7 +3245,6 @@ pmap_protect(pmap_t pm, vm_offset_t sva, flush = ((eva - sva) >= (PAGE_SIZE * 4)) ? 0 : -1; flags = 0; - vm_page_lock_queues(); while (sva < eva) { next_bucket = L2_NEXT_BUCKET(sva); if (next_bucket > eva) @@ -3335,7 +3303,7 @@ pmap_protect(pmap_t pm, vm_offset_t sva, } vm_page_unlock_queues(); - mtx_unlock(&Giant); + PMAP_UNLOCK(pm); } @@ -3356,6 +3324,21 @@ void pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, boolean_t wired) { + + vm_page_lock_queues(); + PMAP_LOCK(pmap); + pmap_enter_locked(pmap, va, m, prot, wired, M_WAITOK); + vm_page_unlock_queues(); + PMAP_UNLOCK(pmap); +} + +/* + * The page queues and pmap must be locked. + */ +static void +pmap_enter_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, + boolean_t wired, int flags) +{ struct l2_bucket *l2b = NULL; struct vm_page *opg; struct pv_entry *pve = NULL; @@ -3364,7 +3347,8 @@ pmap_enter(pmap_t pmap, vm_offset_t va, u_int oflags; vm_paddr_t pa; - vm_page_lock_queues(); + PMAP_ASSERT_LOCKED(pmap); + mtx_assert(&vm_page_queue_mtx, MA_OWNED); if (va == vector_page) { pa = systempage.pv_pa; m = NULL; @@ -3384,10 +3368,22 @@ pmap_enter(pmap_t pmap, vm_offset_t va, l2b = pmap_get_l2_bucket(pmap, va); if (l2b == NULL) l2b = pmap_grow_l2_bucket(pmap, va); - } else + } else { +do_l2b_alloc: l2b = pmap_alloc_l2_bucket(pmap, va); - KASSERT(l2b != NULL, - ("pmap_enter: failed to allocate l2 bucket")); + if (l2b == NULL) { + if (flags & M_WAITOK) { + PMAP_UNLOCK(pmap); + vm_page_unlock_queues(); + VM_WAIT; + vm_page_lock_queues(); + PMAP_LOCK(pmap); + goto do_l2b_alloc; + } + return; + } + } + ptep = &l2b->l2b_kva[l2pte_index(va)]; opte = *ptep; @@ -3428,8 +3424,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, * writable from the outset. */ nflags |= PVF_MOD; - if (!(m->md.pvh_attrs & PVF_MOD) && - pmap_track_modified(va)) + if (!(m->md.pvh_attrs & PVF_MOD)) vm_page_dirty(m); } if (m && opte) @@ -3448,15 +3443,9 @@ pmap_enter(pmap_t pmap, vm_offset_t va, /* * We're changing the attrs of an existing mapping. */ -#if 0 - simple_lock(&pg->mdpage.pvh_slock); -#endif oflags = pmap_modify_pv(m, pmap, va, PVF_WRITE | PVF_EXEC | PVF_WIRED | PVF_MOD | PVF_REF, nflags); -#if 0 - simple_unlock(&pg->mdpage.pvh_slock); -#endif /* * We may need to flush the cache if we're @@ -3478,20 +3467,14 @@ pmap_enter(pmap_t pmap, vm_offset_t va, * It is part of our managed memory so we * must remove it from the PV list */ -#if 0 - simple_lock(&opg->mdpage.pvh_slock); -#endif pve = pmap_remove_pv(opg, pmap, va); - if (m && (m->flags & (PG_UNMANAGED | PG_FICTITIOUS)) && + if (m && (m->flags & (PG_UNMANAGED | PG_FICTITIOUS)) && pve) pmap_free_pv_entry(pve); - else if (!pve && + else if (!pve && !(m->flags & (PG_UNMANAGED | PG_FICTITIOUS))) pve = pmap_get_pv_entry(); KASSERT(pve != NULL, ("No pv")); -#if 0 - simple_unlock(&opg->mdpage.pvh_slock); -#endif oflags = pve->pv_flags; /* @@ -3516,8 +3499,11 @@ pmap_enter(pmap_t pmap, vm_offset_t va, if ((pve = pmap_get_pv_entry()) == NULL) { panic("pmap_enter: no pv entries"); } - if (m && !(m->flags & (PG_UNMANAGED | PG_FICTITIOUS))) + if (m && !(m->flags & (PG_UNMANAGED | PG_FICTITIOUS))) { + KASSERT(va < kmi.clean_sva || va >= kmi.clean_eva, + ("pmap_enter: managed mapping within the clean submap")); pmap_enter_pv(m, pve, pmap, va, nflags); + } } /* * Make sure userland mappings get the right permissions @@ -3578,7 +3564,6 @@ pmap_enter(pmap_t pmap, vm_offset_t va, if (m) pmap_vac_me_harder(m, pmap, va); } - vm_page_unlock_queues(); } /* @@ -3595,16 +3580,10 @@ pmap_enter_quick(pmap_t pmap, vm_offset_ vm_page_t mpte) { - vm_page_busy(m); - vm_page_unlock_queues(); - VM_OBJECT_UNLOCK(m->object); - mtx_lock(&Giant); - pmap_enter(pmap, va, m, prot & (VM_PROT_READ | VM_PROT_EXECUTE), FALSE); - pmap_idcache_wbinv_all(pmap); - mtx_unlock(&Giant); - VM_OBJECT_LOCK(m->object); - vm_page_lock_queues(); - vm_page_wakeup(m); + PMAP_LOCK(pmap); + pmap_enter_locked(pmap, va, m, prot & (VM_PROT_READ | VM_PROT_EXECUTE), + FALSE, M_NOWAIT); + PMAP_UNLOCK(pmap); return (NULL); } @@ -3622,6 +3601,8 @@ pmap_change_wiring(pmap_t pmap, vm_offse pt_entry_t *ptep, pte; vm_page_t pg; + vm_page_lock_queues(); + PMAP_LOCK(pmap); l2b = pmap_get_l2_bucket(pmap, va); KASSERT(l2b, ("No l2b bucket in pmap_change_wiring")); ptep = &l2b->l2b_kva[l2pte_index(va)]; @@ -3629,6 +3610,8 @@ pmap_change_wiring(pmap_t pmap, vm_offse pg = PHYS_TO_VM_PAGE(l2pte_pa(pte)); if (pg) pmap_modify_pv(pg, pmap, va, PVF_WIRED, wired); + vm_page_unlock_queues(); + PMAP_UNLOCK(pmap); } @@ -3656,14 +3639,14 @@ vm_paddr_t pmap_extract(pmap_t pm, vm_offset_t va) { struct l2_dtable *l2; - pd_entry_t *pl1pd, l1pd; + pd_entry_t l1pd; pt_entry_t *ptep, pte; vm_paddr_t pa; u_int l1idx; l1idx = L1_IDX(va); - pl1pd = &pm->pm_l1->l1_kva[l1idx]; - l1pd = *pl1pd; + PMAP_LOCK(pm); + l1pd = pm->pm_l1->l1_kva[l1idx]; if (l1pte_section_p(l1pd)) { /* * These should only happen for pmap_kernel() @@ -3680,14 +3663,17 @@ pmap_extract(pmap_t pm, vm_offset_t va) if (l2 == NULL || (ptep = l2->l2_bucket[L2_BUCKET(l1idx)].l2b_kva) == NULL) { + PMAP_UNLOCK(pm); return (0); } ptep = &ptep[l2pte_index(va)]; pte = *ptep; - if (pte == 0) + if (pte == 0) { + PMAP_UNLOCK(pm); return (0); + } switch (pte & L2_TYPE_MASK) { case L2_TYPE_L: @@ -3700,6 +3686,7 @@ pmap_extract(pmap_t pm, vm_offset_t va) } } + PMAP_UNLOCK(pm); return (pa); } @@ -3713,16 +3700,16 @@ vm_page_t pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot) { struct l2_dtable *l2; - pd_entry_t *pl1pd, l1pd; + pd_entry_t l1pd; pt_entry_t *ptep, pte; vm_paddr_t pa; vm_page_t m = NULL; u_int l1idx; l1idx = L1_IDX(va); - pl1pd = &pmap->pm_l1->l1_kva[l1idx]; - l1pd = *pl1pd; vm_page_lock_queues(); + PMAP_LOCK(pmap); + l1pd = pmap->pm_l1->l1_kva[l1idx]; if (l1pte_section_p(l1pd)) { /* * These should only happen for pmap_kernel() @@ -3744,15 +3731,19 @@ pmap_extract_and_hold(pmap_t pmap, vm_of if (l2 == NULL || (ptep = l2->l2_bucket[L2_BUCKET(l1idx)].l2b_kva) == NULL) { + PMAP_UNLOCK(pmap); + vm_page_unlock_queues(); return (NULL); } ptep = &ptep[l2pte_index(va)]; pte = *ptep; - if (pte == 0) + if (pte == 0) { + PMAP_UNLOCK(pmap); + vm_page_unlock_queues(); return (NULL); - + } if (pte & L2_S_PROT_W || (prot & VM_PROT_WRITE) == 0) { switch (pte & L2_TYPE_MASK) { case L2_TYPE_L: @@ -3768,6 +3759,7 @@ pmap_extract_and_hold(pmap_t pmap, vm_of } } + PMAP_UNLOCK(pmap); vm_page_unlock_queues(); return (m); } @@ -3782,10 +3774,10 @@ pmap_pinit(pmap_t pmap) { PDEBUG(1, printf("pmap_pinit: pmap = %08x\n", (uint32_t) pmap)); + PMAP_LOCK_INIT(pmap); pmap_alloc_l1(pmap); bzero(pmap->pm_l2, sizeof(pmap->pm_l2)); - LIST_INSERT_HEAD(&allpmaps, pmap, pm_list); pmap->pm_count = 1; pmap->pm_active = 0; @@ -3824,11 +3816,10 @@ pmap_get_pv_entry(void) pv_entry_t ret_value; pv_entry_count++; - if (pv_entry_high_water && - (pv_entry_count > pv_entry_high_water) && - (pmap_pagedaemon_waken == 0)) { - pmap_pagedaemon_waken = 1; - wakeup (&vm_pages_needed); + if (pv_entry_count > pv_entry_high_water + && pmap_pagedaemon_waken == 0) { + pmap_pagedaemon_waken = 1; + wakeup (&vm_pages_needed); } ret_value = uma_zalloc(pvzone, M_NOWAIT); return ret_value; @@ -3860,12 +3851,9 @@ pmap_remove(pmap_t pm, vm_offset_t sva, /* * we lock in the pmap => pv_head direction */ -#if 0 - PMAP_MAP_TO_HEAD_LOCK(); - pmap_acquire_pmap_lock(pm); -#endif vm_page_lock_queues(); + PMAP_LOCK(pm); if (!pmap_is_current(pm)) { cleanlist_idx = PMAP_REMOVE_CLEAN_LIST_SIZE + 1; } else @@ -3917,18 +3905,11 @@ pmap_remove(pmap_t pm, vm_offset_t sva, */ if ((pg = PHYS_TO_VM_PAGE(pa)) != NULL) { struct pv_entry *pve; -#if 0 - simple_lock(&pg->mdpage.pvh_slock); -#endif + pve = pmap_remove_pv(pg, pm, sva); if (pve) { -#if 0 - simple_unlock(&pg->mdpage.pvh_slock); -#endif - is_exec = - PV_BEEN_EXECD(pve->pv_flags); - is_refd = - PV_BEEN_REFD(pve->pv_flags); + is_exec = PV_BEEN_EXECD(pve->pv_flags); + is_refd = PV_BEEN_REFD(pve->pv_flags); pmap_free_pv_entry(pve); } } @@ -4022,10 +4003,7 @@ pmap_remove(pmap_t pm, vm_offset_t sva, vm_page_unlock_queues(); if (flushall) cpu_tlb_flushID(); -#if 0 - pmap_release_pmap_lock(pm); - PMAP_MAP_TO_HEAD_UNLOCK(); -#endif + PMAP_UNLOCK(pm); } @@ -4074,7 +4052,7 @@ pmap_zero_page_generic(vm_paddr_t phys, void pmap_zero_page_xscale(vm_paddr_t phys, int off, int size) { - + mtx_lock(&cmtx); /* * Hook in the page, zero it, and purge the cache for that @@ -4175,6 +4153,7 @@ pmap_zero_page_idle(vm_page_t m) pmap_zero_page(m); } +#if 0 /* * pmap_clean_page() * @@ -4261,6 +4240,7 @@ pmap_clean_page(struct pv_entry *pv, boo } return (0); } +#endif /* * pmap_copy_page copies the specified (machine independent) @@ -4280,7 +4260,9 @@ pmap_clean_page(struct pv_entry *pv, boo void pmap_copy_page_generic(vm_paddr_t src, vm_paddr_t dst) { +#if 0 struct vm_page *src_pg = PHYS_TO_VM_PAGE(src); +#endif #ifdef DEBUG struct vm_page *dst_pg = PHYS_TO_VM_PAGE(dst); @@ -4295,10 +4277,12 @@ pmap_copy_page_generic(vm_paddr_t src, v * be created while we have a potentially aliased mapping. */ #if 0 - mtx_lock(&src_pg->md.pvh_mtx); -#endif + /* + * XXX: Not needed while we call cpu_dcache_wbinv_all() in + * pmap_copy_page(). + */ (void) pmap_clean_page(TAILQ_FIRST(&src_pg->md.pv_list), TRUE); - +#endif /* * Map the pages into the page hook points, copy them, and purge * the cache for the appropriate page. Invalidate the TLB @@ -4317,9 +4301,6 @@ pmap_copy_page_generic(vm_paddr_t src, v bcopy_page(csrcp, cdstp); mtx_unlock(&cmtx); cpu_dcache_inv_range(csrcp, PAGE_SIZE); -#if 0 - mtx_lock(&src_pg->md.pvh_mtx); -#endif cpu_dcache_wbinv_range(cdstp, PAGE_SIZE); } #endif /* (ARM_MMU_GENERIC + ARM_MMU_SA1) != 0 */ @@ -4328,7 +4309,10 @@ pmap_copy_page_generic(vm_paddr_t src, v void pmap_copy_page_xscale(vm_paddr_t src, vm_paddr_t dst) { +#if 0 + /* XXX: Only needed for pmap_clean_page(), which is commented out. */ struct vm_page *src_pg = PHYS_TO_VM_PAGE(src); +#endif #ifdef DEBUG struct vm_page *dst_pg = PHYS_TO_VM_PAGE(dst); @@ -4342,8 +4326,13 @@ pmap_copy_page_xscale(vm_paddr_t src, vm * the duration of the copy so that no other mappings can * be created while we have a potentially aliased mapping. */ +#if 0 + /* + * XXX: Not needed while we call cpu_dcache_wbinv_all() in + * pmap_copy_page(). + */ (void) pmap_clean_page(TAILQ_FIRST(&src_pg->md.pv_list), TRUE); - +#endif /* * Map the pages into the page hook points, copy them, and purge * the cache for the appropriate page. Invalidate the TLB @@ -4386,13 +4375,10 @@ pmap_page_exists_quick(pmap_t pmap, vm_p { pv_entry_t pv; int loops = 0; - int s; if (m->flags & PG_FICTITIOUS) return (FALSE); - s = splvm(); - /* * Not found, check current mappings returning immediately */ @@ -4400,14 +4386,12 @@ pmap_page_exists_quick(pmap_t pmap, vm_p pv; pv = TAILQ_NEXT(pv, pv_list)) { if (pv->pv_pmap == pmap) { - splx(s); return (TRUE); } loops++; if (loops >= 16) break; } - splx(s); return (FALSE); } @@ -4559,22 +4543,10 @@ pmap_link_l2pt(vm_offset_t l1pt, vm_offs pd_entry_t *pde = (pd_entry_t *) l1pt, proto; u_int slot = va >> L1_S_SHIFT; -#ifndef ARM32_NEW_VM_LAYOUT - KASSERT((va & ((L1_S_SIZE * 4) - 1)) == 0, ("blah")); - KASSERT((l2pv->pv_pa & PAGE_MASK) == 0, ("ouin")); -#endif - proto = L1_S_DOM(PMAP_DOMAIN_KERNEL) | L1_C_PROTO; pde[slot + 0] = proto | (l2pv->pv_pa + 0x000); -#ifdef ARM32_NEW_VM_LAYOUT PTE_SYNC(&pde[slot]); -#else - pde[slot + 1] = proto | (l2pv->pv_pa + 0x400); - pde[slot + 2] = proto | (l2pv->pv_pa + 0x800); - pde[slot + 3] = proto | (l2pv->pv_pa + 0xc00); - PTE_SYNC_RANGE(&pde[slot + 0], 4); -#endif SLIST_INSERT_HEAD(&kernel_pt_list, l2pv, pv_list); @@ -4614,25 +4586,14 @@ pmap_map_entry(vm_offset_t l1pt, vm_offs if ((pde[va >> L1_S_SHIFT] & L1_TYPE_MASK) != L1_TYPE_C) panic("pmap_map_entry: no L2 table for VA 0x%08x", va); -#ifndef ARM32_NEW_VM_LAYOUT - pte = (pt_entry_t *) - kernel_pt_lookup(pde[va >> L1_S_SHIFT] & L2_S_FRAME); -#else pte = (pt_entry_t *) kernel_pt_lookup(pde[L1_IDX(va)] & L1_C_ADDR_MASK); -#endif if (pte == NULL) panic("pmap_map_entry: can't find L2 table for VA 0x%08x", va); -#ifndef ARM32_NEW_VM_LAYOUT - pte[(va >> PAGE_SHIFT) & 0x3ff] = - L2_S_PROTO | pa | L2_S_PROT(PTE_KERNEL, prot) | fl; - PTE_SYNC(&pte[(va >> PAGE_SHIFT) & 0x3ff]); -#else pte[l2pte_index(va)] = L2_S_PROTO | pa | L2_S_PROT(PTE_KERNEL, prot) | fl; PTE_SYNC(&pte[l2pte_index(va)]); -#endif } /* @@ -4657,7 +4618,7 @@ pmap_map_chunk(vm_offset_t l1pt, vm_offs panic("pmap_map_chunk: no L1 table provided"); #ifdef VERBOSE_INIT_ARM - printf("pmap_map_chunk: pa=0x%lx va=0x%lx size=0x%lx resid=0x%lx " + printf("pmap_map_chunk: pa=0x%x va=0x%x size=0x%x resid=0x%x " "prot=0x%x cache=%d\n", pa, va, size, resid, prot, cache); #endif @@ -4708,13 +4669,8 @@ pmap_map_chunk(vm_offset_t l1pt, vm_offs if ((pde[va >> L1_S_SHIFT] & L1_TYPE_MASK) != L1_TYPE_C) panic("pmap_map_chunk: no L2 table for VA 0x%08x", va); -#ifndef ARM32_NEW_VM_LAYOUT - pte = (pt_entry_t *) - kernel_pt_lookup(pde[va >> L1_S_SHIFT] & L2_S_FRAME); -#else pte = (pt_entry_t *) kernel_pt_lookup( pde[L1_IDX(va)] & L1_C_ADDR_MASK); -#endif if (pte == NULL) panic("pmap_map_chunk: can't find L2 table for VA" "0x%08x", va); @@ -4724,17 +4680,10 @@ pmap_map_chunk(vm_offset_t l1pt, vm_offs printf("L"); #endif for (i = 0; i < 16; i++) { -#ifndef ARM32_NEW_VM_LAYOUT - pte[((va >> PAGE_SHIFT) & 0x3f0) + i] = - L2_L_PROTO | pa | - L2_L_PROT(PTE_KERNEL, prot) | f2l; - PTE_SYNC(&pte[((va >> PAGE_SHIFT) & 0x3f0) + i]); -#else pte[l2pte_index(va) + i] = L2_L_PROTO | pa | L2_L_PROT(PTE_KERNEL, prot) | f2l; PTE_SYNC(&pte[l2pte_index(va) + i]); -#endif } va += L2_L_SIZE; pa += L2_L_SIZE; @@ -4746,15 +4695,9 @@ pmap_map_chunk(vm_offset_t l1pt, vm_offs #ifdef VERBOSE_INIT_ARM printf("P"); #endif -#ifndef ARM32_NEW_VM_LAYOUT - pte[(va >> PAGE_SHIFT) & 0x3ff] = - L2_S_PROTO | pa | L2_S_PROT(PTE_KERNEL, prot) | f2s; - PTE_SYNC(&pte[(va >> PAGE_SHIFT) & 0x3ff]); -#else pte[l2pte_index(va)] = L2_S_PROTO | pa | L2_S_PROT(PTE_KERNEL, prot) | f2s; PTE_SYNC(&pte[l2pte_index(va)]); -#endif va += PAGE_SIZE; pa += PAGE_SIZE; resid -= PAGE_SIZE; @@ -4796,7 +4739,7 @@ pmap_devmap_bootstrap(vm_offset_t l1pt, for (i = 0; pmap_devmap_table[i].pd_size != 0; i++) { #ifdef VERBOSE_INIT_ARM - printf("devmap: %08lx -> %08lx @ %08lx\n", + printf("devmap: %08x -> %08x @ %08x\n", pmap_devmap_table[i].pd_pa, pmap_devmap_table[i].pd_pa + pmap_devmap_table[i].pd_size - 1, Index: arm/at91/uart_dev_at91usart.c =================================================================== RCS file: /cognet/ncvs/src/sys/arm/at91/uart_dev_at91usart.c,v retrieving revision 1.6.2.2 diff -u -p -r1.6.2.2 uart_dev_at91usart.c --- arm/at91/uart_dev_at91usart.c 18 Jul 2006 21:58:49 -0000 1.6.2.2 +++ arm/at91/uart_dev_at91usart.c 19 Jul 2006 20:39:55 -0000 @@ -93,7 +93,7 @@ static void at91_usart_init(struct uart_ static void at91_usart_term(struct uart_bas *bas); static void at91_usart_putc(struct uart_bas *bas, int); static int at91_usart_poll(struct uart_bas *bas); -static int at91_usart_getc(struct uart_bas *bas, struct mtx *mtx); +static int at91_usart_getc(struct uart_bas *bas); extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs; @@ -265,7 +265,7 @@ at91_usart_poll(struct uart_bas *bas) * Block waiting for a character. */ static int -at91_usart_getc(struct uart_bas *bas, struct mtx *mtx) +at91_usart_getc(struct uart_bas *bas) { int c; @@ -426,7 +426,7 @@ at91_usart_bus_transmit(struct uart_soft bus_dmamap_sync(atsc->dmatag, atsc->tx_map, BUS_DMASYNC_PREWRITE); #endif - uart_lock(sc->sc_hwmtx); + mtx_lock_spin(&sc->sc_hwmtx); sc->sc_txbusy = 1; #ifndef SKYEYE_WORKAROUNDS /* @@ -437,7 +437,7 @@ at91_usart_bus_transmit(struct uart_soft WR4(&sc->sc_bas, PDC_TCR, sc->sc_txdatasz); WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_TXTEN); WR4(&sc->sc_bas, USART_IER, USART_CSR_ENDTX); - uart_unlock(sc->sc_hwmtx); + mtx_unlock_spin(&sc->sc_hwmtx); #else for (int i = 0; i < sc->sc_txdatasz; i++) at91_usart_putc(&sc->sc_bas, sc->sc_txbuf[i]); @@ -464,7 +464,7 @@ at91_usart_bus_setsig(struct uart_softc SIGCHG(sig & SER_RTS, new, SER_RTS, SER_DRTS); } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); bas = &sc->sc_bas; - uart_lock(sc->sc_hwmtx); + mtx_lock_spin(&sc->sc_hwmtx); cr = 0; if (new & SER_DTR) cr |= USART_CR_DTREN; @@ -475,7 +475,7 @@ at91_usart_bus_setsig(struct uart_softc else cr |= USART_CR_RTSDIS; WR4(bas, USART_CR, cr); - uart_unlock(sc->sc_hwmtx); + mtx_unlock_spin(&sc->sc_hwmtx); return (0); } static int @@ -506,15 +506,15 @@ at91_usart_bus_ipend(struct uart_softc * BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(atsc->dmatag, atsc->tx_map); } - uart_lock(sc->sc_hwmtx); + mtx_lock_spin(&sc->sc_hwmtx); if (csr & USART_CSR_TXRDY) { if (sc->sc_txbusy) - ipend |= SER_INT_TXIDLE; + ipend |= UART_IPEND_TXIDLE; WR4(&sc->sc_bas, USART_IDR, USART_CSR_TXRDY); } if (csr & USART_CSR_ENDTX) { if (sc->sc_txbusy) - ipend |= SER_INT_TXIDLE; + ipend |= UART_IPEND_TXIDLE; WR4(&sc->sc_bas, USART_IDR, USART_CSR_ENDTX); } @@ -544,7 +544,7 @@ at91_usart_bus_ipend(struct uart_softc * WR4(&sc->sc_bas, PDC_RNPR, atsc->pong->pa); WR4(&sc->sc_bas, PDC_RNCR, sc->sc_rxfifosz); WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_RXTEN); - ipend |= SER_INT_RXREADY; + ipend |= UART_IPEND_RXREADY; } if ((atsc->flags & HAS_TIMEOUT) && (csr & USART_CSR_ENDRX)) { // Shuffle data from 'ping' of ping pong buffer, but @@ -560,7 +560,7 @@ at91_usart_bus_ipend(struct uart_softc * atsc->pong = p; WR4(&sc->sc_bas, PDC_RNPR, atsc->pong->pa); WR4(&sc->sc_bas, PDC_RNCR, sc->sc_rxfifosz); - ipend |= SER_INT_RXREADY; + ipend |= UART_IPEND_RXREADY; } if ((atsc->flags & HAS_TIMEOUT) && (csr & USART_CSR_TIMEOUT)) { // We have one partial buffer. We need to stop the @@ -579,22 +579,22 @@ at91_usart_bus_ipend(struct uart_softc * WR4(&sc->sc_bas, PDC_RCR, sc->sc_rxfifosz); WR4(&sc->sc_bas, USART_CR, USART_CR_STTTO); WR4(&sc->sc_bas, PDC_PTCR, PDC_PTCR_RXTEN); - ipend |= SER_INT_RXREADY; + ipend |= UART_IPEND_RXREADY; } if (!(atsc->flags & HAS_TIMEOUT) && (csr & USART_CSR_RXRDY)) { // We have another charater in a device that doesn't support // timeouts, so we do it one character at a time. uart_rx_put(sc, RD4(&sc->sc_bas, USART_RHR) & 0xff); - ipend |= SER_INT_RXREADY; + ipend |= UART_IPEND_RXREADY; } if (csr & USART_CSR_RXBRK) { unsigned int cr = USART_CR_RSTSTA; - ipend |= SER_INT_BREAK; + ipend |= UART_IPEND_BREAK; WR4(&sc->sc_bas, USART_CR, cr); } - uart_unlock(sc->sc_hwmtx); + mtx_unlock_spin(&sc->sc_hwmtx); return (ipend); } static int @@ -609,7 +609,7 @@ at91_usart_bus_getsig(struct uart_softc uint32_t new, sig; uint8_t csr; - uart_lock(sc->sc_hwmtx); + mtx_lock_spin(&sc->sc_hwmtx); csr = RD4(&sc->sc_bas, USART_CSR); sig = 0; if (csr & USART_CSR_CTS) @@ -620,9 +620,9 @@ at91_usart_bus_getsig(struct uart_softc sig |= SER_DSR; if (csr & USART_CSR_RI) sig |= SER_RI; - new = sig & ~SER_MASK_DELTA; + new = sig & ~UART_SIGMASK_DELTA; sc->sc_hwsig = new; - uart_unlock(sc->sc_hwmtx); + mtx_unlock_spin(&sc->sc_hwmtx); return (sig); } Index: arm/conf/IQ31244 =================================================================== RCS file: /cognet/ncvs/src/sys/arm/conf/IQ31244,v retrieving revision 1.11.2.1 diff -u -p -r1.11.2.1 IQ31244 --- arm/conf/IQ31244 23 Jun 2006 16:56:57 -0000 1.11.2.1 +++ arm/conf/IQ31244 19 Jul 2006 20:25:39 -0000 @@ -25,7 +25,6 @@ options KERNPHYSADDR=0xa0200000 options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm options STARTUP_PAGETABLE_ADDR=0xa0000000 -options ARM32_NEW_VM_LAYOUT include "../xscale/i80321/std.iq31244" #To statically compile in device wiring instead of /boot/device.hints #hints "GENERIC.hints" #Default places to look for devices. Index: arm/conf/KB920X =================================================================== RCS file: /cognet/ncvs/src/sys/arm/conf/KB920X,v retrieving revision 1.7.2.2 diff -u -p -r1.7.2.2 KB920X --- arm/conf/KB920X 18 Jul 2006 22:03:33 -0000 1.7.2.2 +++ arm/conf/KB920X 19 Jul 2006 20:42:03 -0000 @@ -57,7 +57,6 @@ options SYSVSEM #SYSV-style semaphore options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions #options SYSCTL_OMIT_DESCR options MUTEX_NOINLINE -options RWLOCK_NOINLINE options NO_FFS_SNAPSHOT options NO_SWAPPING device genclock @@ -68,8 +67,7 @@ device ether device nexus device uart device ate -device mii -device lxtphy +device miibus # Debugging for use in -current #options INVARIANTS #Enable calls of extra sanity checking Index: arm/conf/SKYEYE =================================================================== RCS file: /cognet/ncvs/src/sys/arm/conf/SKYEYE,v retrieving revision 1.5.2.1 diff -u -p -r1.5.2.1 SKYEYE --- arm/conf/SKYEYE 23 Jun 2006 23:35:35 -0000 1.5.2.1 +++ arm/conf/SKYEYE 19 Jul 2006 20:25:51 -0000 @@ -24,7 +24,6 @@ ident KB920X options KERNPHYSADDR=0xc0000000 options KERNVIRTADDR=0xc0000000 options PHYSADDR=0xc0000000 -options ARM32_NEW_VM_LAYOUT include "../at91/std.kb920x" #To statically compile in device wiring instead of /boot/device.hints #hints "GENERIC.hints" #Default places to look for devices. Index: arm/include/pmap.h =================================================================== RCS file: /cognet/ncvs/src/sys/arm/include/pmap.h,v retrieving revision 1.10.2.1 diff -u -p -r1.10.2.1 pmap.h --- arm/include/pmap.h 23 Jun 2006 17:41:02 -0000 1.10.2.1 +++ arm/include/pmap.h 19 Jul 2006 20:21:20 -0000 @@ -62,6 +62,8 @@ #ifndef LOCORE #include +#include +#include #define PDESIZE sizeof(pd_entry_t) /* for assembly files */ #define PTESIZE sizeof(pt_entry_t) /* for assembly files */ @@ -136,6 +138,7 @@ struct l2_dtable; #define L2_SIZE (1 << L2_LOG2) struct pmap { + struct mtx pm_mtx; u_int8_t pm_domain; struct l1_ttable *pm_l1; struct l2_dtable *pm_l2[L2_SIZE]; @@ -144,7 +147,6 @@ struct pmap { int pm_active; /* active on cpus */ struct pmap_statistics pm_stats; /* pmap statictics */ TAILQ_HEAD(,pv_entry) pm_pvlist; /* list of mappings in pmap */ - LIST_ENTRY(pmap) pm_list; /* List of all pmaps */ }; typedef struct pmap *pmap_t; @@ -153,6 +155,16 @@ typedef struct pmap *pmap_t; extern pmap_t kernel_pmap; #define pmap_kernel() kernel_pmap +#define PMAP_ASSERT_LOCKED(pmap) \ + mtx_assert(&(pmap)->pm_mtx, MA_OWNED) +#define PMAP_LOCK(pmap) mtx_lock(&(pmap)->pm_mtx) +#define PMAP_LOCK_DESTROY(pmap) mtx_destroy(&(pmap)->pm_mtx) +#define PMAP_LOCK_INIT(pmap) mtx_init(&(pmap)->pm_mtx, "pmap", \ + NULL, MTX_DEF | MTX_DUPOK) +#define PMAP_OWNED(pmap) mtx_owned(&(pmap)->pm_mtx) +#define PMAP_MTX(pmap) (&(pmap)->pm_mtx) +#define PMAP_TRYLOCK(pmap) mtx_trylock(&(pmap)->pm_mtx) +#define PMAP_UNLOCK(pmap) mtx_unlock(&(pmap)->pm_mtx) #endif Index: arm/sa11x0/assabet_machdep.c =================================================================== RCS file: /cognet/ncvs/src/sys/arm/sa11x0/assabet_machdep.c,v retrieving revision 1.9 diff -u -p -r1.9 assabet_machdep.c --- arm/sa11x0/assabet_machdep.c 5 Jan 2005 21:58:48 -0000 1.9 +++ arm/sa11x0/assabet_machdep.c 19 Jul 2006 20:26:42 -0000 @@ -47,7 +47,7 @@ #include -__FBSDID("$FreeBSD: src/sys/arm/sa11x0/assabet_machdep.c,v 1.9 2005/01/05 21:58:48 imp Exp $"); +__FBSDID("$FreeBSD: src/sys/arm/sa11x0/assabet_machdep.c,v 1.17 2006/06/07 11:28:17 cognet Exp $"); #include "opt_md.h" @@ -93,6 +93,8 @@ __FBSDID("$FreeBSD: src/sys/arm/sa11x0/a #include #include +#include + #define MDROOT_ADDR 0xd0400000 #define KERNEL_PT_VMEM 0 /* Page table for mapping video memory */ @@ -102,7 +104,7 @@ __FBSDID("$FreeBSD: src/sys/arm/sa11x0/a #define KERNEL_PT_KERNEL 1 /* Page table for mapping kernel */ #define KERNEL_PT_L1 4 /* Page table for mapping l1pt */ #define KERNEL_PT_VMDATA 5 /* Page tables for mapping kernel VM */ -#define KERNEL_PT_VMDATA_NUM 4 /* start with 16MB of KVM */ +#define KERNEL_PT_VMDATA_NUM 7 /* start with 16MB of KVM */ #define NUM_KERNEL_PTS (KERNEL_PT_VMDATA + KERNEL_PT_VMDATA_NUM) /* Define various stack sizes in pages */ @@ -113,7 +115,7 @@ __FBSDID("$FreeBSD: src/sys/arm/sa11x0/a #else #define UND_STACK_SIZE 1 #endif -#define KERNEL_VM_BASE (KERNBASE + 0x00c00000) +#define KERNEL_VM_BASE (KERNBASE + 0x00100000) #define KERNEL_VM_SIZE 0x05000000 extern u_int data_abort_handler_address; @@ -124,7 +126,7 @@ struct pv_addr kernel_pt_table[NUM_KERNE extern void *_end; -int got_mmu = 0; +extern vm_offset_t sa1110_uart_vaddr; extern vm_offset_t sa1_cache_clean_addr; @@ -139,6 +141,7 @@ struct pcpu *pcpup = &__pcpu; /* Physical and virtual addresses for some global pages */ vm_paddr_t phys_avail[10]; +vm_paddr_t dump_avail[4]; vm_paddr_t physical_start; vm_paddr_t physical_end; vm_paddr_t physical_freestart; @@ -150,9 +153,37 @@ struct pv_addr irqstack; struct pv_addr undstack; struct pv_addr abtstack; struct pv_addr kernelstack; -void enable_mmu(vm_offset_t); static struct trapframe proc0_tf; +/* Static device mappings. */ +static const struct pmap_devmap assabet_devmap[] = { + /* + * Map the on-board devices VA == PA so that we can access them + * with the MMU on or off. + */ + { + SACOM1_VBASE, + SACOM1_BASE, + SACOM1_SIZE, + VM_PROT_READ|VM_PROT_WRITE, + PTE_NOCACHE, + }, + { + SAIPIC_BASE, + SAIPIC_BASE, + SAIPIC_SIZE, + VM_PROT_READ|VM_PROT_WRITE, + PTE_NOCACHE, + }, + { + 0, + 0, + 0, + 0, + 0, + } +}; + struct arm32_dma_range * bus_dma_get_range(void) { @@ -190,6 +221,8 @@ initarm(void *arg, void *arg2) vm_size_t pt_size; int i = 0; uint32_t fake_preload[35]; + uint32_t memsize = 32 * 1024 * 1024; + sa1110_uart_vaddr = SACOM1_VBASE; boothowto = RB_VERBOSE | RB_SINGLE; cninit(); @@ -226,7 +259,7 @@ initarm(void *arg, void *arg2) fake_preload[i] = 0; preload_metadata = (void *)fake_preload; - physmem =( 16 * 1024 * 1024) / PAGE_SIZE; + physmem = memsize / PAGE_SIZE; pc = &__pcpu; pcpu_init(pc, 0, sizeof(struct pcpu)); PCPU_SET(curthread, &thread0); @@ -255,9 +288,18 @@ initarm(void *arg, void *arg2) valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE); valloc_pages(md_bla, L2_TABLE_SIZE / PAGE_SIZE); alloc_pages(sa1_cache_clean_addr, CPU_SA110_CACHE_CLEAN_SIZE / PAGE_SIZE); + for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) { - valloc_pages(kernel_pt_table[loop], - L2_TABLE_SIZE / PAGE_SIZE); + if (!(loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) { + valloc_pages(kernel_pt_table[loop], + L2_TABLE_SIZE / PAGE_SIZE); + } else { + kernel_pt_table[loop].pv_pa = freemempos + + (loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL)) * + L2_TABLE_SIZE_REAL; + kernel_pt_table[loop].pv_va = + kernel_pt_table[loop].pv_pa; + } } valloc_pages(systempage, 1); @@ -304,10 +346,10 @@ initarm(void *arg, void *arg2) pmap_link_l2pt(l1pagetable, MDROOT_ADDR, &md_bla); for (loop = 0; loop < KERNEL_PT_VMDATA_NUM; ++loop) - pmap_link_l2pt(l1pagetable, KERNEL_VM_BASE + loop * 0x00400000, + pmap_link_l2pt(l1pagetable, KERNEL_VM_BASE + loop * 0x00100000, &kernel_pt_table[KERNEL_PT_VMDATA + loop]); pmap_map_chunk(l1pagetable, KERNBASE, KERNBASE, - (uint32_t)&end - KERNBASE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); + ((uint32_t)&end - KERNBASE), VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); /* Map the stack pages */ pmap_map_chunk(l1pagetable, irqstack.pv_va, irqstack.pv_pa, IRQ_STACK_SIZE * PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); @@ -333,11 +375,8 @@ initarm(void *arg, void *arg2) /* Map the vector page. */ pmap_map_entry(l1pagetable, vector_page, systempage.pv_pa, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); - /* Map SACOM3. */ - pmap_map_entry(l1pagetable, 0xd000d000, 0x80010000, - VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE); - pmap_map_entry(l1pagetable, 0x90050000, 0x90050000, - VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE); + /* Map the statically mapped devices. */ + pmap_devmap_bootstrap(l1pagetable, assabet_devmap); pmap_map_chunk(l1pagetable, sa1_cache_clean_addr, 0xf0000000, CPU_SA110_CACHE_CLEAN_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); @@ -377,7 +416,7 @@ initarm(void *arg, void *arg2) * After booting there are no gross reloations of the kernel thus * this problem will not occur after initarm(). */ -/* cpu_idcache_wbinv_all();*/ + cpu_idcache_wbinv_all(); bootverbose = 1; @@ -395,7 +434,6 @@ initarm(void *arg, void *arg2) /* Enable MMU, I-cache, D-cache, write buffer. */ cpufunc_control(0x337f, 0x107d); - got_mmu = 1; arm_vector_init(ARM_VECTORS_LOW, ARM_VEC_ALL); pmap_curmaxkvaddr = freemempos + KERNEL_PT_VMDATA_NUM * 0x400000; @@ -407,16 +445,16 @@ initarm(void *arg, void *arg2) mutex_init(); - phys_avail[0] = round_page(virtual_avail); - phys_avail[1] = 0xc0000000 + 0x02000000 - 1; - phys_avail[2] = 0; - phys_avail[3] = 0; + dump_avail[0] = phys_avail[0] = round_page(virtual_avail); + dump_avail[1] = phys_avail[1] = 0xc0000000 + 0x02000000 - 1; + dump_avail[2] = phys_avail[2] = 0; + dump_avail[3] = phys_avail[3] = 0; /* Do basic tuning, hz etc */ init_param1(); init_param2(physmem); kdb_init(); - avail_end = 0xc0000000 + 0x02000000 - 1; + avail_end = 0xc0000000 + memsize - 1; return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP - sizeof(struct pcb))); } Index: conf/options.arm =================================================================== RCS file: /cognet/ncvs/src/sys/conf/options.arm,v retrieving revision 1.5 diff -u -p -r1.5 options.arm --- conf/options.arm 7 Jun 2005 23:05:04 -0000 1.5 +++ conf/options.arm 19 Jul 2006 20:31:32 -0000 @@ -1,5 +1,4 @@ #$FreeBSD: src/sys/conf/options.arm,v 1.5 2005/06/07 23:05:04 cognet Exp $ -ARM32_NEW_VM_LAYOUT opt_vm.h ARM9_CACHE_WRITE_THROUGH opt_global.h ARM_CACHE_LOCK_ENABLE opt_global.h ARMFPE opt_global.h @@ -13,3 +12,5 @@ KERNPHYSADDR opt_global.h KERNVIRTADDR opt_global.h STARTUP_PAGETABLE_ADDR opt_global.h XSCALE_CACHE_READ_WRITE_ALLOCATE opt_global.h +AT91_TSC opt_at91.h +AT91_KWIKBYTE opt_at91.h Index: kern/vfs_subr.c =================================================================== RCS file: /cognet/ncvs/src/sys/kern/vfs_subr.c,v retrieving revision 1.635.2.19 diff -u -p -r1.635.2.19 vfs_subr.c --- kern/vfs_subr.c 5 Jul 2006 16:34:16 -0000 1.635.2.19 +++ kern/vfs_subr.c 19 Jul 2006 20:33:05 -0000 @@ -109,8 +109,7 @@ static int vfs_knllocked(void *arg); * Enable Giant pushdown based on whether or not the vm is mpsafe in this * build. Without mpsafevm the buffer cache can not run Giant free. */ -#if defined(__alpha__) || defined(__amd64__) || defined(__i386__) || \ - defined(__sparc64__) +#if !defined(__powerpc__) int mpsafe_vfs = 1; #else int mpsafe_vfs; Index: vm/vm_meter.c =================================================================== RCS file: /cognet/ncvs/src/sys/vm/vm_meter.c,v retrieving revision 1.85.2.1 diff -u -p -r1.85.2.1 vm_meter.c --- vm/vm_meter.c 2 Jun 2006 00:26:27 -0000 1.85.2.1 +++ vm/vm_meter.c 19 Jul 2006 20:32:29 -0000 @@ -55,7 +55,7 @@ __FBSDID("$FreeBSD: src/sys/vm/vm_meter. /* * Virtual memory MPSAFE temporary workarounds. */ -#if !defined(__arm__) && !defined(__powerpc__) +#if !defined(__powerpc__) int debug_mpsafevm = 1; #else int debug_mpsafevm;