From 1e3003dad7c5c63daba3a0a54023266d94e3244d Mon Sep 17 00:00:00 2001 From: chs Date: Tue, 3 Jul 2001 06:15:16 +0000 Subject: [PATCH] vm_offset_t -> [pv]addr_t. implement pmap_k{enter_pa,remove}() correctly. general cleanup. --- sys/arch/sun3/sun3/pmap.c | 728 ++++++++++++++++++++----------------- sys/arch/sun3/sun3x/pmap.c | 431 ++++++++-------------- 2 files changed, 533 insertions(+), 626 deletions(-) diff --git a/sys/arch/sun3/sun3/pmap.c b/sys/arch/sun3/sun3/pmap.c index b4d02e78416f..1f5954f8f363 100644 --- a/sys/arch/sun3/sun3/pmap.c +++ b/sys/arch/sun3/sun3/pmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.131 2001/06/19 12:59:16 wiz Exp $ */ +/* $NetBSD: pmap.c,v 1.132 2001/07/03 06:15:16 chs Exp $ */ /*- * Copyright (c) 1996 The NetBSD Foundation, Inc. @@ -92,17 +92,13 @@ #include #include #include -#include +#include #include #include #include #include -/* XXX - Pager hacks... (explain?) */ -#define PAGER_SVA (uvm.pager_sva) -#define PAGER_EVA (uvm.pager_eva) - #include #include #include @@ -189,7 +185,8 @@ #define PMD_CREATE 0x200 #define PMD_SEGMAP 0x400 #define PMD_SETPTE 0x800 -#define PMD_FAULT 0x1000 +#define PMD_FAULT 0x1000 +#define PMD_KMAP 0x2000 #define PMD_REMOVE PMD_ENTER #define PMD_UNLINK PMD_LINK @@ -200,7 +197,6 @@ int pmap_db_watchva = -1; int pmap_db_watchpmeg = -1; #endif /* PMAP_DEBUG */ - /* * Miscellaneous variables. * @@ -209,24 +205,24 @@ int pmap_db_watchpmeg = -1; * These are set in pmap_bootstrap() and used in * pmap_next_page(). */ -vm_offset_t virtual_avail, virtual_end; -vm_offset_t avail_start, avail_end; +vaddr_t virtual_avail, virtual_end; +paddr_t avail_start, avail_end; #define managed(pa) (((pa) >= avail_start) && ((pa) < avail_end)) /* used to skip the Sun3/50 video RAM */ -static vm_offset_t hole_start, hole_size; +static vaddr_t hole_start, hole_size; /* This is for pmap_next_page() */ -static vm_offset_t avail_next; +static paddr_t avail_next; /* This is where we map a PMEG without a context. */ -static vm_offset_t temp_seg_va; +static vaddr_t temp_seg_va; /* * Location to store virtual addresses * to be used in copy/zero operations. */ -vm_offset_t tmp_vpages[2] = { +vaddr_t tmp_vpages[2] = { SUN3_MONSHORTSEG, SUN3_MONSHORTSEG + NBPG }; int tmp_vpages_inuse; @@ -235,9 +231,9 @@ static int pmap_version = 1; struct pmap kernel_pmap_store; #define kernel_pmap (&kernel_pmap_store) static u_char kernel_segmap[NSEGMAP]; - -/* memory pool for pmap structures */ -struct pool pmap_pmap_pool; + +/* memory pool for pmap structures */ +struct pool pmap_pmap_pool; /* statistics... */ struct pmap_stats { @@ -254,27 +250,12 @@ struct pmap_stats { int ps_vac_recached; /* re-cached when bad alias gone */ } pmap_stats; - -/* - * locking issues: These used to do spl* stuff. - * XXX: Use these for reentrance detection? - */ -#define PMAP_LOCK() (void)/XXX -#define PMAP_UNLOCK() (void)/XXX - #define pmap_lock(pmap) simple_lock(&pmap->pm_lock) #define pmap_unlock(pmap) simple_unlock(&pmap->pm_lock) #define pmap_add_ref(pmap) ++pmap->pm_refcount #define pmap_del_ref(pmap) --pmap->pm_refcount #define pmap_refcount(pmap) pmap->pm_refcount -/* - * Note that splvm() is used in routines called at splnet() and - * MUST NOT lower the priority. For this reason we arrange that: - * splimp = max(splnet,splbio) - * Would splvm() be more natural here? (same level as splimp). - */ - #ifdef PMAP_DEBUG #define CHECK_SPL() do { \ if ((getsr() & PSL_IPL) < PSL_IPL4) \ @@ -290,17 +271,13 @@ struct pmap_stats { * (i.e. Find all virtual mappings of a physical page.) */ -/* - * XXX - Could eliminate this by causing managed() to return 0 - * ( avail_start = avail_end = 0 ) - */ int pv_initialized = 0; /* One of these for each mapped virtual page. */ struct pv_entry { struct pv_entry *pv_next; pmap_t pv_pmap; - vm_offset_t pv_va; + vaddr_t pv_va; }; typedef struct pv_entry *pv_entry_t; @@ -361,7 +338,7 @@ struct pmeg_state { int pmeg_index; pmap_t pmeg_owner; int pmeg_version; - vm_offset_t pmeg_va; + vaddr_t pmeg_va; int pmeg_wired; int pmeg_reserved; int pmeg_vpages; @@ -387,58 +364,56 @@ static struct pmeg_state pmeg_array[NPMEG]; static int get_pte_pmeg __P((int, int)); static void set_pte_pmeg __P((int, int, int)); -static void context_allocate __P((pmap_t pmap)); -static void context_free __P((pmap_t pmap)); +static void context_allocate __P((pmap_t)); +static void context_free __P((pmap_t)); static void context_init __P((void)); static void pmeg_init __P((void)); -static void pmeg_reserve __P((int pmeg_num)); +static void pmeg_reserve __P((int)); -static pmeg_t pmeg_allocate __P((pmap_t pmap, vm_offset_t va)); -static void pmeg_mon_init __P((vm_offset_t sva, vm_offset_t eva, int keep)); -static void pmeg_release __P((pmeg_t pmegp)); -static void pmeg_free __P((pmeg_t pmegp)); -static pmeg_t pmeg_cache __P((pmap_t pmap, vm_offset_t va)); -static void pmeg_set_wiring __P((pmeg_t pmegp, vm_offset_t va, int)); +static pmeg_t pmeg_allocate __P((pmap_t, vaddr_t)); +static void pmeg_mon_init __P((vaddr_t, vaddr_t, int)); +static void pmeg_release __P((pmeg_t)); +static void pmeg_free __P((pmeg_t)); +static pmeg_t pmeg_cache __P((pmap_t, vaddr_t)); +static void pmeg_set_wiring __P((pmeg_t, vaddr_t, int)); -static int pv_link __P((pmap_t pmap, int pte, vm_offset_t va)); -static void pv_unlink __P((pmap_t pmap, int pte, vm_offset_t va)); -static void pv_remove_all __P((vm_offset_t pa)); -static void pv_changepte __P((vm_offset_t pa, int, int)); +static int pv_link __P((pmap_t, int, vaddr_t)); +static void pv_unlink __P((pmap_t, int, vaddr_t)); +static void pv_remove_all __P((paddr_t)); +static void pv_changepte __P((paddr_t, int, int)); static u_int pv_syncflags __P((pv_entry_t)); static void pv_init __P((void)); -static void pmeg_clean __P((pmeg_t pmegp)); +static void pmeg_clean __P((pmeg_t)); static void pmeg_clean_free __P((void)); -static void pmap_common_init __P((pmap_t pmap)); -static void pmap_kernel_init __P((pmap_t pmap)); -static void pmap_user_init __P((pmap_t pmap)); +static void pmap_common_init __P((pmap_t)); +static void pmap_kernel_init __P((pmap_t)); +static void pmap_user_init __P((pmap_t)); static void pmap_page_upload __P((void)); -static void pmap_enter_kernel __P((vm_offset_t va, - int new_pte, boolean_t wired)); -static void pmap_enter_user __P((pmap_t pmap, vm_offset_t va, - int new_pte, boolean_t wired)); +static void pmap_enter_kernel __P((vaddr_t, int, boolean_t)); +static void pmap_enter_user __P((pmap_t, vaddr_t, int, boolean_t)); -static void pmap_protect1 __P((pmap_t, vm_offset_t, vm_offset_t)); -static void pmap_protect_mmu __P((pmap_t, vm_offset_t, vm_offset_t)); -static void pmap_protect_noctx __P((pmap_t, vm_offset_t, vm_offset_t)); +static void pmap_protect1 __P((pmap_t, vaddr_t, vaddr_t)); +static void pmap_protect_mmu __P((pmap_t, vaddr_t, vaddr_t)); +static void pmap_protect_noctx __P((pmap_t, vaddr_t, vaddr_t)); -static void pmap_remove1 __P((pmap_t pmap, vm_offset_t, vm_offset_t)); -static void pmap_remove_mmu __P((pmap_t, vm_offset_t, vm_offset_t)); -static void pmap_remove_noctx __P((pmap_t, vm_offset_t, vm_offset_t)); +static void pmap_remove1 __P((pmap_t, vaddr_t, vaddr_t)); +static void pmap_remove_mmu __P((pmap_t, vaddr_t, vaddr_t)); +static void pmap_remove_noctx __P((pmap_t, vaddr_t, vaddr_t)); -static int pmap_fault_reload __P((struct pmap *, vm_offset_t, int)); +static int pmap_fault_reload __P((struct pmap *, vaddr_t, int)); /* Called only from locore.s and pmap.c */ -void _pmap_switch __P((pmap_t pmap)); +void _pmap_switch __P((pmap_t)); #ifdef PMAP_DEBUG -void pmap_print __P((pmap_t pmap)); -void pv_print __P((vm_offset_t pa)); -void pmeg_print __P((pmeg_t pmegp)); -static void pmeg_verify_empty __P((vm_offset_t va)); +void pmap_print __P((pmap_t)); +void pv_print __P((struct vm_page *)); +void pmeg_print __P((pmeg_t)); +static void pmeg_verify_empty __P((vaddr_t)); #endif /* PMAP_DEBUG */ void pmap_pinit __P((pmap_t)); void pmap_release __P((pmap_t)); @@ -468,7 +443,7 @@ current_pmap __P((void)) } static inline struct pv_entry ** -pa_to_pvhead(vm_offset_t pa) +pa_to_pvhead(paddr_t pa) { int idx; @@ -481,7 +456,7 @@ pa_to_pvhead(vm_offset_t pa) } static inline u_char * -pa_to_pvflags(vm_offset_t pa) +pa_to_pvflags(paddr_t pa) { int idx; @@ -493,6 +468,18 @@ pa_to_pvflags(vm_offset_t pa) return (&pv_flags_tbl[idx]); } +/* + * Save the MOD bit from the given PTE using its PA + */ +static inline void +save_modref_bits(int pte) +{ + u_char *pv_flags; + + pv_flags = pa_to_pvflags(PG_PA(pte)); + *pv_flags |= ((pte & PG_MODREF) >> PV_SHIFT); +} + static inline pmeg_t pmeg_p(int sme) { @@ -508,7 +495,7 @@ pmeg_p(int sme) static void pmeg_set_wiring(pmegp, va, flag) pmeg_t pmegp; - vm_offset_t va; + vaddr_t va; int flag; { int idx, mask; @@ -522,28 +509,6 @@ pmeg_set_wiring(pmegp, va, flag) pmegp->pmeg_wired &= ~mask; } -/* - * Save the MOD bit from the given PTE using its PA - */ -static void -save_modref_bits(int pte) -{ - u_char *pv_flags; - - if (pv_initialized == 0) - return; - - /* Only main memory is ever in the pv_lists */ - if (!IS_MAIN_MEM(pte)) - return; - - CHECK_SPL(); - - pv_flags = pa_to_pvflags(PG_PA(pte)); - *pv_flags |= ((pte & PG_MODREF) >> PV_SHIFT); -} - - /**************************************************************** * Context management functions. */ @@ -605,8 +570,10 @@ context_allocate(pmap) } TAILQ_REMOVE(&context_free_queue, context, context_link); +#ifdef DIAGNOSTIC if (context->context_upmap != NULL) panic("pmap: context in use???"); +#endif context->context_upmap = pmap; pmap->pm_ctxnum = context->context_num; @@ -632,7 +599,7 @@ context_free(pmap) /* :) */ int saved_ctxnum, ctxnum; int i, sme; context_t contextp; - vm_offset_t va; + vaddr_t va; CHECK_SPL(); @@ -756,10 +723,10 @@ pmeg_reserve(sme) */ static void pmeg_mon_init(sva, eva, keep) - vm_offset_t sva, eva; + vaddr_t sva, eva; int keep; /* true: steal, false: clear */ { - vm_offset_t pgva, endseg; + vaddr_t pgva, endseg; int pte, valid; unsigned char sme; @@ -804,7 +771,7 @@ pmeg_clean(pmegp) pmeg_t pmegp; { int sme; - vm_offset_t va; + vaddr_t va; sme = get_segmap(0); if (sme != SEGINV) @@ -860,7 +827,7 @@ pmeg_clean_free() static pmeg_t pmeg_allocate(pmap, va) pmap_t pmap; - vm_offset_t va; + vaddr_t va; { pmeg_t pmegp; @@ -1006,7 +973,7 @@ pmeg_free(pmegp) static pmeg_t pmeg_cache(pmap, va) pmap_t pmap; - vm_offset_t va; + vaddr_t va; { int sme, segnum; pmeg_t pmegp; @@ -1074,9 +1041,9 @@ pmeg_cache(pmap, va) #ifdef PMAP_DEBUG static void pmeg_verify_empty(va) - vm_offset_t va; + vaddr_t va; { - vm_offset_t eva; + vaddr_t eva; int pte; for (eva = va + NBSG; va < eva; va += NBPG) { @@ -1125,7 +1092,7 @@ pv_init() /* Now allocate the whole thing. */ sz = m68k_round_page(sz); - p = (char*) uvm_km_alloc(kernel_map, sz); + p = (char *)uvm_km_alloc(kernel_map, sz); if (p == NULL) panic("pmap:pv_init: alloc failed"); bzero(p, sz); @@ -1135,11 +1102,11 @@ pv_init() p += (npp * sizeof(*pv_flags_tbl)); pv_head_tbl = (void*) p; p += (npp * sizeof(*pv_head_tbl)); - pv_free_list = (void *) p; + pv_free_list = (void *)p; p += (nvp * sizeof(*pv_free_list)); /* Finally, make pv_free_list into a list. */ - for (pv = pv_free_list; (char*)pv < p; pv++) + for (pv = pv_free_list; (char *)pv < p; pv++) pv->pv_next = &pv[1]; pv[-1].pv_next = 0; @@ -1152,26 +1119,19 @@ pv_init() */ static void pv_changepte(pa, set_bits, clear_bits) - vm_offset_t pa; + paddr_t pa; int set_bits; int clear_bits; { pv_entry_t *head, pv; u_char *pv_flags; pmap_t pmap; - vm_offset_t va; + vaddr_t va; int pte, sme; int saved_ctx; boolean_t in_ctx; u_int flags; - CHECK_SPL(); - - if (!pv_initialized) - return; - if ((set_bits == 0) && (clear_bits == 0)) - return; - pv_flags = pa_to_pvflags(pa); head = pa_to_pvhead(pa); @@ -1192,24 +1152,10 @@ pv_changepte(pa, set_bits, clear_bits) va = pv->pv_va; #ifdef DIAGNOSTIC - if (pmap == NULL) - panic("pv_changepte: null pmap"); if (pmap->pm_segmap == NULL) panic("pv_changepte: null segmap"); #endif - /* XXX don't write protect pager mappings */ - if (clear_bits & PG_WRITE) { - if (va >= PAGER_SVA && va < PAGER_EVA) { -#ifdef PMAP_DEBUG - /* XXX - Does this actually happen? */ - printf("pv_changepte: in pager!\n"); - Debugger(); -#endif - continue; - } - } - /* Is the PTE currently accessible in some context? */ in_ctx = FALSE; sme = SEGINV; /* kill warning */ @@ -1234,12 +1180,16 @@ pv_changepte(pa, set_bits, clear_bits) #endif pte = get_pte(va); } else { + /* * The PTE is not in any context. */ + sme = pmap->pm_segmap[VA_SEGNUM(va)]; +#ifdef DIAGNOSTIC if (sme == SEGINV) panic("pv_changepte: SEGINV"); +#endif pte = get_pte_pmeg(sme, VA_PTE_NUM(va)); } @@ -1279,35 +1229,28 @@ pv_syncflags(pv) pv_entry_t pv; { pmap_t pmap; - vm_offset_t va; + vaddr_t va; int pte, sme; int saved_ctx; boolean_t in_ctx; u_int flags; - CHECK_SPL(); - - if (!pv_initialized) - return(0); - /* If no mappings, no work to do. */ if (pv == NULL) return (0); flags = 0; saved_ctx = get_context(); - for ( ; pv != NULL; pv = pv->pv_next) { + for (; pv != NULL; pv = pv->pv_next) { pmap = pv->pv_pmap; va = pv->pv_va; - sme = SEGINV; /* kill warning */ + sme = SEGINV; #ifdef DIAGNOSTIC /* * Only the head may have a null pmap, and * we checked for that above. */ - if (pmap == NULL) - panic("pv_syncflags: null pmap"); if (pmap->pm_segmap == NULL) panic("pv_syncflags: null segmap"); #endif @@ -1325,24 +1268,28 @@ pv_syncflags(pv) } if (in_ctx == TRUE) { + /* * The PTE is in the current context. * Make sure PTE is up-to-date with VAC. */ + #ifdef HAVECACHE if (cache_size) cache_flush_page(va); #endif pte = get_pte(va); } else { + /* * The PTE is not in any context. - * XXX - Consider syncing MODREF bits - * when the PMEG looses its context? */ + sme = pmap->pm_segmap[VA_SEGNUM(va)]; +#ifdef DIAGNOSTIC if (sme == SEGINV) panic("pv_syncflags: SEGINV"); +#endif pte = get_pte_pmeg(sme, VA_PTE_NUM(va)); } @@ -1372,11 +1319,11 @@ pv_syncflags(pv) /* Remove all mappings for the physical page. */ static void pv_remove_all(pa) - vm_offset_t pa; + paddr_t pa; { pv_entry_t *head, pv; pmap_t pmap; - vm_offset_t va; + vaddr_t va; CHECK_SPL(); @@ -1385,9 +1332,6 @@ pv_remove_all(pa) printf("pv_remove_all(0x%lx)\n", pa); #endif - if (!pv_initialized) - return; - head = pa_to_pvhead(pa); while ((pv = *head) != NULL) { pmap = pv->pv_pmap; @@ -1414,9 +1358,9 @@ static int pv_link(pmap, pte, va) pmap_t pmap; int pte; - vm_offset_t va; + vaddr_t va; { - vm_offset_t pa; + paddr_t pa; pv_entry_t *head, pv; u_char *pv_flags; int flags; @@ -1447,10 +1391,12 @@ pv_link(pmap, pte, va) panic("pv_link: duplicate entry for PA=0x%lx", pa); } #endif +#ifdef HAVECACHE /* * Does this new mapping cause VAC alias problems? */ + *pv_flags |= flags; if ((*pv_flags & PV_NC) == 0) { for (pv = *head; pv != NULL; pv = pv->pv_next) { @@ -1462,6 +1408,7 @@ pv_link(pmap, pte, va) } } } +#endif /* Allocate a PV element (pv_alloc()). */ pv = pv_free_list; @@ -1493,15 +1440,12 @@ static void pv_unlink(pmap, pte, va) pmap_t pmap; int pte; - vm_offset_t va; + vaddr_t va; { - vm_offset_t pa; + paddr_t pa; pv_entry_t *head, *ppv, pv; u_char *pv_flags; - if (!pv_initialized) - return; - CHECK_SPL(); pa = PG_PA(pte); @@ -1577,7 +1521,7 @@ pmap_common_init(pmap) pmap_t pmap; { bzero(pmap, sizeof(struct pmap)); - pmap->pm_refcount=1; + pmap->pm_refcount = 1; pmap->pm_version = pmap_version++; pmap->pm_ctxnum = EMPTY_CONTEXT; simple_lock_init(&pmap->pm_lock); @@ -1591,10 +1535,10 @@ pmap_common_init(pmap) */ void pmap_bootstrap(nextva) - vm_offset_t nextva; + vaddr_t nextva; { struct sunromvec *rvec; - vm_offset_t va, eva; + vaddr_t va, eva; int i, pte, sme; extern char etext[]; @@ -1797,7 +1741,7 @@ pmap_bootstrap(nextva) sunmon_abort(); } #endif /* DIAGNOSTIC */ - for (va = 0; va < (vm_offset_t) (NBSG * NSEGMAP); va += NBSG) { + for (va = 0; va < (vaddr_t) (NBSG * NSEGMAP); va += NBSG) { /* Read the segmap entry from context zero... */ sme = get_segmap(va); /* ... then copy it into all other contexts. */ @@ -1851,7 +1795,7 @@ void pmap_kernel_init(pmap) pmap_t pmap; { - vm_offset_t va; + vaddr_t va; int i, sme; for (i=0, va=0; i < NSEGMAP; i++, va+=NBSG) { @@ -1876,8 +1820,8 @@ pmap_kernel_init(pmap) */ void pmap_virtual_space(v_start, v_end) - vm_offset_t *v_start; - vm_offset_t *v_end; + vaddr_t *v_start; + vaddr_t *v_end; { *v_start = virtual_avail; *v_end = virtual_end; @@ -1916,9 +1860,8 @@ pmap_page_upload() void pmap_init() { - pv_init(); - + /* Initialize the pmap pool. */ pool_init(&pmap_pmap_pool, sizeof(struct pmap), 0, 0, 0, "pmappl", 0, pool_page_alloc_nointr, pool_page_free_nointr, M_VMPMAP); @@ -1930,11 +1873,11 @@ pmap_init() * record the mapping for kernel text/data/bss. * Return VA following the mapped range. */ -vm_offset_t +vaddr_t pmap_map(va, pa, endpa, prot) - vm_offset_t va; - vm_offset_t pa; - vm_offset_t endpa; + vaddr_t va; + paddr_t pa; + paddr_t endpa; int prot; { int sz; @@ -1956,7 +1899,7 @@ pmap_user_init(pmap) { int i; pmap->pm_segmap = malloc(sizeof(char)*NUSEG, M_VMPMAP, M_WAITOK); - for (i=0; i < NUSEG; i++) { + for (i = 0; i < NUSEG; i++) { pmap->pm_segmap[i] = SEGINV; } } @@ -2025,9 +1968,6 @@ pmap_destroy(pmap) { int count; - if (pmap == NULL) - return; /* Duh! */ - #ifdef PMAP_DEBUG if (pmap_debug & PMD_CREATE) printf("pmap_destroy(%p)\n", pmap); @@ -2050,11 +1990,9 @@ void pmap_reference(pmap) pmap_t pmap; { - if (pmap != NULL) { - pmap_lock(pmap); - pmap_add_ref(pmap); - pmap_unlock(pmap); - } + pmap_lock(pmap); + pmap_add_ref(pmap); + pmap_unlock(pmap); } @@ -2077,8 +2015,8 @@ pmap_reference(pmap) int pmap_enter(pmap, va, pa, prot, flags) pmap_t pmap; - vm_offset_t va; - vm_offset_t pa; + vaddr_t va; + paddr_t pa; vm_prot_t prot; int flags; { @@ -2123,16 +2061,14 @@ pmap_enter(pmap, va, pa, prot, flags) static void pmap_enter_kernel(pgva, new_pte, wired) - vm_offset_t pgva; + vaddr_t pgva; int new_pte; boolean_t wired; { pmap_t pmap = kernel_pmap; pmeg_t pmegp; int do_pv, old_pte, sme; - vm_offset_t segva; - - CHECK_SPL(); + vaddr_t segva; /* keep in hardware only, since its mapped into all contexts anyway; @@ -2235,9 +2171,7 @@ pmap_enter_kernel(pgva, new_pte, wired) * If not changing the type or pfnum then re-use pv_entry. * Note we get here only with old_pte having PGT_OBMEM. */ - if ((old_pte & (PG_TYPE|PG_FRAME)) == - (new_pte & (PG_TYPE|PG_FRAME)) ) - { + if ((old_pte & (PG_TYPE|PG_FRAME)) == (new_pte & (PG_TYPE|PG_FRAME))) { do_pv = FALSE; /* re-use pv_entry */ new_pte |= (old_pte & PG_NC); goto add_pte; @@ -2273,16 +2207,14 @@ pmap_enter_kernel(pgva, new_pte, wired) static void pmap_enter_user(pmap, pgva, new_pte, wired) pmap_t pmap; - vm_offset_t pgva; + vaddr_t pgva; int new_pte; boolean_t wired; { int do_pv, old_pte, sme; - vm_offset_t segva; + vaddr_t segva; pmeg_t pmegp; - CHECK_SPL(); - #ifdef DIAGNOSTIC if (pgva >= VM_MAXUSER_ADDRESS) panic("pmap_enter_user: bad va=0x%lx", pgva); @@ -2417,9 +2349,7 @@ pmap_enter_user(pmap, pgva, new_pte, wired) * If not changing the type or pfnum then re-use pv_entry. * Note we get here only with old_pte having PGT_OBMEM. */ - if ((old_pte & (PG_TYPE|PG_FRAME)) == - (new_pte & (PG_TYPE|PG_FRAME)) ) - { + if ((old_pte & (PG_TYPE|PG_FRAME)) == (new_pte & (PG_TYPE|PG_FRAME))) { do_pv = FALSE; /* re-use pv_entry */ new_pte |= (old_pte & PG_NC); goto add_pte; @@ -2458,7 +2388,110 @@ pmap_kenter_pa(va, pa, prot) paddr_t pa; vm_prot_t prot; { - pmap_enter(pmap_kernel(), va, pa, prot, PMAP_WIRED); + int new_pte, s; + pmap_t pmap = kernel_pmap; + pmeg_t pmegp; + int sme; + vaddr_t segva; + +#ifdef PMAP_DEBUG + if ((pmap_debug & PMD_ENTER) || + (va == pmap_db_watchva)) + printf("pmap_kenter_pa(0x%lx, 0x%lx, 0x%x)\n", + va, pa, prot); +#endif + + /* Get page-type bits from low part of the PA... */ + new_pte = (pa & PMAP_SPEC) << PG_MOD_SHIFT; + + /* ...now the valid and writable bits... */ + new_pte |= PG_SYSTEM|PG_VALID; + if (prot & VM_PROT_WRITE) + new_pte |= PG_WRITE; + + /* ...and finally the page-frame number. */ + new_pte |= PA_PGNUM(pa); + + /* + * keep in hardware only, since its mapped into all contexts anyway; + * need to handle possibly allocating additional pmegs + * need to make sure they cant be stolen from the kernel; + * map any new pmegs into all contexts, make sure rest of pmeg is null; + * must also deal with changes too. + */ + + /* + * In detail: + * + * (a) lock pmap + * (b) Is the VA in a already mapped segment, if so + * look to see if that VA address is "valid". If it is, then + * action is a change to an existing pte + * (c) if not mapped segment, need to allocate pmeg + * (d) change/add pte + */ + +#ifdef DIAGNOSTIC + if ((va < virtual_avail) || (va >= DVMA_MAP_END)) + panic("pmap_enter_kernel: bad va=0x%lx", va); +#endif + + if (va >= DVMA_MAP_BASE) { + /* This is DVMA space. Always want it non-cached. */ + new_pte |= PG_NC; + } + + segva = m68k_trunc_seg(va); + + s = splvm(); + + /* Do we have a PMEG? */ + sme = get_segmap(segva); + if (sme != SEGINV) { + KASSERT((get_pte(va) & PG_VALID) == 0); + + /* Found a PMEG in the segmap. Cool. */ + pmegp = pmeg_p(sme); +#ifdef DIAGNOSTIC + /* Make sure it is the right PMEG. */ + if (sme != pmap->pm_segmap[VA_SEGNUM(segva)]) + panic("pmap_enter_kernel: wrong sme at VA=0x%lx", segva); + /* Make sure it is ours. */ + if (pmegp->pmeg_owner != pmap) + panic("pmap_kenter_pa: MMU has bad pmeg 0x%x", sme); +#endif + } else { + + /* No PMEG in the segmap. Have to allocate one. */ + pmegp = pmeg_allocate(pmap, segva); + sme = pmegp->pmeg_index; + pmap->pm_segmap[VA_SEGNUM(segva)] = sme; + set_segmap_allctx(segva, sme); +#ifdef PMAP_DEBUG + pmeg_verify_empty(segva); + if (pmap_debug & PMD_SEGMAP) { + printf("pmap: set_segmap pmap=%p va=0x%lx sme=0x%x (ek)\n", + pmap, segva, sme); + } +#endif + } + + pmeg_set_wiring(pmegp, va, TRUE); + + /* Anything but MAIN_MEM is mapped non-cached. */ + if (!IS_MAIN_MEM(new_pte)) { + new_pte |= PG_NC; + } +#ifdef PMAP_DEBUG + if ((pmap_debug & PMD_SETPTE) || (va == pmap_db_watchva)) { + printf("pmap: set_pte pmap=%p va=0x%lx old=0x%x new=0x%x (ek)\n", + pmap, va, old_pte, new_pte); + } +#endif + /* cache flush done above */ + set_pte(va, new_pte); + pmegp->pmeg_vpages++; + splx(s); } void @@ -2466,9 +2499,96 @@ pmap_kremove(va, len) vaddr_t va; vsize_t len; { - for (len >>= PAGE_SHIFT; len > 0; len--, va += PAGE_SIZE) { - pmap_remove(pmap_kernel(), va, va + PAGE_SIZE); + pmap_t pmap = kernel_pmap; + vaddr_t eva, neva, pgva, segva, segnum; + int pte, sme; + pmeg_t pmegp; +#ifdef HAVECACHE + int flush_by_page = 0; +#endif + int s; + + s = splvm(); + segnum = VA_SEGNUM(va); + for (eva = va + len; va < eva; va = neva, segnum++) { + neva = m68k_trunc_seg(va) + NBSG; + if (neva > eva) { + neva = eva; + } + if (pmap->pm_segmap[segnum] == SEGINV) { + continue; + } + + segva = m68k_trunc_seg(va); + sme = get_segmap(segva); + pmegp = pmeg_p(sme); + +#ifdef HAVECACHE + if (cache_size) { + + /* + * If the range to be removed is larger than the cache, + * it will be cheaper to flush this segment entirely. + */ + + if (cache_size < (eva - va)) { + /* cheaper to flush whole segment */ + cache_flush_segment(segva); + } else { + flush_by_page = 1; + } + } +#endif + + /* Invalidate the PTEs in the given range. */ + for (pgva = va; pgva < neva; pgva += NBPG) { + pte = get_pte(pgva); + if (pte & PG_VALID) { +#ifdef HAVECACHE + if (flush_by_page) { + cache_flush_page(pgva); + /* Get fresh mod/ref bits from write-back. */ + pte = get_pte(pgva); + } +#endif +#ifdef PMAP_DEBUG + if ((pmap_debug & PMD_SETPTE) || (pgva == pmap_db_watchva)) { + printf("pmap: set_pte pmap=%p va=0x%lx" + " old=0x%x new=0x%x (rrmmu)\n", + pmap, pgva, pte, PG_INVAL); + } +#endif + set_pte(pgva, PG_INVAL); + KASSERT(pmegp->pmeg_vpages > 0); + pmegp->pmeg_vpages--; + } + } + KASSERT(pmegp->pmeg_vpages >= 0); + if (pmegp->pmeg_vpages == 0) { + /* We are done with this pmeg. */ +#ifdef PMAP_DEBUG + if (is_pmeg_wired(pmegp)) { + if (pmap_debug & PMD_WIRING) { + db_printf("pmap: removing wired pmeg: %p\n", pmegp); + Debugger(); + } + } + if (pmap_debug & PMD_SEGMAP) { + printf("pmap: set_segmap ctx=%d v=0x%lx old=0x%x new=ff (rm)\n", + pmap->pm_ctxnum, segva, pmegp->pmeg_index); + } + pmeg_verify_empty(segva); +#endif + + /* Remove it from the MMU. */ + set_segmap_allctx(segva, SEGINV); + pmap->pm_segmap[VA_SEGNUM(segva)] = SEGINV; + + /* Now, put it on the free list. */ + pmeg_free(pmegp); + } } + splx(s); } @@ -2483,7 +2603,7 @@ pmap_kremove(va, len) int _pmap_fault(map, va, ftype) struct vm_map *map; - vm_offset_t va; + vaddr_t va; vm_prot_t ftype; { pmap_t pmap; @@ -2527,11 +2647,11 @@ _pmap_fault(map, va, ftype) int pmap_fault_reload(pmap, pgva, ftype) pmap_t pmap; - vm_offset_t pgva; + vaddr_t pgva; vm_prot_t ftype; { int rv, s, pte, chkpte, sme; - vm_offset_t segva; + vaddr_t segva; pmeg_t pmegp; if (pgva >= VM_MAXUSER_ADDRESS) @@ -2614,13 +2734,6 @@ pmap_clear_modify(pg) int s; boolean_t rv; - if (!pv_initialized) - return FALSE; - - /* The VM code may call this on device addresses! */ - if (PA_IS_DEV(pa)) - return FALSE; - pv_flags = pa_to_pvflags(pa); head = pa_to_pvhead(pa); @@ -2635,21 +2748,15 @@ pmap_clear_modify(pg) /* * Tell whether the given physical page has been modified. */ -int +boolean_t pmap_is_modified(pg) struct vm_page *pg; { paddr_t pa = VM_PAGE_TO_PHYS(pg); pv_entry_t *head; u_char *pv_flags; - int rv, s; - - if (!pv_initialized) - return (0); - - /* The VM code may call this on device addresses! */ - if (PA_IS_DEV(pa)) - return (0); + int s; + boolean_t rv; pv_flags = pa_to_pvflags(pa); head = pa_to_pvhead(pa); @@ -2659,7 +2766,6 @@ pmap_is_modified(pg) *pv_flags |= pv_syncflags(*head); rv = (*pv_flags & PV_MOD); splx(s); - return (rv); } @@ -2677,13 +2783,6 @@ pmap_clear_reference(pg) int s; boolean_t rv; - if (!pv_initialized) - return FALSE; - - /* The VM code may call this on device addresses! */ - if (PA_IS_DEV(pa)) - return FALSE; - pv_flags = pa_to_pvflags(pa); head = pa_to_pvhead(pa); @@ -2709,13 +2808,6 @@ pmap_is_referenced(pg) int s; boolean_t rv; - if (!pv_initialized) - return (FALSE); - - /* The VM code may call this on device addresses! */ - if (PA_IS_DEV(pa)) - return (FALSE); - pv_flags = pa_to_pvflags(pa); head = pa_to_pvhead(pa); @@ -2724,7 +2816,6 @@ pmap_is_referenced(pg) *pv_flags |= pv_syncflags(*head); rv = (*pv_flags & PV_REF); splx(s); - return (rv); } @@ -2743,8 +2834,6 @@ void _pmap_switch(pmap) pmap_t pmap; { - - CHECK_SPL(); set_context(pmap->pm_ctxnum); ICIA(); } @@ -2760,24 +2849,20 @@ pmap_activate(p) struct proc *p; { pmap_t pmap = p->p_vmspace->vm_map.pmap; - int s; if (p == curproc) { - s = splvm(); _pmap_switch(pmap); - splx(s); } } /* * Deactivate the address space of the specified process. - * XXX The semantics of this function are not currently well-defined. */ void pmap_deactivate(p) struct proc *p; { - /* not implemented. */ + /* Nothing to do. */ } /* @@ -2790,14 +2875,12 @@ pmap_deactivate(p) void pmap_unwire(pmap, va) pmap_t pmap; - vm_offset_t va; + vaddr_t va; { int s, sme; int wiremask, ptenum; pmeg_t pmegp; - if (pmap == NULL) - return; #ifdef PMAP_DEBUG if (pmap_debug & PMD_WIRING) printf("pmap_unwire(pmap=%p, va=0x%lx)\n", @@ -2822,13 +2905,9 @@ pmap_unwire(pmap, va) wiremask = 1 << ptenum; s = splvm(); - sme = get_segmap(va); - if (sme == SEGINV) - panic("pmap_unwire: invalid va=0x%lx", va); pmegp = pmeg_p(sme); pmegp->pmeg_wired &= ~wiremask; - splx(s); } @@ -2843,9 +2922,9 @@ void pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr) pmap_t dst_pmap; pmap_t src_pmap; - vm_offset_t dst_addr; - vm_size_t len; - vm_offset_t src_addr; + vaddr_t dst_addr; + vsize_t len; + vaddr_t src_addr; { } @@ -2859,7 +2938,7 @@ pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr) boolean_t pmap_extract(pmap, va, pap) pmap_t pmap; - vm_offset_t va; + vaddr_t va; paddr_t *pap; { int s, sme, segnum, ptenum, pte; @@ -2867,7 +2946,6 @@ pmap_extract(pmap, va, pap) pte = 0; s = splvm(); - if (pmap == kernel_pmap) { sme = get_segmap(va); if (sme != SEGINV) @@ -2881,7 +2959,6 @@ pmap_extract(pmap, va, pap) pte = get_pte_pmeg(sme, ptenum); } } - splx(s); if ((pte & PG_VALID) == 0) { @@ -2916,12 +2993,7 @@ pmap_page_protect(pg, prot) paddr_t pa = VM_PAGE_TO_PHYS(pg); int s; - /* The VM code may call this on device addresses! */ - if (PA_IS_DEV(pa)) - return; - s = splvm(); - #ifdef PMAP_DEBUG if (pmap_debug & PMD_PROTECT) printf("pmap_page_protect(0x%lx, 0x%lx)\n", pa, prot); @@ -2938,24 +3010,9 @@ pmap_page_protect(pg, prot) pv_remove_all(pa); break; } - splx(s); } -/* - * Turn a cdevsw d_mmap value into a byte address for pmap_enter. - * XXX this should almost certainly be done differently, and - * elsewhere, or even not at all - */ -#ifndef pmap_phys_address -vm_offset_t -pmap_phys_address(x) - int x; -{ - return (x); -} -#endif - /* * Initialize a preallocated and zeroed pmap structure, * such as one in a vmspace structure. @@ -2976,15 +3033,12 @@ pmap_pinit(pmap) void pmap_protect(pmap, sva, eva, prot) pmap_t pmap; - vm_offset_t sva, eva; + vaddr_t sva, eva; vm_prot_t prot; { - vm_offset_t va, neva; + vaddr_t va, neva; int segnum; - if (pmap == NULL) - return; - /* If leaving writable, nothing to do. */ if (prot & VM_PROT_WRITE) return; @@ -3001,21 +3055,9 @@ pmap_protect(pmap, sva, eva, prot) printf("pmap_protect(%p, 0x%lx, 0x%lx)\n", pmap, sva, eva); #endif - if (pmap == kernel_pmap) { - if (sva < virtual_avail) - sva = virtual_avail; - if (eva > DVMA_MAP_END) { -#ifdef PMAP_DEBUG - db_printf("pmap_protect: eva=0x%lx\n", eva); - Debugger(); -#endif - eva = DVMA_MAP_END; - } - } else { - if (eva > VM_MAXUSER_ADDRESS) - eva = VM_MAXUSER_ADDRESS; - } - + KASSERT((pmap == kernel_pmap) ? + sva >= virtual_avail && eva < DVMA_MAP_END : + eva <= VM_MAXUSER_ADDRESS); va = sva; segnum = VA_SEGNUM(va); while (va < eva) { @@ -3037,7 +3079,7 @@ pmap_protect(pmap, sva, eva, prot) void pmap_protect1(pmap, sva, eva) pmap_t pmap; - vm_offset_t sva, eva; + vaddr_t sva, eva; { int old_ctx, s, sme; boolean_t in_ctx; @@ -3091,10 +3133,10 @@ out: void pmap_protect_mmu(pmap, sva, eva) pmap_t pmap; - vm_offset_t sva, eva; + vaddr_t sva, eva; { pmeg_t pmegp; - vm_offset_t pgva, segva; + vaddr_t pgva, segva; int pte, sme; #ifdef HAVECACHE int flush_by_page = 0; @@ -3131,7 +3173,9 @@ pmap_protect_mmu(pmap, sva, eva) { panic("pmap_protect_mmu: bad pmeg=%p", pmegp); } - if (pmegp->pmeg_vpages <= 0) + if (pmegp->pmeg_vpages < 0) + panic("pmap_protect_mmu: npages corrupted"); + if (pmegp->pmeg_vpages == 0) panic("pmap_protect_mmu: no valid pages?"); #endif @@ -3177,12 +3221,10 @@ pmap_protect_mmu(pmap, sva, eva) void pmap_protect_noctx(pmap, sva, eva) pmap_t pmap; - vm_offset_t sva, eva; + vaddr_t sva, eva; { int old_ctx, pte, sme, segnum; - vm_offset_t pgva, segva; - - CHECK_SPL(); + vaddr_t pgva, segva; #ifdef DIAGNOSTIC /* Kernel always in a context (actually, in all contexts). */ @@ -3237,35 +3279,21 @@ pmap_protect_noctx(pmap, sva, eva) void pmap_remove(pmap, sva, eva) pmap_t pmap; - vm_offset_t sva, eva; + vaddr_t sva, eva; { - vm_offset_t va, neva; + vaddr_t va, neva; int segnum; - if (pmap == NULL) - return; - #ifdef PMAP_DEBUG if ((pmap_debug & PMD_REMOVE) || ((sva <= pmap_db_watchva && eva > pmap_db_watchva))) printf("pmap_remove(%p, 0x%lx, 0x%lx)\n", pmap, sva, eva); #endif - if (pmap == kernel_pmap) { - if (sva < virtual_avail) - sva = virtual_avail; - if (eva > DVMA_MAP_END) { -#ifdef PMAP_DEBUG - db_printf("pmap_remove: eva=0x%lx\n", eva); - Debugger(); -#endif - eva = DVMA_MAP_END; - } - } else { - if (eva > VM_MAXUSER_ADDRESS) - eva = VM_MAXUSER_ADDRESS; - } - + + KASSERT((pmap == kernel_pmap) ? + sva >= virtual_avail && eva < DVMA_MAP_END : + eva <= VM_MAXUSER_ADDRESS); va = sva; segnum = VA_SEGNUM(va); while (va < eva) { @@ -3285,7 +3313,7 @@ pmap_remove(pmap, sva, eva) void pmap_remove1(pmap, sva, eva) pmap_t pmap; - vm_offset_t sva, eva; + vaddr_t sva, eva; { int old_ctx, s, sme; boolean_t in_ctx; @@ -3340,10 +3368,10 @@ out: void pmap_remove_mmu(pmap, sva, eva) pmap_t pmap; - vm_offset_t sva, eva; + vaddr_t sva, eva; { pmeg_t pmegp; - vm_offset_t pgva, segva; + vaddr_t pgva, segva; int pte, sme; #ifdef HAVECACHE int flush_by_page = 0; @@ -3380,7 +3408,9 @@ pmap_remove_mmu(pmap, sva, eva) { panic("pmap_remove_mmu: bad pmeg=%p", pmegp); } - if (pmegp->pmeg_vpages <= 0) + if (pmegp->pmeg_vpages < 0) + panic("pmap_remove_mmu: npages corrupted"); + if (pmegp->pmeg_vpages == 0) panic("pmap_remove_mmu: no valid pages?"); #endif @@ -3422,11 +3452,13 @@ pmap_remove_mmu(pmap, sva, eva) } #endif set_pte(pgva, PG_INVAL); + KASSERT(pmegp->pmeg_vpages > 0); pmegp->pmeg_vpages--; } } - if (pmegp->pmeg_vpages <= 0) { + KASSERT(pmegp->pmeg_vpages >= 0); + if (pmegp->pmeg_vpages == 0) { /* We are done with this pmeg. */ if (is_pmeg_wired(pmegp)) { #ifdef PMAP_DEBUG @@ -3466,11 +3498,11 @@ pmap_remove_mmu(pmap, sva, eva) void pmap_remove_noctx(pmap, sva, eva) pmap_t pmap; - vm_offset_t sva, eva; + vaddr_t sva, eva; { pmeg_t pmegp; int old_ctx, pte, sme, segnum; - vm_offset_t pgva, segva; + vaddr_t pgva, segva; CHECK_SPL(); @@ -3514,6 +3546,7 @@ pmap_remove_noctx(pmap, sva, eva) } #endif set_pte(pgva, PG_INVAL); + KASSERT(pmegp->pmeg_vpages > 0); pmegp->pmeg_vpages--; } } @@ -3525,7 +3558,8 @@ pmap_remove_noctx(pmap, sva, eva) set_segmap(segva, SEGINV); set_context(old_ctx); - if (pmegp->pmeg_vpages <= 0) { + KASSERT(pmegp->pmeg_vpages >= 0); + if (pmegp->pmeg_vpages == 0) { /* We are done with this pmeg. */ if (is_pmeg_wired(pmegp)) { #ifdef PMAP_DEBUG @@ -3606,7 +3640,7 @@ pmap_wired_pages(pmap) */ void pmap_copy_page(src, dst) - vm_offset_t src, dst; + paddr_t src, dst; { int pte; int s; @@ -3618,9 +3652,11 @@ pmap_copy_page(src, dst) printf("pmap_copy_page: 0x%lx -> 0x%lx\n", src, dst); #endif +#ifdef DIAGNOSTIC if (tmp_vpages_inuse) panic("pmap_copy_page: vpages inuse"); tmp_vpages_inuse++; +#endif /* PG_PERM is short for (PG_VALID|PG_WRITE|PG_SYSTEM|PG_NC) */ /* All mappings to vmp_vpages are non-cached, so no flush. */ @@ -3632,7 +3668,9 @@ pmap_copy_page(src, dst) set_pte(tmp_vpages[0], PG_INVAL); set_pte(tmp_vpages[0], PG_INVAL); +#ifdef DIAGNOSTIC tmp_vpages_inuse--; +#endif splx(s); } @@ -3645,7 +3683,7 @@ pmap_copy_page(src, dst) */ void pmap_zero_page(pa) - vm_offset_t pa; + paddr_t pa; { int pte; int s; @@ -3657,9 +3695,11 @@ pmap_zero_page(pa) printf("pmap_zero_page: 0x%lx\n", pa); #endif +#ifdef DIAGNOSTIC if (tmp_vpages_inuse) panic("pmap_zero_page: vpages inuse"); tmp_vpages_inuse++; +#endif /* PG_PERM is short for (PG_VALID|PG_WRITE|PG_SYSTEM|PG_NC) */ /* All mappings to vmp_vpages are non-cached, so no flush. */ @@ -3668,7 +3708,9 @@ pmap_zero_page(pa) zeropage((char *) tmp_vpages[0]); set_pte(tmp_vpages[0], PG_INVAL); +#ifdef DIAGNOSTIC tmp_vpages_inuse--; +#endif splx(s); } @@ -3697,10 +3739,10 @@ pmap_collect(pmap) */ void pmap_prefer(fo, va) - register vm_offset_t fo; - register vm_offset_t *va; + vaddr_t fo; + vaddr_t *va; { - register long d; + long d; d = fo - *va; d &= SEGOFSET; @@ -3715,7 +3757,7 @@ void pmap_kcore_hdr(sh) struct sun3_kcore_hdr *sh; { - vm_offset_t va; + vaddr_t va; u_char *cp, *ep; sh->segshift = SEGSHIFT; @@ -3742,7 +3784,7 @@ pmap_get_pagemap(pt, off) int *pt; int off; { - vm_offset_t va, va_end; + vaddr_t va, va_end; int sme, sme_end; /* SegMap Entry numbers */ sme = (off >> 6); /* PMEG to start on */ @@ -3767,18 +3809,22 @@ pmap_get_pagemap(pt, off) * XXX: These should go away. (Borrow context zero instead.) */ +#ifdef DIAGNOSTIC static int temp_seg_inuse; +#endif static int get_pte_pmeg(int pmeg_num, int page_num) { - vm_offset_t va; + vaddr_t va; int pte; CHECK_SPL(); +#ifdef DIAGNOSTIC if (temp_seg_inuse) panic("get_pte_pmeg: temp_seg_inuse"); temp_seg_inuse++; +#endif va = temp_seg_va; set_segmap(temp_seg_va, pmeg_num); @@ -3786,19 +3832,23 @@ get_pte_pmeg(int pmeg_num, int page_num) pte = get_pte(va); set_segmap(temp_seg_va, SEGINV); +#ifdef DIAGNOSTIC temp_seg_inuse--; +#endif return pte; } static void set_pte_pmeg(int pmeg_num, int page_num, int pte) { - vm_offset_t va; + vaddr_t va; CHECK_SPL(); +#ifdef DIAGNOSTIC if (temp_seg_inuse) panic("set_pte_pmeg: temp_seg_inuse"); temp_seg_inuse++; +#endif /* We never access data in temp_seg_va so no need to flush. */ va = temp_seg_va; @@ -3807,7 +3857,9 @@ set_pte_pmeg(int pmeg_num, int page_num, int pte) set_pte(va, pte); set_segmap(temp_seg_va, SEGINV); +#ifdef DIAGNOSTIC temp_seg_inuse--; +#endif } /* @@ -3855,15 +3907,11 @@ pmeg_print(pmegp) void pv_print(pa) - vm_offset_t pa; + paddr_t pa; { pv_entry_t pv; int idx; - if (!pv_initialized) { - db_printf("no pv_flags_tbl\n"); - return; - } idx = PA_PGNUM(pa); if (idx >= physmem) { db_printf("bad address\n"); diff --git a/sys/arch/sun3/sun3x/pmap.c b/sys/arch/sun3/sun3x/pmap.c index 1b655b58d22d..5aa8481e6c08 100644 --- a/sys/arch/sun3/sun3x/pmap.c +++ b/sys/arch/sun3/sun3x/pmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.68 2001/06/19 13:42:16 wiz Exp $ */ +/* $NetBSD: pmap.c,v 1.69 2001/07/03 06:15:17 chs Exp $ */ /*- * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. @@ -124,9 +124,6 @@ #include -#define PAGER_SVA (uvm.pager_sva) -#define PAGER_EVA (uvm.pager_eva) - #include #include #include @@ -236,7 +233,7 @@ int pmap_debug = 0; * Global variables for storing the base addresses for the areas * labeled above. */ -static vm_offset_t kernAphys; +static vaddr_t kernAphys; static mmu_long_dte_t *kernAbase; static mmu_short_dte_t *kernBbase; static mmu_short_pte_t *kernCbase; @@ -267,8 +264,7 @@ static TAILQ_HEAD(c_pool_head_struct, c_tmgr_struct) c_pool; * Flags used to mark the safety/availability of certain operations or * resources. */ -static boolean_t pv_initialized = FALSE, /* PV system has been initialized. */ - bootstrap_alloc_enabled = FALSE; /*Safe to use pmap_bootstrap_alloc().*/ +static boolean_t bootstrap_alloc_enabled = FALSE; /*Safe to use pmap_bootstrap_alloc().*/ int tmp_vpages_inuse; /* Temporary virtual pages are in use */ /* @@ -276,18 +272,18 @@ int tmp_vpages_inuse; /* Temporary virtual pages are in use */ * used in the old pmap/vm interface (without NONCONTIG). */ /* Kernel virtual address space available: */ -vm_offset_t virtual_avail, virtual_end; +vaddr_t virtual_avail, virtual_end; /* Physical address space available: */ -vm_offset_t avail_start, avail_end; +paddr_t avail_start, avail_end; /* This keep track of the end of the contiguously mapped range. */ -vm_offset_t virtual_contig_end; +vaddr_t virtual_contig_end; /* Physical address used by pmap_next_page() */ -vm_offset_t avail_next; +paddr_t avail_next; /* These are used by pmap_copy_page(), etc. */ -vm_offset_t tmp_vpages[2]; +vaddr_t tmp_vpages[2]; /* memory pool for pmap structures */ struct pool pmap_pmap_pool; @@ -369,8 +365,8 @@ unsigned int NUM_A_TABLES, NUM_B_TABLES, NUM_C_TABLES; void *pmap_bootstrap_alloc(int); -static INLINE void * mmu_ptov __P((vm_offset_t pa)); -static INLINE vm_offset_t mmu_vtop __P((void * va)); +static INLINE void *mmu_ptov __P((paddr_t)); +static INLINE paddr_t mmu_vtop __P((void *)); #if 0 static INLINE a_tmgr_t * mmuA2tmgr __P((mmu_long_dte_t *)); @@ -378,7 +374,7 @@ static INLINE a_tmgr_t * mmuA2tmgr __P((mmu_long_dte_t *)); static INLINE b_tmgr_t * mmuB2tmgr __P((mmu_short_dte_t *)); static INLINE c_tmgr_t * mmuC2tmgr __P((mmu_short_pte_t *)); -static INLINE pv_t *pa2pv __P((vm_offset_t pa)); +static INLINE pv_t *pa2pv __P((paddr_t)); static INLINE int pteidx __P((mmu_short_pte_t *)); static INLINE pmap_t current_pmap __P((void)); @@ -390,9 +386,9 @@ static INLINE pmap_t current_pmap __P((void)); */ static INLINE void * mmu_ptov(pa) - vm_offset_t pa; + paddr_t pa; { - register vm_offset_t va; + vaddr_t va; va = (pa + KERNBASE); #ifdef PMAP_DEBUG @@ -401,13 +397,14 @@ mmu_ptov(pa) #endif return ((void*)va); } -static INLINE vm_offset_t + +static INLINE paddr_t mmu_vtop(vva) void *vva; { - register vm_offset_t va; + vaddr_t va; - va = (vm_offset_t)vva; + va = (vaddr_t)vva; #ifdef PMAP_DEBUG if ((va < KERNBASE) || (va >= virtual_contig_end)) panic("mmu_ptov"); @@ -436,7 +433,7 @@ static INLINE a_tmgr_t * mmuA2tmgr(mmuAtbl) mmu_long_dte_t *mmuAtbl; { - register int idx; + int idx; /* Which table is this in? */ idx = (mmuAtbl - mmuAbase) / MMU_A_TBL_SIZE; @@ -452,7 +449,7 @@ static INLINE b_tmgr_t * mmuB2tmgr(mmuBtbl) mmu_short_dte_t *mmuBtbl; { - register int idx; + int idx; /* Which table is this in? */ idx = (mmuBtbl - mmuBbase) / MMU_B_TBL_SIZE; @@ -472,7 +469,7 @@ static INLINE c_tmgr_t * mmuC2tmgr(mmuCtbl) mmu_short_pte_t *mmuCtbl; { - register int idx; + int idx; /* Which table is this in? */ idx = (mmuCtbl - mmuCbase) / MMU_C_TBL_SIZE; @@ -497,10 +494,10 @@ mmuC2tmgr(mmuCtbl) */ static INLINE pv_t * pa2pv(pa) - vm_offset_t pa; + paddr_t pa; { - register struct pmap_physmem_struct *bank; - register int idx; + struct pmap_physmem_struct *bank; + int idx; bank = &avail_mem[0]; while (pa >= bank->pmem_end) @@ -557,18 +554,6 @@ current_pmap() * all function calls. * *************************************************************************/ -/** External functions - ** - functions used within this module but written elsewhere. - ** both of these functions are in locore.s - ** XXX - These functions were later replaced with their more cryptic - ** hp300 counterparts. They may be removed now. - **/ -#if 0 /* deprecated mmu */ -void mmu_seturp __P((vm_offset_t)); -void mmu_flush __P((int, vm_offset_t)); -void mmu_flusha __P((void)); -#endif /* 0 */ - /** Internal functions ** Most functions used only within this module are defined in ** pmap_pvt.h (why not here if used only here?) @@ -601,11 +586,12 @@ void pmap_release __P((pmap_t)); */ void pmap_bootstrap(nextva) - vm_offset_t nextva; + vaddr_t nextva; { struct physmemory *membank; struct pmap_physmem_struct *pmap_membank; - vm_offset_t va, pa, eva; + vaddr_t va, eva; + paddr_t pa; int b, c, i, j; /* running table counts */ int size, resvmem; @@ -687,7 +673,7 @@ pmap_bootstrap(nextva) * Note: All must be aligned on 256 byte boundaries. * Start with the level-A table (one of those). */ - size = sizeof(mmu_long_dte_t) * MMU_A_TBL_SIZE; + size = sizeof(mmu_long_dte_t) * MMU_A_TBL_SIZE; kernAbase = pmap_bootstrap_alloc(size); bzero(kernAbase, size); @@ -730,7 +716,7 @@ pmap_bootstrap(nextva) size = sizeof(mmu_short_dte_t) * MMU_B_TBL_SIZE * NUM_B_TABLES; mmuBbase = pmap_bootstrap_alloc(size); - size = sizeof(mmu_long_dte_t) * MMU_A_TBL_SIZE * NUM_A_TABLES; + size = sizeof(mmu_long_dte_t) * MMU_A_TBL_SIZE * NUM_A_TABLES; mmuAbase = pmap_bootstrap_alloc(size); /* @@ -770,8 +756,6 @@ pmap_bootstrap(nextva) b += MMU_B_TBL_SIZE; } - /* XXX - Doing kernel_pmap a little further down. */ - pmap_alloc_usermmu(); /* Allocate user MMU tables. */ pmap_alloc_usertmgr(); /* Allocate user MMU table managers.*/ pmap_alloc_pv(); /* Allocate physical->virtual map. */ @@ -841,7 +825,7 @@ pmap_bootstrap(nextva) * Only the mappings created here exist in our tables, so * remember to map anything we expect to use. */ - va = (vm_offset_t) KERNBASE; + va = (vaddr_t)KERNBASE; pa = 0; /* @@ -864,7 +848,7 @@ pmap_bootstrap(nextva) * sharing the same page. Therefore, the last page of kernel text * has to be mapped as read/write, to accomodate the data. */ - eva = m68k_trunc_page((vm_offset_t)etext); + eva = m68k_trunc_page((vaddr_t)etext); for (; va < eva; va += NBPG, pa += NBPG) pmap_enter_kernel(va, pa, VM_PROT_READ|VM_PROT_EXECUTE); @@ -1200,8 +1184,6 @@ pmap_init_pv() pvbase[i].pv_idx = PVE_EOL; /* Indicate no mappings */ pvbase[i].pv_flags = 0; /* Zero out page flags */ } - - pv_initialized = TRUE; } /* get_a_table INTERNAL @@ -1250,25 +1232,6 @@ get_a_table() pmap->pm_a_tmgr = NULL; pmap->pm_a_phys = kernAphys; } -#ifdef NON_REENTRANT - /* - * If the table isn't to be wired down, re-insert it at the - * end of the pool. - */ - if (!wired) - /* - * Quandary - XXX - * Would it be better to let the calling function insert this - * table into the queue? By inserting it here, we are allowing - * it to be stolen immediately. The calling function is - * probably not expecting to use a table that it is not - * assured full control of. - * Answer - In the intrest of re-entrancy, it is best to let - * the calling function determine when a table is available - * for use. Therefore this code block is not used. - */ - TAILQ_INSERT_TAIL(&a_pool, tbl, at_link); -#endif /* NON_REENTRANT */ return tbl; } @@ -1291,13 +1254,6 @@ get_b_table() tbl->bt_parent->at_ecnt--; free_b_table(tbl, FALSE); } -#ifdef NON_REENTRANT - if (!wired) - /* XXX see quandary in get_b_table */ - /* XXX start lock */ - TAILQ_INSERT_TAIL(&b_pool, tbl, bt_link); - /* XXX end lock */ -#endif /* NON_REENTRANT */ return tbl; } @@ -1320,14 +1276,6 @@ get_c_table() tbl->ct_parent->bt_ecnt--; free_c_table(tbl, FALSE); } -#ifdef NON_REENTRANT - if (!wired) - /* XXX See quandary in get_a_table */ - /* XXX start lock */ - TAILQ_INSERT_TAIL(&c_pool, tbl, c_link); - /* XXX end lock */ -#endif /* NON_REENTRANT */ - return tbl; } @@ -1504,34 +1452,6 @@ free_c_table(c_tbl, relink) return removed_cnt; } -#if 0 -/* free_c_table_novalid INTERNAL - ** - * Frees the given C table manager without checking to see whether - * or not it contains any valid page descriptors as it is assumed - * that it does not. - */ -void -free_c_table_novalid(c_tbl) - c_tmgr_t *c_tbl; -{ - TAILQ_REMOVE(&c_pool, c_tbl, ct_link); - TAILQ_INSERT_HEAD(&c_pool, c_tbl, ct_link); - c_tbl->ct_parent->bt_dtbl[c_tbl->ct_pidx].attr.raw = MMU_DT_INVALID; - c_tbl->ct_parent->bt_ecnt--; - /* - * XXX - Should call equiv. of 'free_b_table_novalid' here if - * we just removed the last entry of the parent B table. - * But I want to insure that this will not endanger pmap_enter() - * with sudden removal of tables it is working with. - * - * We should probably add another field to each table, indicating - * whether or not it is 'locked', ie. in the process of being - * modified. - */ - c_tbl->ct_parent = NULL; -} -#endif /* pmap_remove_pte INTERNAL ** @@ -1546,8 +1466,7 @@ pmap_remove_pte(pte) mmu_short_pte_t *pte; { u_short pv_idx, targ_idx; - int s; - vm_offset_t pa; + paddr_t pa; pv_t *pv; pa = MMU_PTE_PA(*pte); @@ -1564,35 +1483,35 @@ pmap_remove_pte(pte) * removed, so that it may be modified to point to its new * neighbor. */ - s = splvm(); + pv_idx = pv->pv_idx; /* Index of first PTE in PV list */ if (pv_idx == targ_idx) { pv->pv_idx = pvebase[targ_idx].pve_next; } else { + /* * Find the PV element pointing to the target * element. Note: may have pv_idx==PVE_EOL */ + for (;;) { if (pv_idx == PVE_EOL) { -#ifdef PMAP_DEBUG - printf("pmap_remove_pte: PVE_EOL\n"); - Debugger(); -#endif goto pv_not_found; } if (pvebase[pv_idx].pve_next == targ_idx) break; pv_idx = pvebase[pv_idx].pve_next; } + /* * At this point, pv_idx is the index of the PV * element just before the target element in the list. * Unlink the target. */ + pvebase[pv_idx].pve_next = pvebase[targ_idx].pve_next; - pv_not_found: } + /* * Save the mod/ref bits of the pte by simply * ORing the entire pte onto the pv_flags member @@ -1601,10 +1520,10 @@ pmap_remove_pte(pte) * for usage information on the pv head than that * which is used on the MMU ptes. */ - pv->pv_flags |= (u_short) pte->attr.raw; - splx(s); - } +pv_not_found: + pv->pv_flags |= (u_short) pte->attr.raw; + } pte->attr.raw = MMU_DT_INVALID; } @@ -1621,7 +1540,7 @@ pmap_remove_pte(pte) boolean_t pmap_stroll(pmap, va, a_tbl, b_tbl, c_tbl, pte, a_idx, b_idx, pte_idx) pmap_t pmap; - vm_offset_t va; + vaddr_t va; a_tmgr_t **a_tbl; b_tmgr_t **b_tbl; c_tmgr_t **c_tbl; @@ -1675,14 +1594,13 @@ pmap_stroll(pmap, va, a_tbl, b_tbl, c_tbl, pte, a_idx, b_idx, pte_idx) int pmap_enter(pmap, va, pa, prot, flags) pmap_t pmap; - vm_offset_t va; - vm_offset_t pa; + vaddr_t va; + paddr_t pa; vm_prot_t prot; int flags; { boolean_t insert, managed; /* Marks the need for PV insertion.*/ u_short nidx; /* PV list index */ - int s; /* Used for splvm()/splx() */ int mapflags; /* Flags for the mapping (see NOTE1) */ u_int a_idx, b_idx, pte_idx; /* table indices */ a_tmgr_t *a_tbl; /* A: long descriptor table manager */ @@ -1695,8 +1613,6 @@ pmap_enter(pmap, va, pa, prot, flags) boolean_t wired; /* is the mapping to be wired? */ enum {NONE, NEWA, NEWB, NEWC} llevel; /* used at end */ - if (pmap == NULL) - return 0; if (pmap == pmap_kernel()) { pmap_enter_kernel(va, pa, prot); return 0; @@ -2036,10 +1952,8 @@ pmap_enter(pmap, va, pa, prot, flags) pv = pa2pv(pa); nidx = pteidx(c_pte); - s = splvm(); pvebase[nidx].pve_next = pv->pv_idx; pv->pv_idx = nidx; - splx(s); } /* Move any allocated tables back into the active pool. */ @@ -2076,16 +1990,16 @@ pmap_enter(pmap, va, pa, prot, flags) */ void pmap_enter_kernel(va, pa, prot) - vm_offset_t va; - vm_offset_t pa; + vaddr_t va; + paddr_t pa; vm_prot_t prot; { boolean_t was_valid, insert; u_short pte_idx; - int s, flags; + int flags; mmu_short_pte_t *pte; pv_t *pv; - vm_offset_t old_pa; + paddr_t old_pa; flags = (pa & ~MMU_PAGE_MASK); pa &= MMU_PAGE_MASK; @@ -2103,7 +2017,6 @@ pmap_enter_kernel(va, pa, prot) /* This array is traditionally named "Sysmap" */ pte = &kernCbase[pte_idx]; - s = splvm(); if (MMU_VALID_DT(*pte)) { was_valid = TRUE; /* @@ -2151,8 +2064,6 @@ pmap_enter_kernel(va, pa, prot) pvebase[pte_idx].pve_next = pv->pv_idx; pv->pv_idx = pte_idx; } - splx(s); - } void @@ -2161,7 +2072,15 @@ pmap_kenter_pa(va, pa, prot) paddr_t pa; vm_prot_t prot; { - pmap_enter(pmap_kernel(), va, pa, prot, PMAP_WIRED); + mmu_short_pte_t *pte; + + /* This array is traditionally named "Sysmap" */ + pte = &kernCbase[(u_long)m68k_btop(va - KERNBASE)]; + + KASSERT(!MMU_VALID_DT(*pte)); + pte->attr.raw = MMU_DT_INVALID | MMU_DT_PAGE | (pa & MMU_PAGE_MASK); + if (!(prot & VM_PROT_WRITE)) + pte->attr.raw |= MMU_SHORT_PTE_WP; } void @@ -2169,8 +2088,20 @@ pmap_kremove(va, len) vaddr_t va; vsize_t len; { - for (len >>= PAGE_SHIFT; len > 0; len--, va += PAGE_SIZE) { - pmap_remove(pmap_kernel(), va, va + PAGE_SIZE); + int idx, eidx; + +#ifdef PMAP_DEBUG + if ((sva & PGOFSET) || (eva & PGOFSET)) + panic("pmap_remove_kernel: alignment"); +#endif + + idx = m68k_btop(va - KERNBASE); + eidx = m68k_btop(va + len - KERNBASE); + + while (idx < eidx) { + kernCbase[idx++].attr.raw = MMU_DT_INVALID; + TBIS(va); + va += NBPG; } } @@ -2182,11 +2113,11 @@ pmap_kremove(va, len) * Used for device mappings and early mapping of the kernel text/data/bss. * Returns the first virtual address beyond the end of the range. */ -vm_offset_t +vaddr_t pmap_map(va, pa, endpa, prot) - vm_offset_t va; - vm_offset_t pa; - vm_offset_t endpa; + vaddr_t va; + paddr_t pa; + paddr_t endpa; int prot; { int sz; @@ -2220,7 +2151,7 @@ pmap_map(va, pa, endpa, prot) void pmap_protect(pmap, startva, endva, prot) pmap_t pmap; - vm_offset_t startva, endva; + vaddr_t startva, endva; vm_prot_t prot; { boolean_t iscurpmap; @@ -2230,8 +2161,6 @@ pmap_protect(pmap, startva, endva, prot) c_tmgr_t *c_tbl; mmu_short_pte_t *pte; - if (pmap == NULL) - return; if (pmap == pmap_kernel()) { pmap_protect_kernel(startva, endva, prot); return; @@ -2284,14 +2213,14 @@ pmap_protect(pmap, startva, endva, prot) if (b_tbl || MMU_VALID_DT(a_tbl->at_dtbl[a_idx])) { if (b_tbl == NULL) { b_tbl = (b_tmgr_t *) a_tbl->at_dtbl[a_idx].addr.raw; - b_tbl = mmu_ptov((vm_offset_t) b_tbl); - b_tbl = mmuB2tmgr((mmu_short_dte_t *) b_tbl); + b_tbl = mmu_ptov((vaddr_t)b_tbl); + b_tbl = mmuB2tmgr((mmu_short_dte_t *)b_tbl); } if (c_tbl || MMU_VALID_DT(b_tbl->bt_dtbl[b_idx])) { if (c_tbl == NULL) { c_tbl = (c_tmgr_t *) MMU_DTE_PA(b_tbl->bt_dtbl[b_idx]); - c_tbl = mmu_ptov((vm_offset_t) c_tbl); - c_tbl = mmuC2tmgr((mmu_short_pte_t *) c_tbl); + c_tbl = mmu_ptov((vaddr_t)c_tbl); + c_tbl = mmuC2tmgr((mmu_short_pte_t *)c_tbl); } if (MMU_VALID_DT(c_tbl->ct_dtbl[c_idx])) { pte = &c_tbl->ct_dtbl[c_idx]; @@ -2340,10 +2269,10 @@ pmap_protect(pmap, startva, endva, prot) */ void pmap_protect_kernel(startva, endva, prot) - vm_offset_t startva, endva; + vaddr_t startva, endva; vm_prot_t prot; { - vm_offset_t va; + vaddr_t va; mmu_short_pte_t *pte; pte = &kernCbase[(unsigned long) m68k_btop(startva - KERNBASE)]; @@ -2383,7 +2312,7 @@ pmap_protect_kernel(startva, endva, prot) void pmap_unwire(pmap, va) pmap_t pmap; - vm_offset_t va; + vaddr_t va; { int a_idx, b_idx, c_idx; a_tmgr_t *a_tbl; @@ -2445,9 +2374,9 @@ pmap_unwire(pmap, va) void pmap_copy(pmap_a, pmap_b, dst, len, src) pmap_t pmap_a, pmap_b; - vm_offset_t dst; - vm_size_t len; - vm_offset_t src; + vaddr_t dst; + vsize_t len; + vaddr_t src; { /* not implemented. */ } @@ -2464,29 +2393,33 @@ pmap_copy(pmap_a, pmap_b, dst, len, src) */ void pmap_copy_page(srcpa, dstpa) - vm_offset_t srcpa, dstpa; + paddr_t srcpa, dstpa; { - vm_offset_t srcva, dstva; + vaddr_t srcva, dstva; int s; srcva = tmp_vpages[0]; dstva = tmp_vpages[1]; s = splvm(); +#ifdef DIAGNOSTIC if (tmp_vpages_inuse++) panic("pmap_copy_page: temporary vpages are in use."); +#endif /* Map pages as non-cacheable to avoid cache polution? */ - pmap_enter_kernel(srcva, srcpa, VM_PROT_READ); - pmap_enter_kernel(dstva, dstpa, VM_PROT_READ|VM_PROT_WRITE); + pmap_kenter_pa(srcva, srcpa, VM_PROT_READ); + pmap_kenter_pa(dstva, dstpa, VM_PROT_READ|VM_PROT_WRITE); /* Hand-optimized version of bcopy(src, dst, NBPG) */ copypage((char *) srcva, (char *) dstva); - pmap_remove_kernel(srcva, srcva + NBPG); - pmap_remove_kernel(dstva, dstva + NBPG); + pmap_kremove(srcva, NBPG); + pmap_kremove(dstva, NBPG); +#ifdef DIAGNOSTIC --tmp_vpages_inuse; +#endif splx(s); } @@ -2499,25 +2432,28 @@ pmap_copy_page(srcpa, dstpa) */ void pmap_zero_page(dstpa) - vm_offset_t dstpa; + paddr_t dstpa; { - vm_offset_t dstva; + vaddr_t dstva; int s; dstva = tmp_vpages[1]; s = splvm(); +#ifdef DIAGNOSTIC if (tmp_vpages_inuse++) panic("pmap_zero_page: temporary vpages are in use."); +#endif /* The comments in pmap_copy_page() above apply here also. */ - pmap_enter_kernel(dstva, dstpa, VM_PROT_READ|VM_PROT_WRITE); + pmap_kenter_pa(dstva, dstpa, VM_PROT_READ|VM_PROT_WRITE); /* Hand-optimized version of bzero(ptr, NBPG) */ zeropage((char *) dstva); - pmap_remove_kernel(dstva, dstva + NBPG); - + pmap_kremove(dstva, NBPG); +#ifdef DIAGNOSTIC --tmp_vpages_inuse; +#endif splx(s); } @@ -2582,8 +2518,6 @@ pmap_release(pmap) * be nothing to do. */ #ifdef PMAP_DEBUG - if (pmap == NULL) - return; if (pmap == pmap_kernel()) panic("pmap_release: kernel pmap"); #endif @@ -2620,9 +2554,6 @@ void pmap_reference(pmap) pmap_t pmap; { - if (pmap == NULL) - return; - pmap_lock(pmap); pmap_add_ref(pmap); pmap_unlock(pmap); @@ -2639,9 +2570,6 @@ pmap_dereference(pmap) { int rtn; - if (pmap == NULL) - return 0; - pmap_lock(pmap); rtn = pmap_del_ref(pmap); pmap_unlock(pmap); @@ -2659,10 +2587,6 @@ void pmap_destroy(pmap) pmap_t pmap; { - if (pmap == NULL) - return; - if (pmap == &kernel_pmap) - panic("pmap_destroy: kernel_pmap!"); if (pmap_dereference(pmap) == 0) { pmap_release(pmap); pool_put(&pmap_pmap_pool, pmap); @@ -2680,38 +2604,27 @@ pmap_is_referenced(pg) { paddr_t pa = VM_PAGE_TO_PHYS(pg); pv_t *pv; - int idx, s; + int idx; - if (!pv_initialized) - return FALSE; - /* XXX - this may be unecessary. */ - if (!is_managed(pa)) - return FALSE; - - pv = pa2pv(pa); /* * Check the flags on the pv head. If they are set, * return immediately. Otherwise a search must be done. */ + + pv = pa2pv(pa); if (pv->pv_flags & PV_FLAGS_USED) return TRUE; - s = splvm(); /* * Search through all pv elements pointing * to this page and query their reference bits */ - for (idx = pv->pv_idx; - idx != PVE_EOL; - idx = pvebase[idx].pve_next) { + for (idx = pv->pv_idx; idx != PVE_EOL; idx = pvebase[idx].pve_next) { if (MMU_PTE_USED(kernCbase[idx])) { - splx(s); return TRUE; } } - splx(s); - return FALSE; } @@ -2726,30 +2639,21 @@ pmap_is_modified(pg) { paddr_t pa = VM_PAGE_TO_PHYS(pg); pv_t *pv; - int idx, s; - - if (!pv_initialized) - return FALSE; - /* XXX - this may be unecessary. */ - if (!is_managed(pa)) - return FALSE; + int idx; /* see comments in pmap_is_referenced() */ pv = pa2pv(pa); if (pv->pv_flags & PV_FLAGS_MDFY) return TRUE; - s = splvm(); for (idx = pv->pv_idx; idx != PVE_EOL; idx = pvebase[idx].pve_next) { if (MMU_PTE_MODIFIED(kernCbase[idx])) { - splx(s); return TRUE; } } - splx(s); return FALSE; } @@ -2766,23 +2670,16 @@ pmap_page_protect(pg, prot) { paddr_t pa = VM_PAGE_TO_PHYS(pg); pv_t *pv; - int idx, s; - vm_offset_t va; + int idx; + vaddr_t va; struct mmu_short_pte_struct *pte; c_tmgr_t *c_tbl; pmap_t pmap, curpmap; - if (!is_managed(pa)) - return; - curpmap = current_pmap(); pv = pa2pv(pa); - s = splvm(); - - for (idx = pv->pv_idx; - idx != PVE_EOL; - idx = pvebase[idx].pve_next) { + for (idx = pv->pv_idx; idx != PVE_EOL; idx = pvebase[idx].pve_next) { pte = &kernCbase[idx]; switch (prot) { case VM_PROT_ALL: @@ -2796,15 +2693,7 @@ pmap_page_protect(pg, prot) * the PTE and flush ATC entries if necessary. */ va = pmap_get_pteinfo(idx, &pmap, &c_tbl); - /* XXX don't write protect pager mappings */ - if (va >= PAGER_SVA && va < PAGER_EVA) { -#ifdef PMAP_DEBUG - /* XXX - Does this actually happen? */ - printf("pmap_page_protect: in pager!\n"); - Debugger(); -#endif - } else - pte->attr.raw |= MMU_SHORT_PTE_WP; + pte->attr.raw |= MMU_SHORT_PTE_WP; if (pmap == curpmap || pmap == pmap_kernel()) TBIS(va); break; @@ -2850,7 +2739,6 @@ pmap_page_protect(pg, prot) */ if (prot == VM_PROT_NONE) pv->pv_idx = PVE_EOL; - splx(s); } /* pmap_get_pteinfo INTERNAL @@ -2862,13 +2750,13 @@ pmap_page_protect(pg, prot) * Returns the pmap in the argument provided, and the virtual address * by return value. */ -vm_offset_t +vaddr_t pmap_get_pteinfo(idx, pmap, tbl) u_int idx; pmap_t *pmap; c_tmgr_t **tbl; { - vm_offset_t va = 0; + vaddr_t va = 0; /* * Determine if the PTE is a kernel PTE or a user PTE. @@ -2915,8 +2803,6 @@ pmap_clear_modify(pg) paddr_t pa = VM_PAGE_TO_PHYS(pg); boolean_t rv; - if (!is_managed(pa)) - return FALSE; rv = pmap_is_modified(pg); pmap_clear_pv(pa, PV_FLAGS_MDFY); return rv; @@ -2934,8 +2820,6 @@ pmap_clear_reference(pg) paddr_t pa = VM_PAGE_TO_PHYS(pg); boolean_t rv; - if (!is_managed(pa)) - return FALSE; rv = pmap_is_referenced(pg); pmap_clear_pv(pa, PV_FLAGS_USED); return rv; @@ -2956,27 +2840,22 @@ pmap_clear_reference(pg) */ void pmap_clear_pv(pa, flag) - vm_offset_t pa; + paddr_t pa; int flag; { pv_t *pv; - int idx, s; - vm_offset_t va; + int idx; + vaddr_t va; pmap_t pmap; mmu_short_pte_t *pte; c_tmgr_t *c_tbl; pv = pa2pv(pa); - - s = splvm(); pv->pv_flags &= ~(flag); - - for (idx = pv->pv_idx; - idx != PVE_EOL; - idx = pvebase[idx].pve_next) { - + for (idx = pv->pv_idx; idx != PVE_EOL; idx = pvebase[idx].pve_next) { pte = &kernCbase[idx]; pte->attr.raw &= ~(flag); + /* * The MC68030 MMU will not set the modified or * referenced bits on any MMU tables for which it has @@ -2992,10 +2871,10 @@ pmap_clear_pv(pa, flag) * I will skip the test and always flush the address. It * does no harm. */ + va = pmap_get_pteinfo(idx, &pmap, &c_tbl); TBIS(va); } - splx(s); } /* pmap_extract INTERFACE @@ -3020,8 +2899,6 @@ pmap_extract(pmap, va, pap) if (pmap == pmap_kernel()) return pmap_extract_kernel(va, pap); - if (pmap == NULL) - return FALSE; if (pmap_stroll(pmap, va, &a_tbl, &b_tbl, &c_tbl, &c_pte, &a_idx, &b_idx, &pte_idx) == FALSE) @@ -3061,8 +2938,8 @@ pmap_extract_kernel(va, pap) */ void pmap_remove_kernel(sva, eva) - vm_offset_t sva; - vm_offset_t eva; + vaddr_t sva; + vaddr_t eva; { int idx, eidx; @@ -3091,8 +2968,8 @@ pmap_remove_kernel(sva, eva) void pmap_remove(pmap, start, end) pmap_t pmap; - vm_offset_t start; - vm_offset_t end; + vaddr_t start; + vaddr_t end; { if (pmap == pmap_kernel()) { @@ -3100,15 +2977,6 @@ pmap_remove(pmap, start, end) return; } - /* - * XXX - Temporary(?) statement to prevent panic caused - * by vm_alloc_with_pager() handing us a software map (ie NULL) - * to remove because it couldn't get backing store. - * (I guess.) - */ - if (pmap == NULL) - return; - /* * If the pmap doesn't have an A table of its own, it has no mappings * that can be removed. @@ -3161,12 +3029,12 @@ pmap_remove(pmap, start, end) boolean_t pmap_remove_a(a_tbl, start, end) a_tmgr_t *a_tbl; - vm_offset_t start; - vm_offset_t end; + vaddr_t start; + vaddr_t end; { boolean_t empty; int idx; - vm_offset_t nstart, nend; + vaddr_t nstart, nend; b_tmgr_t *b_tbl; mmu_long_dte_t *a_dte; mmu_short_dte_t *b_dte; @@ -3351,12 +3219,12 @@ pmap_remove_a(a_tbl, start, end) boolean_t pmap_remove_b(b_tbl, start, end) b_tmgr_t *b_tbl; - vm_offset_t start; - vm_offset_t end; + vaddr_t start; + vaddr_t end; { boolean_t empty; int idx; - vm_offset_t nstart, nend, rstart; + vaddr_t nstart, nend, rstart; c_tmgr_t *c_tbl; mmu_short_dte_t *b_dte; mmu_short_pte_t *c_dte; @@ -3430,8 +3298,8 @@ pmap_remove_b(b_tbl, start, end) boolean_t pmap_remove_c(c_tbl, start, end) c_tmgr_t *c_tbl; - vm_offset_t start; - vm_offset_t end; + vaddr_t start; + vaddr_t end; { boolean_t empty; int idx; @@ -3475,7 +3343,7 @@ pmap_remove_c(c_tbl, start, end) */ boolean_t is_managed(pa) - vm_offset_t pa; + paddr_t pa; { if (pa >= avail_start && pa < avail_end) return TRUE; @@ -3543,9 +3411,9 @@ pmap_bootstrap_aalign(size) */ int pmap_pa_exists(pa) - vm_offset_t pa; + paddr_t pa; { - register int i; + int i; for (i = 0; i < SUN3X_NPHYS_RAM_SEGS; i++) { if ((pa >= avail_mem[i].pmem_start) && @@ -3603,13 +3471,8 @@ void pmap_activate(p) struct proc *p; { - pmap_t pmap = p->p_vmspace->vm_map.pmap; - int s; - if (p == curproc) { - s = splvm(); - _pmap_switch(pmap); - splx(s); + _pmap_switch(p->p_vmspace->vm_map.pmap); } } @@ -3617,13 +3480,12 @@ pmap_activate(p) * pmap_deactivate INTERFACE ** * This is called to deactivate the specified process's address space. - * XXX The semantics of this function are currently not well-defined. */ void pmap_deactivate(p) struct proc *p; { - /* not implemented. */ + /* Nothing to do. */ } /* @@ -3640,7 +3502,7 @@ pmap_kcore_hdr(sh) sh->pg_frame = MMU_SHORT_PTE_BASEADDR; sh->pg_valid = MMU_DT_PAGE; sh->contig_end = virtual_contig_end; - sh->kernCbase = (u_long) kernCbase; + sh->kernCbase = (u_long)kernCbase; for (i = 0; i < SUN3X_NPHYS_RAM_SEGS; i++) { spa = avail_mem[i].pmem_start; spa = m68k_trunc_page(spa); @@ -3659,7 +3521,7 @@ pmap_kcore_hdr(sh) */ void pmap_virtual_space(vstart, vend) - vm_offset_t *vstart, *vend; + vaddr_t *vstart, *vend; { *vstart = virtual_avail; *vend = virtual_end; @@ -3674,7 +3536,7 @@ pmap_virtual_space(vstart, vend) static void pmap_page_upload() { - vm_offset_t a, b; /* memory range */ + paddr_t a, b; /* memory range */ int i; /* Supply the memory in segments. */ @@ -3760,7 +3622,7 @@ pmap_count(pmap, type) extern u_long ptest_addr __P((u_long)); /* XXX: locore.s */ u_int get_pte(va) - vm_offset_t va; + vaddr_t va; { u_long pte_pa; mmu_short_pte_t *pte; @@ -3788,7 +3650,7 @@ get_pte(va) */ void set_pte(va, pte) - vm_offset_t va; + vaddr_t va; u_int pte; { u_long idx; @@ -3832,21 +3694,18 @@ pmap_procwr(p, va, len) */ void pv_list(pa, n) - vm_offset_t pa; + paddr_t pa; int n; { int idx; - vm_offset_t va; + vaddr_t va; pv_t *pv; c_tmgr_t *c_tbl; pmap_t pmap; pv = pa2pv(pa); idx = pv->pv_idx; - - for (;idx != PVE_EOL && n > 0; - idx=pvebase[idx].pve_next, n--) { - + for (; idx != PVE_EOL && n > 0; idx = pvebase[idx].pve_next, n--) { va = pmap_get_pteinfo(idx, &pmap, &c_tbl); printf("idx %d, pmap 0x%x, va 0x%x, c_tbl %x\n", idx, (u_int) pmap, (u_int) va, (u_int) c_tbl);