svn commit: r209805 - in head/sys/mips: include mips

Jayachandran C. jchandra at FreeBSD.org
Thu Jul 8 14:49:56 UTC 2010


Author: jchandra
Date: Thu Jul  8 14:49:55 2010
New Revision: 209805
URL: http://svn.freebsd.org/changeset/base/209805

Log:
  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@

Modified:
  head/sys/mips/include/pmap.h
  head/sys/mips/include/pte.h
  head/sys/mips/mips/pmap.c

Modified: head/sys/mips/include/pmap.h
==============================================================================
--- head/sys/mips/include/pmap.h	Thu Jul  8 14:40:46 2010	(r209804)
+++ head/sys/mips/include/pmap.h	Thu Jul  8 14:49:55 2010	(r209805)
@@ -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)))

Modified: head/sys/mips/include/pte.h
==============================================================================
--- head/sys/mips/include/pte.h	Thu Jul  8 14:40:46 2010	(r209804)
+++ head/sys/mips/include/pte.h	Thu Jul  8 14:49:55 2010	(r209805)
@@ -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.

Modified: head/sys/mips/mips/pmap.c
==============================================================================
--- head/sys/mips/mips/pmap.c	Thu Jul  8 14:40:46 2010	(r209804)
+++ head/sys/mips/mips/pmap.c	Thu Jul  8 14:49:55 2010	(r209805)
@@ -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[
 	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 v
 		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 v
 	/*
 	 * 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
 		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 sv
 		/*
 		 * 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_
 		/*
 		 * 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_off
 
 	rv = FALSE;
 	PMAP_LOCK(pmap);
-	if (*pmap_pde(pmap, addr)) {
+	if (pmap_segmap(pmap, addr) != NULL) {
 		pte = pmap_pte(pmap, addr);
 		rv = (*pte == 0);
 	}


More information about the svn-src-all mailing list