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