Module Name: src Committed By: matt Date: Mon Sep 7 22:08:32 UTC 2009
Modified Files: src/sys/arch/mips/mips [matt-nb5-mips64]: pmap.c Log Message: Add LP64 support. To generate a diff of this commit: cvs rdiff -u -r1.179.16.2 -r1.179.16.3 src/sys/arch/mips/mips/pmap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/mips/mips/pmap.c diff -u src/sys/arch/mips/mips/pmap.c:1.179.16.2 src/sys/arch/mips/mips/pmap.c:1.179.16.3 --- src/sys/arch/mips/mips/pmap.c:1.179.16.2 Sun Aug 23 06:38:07 2009 +++ src/sys/arch/mips/mips/pmap.c Mon Sep 7 22:08:31 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.179.16.2 2009/08/23 06:38:07 matt Exp $ */ +/* $NetBSD: pmap.c,v 1.179.16.3 2009/09/07 22:08:31 matt Exp $ */ /*- * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc. @@ -67,7 +67,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.179.16.2 2009/08/23 06:38:07 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.179.16.3 2009/09/07 22:08:31 matt Exp $"); /* * Manages physical address maps. @@ -147,7 +147,10 @@ CTASSERT((uint32_t)MIPS_KSEG2_START == 0xc0000000); CTASSERT((uint32_t)MIPS_MAX_MEM_ADDR == 0xbe000000); CTASSERT((uint32_t)MIPS_RESERVED_ADDR == 0xbfc80000); +CTASSERT(MIPS_KSEG0_P(MIPS_PHYS_TO_KSEG0(0))); +CTASSERT(MIPS_KSEG1_P(MIPS_PHYS_TO_KSEG1(0))); +CTASSERT(NBPG >= sizeof(struct segtab)); #ifdef DEBUG struct { int kernel; /* entering kernel mapping */ @@ -374,6 +377,7 @@ pmap_kernel()->pm_count = 1; pmap_kernel()->pm_asid = PMAP_ASID_RESERVED; pmap_kernel()->pm_asidgen = 0; + pmap_kernel()->pm_segtab = (void *)(MIPS_KSEG2_START + 0x1eadbeef); pmap_max_asid = MIPS_TLB_NUM_PIDS; pmap_next_asid = 1; @@ -590,22 +594,30 @@ pmap->pm_segtab->seg_tab[0] = NULL; } else { struct segtab *stp; - struct vm_page *mem; + struct vm_page *stp_pg; + paddr_t stp_pa; - do { - mem = uvm_pagealloc(NULL, 0, NULL, + for (;;) { + stp_pg = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_USERESERVE|UVM_PGA_ZERO); - if (mem == NULL) { - /* - * XXX What else can we do? Could we - * XXX deadlock here? - */ - uvm_wait("pmap_create"); - } - } while (mem == NULL); + if (stp_pg != NULL) + break; + /* + * XXX What else can we do? Could we + * XXX deadlock here? + */ + uvm_wait("pmap_create"); + } - pmap->pm_segtab = stp = - (struct segtab *)MIPS_PHYS_TO_KSEG0(VM_PAGE_TO_PHYS(mem)); + stp_pa = VM_PAGE_TO_PHYS(stp_pg); +#ifdef _LP64 + if (stp_pa > MIPS_PHYS_MASK) + stp = (struct segtab *)MIPS_PHYS_TO_XKPHYS( + stp_pa, MIPS3_PG_TO_CCA(mips3_pg_cached)); + else +#endif + stp = (struct segtab *)MIPS_PHYS_TO_KSEG0(stp_pa); + pmap->pm_segtab = stp; i = NBPG / sizeof(struct segtab); while (--i != 0) { stp++; @@ -650,6 +662,7 @@ #endif for (i = 0; i < PMAP_SEGTABSIZE; i++) { + paddr_t pa; /* get pointer to segment map */ pte = pmap->pm_segtab->seg_tab[i]; if (!pte) @@ -673,7 +686,13 @@ if (mips_cache_virtual_alias) mips_dcache_inv_range((vaddr_t)pte, PAGE_SIZE); #endif /* MIPS3_PLUS */ - uvm_pagefree(PHYS_TO_VM_PAGE(MIPS_KSEG0_TO_PHYS(pte))); +#ifdef _LP64 + if (MIPS_XKPHYS_P(pte)) + pa = MIPS_XKPHYS_TO_PHYS(pte); + else +#endif + pa = MIPS_KSEG0_TO_PHYS(pte); + uvm_pagefree(PHYS_TO_VM_PAGE(pa)); pmap->pm_segtab->seg_tab[i] = NULL; } @@ -1284,6 +1303,7 @@ } if (!(pte = pmap_segmap(pmap, va))) { + paddr_t phys; mem = uvm_pagealloc(NULL, 0, NULL, UVM_PGA_USERESERVE|UVM_PGA_ZERO); if (mem == NULL) { @@ -1292,8 +1312,15 @@ panic("pmap_enter: cannot allocate segmap"); } - pmap_segmap(pmap, va) = pte = - (pt_entry_t *)MIPS_PHYS_TO_KSEG0(VM_PAGE_TO_PHYS(mem)); + phys = VM_PAGE_TO_PHYS(mem); +#ifdef _LP64 + if ((vaddr_t)pte > MIPS_PHYS_MASK) + pte = (pt_entry_t *)MIPS_PHYS_TO_XKPHYS(phys, + MIPS3_PG_TO_CCA(mips3_pg_cached)); + else +#endif + pte = (pt_entry_t *)MIPS_PHYS_TO_KSEG0(phys); + pmap_segmap(pmap, va) = pte; #ifdef PARANOIADIAG { int i; @@ -1326,23 +1353,23 @@ pmap->pm_stats.wired_count++; npte |= mips_pg_wired_bit(); } -#ifdef DEBUG +#if defined(DEBUG) if (pmapdebug & PDB_ENTER) { - printf("pmap_enter: new pte %x", npte); + printf("pmap_enter: %p: %#"PRIxVADDR": new pte %#x (pa %#"PRIxPADDR")", pmap, va, npte, pa); if (pmap->pm_asidgen == pmap_asid_generation) - printf(" asid %d", pmap->pm_asid); + printf(" asid %u (%#x)", pmap->pm_asid, pmap->pm_asid); printf("\n"); } #endif #ifdef PARANOIADIAG if (PMAP_IS_ACTIVE(pmap)) { - unsigned asid; + unsigned int asid; __asm volatile("mfc0 %0,$10; nop" : "=r"(asid)); asid = (MIPS_HAS_R4K_MMU) ? (asid & 0xff) : (asid & 0xfc0) >> 6; if (asid != pmap->pm_asid) { - panic("inconsistency for active TLB update: %d <-> %d", + panic("inconsistency for active TLB update: %u <-> %u", asid, pmap->pm_asid); } } @@ -1526,18 +1553,18 @@ printf("pmap_extract(%p, %#"PRIxVADDR") -> ", pmap, va); #endif if (pmap == pmap_kernel()) { - if (va >= (uintptr_t)MIPS_KSEG0_START && va < (uintptr_t)MIPS_KSEG1_START) { + if (MIPS_KSEG0_P(va)) { pa = MIPS_KSEG0_TO_PHYS(va); goto done; } #ifdef _LP64 - if (va >= (uintptr_t)MIPS_XKPHYS_START && va < (uintptr_t)MIPS_XKSEG_START) { + if (MIPS_XKPHYS_P(va)) { pa = MIPS_XKPHYS_TO_PHYS(va); goto done; } #endif #ifdef DIAGNOSTIC - else if (va >= (uintptr_t)MIPS_KSEG1_START && va < (uintptr_t)MIPS_KSEG2_START) + if (MIPS_KSEG1_P(va)) panic("pmap_extract: kseg1 address %#"PRIxVADDR"", va); #endif else @@ -1631,7 +1658,12 @@ if (!(phys < MIPS_MAX_MEM_ADDR)) printf("pmap_zero_page(%#"PRIxPADDR") nonphys\n", phys); #endif - va = MIPS_PHYS_TO_KSEG0(phys); +#ifdef _LP64 + if (phys > MIPS_PHYS_MASK) + va = MIPS_PHYS_TO_XKPHYS(phys, MIPS3_PG_TO_CCA(mips3_pg_cached)); + else +#endif + va = MIPS_PHYS_TO_KSEG0(phys); #if defined(MIPS3_PLUS) /* XXX mmu XXX */ pg = PHYS_TO_VM_PAGE(phys); @@ -1666,11 +1698,24 @@ void pmap_copy_page(paddr_t src, paddr_t dst) { + vaddr_t src_va, dst_va; #ifdef DEBUG if (pmapdebug & PDB_FOLLOW) printf("pmap_copy_page(%#"PRIxPADDR", %#"PRIxPADDR")\n", src, dst); #endif -#ifdef PARANOIADIAG +#ifdef _LP64 + if (src > MIPS_PHYS_MASK) + src_va = MIPS_PHYS_TO_XKPHYS(src, MIPS3_PG_TO_CCA(mips3_pg_cached)); + else +#endif + src_va = MIPS_PHYS_TO_KSEG0(src); +#ifdef _LP64 + if (dst > MIPS_PHYS_MASK) + dst_va = MIPS_PHYS_TO_XKPHYS(dst, MIPS3_PG_TO_CCA(mips3_pg_cached)); + else +#endif + dst_va = MIPS_PHYS_TO_KSEG0(dst); +#if !defined(_LP64) && defined(PARANOIADIAG) if (!(src < MIPS_MAX_MEM_ADDR)) printf("pmap_copy_page(%#"PRIxPADDR") src nonphys\n", src); if (!(dst < MIPS_MAX_MEM_ADDR)) @@ -1700,8 +1745,7 @@ } #endif /* MIPS3_PLUS */ - mips_pagecopy((void *)MIPS_PHYS_TO_KSEG0(dst), - (void *)MIPS_PHYS_TO_KSEG0(src)); + mips_pagecopy((void *)dst_va, (void *)src_va); #if defined(MIPS3_PLUS) /* XXX mmu XXX */ /* @@ -1716,8 +1760,8 @@ * XXXJRT -- This is totally disgusting. */ if (mips_cache_virtual_alias) { - mips_dcache_wbinv_range(MIPS_PHYS_TO_KSEG0(src), PAGE_SIZE); - mips_dcache_wbinv_range(MIPS_PHYS_TO_KSEG0(dst), PAGE_SIZE); + mips_dcache_wbinv_range(src_va, PAGE_SIZE); + mips_dcache_wbinv_range(dst_va, PAGE_SIZE); } #endif /* MIPS3_PLUS */ } @@ -2143,7 +2187,12 @@ return NULL; } phys = VM_PAGE_TO_PHYS(pg); - va = MIPS_PHYS_TO_KSEG0(phys); +#ifdef _LP64 + if (phys > MIPS_PHYS_MASK) + va = MIPS_PHYS_TO_XKPHYS(phys, MIPS3_PG_TO_CCA(mips3_pg_cached)); + else +#endif + va = MIPS_PHYS_TO_KSEG0(phys); #if defined(MIPS3_PLUS) if (mips_cache_virtual_alias) { pg = PHYS_TO_VM_PAGE(phys); @@ -2164,12 +2213,19 @@ void pmap_pv_page_free(struct pool *pp, void *v) { + paddr_t phys; #ifdef MIPS3_PLUS if (mips_cache_virtual_alias) mips_dcache_inv_range((vaddr_t)v, PAGE_SIZE); #endif - uvm_pagefree(PHYS_TO_VM_PAGE(MIPS_KSEG0_TO_PHYS((vaddr_t)v))); +#ifdef _LP64 + if (MIPS_XKPHYS_P(v)) + phys = MIPS_XKPHYS_TO_PHYS((vaddr_t)v); + else +#endif + phys = MIPS_KSEG0_TO_PHYS((vaddr_t)v); + uvm_pagefree(PHYS_TO_VM_PAGE(phys)); } pt_entry_t *