Fix a spl issues. Turn on PMAPCHECK until instability problems are found.

Add a pmap_pvo_verify call you call it from it ddb and verify the pmap
data structures are sound.  Fix warnings when DEBUG was turned on.
This commit is contained in:
matt 2001-06-10 07:56:36 +00:00
parent b9ef9e99da
commit 66822e55be
1 changed files with 98 additions and 18 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap.c,v 1.2 2001/06/08 00:16:25 matt Exp $ */
/* $NetBSD: pmap.c,v 1.3 2001/06/10 07:56:36 matt Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
@ -54,7 +54,13 @@
#include <machine/pcb.h>
#include <machine/powerpc.h>
#if __NetBSD_Version__ > 105010000
#include <powerpc/mpc6xx/bat.h>
#else
#include <powerpc/bat.h>
#endif
#define PMAPCHECK
#if defined(DEBUG) || defined(PMAPCHECK)
#define STATIC
@ -149,7 +155,12 @@ int pmapcheck = 1;
#else
int pmapcheck = 0;
#endif
void pmap_pvo_verify(void);
void pte_print(volatile pte_t *pt);
void pteg_check(void);
void pteg_dist(void);
void print_pte(pmap_t, vaddr_t);
void print_mmuregs(void);
STATIC void pmap_pvo_check(const struct pvo_entry *);
#define PMAP_PVO_CHECK(pvo) \
do { \
@ -212,9 +223,12 @@ tlbia(void)
SYNC();
/* why not use "tlbia"? */
for (i = 0; i < (caddr_t)0x00040000; i += 0x00001000)
for (i = 0; i < (caddr_t)0x00040000; i += 0x00001000) {
TLBIE(i);
EIEIO();
}
TLBSYNC();
SYNC();
}
static __inline int
@ -384,7 +398,9 @@ pte_clear(volatile pte_t *pt, int ptebit)
{
pt->pte_lo &= ~ptebit;
TLBIE(pt);
EIEIO();
TLBSYNC();
SYNC();
}
static __inline void
@ -442,7 +458,9 @@ pte_unset(volatile pte_t *pt, pte_t *pvo_pt, vaddr_t va)
pt->pte_hi &= ~PTE_VALID;
SYNC();
TLBIE(va);
EIEIO();
TLBSYNC();
SYNC();
/*
* Save the ref & chg bits ...
*/
@ -936,6 +954,11 @@ pmap_pvo_find_va(pmap_t pm, vaddr_t va, int *pteidx_p)
ptegidx = va_to_pteg(sr, va);
LIST_FOREACH(pvo, &pvo_table[ptegidx], pvo_olink) {
#ifdef DIAGNOSTIC
if ((uintptr_t) pvo >= SEGMENT_LENGTH)
panic("pmap_pvo_find_va: invalid pvo %p on list %#x",
pvo, ptegidx);
#endif
if (pvo->pvo_pmap == pm && pvo->pvo_vaddr == va) {
if (pteidx_p)
*pteidx_p = pmap_pvo_pte_index(pvo, ptegidx);
@ -1019,6 +1042,29 @@ pmap_pvo_check(const struct pvo_entry *pvo)
volatile pte_t *pt;
int failed = 0;
if ((uintptr_t)(pvo+1) >= SEGMENT_LENGTH)
panic("pmap_pvo_check: pvo %p: invalid address", pvo);
if ((uintptr_t)(pvo->pvo_pmap+1) >= SEGMENT_LENGTH) {
printf("pmap_pvo_check: pvo %p: invalid pmap address %p\n",
pvo, pvo->pvo_pmap);
failed = 1;
}
if ((uintptr_t)pvo->pvo_olink.le_next >= SEGMENT_LENGTH ||
(((uintptr_t)pvo->pvo_olink.le_next) & 0x1f) != 0) {
printf("pmap_pvo_check: pvo %p: invalid ovlink address %p\n",
pvo, pvo->pvo_olink.le_next);
failed = 1;
}
if ((uintptr_t)pvo->pvo_vlink.le_next >= SEGMENT_LENGTH ||
(((uintptr_t)pvo->pvo_vlink.le_next) & 0x1f) != 0) {
printf("pmap_pvo_check: pvo %p: invalid ovlink address %p\n",
pvo, pvo->pvo_vlink.le_next);
failed = 1;
}
if (pvo->pvo_pte.pte_lo & PTE_M) {
pvo_head = pa_to_pvoh(pvo->pvo_pte.pte_lo & PTE_RPGN);
} else {
@ -1040,7 +1086,7 @@ pmap_pvo_check(const struct pvo_entry *pvo)
}
if (pvo != pmap_pvo_find_va(pvo->pvo_pmap, pvo->pvo_vaddr, NULL)) {
printf("pmap_pvo_check: pvo %p: not present "
"on its olist head %p\n", pvo);
"on its olist head\n", pvo);
failed = 1;
}
pt = pmap_pvo_to_pte(pvo, -1);
@ -1069,8 +1115,8 @@ pmap_pvo_check(const struct pvo_entry *pvo)
failed = 1;
}
if (pte_to_va(pt) != pvo->pvo_vaddr) {
printf("pmap_pvo_check: pvo %p: PTE %p derived VA %#x"
" doesn't not match PVO's VA %#x\n",
printf("pmap_pvo_check: pvo %p: PTE %p derived VA %#lx"
" doesn't not match PVO's VA %#lx\n",
pvo, pt, pte_to_va(pt), pvo->pvo_vaddr);
failed = 1;
}
@ -1356,9 +1402,11 @@ pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot)
void
pmap_kremove(vaddr_t va, vsize_t len)
{
#if 0
printf("pmap_kenter_pa(%#x,%#x)\n", va, len);
#endif
if (va < VM_MIN_KERNEL_ADDRESS)
panic("pmap_kremove: attempt to remove "
"non-kernel address %#lx!", va);
DPRINTFN(5,("pmap_kremove(%#lx,%#lx)\n", va, len));
pmap_remove(pmap_kernel(), va, va + len);
}
@ -1483,15 +1531,18 @@ void
pmap_unwire(pmap_t pm, vaddr_t va)
{
struct pvo_entry *pvo;
pvo = pmap_pvo_find_va(pm, va, NULL);
if (pvo == NULL)
return;
int s;
if (pvo->pvo_pte.pte_lo & PTE_WIRED) {
pvo->pvo_pte.pte_lo &= ~PTE_WIRED;
pm->pm_stats.wired_count--;
s = splvm();
pvo = pmap_pvo_find_va(pm, va, NULL);
if (pvo != NULL) {
if (pvo->pvo_pte.pte_lo & PTE_WIRED) {
pvo->pvo_pte.pte_lo &= ~PTE_WIRED;
pm->pm_stats.wired_count--;
}
PMAP_PVO_CHECK(pvo); /* sanity check */
}
PMAP_PVO_CHECK(pvo); /* sanity check */
splx(s);
}
/*
@ -1608,9 +1659,11 @@ pmap_query_bit(struct vm_page *pg, int ptebit)
{
struct pvo_entry *pvo;
volatile pte_t *pt;
int s;
if (pmap_attr_fetch(pg) & ptebit)
return TRUE;
s = splvm();
LIST_FOREACH(pvo, vm_page_to_pvoh(pg), pvo_vlink) {
PMAP_PVO_CHECK(pvo); /* sanity check */
/*
@ -1620,6 +1673,7 @@ pmap_query_bit(struct vm_page *pg, int ptebit)
if (pvo->pvo_pte.pte_lo & ptebit) {
pmap_attr_save(pg, ptebit);
PMAP_PVO_CHECK(pvo); /* sanity check */
splx(s);
return TRUE;
}
}
@ -1642,10 +1696,12 @@ pmap_query_bit(struct vm_page *pg, int ptebit)
if (pvo->pvo_pte.pte_lo & ptebit) {
pmap_attr_save(pg, ptebit);
PMAP_PVO_CHECK(pvo); /* sanity check */
splx(s);
return TRUE;
}
}
}
splx(s);
return FALSE;
}
@ -1655,7 +1711,9 @@ pmap_clear_bit(struct vm_page *pg, int ptebit)
struct pvo_entry *pvo;
volatile pte_t *pt;
int rv = 0;
int s;
s = splvm();
/*
* Clear the cached value.
*/
@ -1686,6 +1744,7 @@ pmap_clear_bit(struct vm_page *pg, int ptebit)
pvo->pvo_pte.pte_lo &= ~ptebit;
PMAP_PVO_CHECK(pvo); /* sanity check */
}
splx(s);
return (rv & ptebit) != 0;
}
@ -1782,7 +1841,7 @@ pte_print(volatile pte_t *pt)
printf("0x%06x 0x%02X",
(pt->pte_hi &~ PTE_VALID)>>PTE_VSID_SHFT,
pt->pte_hi & PTE_API);
printf(" (va 0x%1x%04x000)] ", pte_to_va(pt));
printf(" (va 0x%08lx)] ", pte_to_va(pt));
/* Low word: */
printf(" 0x%08x: [", pt->pte_lo);
printf("0x%05x... ", pt->pte_lo >> 12);
@ -1927,7 +1986,7 @@ print_pte(pmap_t pm, vaddr_t va)
if (pvo != NULL) {
pt = pmap_pvo_to_pte(pvo, pteidx);
if (pt != NULL) {
printf("VA %#x -> %p -> %s %#x, %#x\n",
printf("VA %#lx -> %p -> %s %#x, %#x\n",
va, pt,
pt->pte_hi & PTE_HID ? "(sec)" : "(pri)",
pt->pte_hi, pt->pte_lo);
@ -1972,9 +2031,30 @@ pteg_dist(void)
printf("\n");
printf("Max depth found was %d\n", max_depth);
}
#endif /* DEBUG */
#ifdef PMAPCHECK
void
pmap_pvo_verify(void)
{
int ptegidx;
int s;
s = splvm();
for (ptegidx = 0; ptegidx < pteg_cnt; ptegidx++) {
struct pvo_entry *pvo;
LIST_FOREACH(pvo, &pvo_table[ptegidx], pvo_olink) {
if ((uintptr_t) pvo >= SEGMENT_LENGTH)
panic("pmap_pvo_find_va: invalid pvo %p "
"on list %#x", pvo, ptegidx);
pmap_pvo_check(pvo);
}
}
splx(s);
}
#endif /* PMAPCHECK */
void *
pmap_pool_ualloc(unsigned long size, int flags, int tag)
{