PERFORCE change 106366 for review

Suleiman Souhlal ssouhlal at FreeBSD.org
Tue Sep 19 16:04:19 PDT 2006


http://perforce.freebsd.org/chv.cgi?CH=106366

Change 106366 by ssouhlal at ssouhlal-maho on 2006/09/19 23:03:24

	Various pmap fixes:
	- The MIPS_PA_TO_PFN(), MIPS_PFN_TO_PA() and MIPS_PTE_TO_PFN() macros
	  were wrong.
	- Make pmap_pte work for arbitrary pmaps, not just for the kernel.
	- Make pmap_pinit actually allocate a 2M virtually contiguous page
	  table for new pmaps
	  This is obviously temporary: We will eventually have two-level page
	  tables.
	- Remove unreached statement in pmap_remove_pte()
	- pmap_remove() needs to remove the corresponding PV entry.
	- Add a breakpoint in pmap_mapdev().
	- Make tlb_enter() and tlb_remove() use pmap_pte().
	- Fix tlb_enter()'s usage of MIPS_PA_TO_PFN()
	- Make tlb_enter() actually enter the PTE in the TLB, instead of only
	  adding it to the page table.
	- Fix tlb_remove_range()'s usage of tlb_remove_pages(): the third
	  argument is supposed to be a number of pages, not a number bytes. :-(
	- Make tlb_invalidate_one() use better bogus virtual addresses.

Affected files ...

.. //depot/projects/mips2/src/sys/mips/include/pmap.h#4 edit
.. //depot/projects/mips2/src/sys/mips/include/pte.h#3 edit
.. //depot/projects/mips2/src/sys/mips/mips/pmap.c#9 edit
.. //depot/projects/mips2/src/sys/mips/mips/tlb.c#7 edit

Differences ...

==== //depot/projects/mips2/src/sys/mips/include/pmap.h#4 (text+ko) ====

@@ -84,6 +84,7 @@
 void *pmap_mapdev(vm_offset_t, vm_size_t);
 void pmap_unmapdev(vm_offset_t, vm_size_t);
 void pmap_deactivate(struct thread *);
+pt_entry_t* pmap_pte(pmap_t pmap, vm_offset_t va);
 
 #define	pmap_resident_count(pm)	((pm)->pm_stats.resident_count)
 #define	vtophys(va)	pmap_kextract((vm_offset_t)(va))

==== //depot/projects/mips2/src/sys/mips/include/pte.h#3 (text+ko) ====

@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $P4: //depot/projects/mips2/src/sys/mips/include/pte.h#2 $
+ * $P4: //depot/projects/mips2/src/sys/mips/include/pte.h#3 $
  */
 
 #ifndef	_MACHINE_PTE_H_
@@ -54,9 +54,9 @@
 #define	MIPS_TLB_SWSHIFT	30
 #define	MIPS_PFN_SHIFT		6
 #define	MIPS_PFN_MASK		0xFFFFFF
-#define	MIPS_PA_TO_PFN(pa)	(((pa) >> MIPS_PFN_SHIFT) & MIPS_PFN_MASK)
-#define	MIPS_PFN_TO_PA(pfn)	((pfn) << MIPS_PFN_SHIFT)
-#define	MIPS_PTE_TO_PFN(pte)	((pte) & MIPS_PFN_MASK)
+#define	MIPS_PA_TO_PFN(pa)	(((pa) >> PAGE_SHIFT))
+#define	MIPS_PFN_TO_PA(pfn)	((pfn) << PAGE_SHIFT)
+#define	MIPS_PTE_TO_PFN(pte)	(((pte) >> MIPS_PFN_SHIFT) & MIPS_PFN_MASK)
 #define	MIPS_PTE_TO_PA(pte)	(MIPS_PFN_TO_PA(MIPS_PTE_TO_PFN((pte))))
 
 /*

==== //depot/projects/mips2/src/sys/mips/mips/pmap.c#9 (text+ko) ====

@@ -205,14 +205,23 @@
  * 		Extract the page table entry associated with
  * 		the given map/virtual addresss pair.
  */
-static pt_entry_t*
+pt_entry_t*
 pmap_pte(pmap_t pmap, vm_offset_t va)
 {
-	if (pmap != kernel_pmap)
-		panic("non kernel pmap unsupported");
-	if (pmap == NULL || pmap->pm_lev1 == NULL)
-		return NULL;
-	return tlb_pte_find(pmap->pm_lev1, va);
+	pt_entry_t *pte = NULL;
+	unsigned long lev1;
+
+	if (pmap != kernel_pmap && pmap) {
+		/* XXX Try to avoid TLB refills */
+		lev1 = (unsigned long)pmap->pm_lev1;
+		lev1 = (unsigned long)tlb_pte_find(kptmap, lev1);
+		lev1 = (unsigned long)MIPS_PTE_TO_PA(*(pt_entry_t *)lev1);
+
+		pte = tlb_pte_find(
+		    pt_entry_t *)MIPS_PHYS_TO_KSEG0((pt_entry_t *)lev1), va);
+	} else
+		pte = tlb_pte_find(kptmap, va);
+	return pte;
 }
 
 
