lots of debugging printf flags, serious clean, add pmap_{,de}activate()

This commit is contained in:
cgd 1996-08-20 23:08:08 +00:00
parent 00c4aefc1a
commit 645fb5dd99
1 changed files with 392 additions and 162 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap.c,v 1.14 1996/07/16 04:51:16 cgd Exp $ */ /* $NetBSD: pmap.c,v 1.15 1996/08/20 23:08:08 cgd Exp $ */
/* /*
* Copyright (c) 1992, 1996 Carnegie Mellon University * Copyright (c) 1992, 1996 Carnegie Mellon University
@ -121,10 +121,12 @@ struct pv_entry *pmap_alloc_pv __P((void));
void pmap_free_pv __P((struct pv_entry *pv)); void pmap_free_pv __P((struct pv_entry *pv));
vm_page_t vm_page_grab __P((void)); vm_page_t vm_page_grab __P((void));
vm_offset_t pmap_resident_extract __P((pmap_t, vm_offset_t));
/* For external use... */ /* For external use... */
vm_offset_t kvtophys(vm_offset_t virt) vm_offset_t kvtophys(vm_offset_t virt)
{ {
vm_offset_t pmap_resident_extract();
return pmap_resident_extract(kernel_pmap, virt); return pmap_resident_extract(kernel_pmap, virt);
} }
@ -516,6 +518,42 @@ void pmap_remove_range(); /* forward */
void signal_cpus(); /* forward */ void signal_cpus(); /* forward */
#endif /* NCPUS > 1 */ #endif /* NCPUS > 1 */
int pmap_max_asn;
void pmap_expand __P((pmap_t, vm_offset_t));
/* XXX */
#define PDB_BOOTSTRAP 0x00000001
#define PDB_BOOTSTRAP_ALLOC 0x00000002
#define PDB_UNMAP_PROM 0x00000004
#define PDB_ACTIVATE 0x00000008
#define PDB_DEACTIVATE 0x00000010
#define PDB_TLBPID_INIT 0x00000020
#define PDB_TLBPID_ASSIGN 0x00000040
#define PDB_TLBPID_DESTROY 0x00000080
#define PDB_ENTER 0x00000100
#define PDB_CREATE 0x00000200
#define PDB_PINIT 0x00000400
#define PDB_EXPAND 0x00000800
#define PDB_EXTRACT 0x00001000
#define PDB_PTE 0x00002000
#define PDB_RELEASE 0x00004000
#define PDB_DESTROY 0x00008000
#define PDB_COPY_PAGE 0x00010000
#define PDB_ZERO_PAGE 0x00020000
#define PDB_ANOMALOUS 0x20000000
#define PDB_FOLLOW 0x40000000
#define PDB_VERBOSE 0x80000000
int pmapdebug = PDB_ANOMALOUS |-1 /* -1 */;
#if defined(DEBUG) || 1
#define DOPDB(x) ((pmapdebug & (x)) != 0)
#else
#define DOPDB(x) 0
#endif
#define DOVPDB(x) (DOPDB(x) && DOPDB(PDB_VERBOSE))
/* /*
* Given an offset and a map, compute the address of the * Given an offset and a map, compute the address of the
* pte. If the address is invalid with respect to the map * pte. If the address is invalid with respect to the map
@ -529,24 +567,46 @@ pt_entry_t *pmap_pte(pmap, addr)
register pmap_t pmap; register pmap_t pmap;
register vm_offset_t addr; register vm_offset_t addr;
{ {
register pt_entry_t *ptp; register pt_entry_t *ptp, *ptep;
register pt_entry_t pte; register pt_entry_t pte;
if (pmap->dirbase == 0) if (DOPDB(PDB_FOLLOW|PDB_PTE))
return(PT_ENTRY_NULL); printf("pmap_pte(%p, 0x%lx)\n", pmap, addr);
if (pmap->dirbase == 0) {
if (DOVPDB(PDB_FOLLOW|PDB_PTE))
printf("pmap_pte: dirbase == 0\n");
ptep = PT_ENTRY_NULL;
goto out;
}
/* seg1 */ /* seg1 */
pte = *pmap_pde(pmap,addr); pte = *pmap_pde(pmap,addr);
if ((pte & ALPHA_PTE_VALID) == 0) if ((pte & ALPHA_PTE_VALID) == 0) {
return(PT_ENTRY_NULL); if (DOVPDB(PDB_FOLLOW|PDB_PTE))
printf("pmap_pte: l1 not valid\n");
ptep = PT_ENTRY_NULL;
goto out;
}
/* seg2 */ /* seg2 */
ptp = (pt_entry_t *)ptetokv(pte); ptp = (pt_entry_t *)ptetokv(pte);
pte = ptp[pte2num(addr)]; pte = ptp[pte2num(addr)];
if ((pte & ALPHA_PTE_VALID) == 0) if ((pte & ALPHA_PTE_VALID) == 0) {
return(PT_ENTRY_NULL); if (DOVPDB(PDB_FOLLOW|PDB_PTE))
printf("pmap_pte: l2 not valid\n");
ptep = PT_ENTRY_NULL;
goto out;
}
/* seg3 */ /* seg3 */
ptp = (pt_entry_t *)ptetokv(pte); ptp = (pt_entry_t *)ptetokv(pte);
return(&ptp[pte3num(addr)]); ptep = &ptp[pte3num(addr)];
out:
if (DOPDB(PDB_FOLLOW|PDB_PTE))
printf("pmap_pte: returns %p\n", ptep);
return (ptep);
} }
#define DEBUG_PTE_PAGE 1 #define DEBUG_PTE_PAGE 1
@ -568,14 +628,6 @@ extern vm_offset_t avail_start, avail_end;
*/ */
vm_size_t pmap_kernel_vm = 5; /* each one 8 meg worth */ vm_size_t pmap_kernel_vm = 5; /* each one 8 meg worth */
/* XXX */
int pmapdebug = -1;
#define PDB_BOOTSTRAP 0x00000001
#define PDB_BOOTSTRAP_ALLOC 0x00000002
#define PDB_UNMAP_PROM 0x00000004
#define PDB_FOLLOW 0x40000000
#define PDB_VERBOSE 0x80000000
unsigned int unsigned int
pmap_free_pages() pmap_free_pages()
{ {
@ -583,8 +635,9 @@ pmap_free_pages()
} }
void void
pmap_bootstrap(firstaddr, ptaddr) pmap_bootstrap(firstaddr, ptaddr, maxasn)
vm_offset_t firstaddr, ptaddr; vm_offset_t firstaddr, ptaddr;
int maxasn;
{ {
vm_offset_t pa; vm_offset_t pa;
pt_entry_t template; pt_entry_t template;
@ -594,10 +647,9 @@ pmap_bootstrap(firstaddr, ptaddr)
int i; int i;
long npages; long npages;
#ifdef DEBUG if (DOPDB(PDB_FOLLOW|PDB_BOOTSTRAP))
if (pmapdebug & (PDB_FOLLOW|PDB_BOOTSTRAP)) printf("pmap_bootstrap(0x%lx, 0x%lx, %d)\n", firstaddr, ptaddr,
printf("pmap_bootstrap(0x%lx, 0x%lx)\n", firstaddr, ptaddr); maxasn);
#endif
/* must be page aligned */ /* must be page aligned */
start = firstaddr = alpha_round_page(firstaddr); start = firstaddr = alpha_round_page(firstaddr);
@ -643,18 +695,15 @@ pmap_bootstrap(firstaddr, ptaddr)
*/ */
vallocsz(root_kpdes, pt_entry_t *, PAGE_SIZE); vallocsz(root_kpdes, pt_entry_t *, PAGE_SIZE);
#ifdef DEBUG if (DOVPDB(PDB_BOOTSTRAP))
if (pmapdebug & (PDB_VERBOSE|PDB_BOOTSTRAP))
printf("pmap_bootstrap: root_kpdes = %p\n", root_kpdes); printf("pmap_bootstrap: root_kpdes = %p\n", root_kpdes);
#endif
kernel_pmap->dirbase = root_kpdes; kernel_pmap->dirbase = root_kpdes;
kernel_pmap->dirpfn = alpha_btop(kvtophys((vm_offset_t)root_kpdes));
/* First, copy mappings for things below VM_MIN_KERNEL_ADDRESS */ /* First, copy mappings for things below VM_MIN_KERNEL_ADDRESS */
#ifdef DEBUG if (DOVPDB(PDB_BOOTSTRAP))
if (pmapdebug & (PDB_VERBOSE|PDB_BOOTSTRAP))
printf("pmap_bootstrap: setting up root_kpdes (copy 0x%lx)\n", printf("pmap_bootstrap: setting up root_kpdes (copy 0x%lx)\n",
pdenum(VM_MIN_KERNEL_ADDRESS) * sizeof root_kpdes[0]); pdenum(VM_MIN_KERNEL_ADDRESS) * sizeof root_kpdes[0]);
#endif
bzero(root_kpdes, PAGE_SIZE); bzero(root_kpdes, PAGE_SIZE);
bcopy((caddr_t)ptaddr, root_kpdes, bcopy((caddr_t)ptaddr, root_kpdes,
pdenum(VM_MIN_KERNEL_ADDRESS) * sizeof root_kpdes[0]); pdenum(VM_MIN_KERNEL_ADDRESS) * sizeof root_kpdes[0]);
@ -664,12 +713,11 @@ pmap_bootstrap(firstaddr, ptaddr)
*/ */
pte_ktemplate(template, kvtophys(root_kpdes), pte_ktemplate(template, kvtophys(root_kpdes),
VM_PROT_READ | VM_PROT_WRITE); VM_PROT_READ | VM_PROT_WRITE);
root_kpdes[pdenum(VPTBASE)] = template & ~ALPHA_PTE_GLOBAL; template &= ~ALPHA_PTE_GLOBAL;
#ifdef DEBUG root_kpdes[pdenum(VPTBASE)] = template;
if (pmapdebug & (PDB_VERBOSE|PDB_BOOTSTRAP)) if (DOVPDB(PDB_BOOTSTRAP))
printf("pmap_bootstrap: VPT PTE 0x%lx at 0x%lx)\n", printf("pmap_bootstrap: VPT PTE 0x%lx at 0x%lx)\n",
root_kpdes[pdenum(VPTBASE)], &root_kpdes[pdenum(VPTBASE)]); root_kpdes[pdenum(VPTBASE)], &root_kpdes[pdenum(VPTBASE)]);
#endif
#if 0 #if 0
/* /*
@ -688,17 +736,13 @@ pmap_bootstrap(firstaddr, ptaddr)
*/ */
#define enough_kseg2() (PAGE_SIZE) #define enough_kseg2() (PAGE_SIZE)
#ifdef DEBUG if (DOVPDB(PDB_BOOTSTRAP))
if (pmapdebug & (PDB_VERBOSE|PDB_BOOTSTRAP))
printf("pmap_bootstrap: allocating kvseg segment pages\n"); printf("pmap_bootstrap: allocating kvseg segment pages\n");
#endif
vallocsz(pte, pt_entry_t *, enough_kseg2()); /* virtual */ vallocsz(pte, pt_entry_t *, enough_kseg2()); /* virtual */
pa = kvtophys(pte); /* physical */ pa = kvtophys(pte); /* physical */
bzero(pte, enough_kseg2()); bzero(pte, enough_kseg2());
#ifdef DEBUG if (DOVPDB(PDB_BOOTSTRAP))
if (pmapdebug & (PDB_VERBOSE|PDB_BOOTSTRAP))
printf("pmap_bootstrap: kvseg segment pages at %p\n", pte); printf("pmap_bootstrap: kvseg segment pages at %p\n", pte);
#endif
#undef enough_kseg2 #undef enough_kseg2
@ -706,10 +750,8 @@ pmap_bootstrap(firstaddr, ptaddr)
* Make a note of it in the seg1 table * Make a note of it in the seg1 table
*/ */
#ifdef DEBUG if (DOVPDB(PDB_BOOTSTRAP))
if (pmapdebug & (PDB_VERBOSE|PDB_BOOTSTRAP))
printf("pmap_bootstrap: inserting segment pages into root\n"); printf("pmap_bootstrap: inserting segment pages into root\n");
#endif
tbia(); tbia();
pte_ktemplate(template,pa,VM_PROT_READ|VM_PROT_WRITE); pte_ktemplate(template,pa,VM_PROT_READ|VM_PROT_WRITE);
pde = pmap_pde(kernel_pmap,K2SEG_BASE); pde = pmap_pde(kernel_pmap,K2SEG_BASE);
@ -729,10 +771,8 @@ pmap_bootstrap(firstaddr, ptaddr)
/* /*
* But don't we need some seg2 pagetables to start with ? * But don't we need some seg2 pagetables to start with ?
*/ */
#ifdef DEBUG if (DOVPDB(PDB_BOOTSTRAP))
if (pmapdebug & (PDB_VERBOSE|PDB_BOOTSTRAP))
printf("pmap_bootstrap: allocating kvseg page table pages\n"); printf("pmap_bootstrap: allocating kvseg page table pages\n");
#endif
pde = &pte[pte2num(K2SEG_BASE)]; pde = &pte[pte2num(K2SEG_BASE)];
for (i = pmap_kernel_vm; i > 0; i--) { for (i = pmap_kernel_vm; i > 0; i--) {
register int j; register int j;
@ -754,20 +794,16 @@ pmap_bootstrap(firstaddr, ptaddr)
avail_start = ALPHA_K0SEG_TO_PHYS(firstaddr); avail_start = ALPHA_K0SEG_TO_PHYS(firstaddr);
avail_end = alpha_ptob(lastusablepage + 1); avail_end = alpha_ptob(lastusablepage + 1);
mem_size = avail_end - avail_start; mem_size = avail_end - avail_start;
#ifdef DEBUG if (DOVPDB(PDB_BOOTSTRAP))
if (pmapdebug & (PDB_VERBOSE|PDB_BOOTSTRAP))
printf("pmap_bootstrap: avail: 0x%lx -> 0x%lx (0x%lx)\n", printf("pmap_bootstrap: avail: 0x%lx -> 0x%lx (0x%lx)\n",
avail_start, avail_end, mem_size); avail_start, avail_end, mem_size);
#endif
/* /*
* Allocate memory for the pv_head_table and its * Allocate memory for the pv_head_table and its
* lock bits, and the reference/modify byte array. * lock bits, and the reference/modify byte array.
*/ */
#ifdef DEBUG if (DOVPDB(PDB_BOOTSTRAP))
if (pmapdebug & (PDB_VERBOSE|PDB_BOOTSTRAP))
printf("pmap_bootstrap: allocating page management data\n"); printf("pmap_bootstrap: allocating page management data\n");
#endif
npages = ((BYTE_SIZE * mem_size) / npages = ((BYTE_SIZE * mem_size) /
(BYTE_SIZE * (PAGE_SIZE + sizeof (struct pv_entry) + 1) + 1)); (BYTE_SIZE * (PAGE_SIZE + sizeof (struct pv_entry) + 1) + 1));
@ -785,41 +821,31 @@ pmap_bootstrap(firstaddr, ptaddr)
if (npages > pmap_free_pages()) if (npages > pmap_free_pages())
panic("pmap_bootstrap"); panic("pmap_bootstrap");
mem_size = avail_end - avail_start; mem_size = avail_end - avail_start;
#ifdef DEBUG if (DOVPDB(PDB_BOOTSTRAP))
if (pmapdebug & (PDB_VERBOSE|PDB_BOOTSTRAP))
printf("pmap_bootstrap: avail: 0x%lx -> 0x%lx (0x%lx)\n", printf("pmap_bootstrap: avail: 0x%lx -> 0x%lx (0x%lx)\n",
avail_start, avail_end, mem_size); avail_start, avail_end, mem_size);
#endif
/* /*
* Assert kernel limits (cuz pmap_expand) * Assert kernel limits (because of pmap_expand).
*/ */
virtual_avail = alpha_round_page(K2SEG_BASE); virtual_avail = alpha_round_page(K2SEG_BASE);
virtual_end = trunc_page(K2SEG_BASE + pde2tova(pmap_kernel_vm)); virtual_end = trunc_page(K2SEG_BASE + pde2tova(pmap_kernel_vm));
#ifdef DEBUG if (DOVPDB(PDB_BOOTSTRAP)) {
if (pmapdebug & (PDB_VERBOSE|PDB_BOOTSTRAP)) {
printf("pmap_bootstrap: virtual_avail = %p\n", virtual_avail); printf("pmap_bootstrap: virtual_avail = %p\n", virtual_avail);
printf("pmap_bootstrap: virtual_end = %p\n", virtual_end); printf("pmap_bootstrap: virtual_end = %p\n", virtual_end);
} }
#endif
/* /*
* The distinguished tlbpid value of 0 is reserved for * The distinguished tlbpid value of 0 is reserved for
* the kernel pmap. Initialize the tlbpid allocator, * the kernel pmap. Initialize the tlbpid allocator,
* who knows about this. * who knows about this.
*/ */
#ifdef DEBUG
if (pmapdebug & (PDB_VERBOSE|PDB_BOOTSTRAP))
printf("pmap_bootstrap: setting up tlbpid machinery\n");
#endif
kernel_pmap->pid = 0; kernel_pmap->pid = 0;
pmap_tlbpid_init(); pmap_tlbpid_init(maxasn);
#ifdef DEBUG if (DOVPDB(PDB_BOOTSTRAP))
if (pmapdebug & (PDB_VERBOSE|PDB_BOOTSTRAP))
printf("pmap_bootstrap: leaving\n"); printf("pmap_bootstrap: leaving\n");
#endif
} }
pmap_rid_of_console() pmap_rid_of_console()
@ -853,10 +879,8 @@ pmap_bootstrap_alloc(size)
vm_offset_t val; vm_offset_t val;
extern boolean_t vm_page_startup_initialized; extern boolean_t vm_page_startup_initialized;
#ifdef DEBUG if (DOPDB(PDB_FOLLOW|PDB_BOOTSTRAP_ALLOC))
if (pmapdebug & (PDB_FOLLOW|PDB_BOOTSTRAP_ALLOC))
printf("pmap_bootstrap_alloc(%lx)\n", size); printf("pmap_bootstrap_alloc(%lx)\n", size);
#endif
if (vm_page_startup_initialized) if (vm_page_startup_initialized)
panic("pmap_bootstrap_alloc: called after startup initialized"); panic("pmap_bootstrap_alloc: called after startup initialized");
@ -868,10 +892,8 @@ pmap_bootstrap_alloc(size)
bzero((caddr_t)val, size); bzero((caddr_t)val, size);
#ifdef DEBUG if (DOVPDB(PDB_BOOTSTRAP_ALLOC))
if (pmapdebug & (PDB_VERBOSE|PDB_BOOTSTRAP_ALLOC))
printf("pmap_bootstrap_alloc: returns %p\n", val); printf("pmap_bootstrap_alloc: returns %p\n", val);
#endif
return ((void *)val); return ((void *)val);
} }
@ -889,29 +911,23 @@ pmap_unmap_prom()
extern int prom_mapped; extern int prom_mapped;
extern pt_entry_t *rom_ptep, rom_pte; extern pt_entry_t *rom_ptep, rom_pte;
#ifdef DEBUG if (DOPDB(PDB_FOLLOW|PDB_UNMAP_PROM))
if (pmapdebug & (PDB_FOLLOW|PDB_UNMAP_PROM))
printf("pmap_unmap_prom\n"); printf("pmap_unmap_prom\n");
#endif
/* XXX save old pte so that we can remap prom if necessary */ /* XXX save old pte so that we can remap prom if necessary */
rom_ptep = &root_kpdes[0]; /* XXX */ rom_ptep = &root_kpdes[0]; /* XXX */
rom_pte = *rom_ptep & ~ALPHA_PTE_ASM; /* XXX */ rom_pte = *rom_ptep & ~ALPHA_PTE_ASM; /* XXX */
#ifdef DEBUG if (DOVPDB(PDB_UNMAP_PROM))
if (pmapdebug & (PDB_VERBOSE|PDB_UNMAP_PROM))
printf("pmap_unmap_prom: zero 0x%lx, rom_pte was 0x%lx\n", printf("pmap_unmap_prom: zero 0x%lx, rom_pte was 0x%lx\n",
pdenum(VM_MIN_KERNEL_ADDRESS) * sizeof root_kpdes[0], pdenum(VM_MIN_KERNEL_ADDRESS) * sizeof root_kpdes[0],
rom_pte); rom_pte);
#endif
/* Mark all mappings before VM_MIN_KERNEL_ADDRESS as invalid. */ /* Mark all mappings before VM_MIN_KERNEL_ADDRESS as invalid. */
bzero(root_kpdes, pdenum(VM_MIN_KERNEL_ADDRESS) * sizeof root_kpdes[0]); bzero(root_kpdes, pdenum(VM_MIN_KERNEL_ADDRESS) * sizeof root_kpdes[0]);
prom_mapped = 0; prom_mapped = 0;
ALPHA_TBIA(); ALPHA_TBIA();
#ifdef DEBUG if (DOVPDB(PDB_UNMAP_PROM))
if (pmapdebug & (PDB_VERBOSE|PDB_UNMAP_PROM))
printf("pmap_unmap_prom: leaving\n"); printf("pmap_unmap_prom: leaving\n");
#endif
} }
/* /*
@ -1052,17 +1068,22 @@ pmap_page_table_page_dealloc(pa)
* the map will be used in software only, and * the map will be used in software only, and
* is bounded by that size. * is bounded by that size.
*/ */
pmap_t pmap_create(size) pmap_t
pmap_create(size)
vm_size_t size; vm_size_t size;
{ {
register pmap_t p; register pmap_t p;
if (DOPDB(PDB_FOLLOW|PDB_CREATE))
printf("pmap_create(%d)\n", size);
/* /*
* A software use-only map doesn't even need a map. * A software use-only map doesn't even need a map.
*/ */
if (size != 0) { if (size != 0) {
return(PMAP_NULL); p = PMAP_NULL;
goto out;
} }
/* XXX: is it ok to wait here? */ /* XXX: is it ok to wait here? */
@ -1072,6 +1093,10 @@ pmap_t pmap_create(size)
bzero(p, sizeof (*p)); bzero(p, sizeof (*p));
pmap_pinit(p); pmap_pinit(p);
out:
if (DOVPDB(PDB_FOLLOW|PDB_CREATE))
printf("pmap_create: returning %p\n", p);
return (p); return (p);
} }
@ -1080,14 +1105,40 @@ pmap_pinit(p)
struct pmap *p; struct pmap *p;
{ {
register pmap_statistics_t stats; register pmap_statistics_t stats;
extern struct vmspace vmspace0;
if (DOPDB(PDB_FOLLOW|PDB_PINIT))
printf("pmap_init(%p)\n", p);
#if 0
/* XXX cgd WHY NOT pmap_page_table_page_alloc()? */ /* XXX cgd WHY NOT pmap_page_table_page_alloc()? */
if ((p->dirbase = (void *)kmem_alloc(kernel_map, ALPHA_PGBYTES)) == NULL) p->dirbase = (void *)kmem_alloc(kernel_map, ALPHA_PGBYTES);
#else
p->dirbase = (void *)phystokv(pmap_page_table_page_alloc());
#endif
if (p->dirbase == NULL)
panic("pmap_create"); panic("pmap_create");
p->dirpfn = alpha_btop(pmap_resident_extract(kernel_pmap,
(vm_offset_t)p->dirbase));
if (DOVPDB(PDB_FOLLOW|PDB_PINIT))
printf("pmap_init(%p): dirbase = %p, dirpfn = 0x%x\n", p,
p->dirbase, p->dirpfn);
aligned_block_copy(root_kpdes, p->dirbase, ALPHA_PGBYTES); aligned_block_copy(root_kpdes, p->dirbase, ALPHA_PGBYTES);
p->ref_count = 1; p->ref_count = 1;
p->pid = -1; p->pid = -1;
if (DOVPDB(PDB_FOLLOW|PDB_PINIT))
printf("pmap_init(%p): first pde = 0x%lx\n", p->dirbase[0]);
{
pt_entry_t template;
pte_ktemplate(template, kvtophys(p->dirbase),
VM_PROT_READ | VM_PROT_WRITE);
template &= ~ALPHA_PTE_GLOBAL;
p->dirbase[pdenum(VPTBASE)] = template;
}
printf("PMAP_PINIT: FIRST ENT = 0x%lx\n", p->dirbase[0]);
simple_lock_init(&p->lock); simple_lock_init(&p->lock);
p->cpus_using = 0; p->cpus_using = 0;
@ -1101,7 +1152,9 @@ pmap_pinit(p)
stats->resident_count = 0; stats->resident_count = 0;
stats->wired_count = 0; stats->wired_count = 0;
if (pmap_debug) db_printf("pmap_create(%x->%x)\n", p, p->dirbase); out:
if (DOVPDB(PDB_FOLLOW|PDB_PINIT))
printf("pmap_init: leaving\n", p);
} }
/* /*
@ -1116,8 +1169,11 @@ void pmap_destroy(p)
register int c; register int c;
register spl_t s; register spl_t s;
if (DOPDB(PDB_FOLLOW|PDB_DESTROY))
printf("pmap_destroy(%p)\n", p);
if (p == PMAP_NULL) if (p == PMAP_NULL)
return; goto out;
SPLVM(s); SPLVM(s);
simple_lock(&p->lock); simple_lock(&p->lock);
@ -1129,6 +1185,9 @@ void pmap_destroy(p)
pmap_release(p); pmap_release(p);
free(p, M_VMPMAP); free(p, M_VMPMAP);
} }
out:
if (DOVPDB(PDB_FOLLOW|PDB_DESTROY))
printf("pmap_destroy: leaving\n");
} }
void void
@ -1138,7 +1197,16 @@ pmap_release(p)
register pt_entry_t *pdep, *ptep, *eptep; register pt_entry_t *pdep, *ptep, *eptep;
register vm_offset_t pa; register vm_offset_t pa;
if (pmap_debug) db_printf("pmap_destroy(%x->%x)\n", p, p->dirbase); if (DOPDB(PDB_FOLLOW|PDB_RELEASE))
printf("pmap_release(%p)\n", p);
if (p->dirbase == NULL) {
if (DOPDB(PDB_FOLLOW|PDB_ANOMALOUS|PDB_RELEASE))
printf("pmap_release: already reclaimed\n");
/* resources already reclaimed */
goto out;
}
/* /*
* Free the memory maps, then the * Free the memory maps, then the
* pmap structure. * pmap structure.
@ -1158,8 +1226,18 @@ if (pmap_debug) db_printf("pmap_destroy(%x->%x)\n", p, p->dirbase);
pmap_page_table_page_dealloc(pa); pmap_page_table_page_dealloc(pa);
} }
} }
pmap_destroy_tlbpid(p->pid, FALSE); pmap_tlbpid_destroy(p->pid, FALSE);
#if 0
kmem_free(kernel_map, (vm_offset_t)p->dirbase, ALPHA_PGBYTES); kmem_free(kernel_map, (vm_offset_t)p->dirbase, ALPHA_PGBYTES);
#else
pmap_page_table_page_dealloc(kvtophys(p->dirbase));
#endif
p->dirbase = NULL;
out:
if (DOVPDB(PDB_FOLLOW|PDB_RELEASE))
printf("pmap_release: leaving\n");
} }
/* /*
@ -1642,7 +1720,8 @@ db_printf("[%d]pmap_protect(%x,%x,%x,%x)\n", cpu_number(), map, s, e, prot);
* or lose information. That is, this routine must actually * or lose information. That is, this routine must actually
* insert this page into the given map NOW. * insert this page into the given map NOW.
*/ */
void pmap_enter(pmap, v, pa, prot, wired) void
pmap_enter(pmap, v, pa, prot, wired)
register pmap_t pmap; register pmap_t pmap;
vm_offset_t v; vm_offset_t v;
register vm_offset_t pa; register vm_offset_t pa;
@ -1657,12 +1736,16 @@ void pmap_enter(pmap, v, pa, prot, wired)
spl_t spl; spl_t spl;
vm_offset_t old_pa; vm_offset_t old_pa;
if (DOPDB(PDB_FOLLOW|PDB_ENTER))
printf("pmap_enter(%p, 0x%lx, 0x%lx, 0x%x, %d)\n",
pmap, v, pa, prot, wired);
assert(pa != vm_page_fictitious_addr); assert(pa != vm_page_fictitious_addr);
if (pmap_debug || ((v > pmap_suspect_vs) && (v < pmap_suspect_ve))) if (pmap_debug || ((v > pmap_suspect_vs) && (v < pmap_suspect_ve)))
db_printf("[%d]pmap_enter(%x(%d), %x, %x, %x, %x)\n", cpu_number(), pmap, pmap->pid, v, pa, prot, wired); db_printf("[%d]pmap_enter(%x(%d), %x, %x, %x, %x)\n", cpu_number(), pmap, pmap->pid, v, pa, prot, wired);
if (pmap == PMAP_NULL) if (pmap == PMAP_NULL)
return; goto out;
assert(pmap->pid >= 0); assert(!pmap_max_asn || pmap->pid >= 0);
/* /*
* Must allocate a new pvlist entry while we're unlocked; * Must allocate a new pvlist entry while we're unlocked;
@ -1702,6 +1785,10 @@ Retry:
* May be changing its wired attribute or protection * May be changing its wired attribute or protection
*/ */
if (DOVPDB(PDB_FOLLOW|PDB_ENTER))
printf("pmap_enter: same PA already mapped there (0x%lx)\n",
*pte);
if (wired && !(*pte & ALPHA_PTE_WIRED)) if (wired && !(*pte & ALPHA_PTE_WIRED))
pmap->stats.wired_count++; pmap->stats.wired_count++;
else if (!wired && (*pte & ALPHA_PTE_WIRED)) else if (!wired && (*pte & ALPHA_PTE_WIRED))
@ -1727,6 +1814,9 @@ Retry:
* Remove old mapping from the PV list if necessary. * Remove old mapping from the PV list if necessary.
*/ */
if (*pte) { if (*pte) {
if (DOVPDB(PDB_FOLLOW|PDB_ENTER))
printf("pmap_enter: removing old PTE (0x%lx)\n", *pte);
/* /*
* Invalidate the translation buffer, * Invalidate the translation buffer,
* then remove the mapping. * then remove the mapping.
@ -1742,6 +1832,8 @@ Retry:
} }
if (valid_page(pa)) { if (valid_page(pa)) {
if (DOVPDB(PDB_FOLLOW|PDB_ENTER))
printf("pmap_enter: valid page\n");
/* /*
* Enter the mapping in the PV list for this * Enter the mapping in the PV list for this
@ -1756,6 +1848,8 @@ Retry:
/* /*
* No mappings yet * No mappings yet
*/ */
if (DOVPDB(PDB_FOLLOW|PDB_ENTER))
printf("pmap_enter: first mapping\n");
pv_h->va = v; pv_h->va = v;
pv_h->pmap = pmap; pv_h->pmap = pmap;
pv_h->next = PV_ENTRY_NULL; pv_h->next = PV_ENTRY_NULL;
@ -1763,6 +1857,9 @@ Retry:
alphacache_Iflush(); alphacache_Iflush();
} }
else { else {
if (DOVPDB(PDB_FOLLOW|PDB_ENTER))
printf("pmap_enter: second+ mapping\n");
#if DEBUG #if DEBUG
{ {
/* check that this mapping is not already there */ /* check that this mapping is not already there */
@ -1825,10 +1922,14 @@ Retry:
template |= ALPHA_PTE_WIRED; template |= ALPHA_PTE_WIRED;
i = ptes_per_vm_page; i = ptes_per_vm_page;
do { do {
if (DOVPDB(PDB_FOLLOW|PDB_ENTER))
printf("pmap_enter: entering PTE 0x%lx at %p\n",
template, pte);
*pte = template; *pte = template;
pte++; pte++;
pte_increment_pa(template); pte_increment_pa(template);
} while (--i > 0); } while (--i > 0);
ALPHA_TBIA();
} }
if (pv_e != PV_ENTRY_NULL) { if (pv_e != PV_ENTRY_NULL) {
@ -1836,6 +1937,9 @@ Retry:
} }
PMAP_READ_UNLOCK(pmap, spl); PMAP_READ_UNLOCK(pmap, spl);
out:
if (DOVPDB(PDB_FOLLOW|PDB_ENTER))
printf("pmap_enter: done\n");
} }
/* /*
@ -1895,7 +1999,8 @@ if (pmap_debug) db_printf("pmap_change_wiring(%x,%x,%x)\n", map, v, wired);
* with the given map/virtual_address pair. * with the given map/virtual_address pair.
*/ */
vm_offset_t pmap_extract(pmap, va) vm_offset_t
pmap_extract(pmap, va)
register pmap_t pmap; register pmap_t pmap;
vm_offset_t va; vm_offset_t va;
{ {
@ -1903,13 +2008,19 @@ vm_offset_t pmap_extract(pmap, va)
register vm_offset_t pa; register vm_offset_t pa;
spl_t spl; spl_t spl;
if (pmap_debug) db_printf("[%d]pmap_extract(%x,%x)\n", cpu_number(), pmap, va); if (DOPDB(PDB_FOLLOW|PDB_EXTRACT))
printf("pmap_extract(%p, 0x%lx)\n", pmap, va);
/* /*
* Special translation for kernel addresses in * Special translation for kernel addresses in
* K0 space (directly mapped to physical addresses). * K0 space (directly mapped to physical addresses).
*/ */
if (ISA_K0SEG(va)) if (ISA_K0SEG(va)) {
return K0SEG_TO_PHYS(va); pa = K0SEG_TO_PHYS(va);
if (DOPDB(PDB_FOLLOW|PDB_EXTRACT))
printf("pmap_extract: returns 0x%lx\n", pa);
goto out;
}
SPLVM(spl); SPLVM(spl);
simple_lock(&pmap->lock); simple_lock(&pmap->lock);
@ -1925,10 +2036,15 @@ if (pmap_debug) db_printf("[%d]pmap_extract(%x,%x)\n", cpu_number(), pmap, va);
* Beware: this puts back this thread in the cpus_active set * Beware: this puts back this thread in the cpus_active set
*/ */
SPLX(spl); SPLX(spl);
out:
if (DOPDB(PDB_FOLLOW|PDB_EXTRACT))
printf("pmap_extract: returns 0x%lx\n", pa);
return(pa); return(pa);
} }
vm_offset_t pmap_resident_extract(pmap, va) vm_offset_t
pmap_resident_extract(pmap, va)
register pmap_t pmap; register pmap_t pmap;
vm_offset_t va; vm_offset_t va;
{ {
@ -1939,8 +2055,10 @@ vm_offset_t pmap_resident_extract(pmap, va)
* Special translation for kernel addresses in * Special translation for kernel addresses in
* K0 space (directly mapped to physical addresses). * K0 space (directly mapped to physical addresses).
*/ */
if (ISA_K0SEG(va)) if (ISA_K0SEG(va)) {
return K0SEG_TO_PHYS(va); pa = K0SEG_TO_PHYS(va);
goto out;
}
if ((pte = pmap_pte(pmap, va)) == PT_ENTRY_NULL) if ((pte = pmap_pte(pmap, va)) == PT_ENTRY_NULL)
pa = (vm_offset_t) 0; pa = (vm_offset_t) 0;
@ -1948,6 +2066,8 @@ vm_offset_t pmap_resident_extract(pmap, va)
pa = (vm_offset_t) 0; pa = (vm_offset_t) 0;
else else
pa = pte_to_pa(*pte) + (va & ALPHA_OFFMASK); pa = pte_to_pa(*pte) + (va & ALPHA_OFFMASK);
out:
return(pa); return(pa);
} }
@ -1961,16 +2081,21 @@ vm_offset_t pmap_resident_extract(pmap, va)
* Thus it must be called in a loop that checks whether the map * Thus it must be called in a loop that checks whether the map
* has been expanded enough. * has been expanded enough.
*/ */
void
pmap_expand(map, v) pmap_expand(map, v)
register pmap_t map; register pmap_t map;
register vm_offset_t v; register vm_offset_t v;
{ {
pt_entry_t template;
pt_entry_t *pdp; pt_entry_t *pdp;
register vm_page_t m; register vm_page_t m;
register vm_offset_t pa; register vm_offset_t pa;
register int i; register int i;
spl_t spl; spl_t spl;
if (DOPDB(PDB_FOLLOW|PDB_EXPAND))
printf("pmap_expand(%p, 0x%lx)\n", map, v);
/* Would have to go through all maps to add this page */ /* Would have to go through all maps to add this page */
if (map == kernel_pmap) if (map == kernel_pmap)
panic("pmap_expand"); panic("pmap_expand");
@ -1981,9 +2106,11 @@ pmap_expand(map, v)
*/ */
pdp = pmap_pde(map,v); pdp = pmap_pde(map,v);
if ((*pdp & ALPHA_PTE_VALID) == 0) { if ((*pdp & ALPHA_PTE_VALID) == 0) {
pt_entry_t *pte; pt_entry_t *pte;
if (DOVPDB(PDB_FOLLOW|PDB_EXPAND))
printf("pmap_expand: needs pde\n");
pa = pmap_page_table_page_alloc(); pa = pmap_page_table_page_alloc();
/* /*
@ -2002,15 +2129,22 @@ pmap_expand(map, v)
pmap_page_table_page_dealloc(pa); pmap_page_table_page_dealloc(pa);
return; return;
} }
/* /*
* Map the page. * Map the page.
*/ */
i = ptes_per_vm_page; i = ptes_per_vm_page;
pte = pdp; pte = pdp;
pte_ktemplate(template,pa,VM_PROT_READ|VM_PROT_WRITE);
if (map != kernel_pmap)
template &= ~ALPHA_PTE_ASM;
do { do {
pte_ktemplate(*pte,pa,VM_PROT_READ|VM_PROT_WRITE); *pte = template;
if (DOVPDB(PDB_FOLLOW|PDB_EXPAND))
printf("pmap_expand: inserted l1 pte (0x%lx) at %p\n",
template, pte);
pte++; pte++;
pa += ALPHA_PGBYTES; pte_increment_pa(template);
} while (--i > 0); } while (--i > 0);
PMAP_READ_UNLOCK(map, spl); PMAP_READ_UNLOCK(map, spl);
} }
@ -2042,12 +2176,22 @@ pmap_expand(map, v)
i = ptes_per_vm_page; i = ptes_per_vm_page;
pdp = (pt_entry_t *)ptetokv(*pdp); pdp = (pt_entry_t *)ptetokv(*pdp);
pdp = &pdp[pte2num(v)]; pdp = &pdp[pte2num(v)];
pte_ktemplate(template,pa,VM_PROT_READ|VM_PROT_WRITE);
if (map != kernel_pmap)
template &= ~ALPHA_PTE_ASM;
do { do {
pte_ktemplate(*pdp,pa,VM_PROT_READ|VM_PROT_WRITE); *pdp = template;
if (DOVPDB(PDB_FOLLOW|PDB_EXPAND))
printf("pmap_expand: inserted l2 pte (0x%lx) at %p\n",
template, pdp);
pdp++; pdp++;
pa += ALPHA_PGBYTES; pte_increment_pa(template);
} while (--i > 0); } while (--i > 0);
PMAP_READ_UNLOCK(map, spl); PMAP_READ_UNLOCK(map, spl);
out:
if (DOVPDB(PDB_FOLLOW|PDB_EXPAND))
printf("pmap_expand: leaving\n");
return; return;
} }
@ -2105,7 +2249,7 @@ void pmap_collect(p)
*/ */
PMAP_READ_LOCK(p, spl); PMAP_READ_LOCK(p, spl);
PMAP_UPDATE_TLBS(p, VM_MIN_ADDRESS, VM_MAX_ADDRESS); PMAP_UPDATE_TLBS(p, VM_MIN_ADDRESS, VM_MAX_ADDRESS);
pmap_destroy_tlbpid(p->pid, FALSE); pmap_tlbpid_destroy(p->pid, FALSE);
for (pdp = p->dirbase; for (pdp = p->dirbase;
pdp < pmap_pde(p,VM_MIN_KERNEL_ADDRESS); pdp < pmap_pde(p,VM_MIN_KERNEL_ADDRESS);
@ -2185,15 +2329,31 @@ void pmap_collect(p)
* Binds the given physical map to the given * Binds the given physical map to the given
* processor, and returns a hardware map description. * processor, and returns a hardware map description.
*/ */
#if 0 void
void pmap_activate(my_pmap, th, my_cpu) pmap_activate(pmap, hwpcb, cpu)
register pmap_t my_pmap; register pmap_t pmap;
thread_t th; struct alpha_pcb *hwpcb;
int my_cpu; int cpu;
{ {
if (DOPDB(PDB_FOLLOW|PDB_ACTIVATE))
printf("pmap_activate(%p, %p, %d)\n", pmap, hwpcb, cpu);
#if 0
PMAP_ACTIVATE(my_pmap, th, my_cpu); PMAP_ACTIVATE(my_pmap, th, my_cpu);
} #else
if (DOVPDB(PDB_ACTIVATE))
printf("pmap_activate: old pid = %d\n", pmap->pid);
if (pmap->pid < 0) pmap_tlbpid_assign(pmap);
hwpcb->apcb_asn = pmap->pid;
hwpcb->apcb_ptbr = pmap->dirpfn;
if (pmap != kernel_pmap)
pmap->cpus_using = TRUE;
if (DOVPDB(PDB_ACTIVATE))
printf("pmap_activate: new pid = %d, new ptbr = 0x%lx\n",
pmap->pid, pmap->dirpfn);
#endif #endif
}
/* /*
* Routine: pmap_deactivate * Routine: pmap_deactivate
@ -2202,18 +2362,24 @@ void pmap_activate(my_pmap, th, my_cpu)
* in use on the specified processor. (This is a macro * in use on the specified processor. (This is a macro
* in pmap.h) * in pmap.h)
*/ */
#if 0 void
void pmap_deactivate(pmap, th, which_cpu) pmap_deactivate(pmap, hwpcb, cpu)
pmap_t pmap; register pmap_t pmap;
thread_t th; struct alpha_pcb *hwpcb;
int which_cpu; int cpu;
{ {
#ifdef lint if (DOPDB(PDB_FOLLOW|PDB_DEACTIVATE))
pmap++; th++; which_cpu++; printf("pmap_deactivate(%p, %p, %d)\n", pmap, hwpcb, cpu);
#endif
#if 0
PMAP_DEACTIVATE(pmap, th, which_cpu); PMAP_DEACTIVATE(pmap, th, which_cpu);
} #else
if (DOVPDB(PDB_DEACTIVATE))
printf("pmap_deactivate: pid = %d, ptbr = 0x%lx\n",
pmap->pid, pmap->dirpfn);
pmap->cpus_using = FALSE;
#endif #endif
}
/* /*
* Routine: pmap_kernel * Routine: pmap_kernel
@ -2237,10 +2403,15 @@ pmap_zero_page(phys)
register vm_offset_t phys; register vm_offset_t phys;
{ {
if (DOPDB(PDB_FOLLOW|PDB_ZERO_PAGE))
printf("pmap_zero_page(0x%lx)\n", phys);
assert(phys != vm_page_fictitious_addr); assert(phys != vm_page_fictitious_addr);
if (pmap_debug || (phys == pmap_suspect_phys)) db_printf("pmap_zero_page(%x)\n", phys);
bzero((void *)phystokv(phys), PAGE_SIZE); bzero((void *)phystokv(phys), PAGE_SIZE);
if (DOVPDB(PDB_FOLLOW|PDB_ZERO_PAGE))
printf("pmap_zero_page: leaving\n");
} }
#endif #endif
@ -2253,12 +2424,17 @@ void
pmap_copy_page(src, dst) pmap_copy_page(src, dst)
vm_offset_t src, dst; vm_offset_t src, dst;
{ {
if (DOPDB(PDB_FOLLOW|PDB_COPY_PAGE))
printf("pmap_copy_page(0x%lx, 0x%lx)\n", src, dst);
assert(src != vm_page_fictitious_addr); assert(src != vm_page_fictitious_addr);
assert(dst != vm_page_fictitious_addr); assert(dst != vm_page_fictitious_addr);
if (pmap_debug || (src == pmap_suspect_phys) || (dst == pmap_suspect_phys)) db_printf("pmap_copy_page(%x,%x)\n", src, dst);
aligned_block_copy(phystokv(src), phystokv(dst), PAGE_SIZE); aligned_block_copy(phystokv(src), phystokv(dst), PAGE_SIZE);
if (DOVPDB(PDB_FOLLOW|PDB_COPY_PAGE))
printf("pmap_copy_page: leaving\n");
} }
#endif #endif
@ -2791,7 +2967,7 @@ set_ptbr(pmap_t map, pcb_t pcb, boolean_t switchit)
/* optimize later */ /* optimize later */
vm_offset_t pa; vm_offset_t pa;
pa = pmap_resident_extract(kernel_pmap, map->dirbase); pa = pmap_resident_extract(kernel_pmap, (vm_offset_t)map->dirbase);
printf("set_ptbr (switch = %d): dirbase = 0x%lx, pa = 0x%lx\n", switchit, map->dirbase, pa); printf("set_ptbr (switch = %d): dirbase = 0x%lx, pa = 0x%lx\n", switchit, map->dirbase, pa);
if (pa == 0) if (pa == 0)
panic("set_ptbr"); panic("set_ptbr");
@ -2819,21 +2995,32 @@ printf("set_ptbr (switch = %d): dirbase = 0x%lx, pa = 0x%lx\n", switchit, map->d
* All things considered, I did it right in the MIPS case. * All things considered, I did it right in the MIPS case.
*/ */
int pmap_max_asn = 63; /* Default value at boot. Should be 2^ */ #if 0
/* above */
int pmap_max_asn;
#endif
decl_simple_lock_data(static, tlbpid_lock) decl_simple_lock_data(static, tlbpid_lock)
static struct pmap **pids_in_use; static struct pmap **pids_in_use;
static int pmap_next_pid; static int pmap_next_pid;
pmap_tlbpid_init() pmap_tlbpid_init(maxasn)
int maxasn;
{ {
simple_lock_init(&tlbpid_lock); simple_lock_init(&tlbpid_lock);
#define MAX_PID_EVER 1023 /* change if necessary, this is one page */ if (DOVPDB(PDB_FOLLOW|PDB_TLBPID_INIT))
printf("pmap_tlbpid_init: maxasn = %d\n", maxasn);
pmap_max_asn = maxasn;
if (maxasn == 0) {
/* ASNs not implemented... Is this the right way to check? */
return;
}
pids_in_use = (struct pmap **) pids_in_use = (struct pmap **)
pmap_bootstrap_alloc( (MAX_PID_EVER+1) * sizeof(struct pmap *)); pmap_bootstrap_alloc((maxasn + 1) * sizeof(struct pmap *));
bzero(pids_in_use, (MAX_PID_EVER+1) * sizeof(struct pmap *)); bzero(pids_in_use, (maxasn + 1) * sizeof(struct pmap *));
#undef MAX_PID_EVER
pmap_next_pid = 1; pmap_next_pid = 1;
} }
@ -2845,17 +3032,20 @@ pmap_tlbpid_init()
* - pmap.pid prevents from making duplicates: if -1 there is no * - pmap.pid prevents from making duplicates: if -1 there is no
* pid for it, otherwise there is one and only one entry at that index. * pid for it, otherwise there is one and only one entry at that index.
* *
* pmap_assign_tlbpid provides a tlbpid for the given pmap, creating * pmap_tlbpid_assign provides a tlbpid for the given pmap, creating
* a new one if necessary * a new one if necessary
* pmap_destroy_tlbpid returns a tlbpid to the pool of available ones * pmap_tlbpid_destroy returns a tlbpid to the pool of available ones
*/ */
pmap_assign_tlbpid(map) pmap_tlbpid_assign(map)
struct pmap *map; struct pmap *map;
{ {
register int pid, next_pid; register int pid, next_pid;
if (map->pid < 0) { if (DOVPDB(PDB_FOLLOW|PDB_TLBPID_ASSIGN))
printf("pmap_tlbpid_assign: pmap %p had %d\n", map, map->pid);
if (pmap_max_asn && map->pid < 0) {
simple_lock(&tlbpid_lock); simple_lock(&tlbpid_lock);
@ -2873,7 +3063,7 @@ pmap_assign_tlbpid(map)
if (++next_pid == pmap_max_asn) if (++next_pid == pmap_max_asn)
next_pid = 1; next_pid = 1;
} }
pmap_destroy_tlbpid(next_pid, TRUE); pmap_tlbpid_destroy(next_pid, TRUE);
} }
got_a_free_one: got_a_free_one:
pids_in_use[next_pid] = map; pids_in_use[next_pid] = map;
@ -2884,23 +3074,31 @@ got_a_free_one:
simple_unlock(&tlbpid_lock); simple_unlock(&tlbpid_lock);
} }
if (DOVPDB(PDB_FOLLOW|PDB_TLBPID_ASSIGN))
printf("pmap_tlbpid_assign: pmap %p got %d\n", map, map->pid);
} }
pmap_destroy_tlbpid(pid, locked) pmap_tlbpid_destroy(pid, locked)
int pid; int pid;
boolean_t locked; boolean_t locked;
{ {
struct pmap *map; struct pmap *map;
if (DOVPDB(PDB_FOLLOW|PDB_TLBPID_DESTROY))
printf("pmap_tlbpid_destroy(%d, %d)\n", pid, locked);
if (pid < 0) /* no longer in use */ if (pid < 0) /* no longer in use */
return; return;
assert(pmap_max_asn);
if (!locked) simple_lock(&tlbpid_lock); if (!locked) simple_lock(&tlbpid_lock);
/* /*
* Make the pid available, and the map unassigned. * Make the pid available, and the map unassigned.
*/ */
map = pids_in_use[pid]; map = pids_in_use[pid];
assert(map != NULL);
pids_in_use[pid] = PMAP_NULL; pids_in_use[pid] = PMAP_NULL;
map->pid = -1; map->pid = -1;
@ -3087,3 +3285,35 @@ pmap_free_pv(pv)
break; break;
} }
} }
#if 0
sanity(pmap, addr)
register pmap_t pmap;
register vm_offset_t addr;
{
register pt_entry_t *ptp;
register pt_entry_t pte;
printf("checking dirbase...\n");
assert(pmap->dirbase != 0);
printf("checking dirpfn...\n");
assert(pmap->dirpfn == curproc->p_addr->u_pcb.pcb_hw.apcb_ptbr);
printf("checking pid...\n");
assert(pmap->pid == curproc->p_addr->u_pcb.pcb_hw.apcb_asn);
/* seg1 */
pte = *pmap_pde(pmap,addr);
if ((pte & ALPHA_PTE_VALID) == 0)
return(PT_ENTRY_NULL);
/* seg2 */
ptp = (pt_entry_t *)ptetokv(pte);
pte = ptp[pte2num(addr)];
if ((pte & ALPHA_PTE_VALID) == 0)
return(PT_ENTRY_NULL);
/* seg3 */
ptp = (pt_entry_t *)ptetokv(pte);
return(&ptp[pte3num(addr)]);
}
#endif