Merge jmallett@'s n64 work into HEAD - changeset 8

Updated PTE/PDE macros from http://svn.freebsd.org/base/user/jmallett/octeon
Introduce pmap_segshift() macro, use pmap_segmap() in place of pmap_pde, and
remove pmap_pde().

Approved by:	rrs (mentor)
Obtained from:	jmallett@
This commit is contained in:
Jayachandran C. 2010-07-08 14:49:55 +00:00
parent 900d6c6a00
commit 44fa0bf256
3 changed files with 41 additions and 31 deletions

View file

@ -50,7 +50,6 @@
#include <machine/pte.h>
#define NKPT 120 /* actual number of kernel page tables */
#define NUSERPGTBLS (VM_MAXUSER_ADDRESS >> SEGSHIFT)
#ifndef LOCORE
@ -97,7 +96,6 @@ typedef struct pmap *pmap_t;
#ifdef _KERNEL
pt_entry_t *pmap_pte(pmap_t, vm_offset_t);
pd_entry_t pmap_segmap(pmap_t pmap, vm_offset_t va);
vm_offset_t pmap_kextract(vm_offset_t va);
#define vtophys(va) pmap_kextract(((vm_offset_t) (va)))

View file

@ -29,6 +29,12 @@
#ifndef _MACHINE_PTE_H_
#define _MACHINE_PTE_H_
#ifndef _LOCORE
/* pt_entry_t is 32 bit for now, has to be made 64 bit for n64 */
typedef uint32_t pt_entry_t;
typedef pt_entry_t *pd_entry_t;
#endif
/*
* TLB and PTE management. Most things operate within the context of
* EntryLo0,1, and begin with TLBLO_. Things which work with EntryHi
@ -65,25 +71,20 @@
#define TLBLO_PTE_TO_PA(pte) (TLBLO_PFN_TO_PA(TLBLO_PTE_TO_PFN((pte))))
/*
* XXX This comment is not correct for anything more modern than R4K.
*
* VPN for EntryHi register. Upper two bits select user, supervisor,
* or kernel. Bits 61 to 40 copy bit 63. VPN2 is bits 39 and down to
* as low as 13, down to PAGE_SHIFT, to index 2 TLB pages*. From bit 12
* to bit 8 there is a 5-bit 0 field. Low byte is ASID.
*
* XXX This comment is not correct for FreeBSD.
* Note that in FreeBSD, we map 2 TLB pages is equal to 1 VM page.
*/
#define TLBHI_ASID_MASK (0xff)
#define TLBHI_PAGE_MASK (2 * PAGE_SIZE - 1)
#define TLBHI_ENTRY(va, asid) (((va) & ~TLBHI_PAGE_MASK) | ((asid) & TLBHI_ASID_MASK))
#ifndef _LOCORE
typedef uint32_t pt_entry_t;
typedef pt_entry_t *pd_entry_t;
#endif
#define PDESIZE sizeof(pd_entry_t) /* for assembly files */
#define PTESIZE sizeof(pt_entry_t) /* for assembly files */
/*
* TLB flags managed in hardware:
* C: Cache attribute.

View file

@ -118,14 +118,25 @@ __FBSDID("$FreeBSD$");
/*
* Get PDEs and PTEs for user/kernel address space
*
* XXX The & for pmap_segshift() is wrong, as is the fact that it doesn't
* trim off gratuitous bits of the address space. By having the &
* there, we break defining NUSERPGTBLS below because the address space
* is defined such that it ends immediately after NPDEPG*NPTEPG*PAGE_SIZE,
* so we end up getting NUSERPGTBLS of 0.
*/
#define pmap_pde(m, v) (&((m)->pm_segtab[(vm_offset_t)(v) >> SEGSHIFT]))
#define segtab_pde(m, v) (m[(vm_offset_t)(v) >> SEGSHIFT])
#define pmap_segshift(v) (((v) >> SEGSHIFT) & (NPDEPG - 1))
#define segtab_pde(m, v) ((m)[pmap_segshift((v))])
#define MIPS_SEGSIZE (1L << SEGSHIFT)
#define mips_segtrunc(va) ((va) & ~(MIPS_SEGSIZE-1))
#define NUSERPGTBLS (pmap_segshift(VM_MAXUSER_ADDRESS))
#define mips_segtrunc(va) ((va) & ~SEGOFSET)
#define is_kernel_pmap(x) ((x) == kernel_pmap)
#define vad_to_pte_offset(adr) (((adr) >> PAGE_SHIFT) & (NPTEPG -1))
/*
* Given a virtual address, get the offset of its PTE within its page
* directory page.
*/
#define PDE_OFFSET(va) (((vm_offset_t)(va) >> PAGE_SHIFT) & (NPTEPG - 1))
struct pmap kernel_pmap_store;
pd_entry_t *kernel_segmap;
@ -246,13 +257,13 @@ static struct local_sysmaps sysmap_lmem[MAXCPU];
sysm->valid2 = 0; \
intr_restore(intr)
pd_entry_t
static inline pt_entry_t *
pmap_segmap(pmap_t pmap, vm_offset_t va)
{
if (pmap->pm_segtab)
return (pmap->pm_segtab[((vm_offset_t)(va) >> SEGSHIFT)]);
if (pmap->pm_segtab != NULL)
return (segtab_pde(pmap->pm_segtab, va));
else
return ((pd_entry_t)0);
return (NULL);
}
/*
@ -267,9 +278,9 @@ pmap_pte(pmap_t pmap, vm_offset_t va)
pt_entry_t *pdeaddr;
if (pmap) {
pdeaddr = (pt_entry_t *)pmap_segmap(pmap, va);
pdeaddr = pmap_segmap(pmap, va);
if (pdeaddr) {
return pdeaddr + vad_to_pte_offset(va);
return pdeaddr + PDE_OFFSET(va);
}
}
return ((pt_entry_t *)0);
@ -878,12 +889,12 @@ pmap_unuse_pt(pmap_t pmap, vm_offset_t va, vm_page_t mpte)
return (0);
if (mpte == NULL) {
ptepindex = (va >> SEGSHIFT);
ptepindex = pmap_segshift(va);
if (pmap->pm_ptphint &&
(pmap->pm_ptphint->pindex == ptepindex)) {
mpte = pmap->pm_ptphint;
} else {
pteva = *pmap_pde(pmap, va);
pteva = pmap_segmap(pmap, va);
mpte = PHYS_TO_VM_PAGE(MIPS_KSEG0_TO_PHYS(pteva));
pmap->pm_ptphint = mpte;
}
@ -1082,7 +1093,7 @@ pmap_allocpte(pmap_t pmap, vm_offset_t va, int flags)
/*
* Calculate pagetable page index
*/
ptepindex = va >> SEGSHIFT;
ptepindex = pmap_segshift(va);
retry:
/*
* Get the page directory entry
@ -1205,7 +1216,7 @@ pmap_growkernel(vm_offset_t addr)
nkpt++;
pte = (pt_entry_t *)pageva;
segtab_pde(kernel_segmap, kernel_vm_end) = (pd_entry_t)pte;
segtab_pde(kernel_segmap, kernel_vm_end) = pte;
/*
* The R[4-7]?00 stores only one copy of the Global bit in
@ -1529,8 +1540,8 @@ pmap_remove(struct pmap *pmap, vm_offset_t sva, vm_offset_t eva)
goto out;
}
for (va = sva; va < eva; va = nva) {
if (!*pmap_pde(pmap, va)) {
nva = mips_segtrunc(va + MIPS_SEGSIZE);
if (pmap_segmap(pmap, va) == NULL) {
nva = mips_segtrunc(va + NBSEG);
continue;
}
pmap_remove_page(pmap, va);
@ -1646,8 +1657,8 @@ pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
/*
* If segment table entry is empty, skip this segment.
*/
if (!*pmap_pde(pmap, sva)) {
sva = mips_segtrunc(sva + MIPS_SEGSIZE);
if (pmap_segmap(pmap, sva) == NULL) {
sva = mips_segtrunc(sva + NBSEG);
continue;
}
/*
@ -1934,7 +1945,7 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m,
/*
* Calculate pagetable page index
*/
ptepindex = va >> SEGSHIFT;
ptepindex = pmap_segshift(va);
if (mpte && (mpte->pindex == ptepindex)) {
mpte->wire_count++;
} else {
@ -2619,7 +2630,7 @@ pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr)
rv = FALSE;
PMAP_LOCK(pmap);
if (*pmap_pde(pmap, addr)) {
if (pmap_segmap(pmap, addr) != NULL) {
pte = pmap_pte(pmap, addr);
rv = (*pte == 0);
}