diff options
author | jchandra <jchandra@FreeBSD.org> | 2010-07-08 14:49:55 +0000 |
---|---|---|
committer | jchandra <jchandra@FreeBSD.org> | 2010-07-08 14:49:55 +0000 |
commit | 5be567ad5ff8f316da952b9fbb9352193137f28a (patch) | |
tree | 410b08c5351bfcac4a2c92c1c71b0daf33c66846 | |
parent | 4e687ef5c7e93f46480469e803cc4911c39d8254 (diff) | |
download | FreeBSD-src-5be567ad5ff8f316da952b9fbb9352193137f28a.zip FreeBSD-src-5be567ad5ff8f316da952b9fbb9352193137f28a.tar.gz |
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@
-rw-r--r-- | sys/mips/include/pmap.h | 2 | ||||
-rw-r--r-- | sys/mips/include/pte.h | 17 | ||||
-rw-r--r-- | sys/mips/mips/pmap.c | 53 |
3 files changed, 41 insertions, 31 deletions
diff --git a/sys/mips/include/pmap.h b/sys/mips/include/pmap.h index f2ff691..3e7b937 100644 --- a/sys/mips/include/pmap.h +++ b/sys/mips/include/pmap.h @@ -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))) diff --git a/sys/mips/include/pte.h b/sys/mips/include/pte.h index 7a05367..a767b04 100644 --- a/sys/mips/include/pte.h +++ b/sys/mips/include/pte.h @@ -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. diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index a529254..2765fda 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -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); } |