version 1.14, 2001/07/08 19:44:43 |
version 1.14.2.1, 2001/08/03 04:10:58 |
|
|
#include <sys/malloc.h> |
#include <sys/malloc.h> |
#include <sys/user.h> |
#include <sys/user.h> |
#include <sys/pool.h> |
#include <sys/pool.h> |
|
#include <sys/cdefs.h> |
|
|
#include <uvm/uvm.h> |
#include <uvm/uvm.h> |
|
|
#include <machine/bootconfig.h> |
#include <machine/bootconfig.h> |
|
|
#include <machine/pcb.h> |
#include <machine/pcb.h> |
#include <machine/param.h> |
#include <machine/param.h> |
#include <machine/katelib.h> |
#include <machine/katelib.h> |
|
|
|
__KERNEL_RCSID(0, "$NetBSD$"); |
|
|
#ifdef PMAP_DEBUG |
#ifdef PMAP_DEBUG |
#define PDEBUG(_lev_,_stat_) \ |
#define PDEBUG(_lev_,_stat_) \ |
if (pmap_debug_level >= (_lev_)) \ |
if (pmap_debug_level >= (_lev_)) \ |
Line 151 int pmap_debug_level = -2; |
|
Line 154 int pmap_debug_level = -2; |
|
#endif /* PMAP_DEBUG */ |
#endif /* PMAP_DEBUG */ |
|
|
struct pmap kernel_pmap_store; |
struct pmap kernel_pmap_store; |
pmap_t kernel_pmap; |
|
|
|
/* |
/* |
* pool that pmap structures are allocated from |
* pool that pmap structures are allocated from |
Line 192 extern pv_addr_t systempage; |
|
Line 194 extern pv_addr_t systempage; |
|
|
|
#define ALLOC_PAGE_HOOK(x, s) \ |
#define ALLOC_PAGE_HOOK(x, s) \ |
x.va = virtual_start; \ |
x.va = virtual_start; \ |
x.pte = (pt_entry_t *)pmap_pte(kernel_pmap, virtual_start); \ |
x.pte = (pt_entry_t *)pmap_pte(pmap_kernel(), virtual_start); \ |
virtual_start += s; |
virtual_start += s; |
|
|
/* Variables used by the L1 page table queue code */ |
/* Variables used by the L1 page table queue code */ |
Line 206 int l1pt_create_count; /* stat - L1's |
|
Line 208 int l1pt_create_count; /* stat - L1's |
|
int l1pt_reuse_count; /* stat - L1's reused count */ |
int l1pt_reuse_count; /* stat - L1's reused count */ |
|
|
/* Local function prototypes (not used outside this file) */ |
/* Local function prototypes (not used outside this file) */ |
pt_entry_t *pmap_pte __P((pmap_t pmap, vaddr_t va)); |
pt_entry_t *pmap_pte __P((struct pmap *pmap, vaddr_t va)); |
void map_pagetable __P((vaddr_t pagetable, vaddr_t va, |
void map_pagetable __P((vaddr_t pagetable, vaddr_t va, |
paddr_t pa, unsigned int flags)); |
paddr_t pa, unsigned int flags)); |
void pmap_copy_on_write __P((paddr_t pa)); |
void pmap_copy_on_write __P((paddr_t pa)); |
void pmap_pinit __P((pmap_t)); |
void pmap_pinit __P((struct pmap *)); |
void pmap_freepagedir __P((pmap_t)); |
void pmap_freepagedir __P((struct pmap *)); |
void pmap_release __P((pmap_t)); |
void pmap_release __P((struct pmap *)); |
|
|
/* Other function prototypes */ |
/* Other function prototypes */ |
extern void bzero_page __P((vaddr_t)); |
extern void bzero_page __P((vaddr_t)); |
extern void bcopy_page __P((vaddr_t, vaddr_t)); |
extern void bcopy_page __P((vaddr_t, vaddr_t)); |
|
|
struct l1pt *pmap_alloc_l1pt __P((void)); |
struct l1pt *pmap_alloc_l1pt __P((void)); |
static __inline void pmap_map_in_l1 __P((pmap_t pmap, vaddr_t va, |
static __inline void pmap_map_in_l1 __P((struct pmap *pmap, vaddr_t va, |
vaddr_t l2pa)); |
vaddr_t l2pa)); |
|
|
static pt_entry_t *pmap_map_ptes __P((struct pmap *)); |
static pt_entry_t *pmap_map_ptes __P((struct pmap *)); |
Line 450 pmap_collect_pv() |
|
Line 452 pmap_collect_pv() |
|
|
|
/*__inline*/ void |
/*__inline*/ void |
pmap_enter_pv(pmap, va, pv, flags) |
pmap_enter_pv(pmap, va, pv, flags) |
pmap_t pmap; |
struct pmap *pmap; |
vaddr_t va; |
vaddr_t va; |
struct pv_entry *pv; |
struct pv_entry *pv; |
u_int flags; |
u_int flags; |
Line 514 pmap_enter_pv(pmap, va, pv, flags) |
|
Line 516 pmap_enter_pv(pmap, va, pv, flags) |
|
|
|
/*__inline*/ void |
/*__inline*/ void |
pmap_remove_pv(pmap, va, pv) |
pmap_remove_pv(pmap, va, pv) |
pmap_t pmap; |
struct pmap *pmap; |
vaddr_t va; |
vaddr_t va; |
struct pv_entry *pv; |
struct pv_entry *pv; |
{ |
{ |
Line 571 pmap_remove_pv(pmap, va, pv) |
|
Line 573 pmap_remove_pv(pmap, va, pv) |
|
|
|
/*__inline */ u_int |
/*__inline */ u_int |
pmap_modify_pv(pmap, va, pv, bic_mask, eor_mask) |
pmap_modify_pv(pmap, va, pv, bic_mask, eor_mask) |
pmap_t pmap; |
struct pmap *pmap; |
vaddr_t va; |
vaddr_t va; |
struct pv_entry *pv; |
struct pv_entry *pv; |
u_int bic_mask; |
u_int bic_mask; |
Line 628 pmap_modify_pv(pmap, va, pv, bic_mask, e |
|
Line 630 pmap_modify_pv(pmap, va, pv, bic_mask, e |
|
*/ |
*/ |
static /*__inline*/ void |
static /*__inline*/ void |
pmap_map_in_l1(pmap, va, l2pa) |
pmap_map_in_l1(pmap, va, l2pa) |
pmap_t pmap; |
struct pmap *pmap; |
vaddr_t va, l2pa; |
vaddr_t va, l2pa; |
{ |
{ |
vaddr_t ptva; |
vaddr_t ptva; |
Line 658 pmap_map_in_l1(pmap, va, l2pa) |
|
Line 660 pmap_map_in_l1(pmap, va, l2pa) |
|
#if 0 |
#if 0 |
static /*__inline*/ void |
static /*__inline*/ void |
pmap_unmap_in_l1(pmap, va) |
pmap_unmap_in_l1(pmap, va) |
pmap_t pmap; |
struct pmap *pmap; |
vaddr_t va; |
vaddr_t va; |
{ |
{ |
vaddr_t ptva; |
vaddr_t ptva; |
Line 734 pmap_bootstrap(kernel_l1pt, kernel_ptpt) |
|
Line 736 pmap_bootstrap(kernel_l1pt, kernel_ptpt) |
|
#endif |
#endif |
vsize_t size; |
vsize_t size; |
|
|
kernel_pmap = &kernel_pmap_store; |
pmap_kernel()->pm_pdir = kernel_l1pt; |
|
pmap_kernel()->pm_pptpt = kernel_ptpt.pv_pa; |
kernel_pmap->pm_pdir = kernel_l1pt; |
pmap_kernel()->pm_vptpt = kernel_ptpt.pv_va; |
kernel_pmap->pm_pptpt = kernel_ptpt.pv_pa; |
simple_lock_init(&pmap_kernel()->pm_lock); |
kernel_pmap->pm_vptpt = kernel_ptpt.pv_va; |
pmap_kernel()->pm_obj.pgops = NULL; |
simple_lock_init(&kernel_pmap->pm_lock); |
TAILQ_INIT(&(pmap_kernel()->pm_obj.memq)); |
kernel_pmap->pm_count = 1; |
pmap_kernel()->pm_obj.uo_npages = 0; |
|
pmap_kernel()->pm_obj.uo_refs = 1; |
|
|
/* |
/* |
* Initialize PAGE_SIZE-dependent variables. |
* Initialize PAGE_SIZE-dependent variables. |
*/ |
*/ |
Line 837 pmap_bootstrap(kernel_l1pt, kernel_ptpt) |
|
Line 840 pmap_bootstrap(kernel_l1pt, kernel_ptpt) |
|
virtual_start += NBPG; |
virtual_start += NBPG; |
|
|
msgbufaddr = (caddr_t)virtual_start; |
msgbufaddr = (caddr_t)virtual_start; |
msgbufpte = (pt_entry_t)pmap_pte(kernel_pmap, virtual_start); |
msgbufpte = (pt_entry_t)pmap_pte(pmap_kernel(), virtual_start); |
virtual_start += round_page(MSGBUFSIZE); |
virtual_start += round_page(MSGBUFSIZE); |
|
|
size = npages * sizeof(struct pv_entry); |
size = npages * sizeof(struct pv_entry); |
|
|
pmap_t |
pmap_t |
pmap_create() |
pmap_create() |
{ |
{ |
pmap_t pmap; |
struct pmap *pmap; |
|
|
/* |
/* |
* Fetch pmap entry from the pool |
* Fetch pmap entry from the pool |
|
|
pmap = pool_get(&pmap_pmap_pool, PR_WAITOK); |
pmap = pool_get(&pmap_pmap_pool, PR_WAITOK); |
bzero(pmap, sizeof(*pmap)); |
bzero(pmap, sizeof(*pmap)); |
|
|
|
simple_lock_init(&pmap->pm_obj.vmobjlock); |
|
pmap->pm_obj.pgops = NULL; /* currently not a mappable object */ |
|
TAILQ_INIT(&pmap->pm_obj.memq); |
|
pmap->pm_obj.uo_npages = 0; |
|
pmap->pm_obj.uo_refs = 1; |
|
pmap->pm_stats.wired_count = 0; |
|
pmap->pm_stats.resident_count = 1; |
|
|
/* Now init the machine part of the pmap */ |
/* Now init the machine part of the pmap */ |
pmap_pinit(pmap); |
pmap_pinit(pmap); |
return(pmap); |
return(pmap); |
Line 1067 pmap_free_l1pt(pt) |
|
Line 1078 pmap_free_l1pt(pt) |
|
struct l1pt *pt; |
struct l1pt *pt; |
{ |
{ |
/* Separate the physical memory for the virtual space */ |
/* Separate the physical memory for the virtual space */ |
pmap_remove(kernel_pmap, pt->pt_va, pt->pt_va + PD_SIZE); |
pmap_remove(pmap_kernel(), pt->pt_va, pt->pt_va + PD_SIZE); |
pmap_update(); |
pmap_update(); |
|
|
/* Return the physical memory */ |
/* Return the physical memory */ |
Line 1131 pmap_allocpagedir(pmap) |
|
Line 1142 pmap_allocpagedir(pmap) |
|
if (!(pt->pt_flags & PTFLAG_KPT)) { |
if (!(pt->pt_flags & PTFLAG_KPT)) { |
/* Duplicate the kernel mapping i.e. all mappings 0xf0000000+ */ |
/* Duplicate the kernel mapping i.e. all mappings 0xf0000000+ */ |
|
|
bcopy((char *)kernel_pmap->pm_pdir + (PD_SIZE - KERNEL_PD_SIZE), |
bcopy((char *)pmap_kernel()->pm_pdir + (PD_SIZE - KERNEL_PD_SIZE), |
(char *)pmap->pm_pdir + (PD_SIZE - KERNEL_PD_SIZE), |
(char *)pmap->pm_pdir + (PD_SIZE - KERNEL_PD_SIZE), |
KERNEL_PD_SIZE); |
KERNEL_PD_SIZE); |
pt->pt_flags |= PTFLAG_KPT; |
pt->pt_flags |= PTFLAG_KPT; |
Line 1151 pmap_allocpagedir(pmap) |
|
Line 1162 pmap_allocpagedir(pmap) |
|
return(ENOMEM); |
return(ENOMEM); |
} |
} |
|
|
(void) pmap_extract(kernel_pmap, pmap->pm_vptpt, &pmap->pm_pptpt); |
(void) pmap_extract(pmap_kernel(), pmap->pm_vptpt, &pmap->pm_pptpt); |
pmap->pm_pptpt &= PG_FRAME; |
pmap->pm_pptpt &= PG_FRAME; |
/* Revoke cacheability and bufferability */ |
/* Revoke cacheability and bufferability */ |
/* XXX should be done better than this */ |
/* XXX should be done better than this */ |
pte = pmap_pte(kernel_pmap, pmap->pm_vptpt); |
pte = pmap_pte(pmap_kernel(), pmap->pm_vptpt); |
*pte = *pte & ~(PT_C | PT_B); |
*pte = *pte & ~(PT_C | PT_B); |
|
|
/* Wire in this page table */ |
/* Wire in this page table */ |
Line 1174 pmap_allocpagedir(pmap) |
|
Line 1185 pmap_allocpagedir(pmap) |
|
(char *)pmap->pm_vptpt + ((PD_SIZE - KERNEL_PD_SIZE) >> 2), |
(char *)pmap->pm_vptpt + ((PD_SIZE - KERNEL_PD_SIZE) >> 2), |
(KERNEL_PD_SIZE >> 2)); |
(KERNEL_PD_SIZE >> 2)); |
|
|
pmap->pm_count = 1; |
|
simple_lock_init(&pmap->pm_lock); |
|
|
|
return(0); |
return(0); |
} |
} |
|
|
Line 1224 pmap_pinit(pmap) |
|
Line 1232 pmap_pinit(pmap) |
|
|
|
void |
void |
pmap_freepagedir(pmap) |
pmap_freepagedir(pmap) |
pmap_t pmap; |
struct pmap *pmap; |
{ |
{ |
/* Free the memory used for the page table mapping */ |
/* Free the memory used for the page table mapping */ |
if (pmap->pm_vptpt != 0) |
if (pmap->pm_vptpt != 0) |
Line 1255 pmap_freepagedir(pmap) |
|
Line 1263 pmap_freepagedir(pmap) |
|
|
|
void |
void |
pmap_destroy(pmap) |
pmap_destroy(pmap) |
pmap_t pmap; |
struct pmap *pmap; |
{ |
{ |
int count; |
int count; |
|
|
Line 1264 pmap_destroy(pmap) |
|
Line 1272 pmap_destroy(pmap) |
|
|
|
PDEBUG(0, printf("pmap_destroy(%p)\n", pmap)); |
PDEBUG(0, printf("pmap_destroy(%p)\n", pmap)); |
simple_lock(&pmap->pm_lock); |
simple_lock(&pmap->pm_lock); |
count = --pmap->pm_count; |
count = --pmap->pm_obj.uo_refs; |
simple_unlock(&pmap->pm_lock); |
simple_unlock(&pmap->pm_lock); |
if (count == 0) { |
if (count == 0) { |
pmap_release(pmap); |
pmap_release(pmap); |
Line 1281 pmap_destroy(pmap) |
|
Line 1289 pmap_destroy(pmap) |
|
|
|
void |
void |
pmap_release(pmap) |
pmap_release(pmap) |
pmap_t pmap; |
struct pmap *pmap; |
{ |
{ |
struct vm_page *page; |
struct vm_page *page; |
pt_entry_t *pte; |
|
int loop; |
|
|
|
PDEBUG(0, printf("pmap_release(%p)\n", pmap)); |
PDEBUG(0, printf("pmap_release(%p)\n", pmap)); |
|
|
#if 0 |
|
if (pmap->pm_count != 1) /* XXX: needs sorting */ |
|
panic("pmap_release count %d", pmap->pm_count); |
|
#endif |
|
|
|
/* Remove the zero page mapping */ |
/* Remove the zero page mapping */ |
pmap_remove(pmap, 0x00000000, 0x00000000 + NBPG); |
pmap_remove(pmap, 0x00000000, 0x00000000 + NBPG); |
pmap_update(); |
pmap_update(); |
Line 1303 pmap_release(pmap) |
|
Line 1304 pmap_release(pmap) |
|
* This is only temporay until pmap_enter can count the number |
* This is only temporay until pmap_enter can count the number |
* of mappings made in a page table. Then pmap_remove() can |
* of mappings made in a page table. Then pmap_remove() can |
* reduce the count and free the pagetable when the count |
* reduce the count and free the pagetable when the count |
* reaches zero. |
* reaches zero. Note that entries in this list should match the |
|
* contents of the ptpt, however this is faster than walking a 1024 |
|
* entries looking for pt's |
|
* taken from i386 pmap.c |
*/ |
*/ |
for (loop = 0; loop < (((PD_SIZE - KERNEL_PD_SIZE) >> 4) - 1); ++loop) { |
while (pmap->pm_obj.memq.tqh_first != NULL) { |
pte = (pt_entry_t *)(pmap->pm_vptpt + loop * 4); |
page = pmap->pm_obj.memq.tqh_first; |
if (*pte != 0) { |
#ifdef DIAGNOSTIC |
PDEBUG(0, printf("%x: pte=%p:%08x\n", loop, pte, *pte)); |
if (page->flags & PG_BUSY) |
page = PHYS_TO_VM_PAGE(pmap_pte_pa(pte)); |
panic("pmap_release: busy page table page"); |
if (page == NULL) |
#endif |
panic("pmap_release: bad address for phys page"); |
/* pmap_page_protect? currently no need for it. */ |
uvm_pagefree(page); |
|
} |
page->wire_count = 0; |
|
uvm_pagefree(page); |
} |
} |
|
|
/* Free the page dir */ |
/* Free the page dir */ |
pmap_freepagedir(pmap); |
pmap_freepagedir(pmap); |
} |
} |
|
|
|
|
/* |
/* |
* void pmap_reference(pmap_t pmap) |
* void pmap_reference(struct pmap *pmap) |
* |
* |
* Add a reference to the specified pmap. |
* Add a reference to the specified pmap. |
*/ |
*/ |
|
|
void |
void |
pmap_reference(pmap) |
pmap_reference(pmap) |
pmap_t pmap; |
struct pmap *pmap; |
{ |
{ |
if (pmap == NULL) |
if (pmap == NULL) |
return; |
return; |
|
|
simple_lock(&pmap->pm_lock); |
simple_lock(&pmap->pm_lock); |
pmap->pm_count++; |
pmap->pm_obj.uo_refs++; |
simple_unlock(&pmap->pm_lock); |
simple_unlock(&pmap->pm_lock); |
} |
} |
|
|
|
|
pmap_activate(p) |
pmap_activate(p) |
struct proc *p; |
struct proc *p; |
{ |
{ |
pmap_t pmap = p->p_vmspace->vm_map.pmap; |
struct pmap *pmap = p->p_vmspace->vm_map.pmap; |
struct pcb *pcb = &p->p_addr->u_pcb; |
struct pcb *pcb = &p->p_addr->u_pcb; |
|
|
(void) pmap_extract(kernel_pmap, (vaddr_t)pmap->pm_pdir, |
(void) pmap_extract(pmap_kernel(), (vaddr_t)pmap->pm_pdir, |
(paddr_t *)&pcb->pcb_pagedir); |
(paddr_t *)&pcb->pcb_pagedir); |
|
|
PDEBUG(0, printf("pmap_activate: p=%p pmap=%p pcb=%p pdir=%p l1=%p\n", |
PDEBUG(0, printf("pmap_activate: p=%p pmap=%p pcb=%p pdir=%p l1=%p\n", |
Line 1566 pmap_next_phys_page(addr) |
|
Line 1572 pmap_next_phys_page(addr) |
|
#if 0 |
#if 0 |
void |
void |
pmap_pte_addref(pmap, va) |
pmap_pte_addref(pmap, va) |
pmap_t pmap; |
struct pmap *pmap; |
vaddr_t va; |
vaddr_t va; |
{ |
{ |
pd_entry_t *pde; |
pd_entry_t *pde; |
Line 1588 pmap_pte_addref(pmap, va) |
|
Line 1594 pmap_pte_addref(pmap, va) |
|
|
|
void |
void |
pmap_pte_delref(pmap, va) |
pmap_pte_delref(pmap, va) |
pmap_t pmap; |
struct pmap *pmap; |
vaddr_t va; |
vaddr_t va; |
{ |
{ |
pd_entry_t *pde; |
pd_entry_t *pde; |
Line 1748 pmap_vac_me_harder(struct pmap *pmap, st |
|
Line 1754 pmap_vac_me_harder(struct pmap *pmap, st |
|
|
|
void |
void |
pmap_remove(pmap, sva, eva) |
pmap_remove(pmap, sva, eva) |
pmap_t pmap; |
struct pmap *pmap; |
vaddr_t sva; |
vaddr_t sva; |
vaddr_t eva; |
vaddr_t eva; |
{ |
{ |
Line 1782 pmap_remove(pmap, sva, eva) |
|
Line 1788 pmap_remove(pmap, sva, eva) |
|
pte = &ptes[arm_byte_to_page(sva)]; |
pte = &ptes[arm_byte_to_page(sva)]; |
/* Note if the pmap is active thus require cache and tlb cleans */ |
/* Note if the pmap is active thus require cache and tlb cleans */ |
if ((curproc && curproc->p_vmspace->vm_map.pmap == pmap) |
if ((curproc && curproc->p_vmspace->vm_map.pmap == pmap) |
|| (pmap == kernel_pmap)) |
|| (pmap == pmap_kernel())) |
pmap_active = 1; |
pmap_active = 1; |
else |
else |
pmap_active = 0; |
pmap_active = 0; |
Line 1900 pmap_remove_all(pa) |
|
Line 1906 pmap_remove_all(pa) |
|
paddr_t pa; |
paddr_t pa; |
{ |
{ |
struct pv_entry *ph, *pv, *npv; |
struct pv_entry *ph, *pv, *npv; |
pmap_t pmap; |
struct pmap *pmap; |
pt_entry_t *pte, *ptes; |
pt_entry_t *pte, *ptes; |
int s; |
int s; |
|
|
Line 1976 reduce wiring count on page table pages |
|
Line 1982 reduce wiring count on page table pages |
|
|
|
void |
void |
pmap_protect(pmap, sva, eva, prot) |
pmap_protect(pmap, sva, eva, prot) |
pmap_t pmap; |
struct pmap *pmap; |
vaddr_t sva; |
vaddr_t sva; |
vaddr_t eva; |
vaddr_t eva; |
vm_prot_t prot; |
vm_prot_t prot; |
|
|
} |
} |
|
|
/* |
/* |
* void pmap_enter(pmap_t pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, |
* void pmap_enter(struct pmap *pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, |
* int flags) |
* int flags) |
* |
* |
* Insert the given physical page (p) at |
* Insert the given physical page (p) at |
|
|
|
|
int |
int |
pmap_enter(pmap, va, pa, prot, flags) |
pmap_enter(pmap, va, pa, prot, flags) |
pmap_t pmap; |
struct pmap *pmap; |
vaddr_t va; |
vaddr_t va; |
paddr_t pa; |
paddr_t pa; |
vm_prot_t prot; |
vm_prot_t prot; |
Line 2130 pmap_enter(pmap, va, pa, prot, flags) |
|
Line 2136 pmap_enter(pmap, va, pa, prot, flags) |
|
|
|
/* Allocate a page table */ |
/* Allocate a page table */ |
for (;;) { |
for (;;) { |
m = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_USERESERVE); |
m = uvm_pagealloc(&(pmap->pm_obj), 0, NULL, |
|
UVM_PGA_USERESERVE); |
if (m != NULL) |
if (m != NULL) |
break; |
break; |
|
|
Line 2159 pmap_enter(pmap, va, pa, prot, flags) |
|
Line 2166 pmap_enter(pmap, va, pa, prot, flags) |
|
pmap_zero_page(l2pa); |
pmap_zero_page(l2pa); |
pmap_map_in_l1(pmap, va, l2pa); |
pmap_map_in_l1(pmap, va, l2pa); |
++pmap->pm_stats.resident_count; |
++pmap->pm_stats.resident_count; |
|
m->flags &= ~PG_BUSY; /* never busy */ |
|
m->wire_count = 1; /* no mappings yet */ |
|
|
pte = pmap_pte(pmap, va); |
pte = pmap_pte(pmap, va); |
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
if (!pte) |
if (!pte) |
Line 2283 pmap_enter(pmap, va, pa, prot, flags) |
|
Line 2292 pmap_enter(pmap, va, pa, prot, flags) |
|
*/ |
*/ |
ptes = pmap_map_ptes(pmap); |
ptes = pmap_map_ptes(pmap); |
if ((curproc && curproc->p_vmspace->vm_map.pmap == pmap) |
if ((curproc && curproc->p_vmspace->vm_map.pmap == pmap) |
|| (pmap == kernel_pmap)) |
|| (pmap == pmap_kernel())) |
pmap_active = TRUE; |
pmap_active = TRUE; |
pmap_vac_me_harder(pmap, pv, ptes, pmap_active); |
pmap_vac_me_harder(pmap, pv, ptes, pmap_active); |
pmap_unmap_ptes(pmap); |
pmap_unmap_ptes(pmap); |
Line 2316 pmap_kenter_pa(va, pa, prot) |
|
Line 2325 pmap_kenter_pa(va, pa, prot) |
|
*/ |
*/ |
|
|
/* Allocate a page table */ |
/* Allocate a page table */ |
pg = uvm_pagealloc(NULL, 0, NULL, |
pg = uvm_pagealloc(&(pmap_kernel()->pm_obj), 0, NULL, |
UVM_PGA_USERESERVE | UVM_PGA_ZERO); |
UVM_PGA_USERESERVE | UVM_PGA_ZERO); |
if (pg == NULL) { |
if (pg == NULL) { |
panic("pmap_kenter_pa: no free pages"); |
panic("pmap_kenter_pa: no free pages"); |
} |
} |
|
pg->flags &= ~PG_BUSY; /* never busy */ |
|
|
/* Wire this page table into the L1. */ |
/* Wire this page table into the L1. */ |
pmap_map_in_l1(pmap, va, VM_PAGE_TO_PHYS(pg)); |
pmap_map_in_l1(pmap, va, VM_PAGE_TO_PHYS(pg)); |
Line 2393 pmap_page_protect(pg, prot) |
|
Line 2403 pmap_page_protect(pg, prot) |
|
|
|
void |
void |
pmap_unwire(pmap, va) |
pmap_unwire(pmap, va) |
pmap_t pmap; |
struct pmap *pmap; |
vaddr_t va; |
vaddr_t va; |
{ |
{ |
pt_entry_t *pte; |
pt_entry_t *pte; |
Line 2423 pmap_unwire(pmap, va) |
|
Line 2433 pmap_unwire(pmap, va) |
|
} |
} |
|
|
/* |
/* |
* pt_entry_t *pmap_pte(pmap_t pmap, vaddr_t va) |
* pt_entry_t *pmap_pte(struct pmap *pmap, vaddr_t va) |
* |
* |
* Return the pointer to a page table entry corresponding to the supplied |
* Return the pointer to a page table entry corresponding to the supplied |
* virtual address. |
* virtual address. |
Line 2438 pmap_unwire(pmap, va) |
|
Line 2448 pmap_unwire(pmap, va) |
|
*/ |
*/ |
pt_entry_t * |
pt_entry_t * |
pmap_pte(pmap, va) |
pmap_pte(pmap, va) |
pmap_t pmap; |
struct pmap *pmap; |
vaddr_t va; |
vaddr_t va; |
{ |
{ |
pt_entry_t *ptp; |
pt_entry_t *ptp; |
Line 2471 pmap_pte(pmap, va) |
|
Line 2481 pmap_pte(pmap, va) |
|
* Otherwise we need to map the page tables to an alternative |
* Otherwise we need to map the page tables to an alternative |
* address and reference them there. |
* address and reference them there. |
*/ |
*/ |
if (pmap == kernel_pmap || pmap->pm_pptpt |
if (pmap == pmap_kernel() || pmap->pm_pptpt |
== (*((pt_entry_t *)(PROCESS_PAGE_TBLS_BASE |
== (*((pt_entry_t *)(PROCESS_PAGE_TBLS_BASE |
+ ((PROCESS_PAGE_TBLS_BASE >> (PGSHIFT - 2)) & |
+ ((PROCESS_PAGE_TBLS_BASE >> (PGSHIFT - 2)) & |
~3) + (PROCESS_PAGE_TBLS_BASE >> PDSHIFT))) & PG_FRAME)) { |
~3) + (PROCESS_PAGE_TBLS_BASE >> PDSHIFT))) & PG_FRAME)) { |
Line 2530 pmap_pte(pmap, va) |
|
Line 2540 pmap_pte(pmap, va) |
|
*/ |
*/ |
boolean_t |
boolean_t |
pmap_extract(pmap, va, pap) |
pmap_extract(pmap, va, pap) |
pmap_t pmap; |
struct pmap *pmap; |
vaddr_t va; |
vaddr_t va; |
paddr_t *pap; |
paddr_t *pap; |
{ |
{ |
Line 2589 pmap_extract(pmap, va, pap) |
|
Line 2599 pmap_extract(pmap, va, pap) |
|
|
|
void |
void |
pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr) |
pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr) |
pmap_t dst_pmap; |
struct pmap *dst_pmap; |
pmap_t src_pmap; |
struct pmap *src_pmap; |
vaddr_t dst_addr; |
vaddr_t dst_addr; |
vsize_t len; |
vsize_t len; |
vaddr_t src_addr; |
vaddr_t src_addr; |
Line 2803 pmap_is_referenced(pg) |
|
Line 2813 pmap_is_referenced(pg) |
|
|
|
int |
int |
pmap_modified_emulation(pmap, va) |
pmap_modified_emulation(pmap, va) |
pmap_t pmap; |
struct pmap *pmap; |
vaddr_t va; |
vaddr_t va; |
{ |
{ |
pt_entry_t *pte; |
pt_entry_t *pte; |
Line 2865 pmap_modified_emulation(pmap, va) |
|
Line 2875 pmap_modified_emulation(pmap, va) |
|
|
|
int |
int |
pmap_handled_emulation(pmap, va) |
pmap_handled_emulation(pmap, va) |
pmap_t pmap; |
struct pmap *pmap; |
vaddr_t va; |
vaddr_t va; |
{ |
{ |
pt_entry_t *pte; |
pt_entry_t *pte; |
Line 2919 pmap_handled_emulation(pmap, va) |
|
Line 2929 pmap_handled_emulation(pmap, va) |
|
|
|
void |
void |
pmap_collect(pmap) |
pmap_collect(pmap) |
pmap_t pmap; |
struct pmap *pmap; |
{ |
{ |
} |
} |
|
|