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 *

Reply via email to