@@ -708,7 +717,7 @@
 pmap_pinit(pmap)
 	register struct pmap *pmap;
 {
-#ifdef notyet
+#if notyet
 	vm_page_t lev1pg;
 	int i;
 
@@ -737,8 +746,16 @@
 	pmap->pm_lev1[PTLEV1I] = pmap_phys_to_pte(VM_PAGE_TO_PHYS(lev1pg))
 		| PG_V | PG_KRE | PG_KWE;
 #else
-	pmap->pm_lev1 = NULL;
+	char *lev1pg;
+
+	/* XXX */
+	lev1pg = malloc(2097152, M_TEMP, M_WAITOK);
+	if (lev1pg == NULL)
+		panic("no lev1pg\n");
+
+	pmap->pm_lev1 = (pt_entry_t*) lev1pg;
 #endif
+
 	pmap->pm_ptphint = NULL;
 	pmap->pm_active = 0;
 	pmap->pm_asid = 0;
@@ -961,8 +978,6 @@
 	if ((oldpte & PG_D) == 0)
 		vm_page_flag_set(m, PG_REFERENCED);
 	return pmap_remove_entry(pmap, m, va);
-
-	return 0;
 }
 
 /*
@@ -974,6 +989,9 @@
 void
 pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
 {
+	int count;
+	vm_offset_t va;
+	pt_entry_t *pte;
 
 	if (pmap == NULL)
 		return;
@@ -981,7 +999,14 @@
 	if (pmap->pm_stats.resident_count == 0)
 		return;
 
-	tlb_remove_range(pmap, sva, eva);
+	count = (eva - sva) >> PAGE_SHIFT;
+	va = sva;
+	while (count--) {
+		pte = pmap_pte(pmap, va);
+		pmap_remove_pte(pmap, pte, va);
+		tlb_remove(pmap, va);
+		va += PAGE_SIZE;
+	}
 }
 
 /*
@@ -1148,7 +1173,6 @@
 	 * resident, we are creating it here.
 	 */
 	if (va < VM_MAXUSER_ADDRESS) {
-		panic("need to allocate mpte\n");
 	}
 
 	pte = pmap_pte(pmap, va);
@@ -1652,6 +1676,7 @@
 pmap_mapdev(vm_offset_t pa, vm_size_t size)
 {
 	/* XXXMIPS: return (void *)MIPS_PHYS_TO_KSEG1(pa); */
+	__asm __volatile("break");
 	return 0;
 }
 

==== //depot/projects/mips2/src/sys/mips/mips/tlb.c#7 (text+ko) ====

@@ -56,6 +56,7 @@
 #include <machine/locore.h>
 #include <machine/md_var.h>
 #include <machine/tlb.h>
+#include <machine/pmap.h>
 
 pt_entry_t *kptmap;
 vm_size_t kptsize;
@@ -133,7 +134,7 @@
 	pa &= ~PAGE_MASK;
 	va &= ~PAGE_MASK;
 
-	pte = tlb_pte_find(pmap->pm_lev1, va);
+	pte = pmap_pte(pmap, va);
 	if (pte_valid(pte))
 		tlb_invalidate_page(va);
 	else
@@ -142,8 +143,13 @@
 		panic("pmap %p entering invalid mapping for va %lx to pa %lx [%lx]",
 		       pmap, (u_long)va, (u_long)pa, (u_long)bits);
 	*pte &= PG_G;
-	*pte |= MIPS_PA_TO_PFN(pa) | bits;
+	*pte |= (MIPS_PA_TO_PFN(pa) << MIPS_PFN_SHIFT) | bits;
 	*pte |= PG_C_UNCACHED;
+
+	if ((va >> PAGE_SHIFT) & 1)
+		tlb_update(va, pte[-1], pte[0]);
+	else 
+		tlb_update(va, pte[0], pte[1]);
 }
 
 void
@@ -153,7 +159,7 @@
 
 	va &= ~PAGE_MASK;
 
-	pte = tlb_pte_find(pmap->pm_lev1, va);
+	pte = pmap_pte(pmap, va);
 	pte_clear(pte, PG_V);
 	tlb_invalidate_page(va);
 }
@@ -171,7 +177,7 @@
 void
 tlb_remove_range(pmap_t pmap, vm_offset_t va, vm_offset_t eva)
 {
-	tlb_remove_pages(pmap, va, eva - va);
+	tlb_remove_pages(pmap, va, (eva - va) >> PAGE_SHIFT);
 }
 
 void
@@ -212,7 +218,7 @@
 	u_long ehi;
 
 	/* Bogus VPN2. */
-	ehi = MIPS_KSEG1_END + 2 * i * PAGE_SIZE;
+	ehi = MIPS_KSEG2_START + 0x0fff0000 + 2 * i * PAGE_SIZE;
 	mips_wr_index(i);
 	mips_wr_entrylo0(0);
 	mips_wr_entrylo1(0);


More information about the p4-projects mailing list