Date: Tue, 19 Sep 2006 23:04:18 GMT From: Suleiman Souhlal <ssouhlal@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 106366 for review Message-ID: <200609192304.k8JN4IGs020329@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=106366 Change 106366 by ssouhlal@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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200609192304.k8JN4IGs020329>