diff options
Diffstat (limited to 'sys/arch/sun3/sun3/pmap.c')
-rw-r--r-- | sys/arch/sun3/sun3/pmap.c | 183 |
1 files changed, 93 insertions, 90 deletions
diff --git a/sys/arch/sun3/sun3/pmap.c b/sys/arch/sun3/sun3/pmap.c index 01f3a4eadd0..dad84c28933 100644 --- a/sys/arch/sun3/sun3/pmap.c +++ b/sys/arch/sun3/sun3/pmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.64 1996/11/20 18:57:35 gwr Exp $ */ +/* $NetBSD: pmap.c,v 1.65 1996/12/17 21:11:38 gwr Exp $ */ /*- * Copyright (c) 1996 The NetBSD Foundation, Inc. @@ -57,6 +57,13 @@ */ /* + * Cache management: + * All sun3 cache implementations are write-back. + * Flushes must be done before removing translations + * from the MMU because the cache uses the MMU. + */ + +/* * wanted attributes: * pmegs that aren't needed by a pmap remain in the MMU. * quick context switches between pmaps @@ -83,26 +90,13 @@ #include <machine/dvma.h> #include <machine/pmap.h> -#include "cache.h" +#include "machdep.h" + #if (PMAP_OBIO << PG_MOD_SHIFT) != PGT_OBIO #error "PMAP_XXX definitions don't match pte.h!" #endif -/* - * Globals shared between here and sun3_startup: - * For simplicity, this interface retains the variables - * that were used in the old interface (without NONCONTIG). - * These are set in pmap_bootstrap() and used - * in pmap_next_page(). - */ -/* Kernel virtual address space available: */ -extern vm_offset_t virtual_avail, virtual_end; -/* Physical address space available: */ -extern vm_offset_t avail_start, avail_end; -/* The "hole" (used to skip the Sun3/50 video RAM) */ -extern vm_offset_t hole_start, hole_size; - /* statistics... */ struct pmap_stats { int ps_enter_firstpv; /* pv heads entered */ @@ -188,6 +182,7 @@ typedef struct pv_entry *pv_entry_t; pv_entry_t pv_head_table = NULL; #ifdef DIAGNOSTIC +static struct pv_entry * pa_to_pvp __P((vm_offset_t pa)); static struct pv_entry * pa_to_pvp(pa) vm_offset_t pa; @@ -310,6 +305,13 @@ struct pmeg_tailq pmeg_free_queue, pmeg_inactive_queue, static struct pmeg_state pmeg_array[NPMEG]; #ifdef PMAP_DEBUG +void pmap_print __P((pmap_t pmap)); +void pv_print __P((vm_offset_t pa)); + +static pmeg_t pmeg_p __P((int sme)); +static void pmeg_verify_empty __P((vm_offset_t va)); +static void pmeg_print __P((pmeg_t pmegp)); + static pmeg_t pmeg_p(sme) int sme; @@ -354,14 +356,12 @@ static void context_allocate __P((pmap_t pmap)); static void context_free __P((pmap_t pmap)); static void context_init __P((void)); -static void pmeg_flush __P((pmeg_t pmegp)); static pmeg_t pmeg_allocate __P((pmap_t pmap, vm_offset_t va)); static void pmeg_release __P((pmeg_t pmegp)); static void pmeg_free __P((pmeg_t pmegp, int segnum)); 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 int pv_compute_cache __P((pv_entry_t head)); static int pv_link __P((pmap_t pmap, vm_offset_t, vm_offset_t, u_int)); static void pv_unlink __P((pmap_t, vm_offset_t, vm_offset_t)); static void pv_remove_all __P(( vm_offset_t pa)); @@ -369,8 +369,9 @@ static void pv_changepte __P((pv_entry_t, int, int)); static void pv_syncflags __P((pv_entry_t head)); static void pv_init __P((void)); -void sun3_pmeg_init __P((void)); -void sun3_reserve_pmeg __P((int pmeg_num)); +static void pmeg_clean __P((pmeg_t pmegp)); +static void pmeg_clean_free __P((void)); + void sun3_protection_init __P((void)); static void pmap_common_init __P((pmap_t pmap)); @@ -417,7 +418,6 @@ int pmap_db_watchpmeg = -1; #endif /* PMAP_DEBUG */ #ifdef PMAP_DEBUG /* XXX */ -extern int getsr(); #define CHECK_SPL() do { \ if ((getsr() & PSL_IPL) < PSL_IPL3) \ panic("pmap: bad spl, line %d", __LINE__); \ @@ -436,20 +436,22 @@ context_allocate(pmap) PMAP_LOCK(); #ifdef PMAP_DEBUG if (pmap_debug & PMD_CONTEXT) - printf("context_allocate: for pmap %x\n", pmap); + printf("context_allocate: for pmap %p\n", pmap); #endif if (pmap == kernel_pmap) panic("context_allocate: kernel_pmap"); if (has_context(pmap)) panic("pmap: pmap already has context allocated to it"); - if (TAILQ_EMPTY(&context_free_queue)) { - /* Steal one from the active queue. */ - if (TAILQ_EMPTY(&context_active_queue)) - panic("pmap: no contexts to be found"); - context_free((&context_active_queue)->tqh_first->context_upmap); + context = (&context_free_queue)->tqh_first; + if (context == NULL) { + /* Steal the head of the active queue. */ + context = (&context_active_queue)->tqh_first; + if (context == NULL) + panic("pmap: no contexts left?"); + context_free(context->context_upmap); #ifdef PMAP_DEBUG if (pmap_debug & PMD_CONTEXT) - printf("context_allocate: pmap %x, take context %x num %d\n", + printf("context_allocate: pmap %p, take context %p num %d\n", pmap, context, context->context_num); #endif } @@ -461,7 +463,7 @@ context_allocate(pmap) context->context_upmap = pmap; #ifdef PMAP_DEBUG if (pmap_debug & PMD_CONTEXT) - printf("context_allocate: pmap %x given context %x num %d\n", + printf("context_allocate: pmap %p given context %p num %d\n", pmap, context, context->context_num); #endif @@ -489,7 +491,7 @@ context_free(pmap) /* :) */ ctxnum = pmap->pm_ctxnum; #ifdef PMAP_DEBUG if (pmap_debug & PMD_CONTEXT) - printf("context_free: freeing context num %d of pmap 0x%x\n", + printf("context_free: freeing context num %d of pmap %p\n", ctxnum, pmap); #endif @@ -536,7 +538,7 @@ context_free(pmap) /* :) */ pmap->pm_ctxnum = CTXINVAL; #ifdef PMAP_DEBUG if (pmap_debug & PMD_CONTEXT) - printf("context_free: pmap %x context removed\n", pmap); + printf("context_free: pmap %p context removed\n", pmap); #endif PMAP_UNLOCK(); } @@ -556,21 +558,22 @@ context_init() context_link); #ifdef PMAP_DEBUG if (pmap_debug & PMD_CONTEXT) - printf("context_init: context num %d is %x\n", + printf("context_init: context num %d is %p\n", i, &context_array[i]); #endif } } #ifdef PMAP_DEBUG -void pmap_print(pmap) +void +pmap_print(pmap) pmap_t pmap; { printf(" pm_ctxnum=%d\n", pmap->pm_ctxnum); printf(" pm_version=0x%x\n", pmap->pm_version); - printf(" pm_segmap=0x%x\n", pmap->pm_segmap); + printf(" pm_segmap=%p\n", pmap->pm_segmap); } -#endif +#endif /* PMAP_DEBUG */ /* * Reserve a pmeg (forever) for use by PROM, etc. @@ -659,23 +662,24 @@ pmeg_verify_empty(va) panic("pmeg_verify_empty"); } } +#endif /* PMAP_DEBUG */ -static void +#ifdef PMAP_DEBUG +void pmeg_print(pmegp) pmeg_t pmegp; { - printf("link_next=0x%x link_prev=0x%x\n", - pmegp->pmeg_link.tqe_next, - pmegp->pmeg_link.tqe_prev); - printf("index=0x%x owner=0x%x own_vers=0x%x\n", - pmegp->pmeg_index, pmegp->pmeg_owner, - pmegp->pmeg_version); + printf("link_next=%p link_prev=%p\n", + pmegp->pmeg_link.tqe_next, + pmegp->pmeg_link.tqe_prev); + printf("index=0x%x owner=%p own_vers=0x%x\n", + pmegp->pmeg_index, pmegp->pmeg_owner, pmegp->pmeg_version); printf("va=0x%x wired=0x%x reserved=0x%x vpgs=0x%x qstate=0x%x\n", - pmegp->pmeg_va, pmegp->pmeg_wired, - pmegp->pmeg_reserved, pmegp->pmeg_vpages, - pmegp->pmeg_qstate); + pmegp->pmeg_va, pmegp->pmeg_wired, + pmegp->pmeg_reserved, pmegp->pmeg_vpages, + pmegp->pmeg_qstate); } -#endif +#endif /* PMAP_DEBUG */ /* * Allocate a PMEG by whatever means necessary. @@ -760,7 +764,7 @@ pmeg_allocate(pmap, va) pmegp->pmeg_qstate = PMEGQ_ACTIVE; #ifdef PMAP_DEBUG if (pmap_debug & PMD_SEGMAP) { - printf("pm_segmap: pmap=%x i=%x old=%x new=%x (pget)\n", + printf("pm_segmap: pmap=%p i=%x old=%x new=%x (pget)\n", pmap, VA_SEGNUM(va), pmap->pm_segmap[VA_SEGNUM(va)], pmegp->pmeg_index); @@ -963,7 +967,8 @@ sun3_pmeg_init() } #ifdef PMAP_DEBUG -static void +/* call from debugger */ +void pv_print(pa) vm_offset_t pa; { @@ -975,7 +980,7 @@ pv_print(pa) pv = pa_to_pvp(pa); printf("pv_list for pa %x: flags=%x\n", pa, pv->pv_flags); while (pv) { - printf("pv_entry %x pmap %x va %x next %x\n", + printf("pv_entry %p pmap %p va %x next %p\n", pv, pv->pv_pmap, pv->pv_va, pv->pv_next); pv = pv->pv_next; } @@ -1017,6 +1022,8 @@ pv_changepte(head, set_bits, clear_bits) for (pv = head; pv != NULL; pv = pv->pv_next) { pmap = pv->pv_pmap; va = pv->pv_va; + sme = SEGINV; /* kill warning */ + #ifdef DIAGNOSTIC /* * Only the head may have a null pmap, and @@ -1117,6 +1124,8 @@ pv_syncflags(head) for (pv = head; pv != NULL; pv = pv->pv_next) { pmap = pv->pv_pmap; va = pv->pv_va; + sme = SEGINV; /* kill warning */ + #ifdef DIAGNOSTIC /* * Only the head may have a null pmap, and @@ -1244,7 +1253,7 @@ pv_link(pmap, pa, va, flags) #ifdef PMAP_DEBUG if ((pmap_debug & PMD_LINK) || (va == pmap_db_watchva)) { - printf("pv_link(%x, %x, %x, %x)\n", pmap, pa, va, flags); + printf("pv_link(%p, %x, %x, %x)\n", pmap, pa, va, flags); /* pv_print(pa); */ } #endif @@ -1323,7 +1332,7 @@ pv_unlink(pmap, pa, va) if ((pmap_debug & PMD_UNLINK) || (va == pmap_db_watchva)) { - printf("pv_unlink(%x, %x, %x)\n", pmap, pa, va); + printf("pv_unlink(%p, %x, %x)\n", pmap, pa, va); } #endif head = pa_to_pvp(pa); @@ -1444,7 +1453,6 @@ pmap_common_init(pmap) void pmap_bootstrap() { - extern void vm_set_page_size(); /* * Reserve a segment for the kernel to use to access a pmeg @@ -1558,7 +1566,7 @@ int pmap_page_index(pa) vm_offset_t pa; { - u_long idx; + int idx; #ifdef DIAGNOSTIC if (pa < avail_start || pa >= avail_end) @@ -1570,7 +1578,8 @@ pmap_page_index(pa) } #endif - return (sun3_btop(pa)); + idx = sun3_btop(pa); + return (idx); } @@ -1682,7 +1691,7 @@ pmap_destroy(pmap) #ifdef PMAP_DEBUG if (pmap_debug & PMD_CREATE) - printf("pmap_destroy(%x)\n", pmap); + printf("pmap_destroy(%p)\n", pmap); #endif if (pmap == kernel_pmap) panic("pmap_destroy: kernel_pmap!"); @@ -1757,7 +1766,6 @@ pmap_remove_range_mmu(pmap, sva, eva) pmap_t pmap; vm_offset_t sva, eva; { - int old_ctx, i; pmeg_t pmegp; vm_offset_t va; int pte, sme; @@ -1766,7 +1774,7 @@ pmap_remove_range_mmu(pmap, sva, eva) #ifdef PMAP_DEBUG if ((pmap_debug & PMD_REMOVE) || ((sva <= pmap_db_watchva && eva > pmap_db_watchva))) - printf("pmap_remove_range_mmu(%x, %x, %x)\n", pmap, sva, eva); + printf("pmap_remove_range_mmu(%p, %x, %x)\n", pmap, sva, eva); #endif /* Interrupt level handled by caller. */ @@ -1841,7 +1849,7 @@ pmap_remove_range_mmu(pmap, sva, eva) } #ifdef PMAP_DEBUG if ((pmap_debug & PMD_SETPTE) || (va == pmap_db_watchva)) { - printf("pmap: set_pte pmap=%x va=%x old=%x new=%x (rrmmu)\n", + printf("pmap: set_pte pmap=%p va=%x old=%x new=%x (rrmmu)\n", pmap, va, pte, PG_INVAL); } #endif @@ -1855,7 +1863,7 @@ pmap_remove_range_mmu(pmap, sva, eva) if (is_pmeg_wired(pmegp)) { #ifdef PMAP_DEBUG if (pmap_debug & PMD_WIRING) { - printf("pmap: removing wired pmeg: 0x%x\n", pmegp); + printf("pmap: removing wired pmeg: %p\n", pmegp); Debugger(); /* XXX */ } #endif /* PMAP_DEBUG */ @@ -1894,7 +1902,7 @@ pmap_remove_range_noctx(pmap, sva, eva) #ifdef PMAP_DEBUG if ((pmap_debug & PMD_REMOVE) || ((sva <= pmap_db_watchva && eva > pmap_db_watchva))) - printf("pmap_remove_range_noctx(%x, %x, %x)\n", pmap, sva, eva); + printf("pmap_remove_range_noctx(%p, %x, %x)\n", pmap, sva, eva); #endif /* Interrupt level handled by caller. */ @@ -1922,7 +1930,7 @@ pmap_remove_range_noctx(pmap, sva, eva) } #ifdef PMAP_DEBUG if ((pmap_debug & PMD_SETPTE) || (va == pmap_db_watchva)) { - printf("pmap: set_pte pmap=%x va=%x old=%x new=%x (rrncx)\n", + printf("pmap: set_pte pmap=%p va=%x old=%x new=%x (rrncx)\n", pmap, va, pte, PG_INVAL); } #endif @@ -1947,7 +1955,7 @@ pmap_remove_range(pmap, sva, eva) pmap_t pmap; vm_offset_t sva, eva; { - int c, s, sme; + int s, sme; int old_ctx; boolean_t in_ctx; @@ -2054,8 +2062,7 @@ pmap_enter_kernel(va, pa, prot, wired, new_pte) boolean_t wired; int new_pte; { - int s, i, c; - int sme, old_pte; + int s, sme, old_pte; int nflags, do_pv; vm_offset_t seg_va; pmeg_t pmegp; @@ -2112,12 +2119,13 @@ pmap_enter_kernel(va, pa, prot, wired, new_pte) set_segmap_allctx(va, sme); #ifdef PMAP_DEBUG if (pmap_debug & PMD_SEGMAP) { - printf("pmap: set_segmap pmap=%x va=%x sme=%x (ek1)\n", + printf("pmap: set_segmap pmap=%p va=%x sme=%x (ek1)\n", kernel_pmap, seg_va, sme); } pmeg_verify_empty(sun3_trunc_seg(va)); #endif /* There are no existing mappings to deal with. */ + old_pte = 0; goto add_pte; } @@ -2190,7 +2198,7 @@ pmap_enter_kernel(va, pa, prot, wired, new_pte) } #ifdef PMAP_DEBUG if ((pmap_debug & PMD_SETPTE) || (va == pmap_db_watchva)) { - printf("pmap: set_pte pmap=%x va=%x old=%x new=%x (ek)\n", + printf("pmap: set_pte pmap=%p va=%x old=%x new=%x (ek)\n", kernel_pmap, va, old_pte, new_pte); } #endif @@ -2228,7 +2236,7 @@ pmap_enter_user(pmap, va, pa, prot, wired, new_pte) */ if (wired && (pmap_debug & PMD_WIRING)) { printf("pmap_enter_user: attempt to wire user page, ignored\n"); - printf("pmap=0x%x va=0x%x pa=0x%x\n", pmap, va, pa); + printf("pmap=%p va=0x%x pa=0x%x\n", pmap, va, pa); } #endif #ifdef DIAGNOSTIC @@ -2289,12 +2297,13 @@ pmap_enter_user(pmap, va, pa, prot, wired, new_pte) set_segmap(va, sme); #ifdef PMAP_DEBUG if (pmap_debug & PMD_SEGMAP) { - printf("pmap: set_segmap pmap=%x va=%x sme=%x (eu1)\n", + printf("pmap: set_segmap pmap=%p va=%x sme=%x (eu1)\n", pmap, seg_va, sme); } pmeg_verify_empty(seg_va); #endif /* There are no existing mappings to deal with. */ + old_pte = 0; goto add_pte; } @@ -2318,7 +2327,7 @@ pmap_enter_user(pmap, va, pa, prot, wired, new_pte) set_segmap(va, sme); #ifdef PMAP_DEBUG if (pmap_debug & PMD_SEGMAP) { - printf("pmap: set_segmap pmap=%x va=%x sme=%x (eu2)\n", + printf("pmap: set_segmap pmap=%p va=%x sme=%x (eu2)\n", pmap, seg_va, sme); } #endif @@ -2386,7 +2395,7 @@ pmap_enter_user(pmap, va, pa, prot, wired, new_pte) } #ifdef PMAP_DEBUG if ((pmap_debug & PMD_SETPTE) || (va == pmap_db_watchva)) { - printf("pmap: set_pte pmap=%x va=%x old=%x new=%x (eu)\n", + printf("pmap: set_pte pmap=%p va=%x old=%x new=%x (eu)\n", pmap, va, old_pte, new_pte); } #endif @@ -2431,7 +2440,7 @@ pmap_enter(pmap, va, pa, prot, wired) #ifdef PMAP_DEBUG if ((pmap_debug & PMD_ENTER) || (va == pmap_db_watchva)) - printf("pmap_enter(%x, %x, %x, %x, %x)\n", + printf("pmap_enter(%p, %x, %x, %x, %x)\n", pmap, va, pa, prot, wired); #endif @@ -2478,7 +2487,7 @@ int pmap_fault_reload(pmap, va, ftype) vm_offset_t va; vm_prot_t ftype; { - int rv, s, pte, chkpte, sme, segnum, ctx; + int rv, s, pte, chkpte, sme, ctx; vm_offset_t seg_va; pmeg_t pmegp; @@ -2529,7 +2538,7 @@ int pmap_fault_reload(pmap, va, ftype) rv = 1; } } - + PMAP_UNLOCK(); return (0); } @@ -2628,7 +2637,7 @@ pmap_activate(pmap, pcbp) context_allocate(pmap); #ifdef PMAP_DEBUG if (pmap_debug & PMD_SWITCH) - printf("pmap_activate(%x) takes context %d\n", + printf("pmap_activate(%p) takes context %d\n", pmap, pmap->pm_ctxnum); #endif } @@ -2637,7 +2646,7 @@ pmap_activate(pmap, pcbp) if (pmap_debug & PMD_SWITCH) { int old_ctx = get_context(); if (old_ctx != pmap->pm_ctxnum) { - printf("pmap_activate(%x) old_ctx=%d new_ctx=%d\n", + printf("pmap_activate(%p) old_ctx=%d new_ctx=%d\n", pmap, old_ctx, pmap->pm_ctxnum); } } @@ -2653,7 +2662,7 @@ pmap_deactivate(pmap, pcbp) { #ifdef PMAP_DEBUG if (pmap_debug & PMD_SWITCH) - printf("pmap_deactivate(%x, %x)\n", pmap, pcbp); + printf("pmap_deactivate(%p, %p)\n", pmap, pcbp); #endif /* Nothing to do really, and not called anyway... */ } @@ -2679,7 +2688,7 @@ pmap_change_wiring(pmap, va, wired) return; #ifdef PMAP_DEBUG if (pmap_debug & PMD_WIRING) - printf("pmap_change_wiring(pmap=0x%x, va=0x%x, wire=%d)\n", + printf("pmap_change_wiring(pmap=%p, va=0x%x, wire=%d)\n", pmap, va, wired); #endif /* @@ -2829,11 +2838,9 @@ pmap_protect_range_mmu(pmap, sva, eva) pmap_t pmap; vm_offset_t sva, eva; { - int old_ctx, i; pmeg_t pmegp; vm_offset_t va; int pte, sme; - int nflags; int flush_by_page = 0; /* Interrupt level handled by caller. */ @@ -2923,7 +2930,6 @@ pmap_protect_range_noctx(pmap, sva, eva) int pte, sme, ptenum, segnum; vm_offset_t va; pmeg_t pmegp; - int nflags; /* Interrupt level handled by caller. */ CHECK_SPL(); @@ -2964,7 +2970,7 @@ pmap_protect_range(pmap, sva, eva) pmap_t pmap; vm_offset_t sva, eva; { - int c, s, sme; + int s, sme; int old_ctx; boolean_t in_ctx; @@ -2973,7 +2979,7 @@ pmap_protect_range(pmap, sva, eva) #ifdef PMAP_DEBUG if ((pmap_debug & PMD_PROTECT) || ((sva <= pmap_db_watchva && eva > pmap_db_watchva))) - printf("pmap_protect_range(%x, %x, %x)\n", pmap, sva, eva); + printf("pmap_protect_range(%p, %x, %x)\n", pmap, sva, eva); #endif #ifdef DIAGNOSTIC if (sun3_trunc_seg(sva) != sun3_trunc_seg(eva-NBPG)) @@ -3034,7 +3040,7 @@ pmap_protect(pmap, sva, eva, prot) #ifdef PMAP_DEBUG if (pmap_debug & PMD_PROTECT) - printf("pmap_protect(%x, %x, %x, %x)\n", pmap, sva, eva, prot); + printf("pmap_protect(%p, %x, %x, %x)\n", pmap, sva, eva, prot); #endif if (pmap == NULL) @@ -3225,11 +3231,10 @@ pmap_prefer(fo, va) * Copy the kernel segmap into the passed buffer (256 bytes). */ void -pmap_get_ksegmap(vaddr) - vm_offset_t vaddr; +pmap_get_ksegmap(cp) + u_char *cp; { vm_offset_t va; - u_char *cp = (u_char*)vaddr; va = KERNBASE; do { @@ -3244,15 +3249,13 @@ pmap_get_ksegmap(vaddr) * starting at OFF in the pagemap RAM. */ void -pmap_get_pagemap(vaddr, off) - vm_offset_t vaddr; +pmap_get_pagemap(pt, off) + int *pt; int off; { vm_offset_t va, va_end; int sme, sme_end; /* SegMap Entry numbers */ - int *pt; - pt = (int*)vaddr; /* destination */ sme = (off >> 6); /* PMEG to start on */ sme_end = sme + 128; /* where to stop */ va_end = temp_seg_va + NBSG; |