svn commit: r190002 - in stable/7/sys: . boot/sparc64/loader contrib/pf dev/ath/ath_hal dev/cxgb

Marius Strobl marius at FreeBSD.org
Wed Mar 18 16:50:26 PDT 2009


Author: marius
Date: Wed Mar 18 23:50:25 2009
New Revision: 190002
URL: http://svn.freebsd.org/changeset/base/190002

Log:
  MFC: r182478, r182766
  
  - Read ASI_{D,I}TLB_DATA_ACCESS_REG twice in order to work around
    errata of USIII and beyond (USIII erratum #19, USIII+ erratum #1,
    USIIIi erratum #1).
  - Use the cheetah PA mask in {d,i}tlb_va_to_pa_sun4u() for USIII
    and beyond. This is done so that these functions will still mask
    the debug bits of spitfire-class CPUs once we increase TD_PA_BITS
    to match the number of bits used for the PA by cheetah-class CPUs.
  - Change {d,i}tlb_enter_sun4u() to also set TLB_CTX_KERNEL as the
    context of the mappings entered. This is more or less cosmetic as
    TLB_CTX_KERNEL is 0.
  - Now that we have to distinguish between different sun4u CPUs in
    the loader anyway, no longer do trial and error when reading the
    portid property.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/boot/sparc64/loader/main.c
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/ath/ath_hal/   (props changed)
  stable/7/sys/dev/cxgb/   (props changed)

Modified: stable/7/sys/boot/sparc64/loader/main.c
==============================================================================
--- stable/7/sys/boot/sparc64/loader/main.c	Wed Mar 18 23:35:40 2009	(r190001)
+++ stable/7/sys/boot/sparc64/loader/main.c	Wed Mar 18 23:50:25 2009	(r190002)
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/tte.h>
 #include <machine/tlb.h>
 #include <machine/upa.h>
+#include <machine/ver.h>
 
 #include "bootstrap.h"
 #include "libofw.h"
@@ -57,8 +58,10 @@ static struct mmu_ops {
 typedef void kernel_entry_t(vm_offset_t mdp, u_long o1, u_long o2, u_long o3,
     void *openfirmware);
 
+static inline u_long dtlb_get_data_sun4u(int slot);
 static void dtlb_enter_sun4u(u_long vpn, u_long data);
 static vm_offset_t dtlb_va_to_pa_sun4u(vm_offset_t);
+static inline u_long itlb_get_data_sun4u(int slot);
 static void itlb_enter_sun4u(u_long vpn, u_long data);
 static vm_offset_t itlb_va_to_pa_sun4u(vm_offset_t);
 extern vm_offset_t md_load(char *, vm_offset_t *);
@@ -92,6 +95,7 @@ struct tlb_entry *dtlb_store;
 struct tlb_entry *itlb_store;
 int dtlb_slot;
 int itlb_slot;
+int cpu_impl;
 static int dtlb_slot_max;
 static int itlb_slot_max;
 
@@ -365,60 +369,98 @@ __elfN(exec)(struct preloaded_file *fp)
 	panic("%s: exec returned", __func__);
 }
 
+static inline u_long
+dtlb_get_data_sun4u(int slot)
+{
+
+	/*
+	 * We read ASI_DTLB_DATA_ACCESS_REG twice in order to work
+	 * around errata of USIII and beyond.
+	 */
+	(void)ldxa(TLB_DAR_SLOT(slot), ASI_DTLB_DATA_ACCESS_REG);
+	return (ldxa(TLB_DAR_SLOT(slot), ASI_DTLB_DATA_ACCESS_REG));
+}
+
+static inline u_long
+itlb_get_data_sun4u(int slot)
+{
+
+	/*
+	 * We read ASI_ITLB_DATA_ACCESS_REG twice in order to work
+	 * around errata of USIII and beyond.
+	 */
+	(void)ldxa(TLB_DAR_SLOT(slot), ASI_ITLB_DATA_ACCESS_REG);
+	return (ldxa(TLB_DAR_SLOT(slot), ASI_ITLB_DATA_ACCESS_REG));
+}
+
 static vm_offset_t
 dtlb_va_to_pa_sun4u(vm_offset_t va)
 {
-	u_long reg;
+	u_long pstate, reg;
 	int i;
 
+	pstate = rdpr(pstate);
+	wrpr(pstate, pstate & ~PSTATE_IE, 0);
 	for (i = 0; i < dtlb_slot_max; i++) {
 		reg = ldxa(TLB_DAR_SLOT(i), ASI_DTLB_TAG_READ_REG);
 		if (TLB_TAR_VA(reg) != va)
 			continue;
-		reg = ldxa(TLB_DAR_SLOT(i), ASI_DTLB_DATA_ACCESS_REG);
+		reg = dtlb_get_data_sun4u(i);
+		wrpr(pstate, pstate, 0);
+		if (cpu_impl >= CPU_IMPL_ULTRASPARCIII)
+			return ((reg & TD_PA_CH_MASK) >> TD_PA_SHIFT);
 		return ((reg & TD_PA_SF_MASK) >> TD_PA_SHIFT);
 	}
+	wrpr(pstate, pstate, 0);
 	return (-1);
 }
 
 static vm_offset_t
 itlb_va_to_pa_sun4u(vm_offset_t va)
 {
-	u_long reg;
+	u_long pstate, reg;
 	int i;
 
+	pstate = rdpr(pstate);
+	wrpr(pstate, pstate & ~PSTATE_IE, 0);
 	for (i = 0; i < itlb_slot_max; i++) {
 		reg = ldxa(TLB_DAR_SLOT(i), ASI_ITLB_TAG_READ_REG);
 		if (TLB_TAR_VA(reg) != va)
 			continue;
-		reg = ldxa(TLB_DAR_SLOT(i), ASI_ITLB_DATA_ACCESS_REG);
+		reg = itlb_get_data_sun4u(i);
+		wrpr(pstate, pstate, 0);
+		if (cpu_impl >= CPU_IMPL_ULTRASPARCIII)
+			return ((reg & TD_PA_CH_MASK) >> TD_PA_SHIFT);
 		return ((reg & TD_PA_SF_MASK) >> TD_PA_SHIFT);
 	}
+	wrpr(pstate, pstate, 0);
 	return (-1);
 }
 
 static void
-itlb_enter_sun4u(u_long vpn, u_long data)
+dtlb_enter_sun4u(u_long vpn, u_long data)
 {
 	u_long reg;
 
 	reg = rdpr(pstate);
 	wrpr(pstate, reg & ~PSTATE_IE, 0);
-	stxa(AA_IMMU_TAR, ASI_IMMU, vpn);
-	stxa(0, ASI_ITLB_DATA_IN_REG, data);
+	stxa(AA_DMMU_TAR, ASI_DMMU,
+	     TLB_TAR_VA(vpn) | TLB_TAR_CTX(TLB_CTX_KERNEL));
+	stxa(0, ASI_DTLB_DATA_IN_REG, data);
 	membar(Sync);
 	wrpr(pstate, reg, 0);
 }
 
 static void
-dtlb_enter_sun4u(u_long vpn, u_long data)
+itlb_enter_sun4u(u_long vpn, u_long data)
 {
 	u_long reg;
 
 	reg = rdpr(pstate);
 	wrpr(pstate, reg & ~PSTATE_IE, 0);
-	stxa(AA_DMMU_TAR, ASI_DMMU, vpn);
-	stxa(0, ASI_DTLB_DATA_IN_REG, data);
+	stxa(AA_IMMU_TAR, ASI_IMMU,
+	     TLB_TAR_VA(vpn) | TLB_TAR_CTX(TLB_CTX_KERNEL));
+	stxa(0, ASI_ITLB_DATA_IN_REG, data);
 	membar(Sync);
 	wrpr(pstate, reg, 0);
 }
@@ -539,19 +581,18 @@ tlb_init_sun4u(void)
 	u_int bootcpu;
 	u_int cpu;
 
+	cpu_impl = VER_IMPL(rdpr(ver));
 	bootcpu = UPA_CR_GET_MID(ldxa(0, ASI_UPA_CONFIG_REG));
 	for (child = OF_child(root); child != 0; child = OF_peer(child)) {
-		if (child == -1)
-			panic("%s: can't get child phandle", __func__);
-		if (OF_getprop(child, "device_type", buf, sizeof(buf)) > 0 &&
-		    strcmp(buf, "cpu") == 0) {
-			if (OF_getprop(child, "upa-portid", &cpu,
-			    sizeof(cpu)) == -1 && OF_getprop(child, "portid",
-			    &cpu, sizeof(cpu)) == -1)
-				panic("%s: can't get portid", __func__);
-			if (cpu == bootcpu)
-				break;
-		}
+		if (OF_getprop(child, "device_type", buf, sizeof(buf)) <= 0)
+			continue;
+		if (strcmp(buf, "cpu") != 0)
+			continue;
+		if (OF_getprop(child, cpu_impl < CPU_IMPL_ULTRASPARCIII ?
+		    "upa-portid" : "portid", &cpu, sizeof(cpu)) <= 0)
+			continue;
+		if (cpu == bootcpu)
+			break;
 	}
 	if (cpu != bootcpu)
 		panic("%s: no node for bootcpu?!?!", __func__);
@@ -712,10 +753,14 @@ static void
 pmap_print_tlb_sun4u(void)
 {
 	tte_t tag, tte;
+	u_long pstate;
 	int i;
 
+	pstate = rdpr(pstate);
 	for (i = 0; i < itlb_slot_max; i++) {
-		tte = ldxa(TLB_DAR_SLOT(i), ASI_ITLB_DATA_ACCESS_REG);
+		wrpr(pstate, pstate & ~PSTATE_IE, 0);
+		tte = itlb_get_data_sun4u(i);
+		wrpr(pstate, pstate, 0);
 		if (!(tte & TD_V))
 			continue;
 		tag = ldxa(TLB_DAR_SLOT(i), ASI_ITLB_TAG_READ_REG);
@@ -723,7 +768,9 @@ pmap_print_tlb_sun4u(void)
 		pmap_print_tte_sun4u(tag, tte);
 	}
 	for (i = 0; i < dtlb_slot_max; i++) {
-		tte = ldxa(TLB_DAR_SLOT(i), ASI_DTLB_DATA_ACCESS_REG);
+		wrpr(pstate, pstate & ~PSTATE_IE, 0);
+		tte = dtlb_get_data_sun4u(i);
+		wrpr(pstate, pstate, 0);
 		if (!(tte & TD_V))
 			continue;
 		tag = ldxa(TLB_DAR_SLOT(i), ASI_DTLB_TAG_READ_REG);


More information about the svn-src-all mailing list