PERFORCE change 147673 for review

Marius Strobl marius at FreeBSD.org
Sun Aug 17 21:10:07 UTC 2008


http://perforce.freebsd.org/chv.cgi?CH=147673

Change 147673 by marius at flak on 2008/08/17 21:09:44

	Flesh out; this is self-hosting on Blade 1000 (USIII MP; CPUs at
	mixed speeds thought to be working but untested), Blade 1500
	(USIIIi), Blade 2000 (USIII+ MP) and Fire V210 (USIIIi MP).

Affected files ...

.. //depot/projects/usiii/boot/common/dev_net.c#3 edit
.. //depot/projects/usiii/boot/sparc64/loader/main.c#3 edit
.. //depot/projects/usiii/conf/files.sparc64#6 edit
.. //depot/projects/usiii/conf/options.sparc64#2 edit
.. //depot/projects/usiii/sparc64/include/cache.h#3 edit
.. //depot/projects/usiii/sparc64/include/clock.h#3 edit
.. //depot/projects/usiii/sparc64/include/cpu.h#2 edit
.. //depot/projects/usiii/sparc64/include/cpufunc.h#3 edit
.. //depot/projects/usiii/sparc64/include/dcr.h#1 add
.. //depot/projects/usiii/sparc64/include/pcpu.h#3 edit
.. //depot/projects/usiii/sparc64/include/smp.h#3 edit
.. //depot/projects/usiii/sparc64/include/tick.h#2 edit
.. //depot/projects/usiii/sparc64/include/tlb.h#4 edit
.. //depot/projects/usiii/sparc64/include/trap.h#2 edit
.. //depot/projects/usiii/sparc64/include/tte.h#3 edit
.. //depot/projects/usiii/sparc64/include/ver.h#2 edit
.. //depot/projects/usiii/sparc64/pci/ofw_pci.h#3 edit
.. //depot/projects/usiii/sparc64/pci/ofw_pcibus.c#8 edit
.. //depot/projects/usiii/sparc64/pci/psycho.c#11 edit
.. //depot/projects/usiii/sparc64/pci/schizo.c#9 edit
.. //depot/projects/usiii/sparc64/pci/schizoreg.h#3 edit
.. //depot/projects/usiii/sparc64/pci/schizovar.h#3 edit
.. //depot/projects/usiii/sparc64/sparc64/cache.c#3 edit
.. //depot/projects/usiii/sparc64/sparc64/cheetah.c#5 edit
.. //depot/projects/usiii/sparc64/sparc64/clock.c#4 edit
.. //depot/projects/usiii/sparc64/sparc64/exception.S#5 edit
.. //depot/projects/usiii/sparc64/sparc64/genassym.c#3 edit
.. //depot/projects/usiii/sparc64/sparc64/jbusppm.c#1 add
.. //depot/projects/usiii/sparc64/sparc64/locore.S#3 edit
.. //depot/projects/usiii/sparc64/sparc64/machdep.c#6 edit
.. //depot/projects/usiii/sparc64/sparc64/mp_exception.S#2 edit
.. //depot/projects/usiii/sparc64/sparc64/mp_locore.S#3 edit
.. //depot/projects/usiii/sparc64/sparc64/mp_machdep.c#6 edit
.. //depot/projects/usiii/sparc64/sparc64/pmap.c#7 edit
.. //depot/projects/usiii/sparc64/sparc64/schppm.c#1 add
.. //depot/projects/usiii/sparc64/sparc64/spitfire.c#4 edit
.. //depot/projects/usiii/sparc64/sparc64/support.S#3 edit
.. //depot/projects/usiii/sparc64/sparc64/swtch.S#3 edit
.. //depot/projects/usiii/sparc64/sparc64/tick.c#5 edit
.. //depot/projects/usiii/sparc64/sparc64/tlb.c#4 edit
.. //depot/projects/usiii/sparc64/sparc64/trap.c#5 edit

Differences ...

==== //depot/projects/usiii/boot/common/dev_net.c#3 (text+ko) ====

@@ -144,6 +144,9 @@
 		return (error);
 	    }
 	}
+#if defined(__sparc64__)
+	netdev_opens++;
+#endif
     }
     netdev_opens++;
     f->f_devdata = &netdev_sock;

==== //depot/projects/usiii/boot/sparc64/loader/main.c#3 (text+ko) ====

@@ -6,9 +6,35 @@
  * As long as the above copyright statement and this notice remain
  * unchanged, you can do what ever you want with this file.
  */
+/*-
+ * Copyright (c) 2008 Marius Strobl <marius at FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
 
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD: src/sys/boot/sparc64/loader/main.c,v 1.33 2008/08/07 22:46:25 marius Exp $");
+
 /*
  * FreeBSD/sparc64 kernel loader - machine dependent part
  *
@@ -28,7 +54,6 @@
 
 #include <vm/vm.h>
 #include <machine/asi.h>
-#include <machine/atomic.h>
 #include <machine/cpufunc.h>
 #include <machine/elf.h>
 #include <machine/lsu.h>
@@ -36,6 +61,8 @@
 #include <machine/tte.h>
 #include <machine/tlb.h>
 #include <machine/upa.h>
+#include <machine/ver.h>
+#include <machine/vmparam.h>
 
 #include "bootstrap.h"
 #include "libofw.h"
@@ -57,10 +84,13 @@
 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);
+static void itlb_relocate_locked0_sun4u(void);
 extern vm_offset_t md_load(char *, vm_offset_t *);
 static int sparc64_autoload(void);
 static ssize_t sparc64_readin(const int, vm_offset_t, const size_t);
@@ -92,6 +122,7 @@
 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,6 +396,30 @@
 	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)
 {
@@ -375,7 +430,9 @@
 		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);
+		if (cpu_impl >= CPU_IMPL_ULTRASPARCIII)
+			return ((reg & TD_PA_CH_MASK) >> TD_PA_SHIFT);
 		return ((reg & TD_PA_SF_MASK) >> TD_PA_SHIFT);
 	}
 	return (-1);
@@ -391,38 +448,107 @@
 		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);
+		if (cpu_impl >= CPU_IMPL_ULTRASPARCIII)
+			return ((reg & TD_PA_CH_MASK) >> TD_PA_SHIFT);
 		return ((reg & TD_PA_SF_MASK) >> TD_PA_SHIFT);
 	}
 	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;
+	int i;
 
 	reg = rdpr(pstate);
 	wrpr(pstate, reg & ~PSTATE_IE, 0);
-	stxa(AA_DMMU_TAR, ASI_DMMU, vpn);
-	stxa(0, ASI_DTLB_DATA_IN_REG, data);
-	membar(Sync);
+
+	if (cpu_impl == CPU_IMPL_ULTRASPARCIIIp) {
+		/*
+		 * Search an unused slot != 0 and explicitly enter the data
+		 * and tag there in order to avoid Cheetah+ erratum 34.
+		 */
+		for (i = 1; i < itlb_slot_max; i++) {
+			if ((itlb_get_data_sun4u(i) & TD_V) != 0)
+				continue;
+
+			stxa(AA_IMMU_TAR, ASI_IMMU,
+			     TLB_TAR_VA(vpn) | TLB_TAR_CTX(TLB_CTX_KERNEL));
+			stxa(TLB_DAR_SLOT(i), ASI_ITLB_DATA_ACCESS_REG, data);
+			flush(KERNBASE);
+			break;
+		}
+		wrpr(pstate, reg, 0);
+		if (i == itlb_slot_max)
+			panic("%s: could not find an unused slot", __func__);
+		return;
+	}
+
+	stxa(AA_IMMU_TAR, ASI_IMMU,
+	     TLB_TAR_VA(vpn) | TLB_TAR_CTX(TLB_CTX_KERNEL));
+	stxa(0, ASI_ITLB_DATA_IN_REG, data);
+	flush(KERNBASE);
 	wrpr(pstate, reg, 0);
 }
 
+static void
+itlb_relocate_locked0_sun4u(void)
+{
+	u_long data, pstate, tag;
+	int i;
+
+	if (cpu_impl != CPU_IMPL_ULTRASPARCIIIp)
+		return;
+
+	pstate = rdpr(pstate);
+	wrpr(pstate, pstate & ~PSTATE_IE, 0);
+
+	data = itlb_get_data_sun4u(0);
+	if ((data & (TD_V | TD_L)) != (TD_V | TD_L)) {
+		wrpr(pstate, pstate, 0);
+		return;
+	}
+
+	/* Flush the mapping of slot 0. */
+	tag = ldxa(TLB_DAR_SLOT(0), ASI_ITLB_TAG_READ_REG);
+	stxa(TLB_DEMAP_VA(TLB_TAR_VA(tag)) | TLB_DEMAP_PRIMARY |
+	    TLB_DEMAP_PAGE, ASI_IMMU_DEMAP, 0);
+	flush(0);	/* The USIII-family ignores the address. */
+
+	/*
+	 * Search a replacement slot != 0 and enter the data and tag
+	 * that formerly were in slot 0.
+	 */
+	for (i = 1; i < itlb_slot_max; i++) {
+		if ((itlb_get_data_sun4u(i) & TD_V) != 0)
+			continue;
+
+		stxa(AA_IMMU_TAR, ASI_IMMU, tag);
+		stxa(TLB_DAR_SLOT(i), ASI_ITLB_DATA_ACCESS_REG, data);
+		flush(0);	/* The USIII-family ignores the address. */
+		break;
+	}
+	wrpr(pstate, pstate, 0);
+	if (i == itlb_slot_max)
+		panic("%s: could not find a replacement slot", __func__);
+}
+
 static int
 mmu_mapin_sun4u(vm_offset_t va, vm_size_t len)
 {
@@ -438,7 +564,7 @@
 	while (len) {
 		if (dtlb_va_to_pa_sun4u(va) == (vm_offset_t)-1 ||
 		    itlb_va_to_pa_sun4u(va) == (vm_offset_t)-1) {
-			/* Allocate a physical page, claim the virtual area */
+			/* Allocate a physical page, claim the virtual area. */
 			if (pa == (vm_offset_t)-1) {
 				pa = alloc_phys(PAGE_SIZE_4M, PAGE_SIZE_4M);
 				if (pa == (vm_offset_t)-1)
@@ -448,7 +574,9 @@
 					panic("%s: can't claim virtual page "
 					    "(wanted %#lx, got %#lx)",
 					    __func__, va, mva);
-				/* The mappings may have changed, be paranoid. */
+				/*
+				 * The mappings may have changed, be paranoid.
+				 */
 				continue;
 			}
 			/*
@@ -537,27 +665,46 @@
 	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__);
+
 	if (OF_getprop(child, "#dtlb-entries", &dtlb_slot_max,
 	    sizeof(dtlb_slot_max)) == -1 ||
 	    OF_getprop(child, "#itlb-entries", &itlb_slot_max,
 	    sizeof(itlb_slot_max)) == -1)
 		panic("%s: can't get TLB slot max.", __func__);
+
+	if (cpu_impl == CPU_IMPL_ULTRASPARCIIIp) {
+#ifdef LOADER_DEBUG
+		printf("pre fixup:\n");
+		pmap_print_tlb_sun4u();
+#endif
+
+		/*
+		 * Relocate the locked entry in it16 slot 0 (if existent)
+		 * as part of working around Cheetah+ erratum 34.
+		 */
+		itlb_relocate_locked0_sun4u();
+
+#ifdef LOADER_DEBUG
+		printf("post fixup:\n");
+		pmap_print_tlb_sun4u();
+#endif
+	}
+
 	dtlb_store = malloc(dtlb_slot_max * sizeof(*dtlb_store));
 	itlb_store = malloc(itlb_slot_max * sizeof(*itlb_store));
 	if (dtlb_store == NULL || itlb_store == NULL)
@@ -580,7 +727,7 @@
 	struct devsw **dp;
 
 	/*
-	 * Tell the Open Firmware functions where they find the ofw gate.
+	 * Tell the Open Firmware functions where they find the OFW gate.
 	 */
 	OF_init(openfirm);
 
@@ -709,10 +856,14 @@
 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);
@@ -720,7 +871,9 @@
 		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);

==== //depot/projects/usiii/conf/files.sparc64#6 (text+ko) ====

@@ -101,19 +101,23 @@
 sparc64/sparc64/db_hwwatch.c	optional	ddb
 sparc64/sparc64/dump_machdep.c	standard
 sparc64/sparc64/elf_machdep.c	standard
-sparc64/sparc64/exception.S	standard	no-obj
+sparc64/sparc64/exception.S	standard	no-obj			\
+	compile-with "${NORMAL_S} -mcpu=ultrasparc"
 sparc64/sparc64/eeprom.c	optional	eeprom ebus | eeprom fhc | \
 						eeprom sbus
 sparc64/sparc64/gdb_machdep.c	optional	gdb
 sparc64/sparc64/identcpu.c	standard
 sparc64/sparc64/in_cksum.c	optional	inet
-sparc64/sparc64/interrupt.S	standard	no-obj
+sparc64/sparc64/interrupt.S	standard	no-obj			\
+	compile-with "${NORMAL_S} -mcpu=ultrasparc"
 sparc64/sparc64/intr_machdep.c	standard
 sparc64/sparc64/iommu.c		standard
+sparc64/sparc64/jbusppm.c	standard
 sparc64/sparc64/locore.S	standard	no-obj
 sparc64/sparc64/machdep.c	standard
 sparc64/sparc64/mem.c		optional	mem
-sparc64/sparc64/mp_exception.S	optional	smp
+sparc64/sparc64/mp_exception.S	optional	smp			\
+	compile-with "${NORMAL_S} -mcpu=ultrasparc"
 sparc64/sparc64/mp_locore.S	optional	smp
 sparc64/sparc64/mp_machdep.c	optional	smp
 sparc64/sparc64/nexus.c		standard
@@ -124,9 +128,11 @@
 sparc64/sparc64/rtc.c		optional	rtc ebus | rtc isa
 sparc64/sparc64/rwindow.c	standard
 sparc64/sparc64/sc_machdep.c	optional	sc
+sparc64/sparc64/schppm.c	standard
 sparc64/sparc64/spitfire.c	standard
 sparc64/sparc64/stack_machdep.c	optional	ddb | stack
-sparc64/sparc64/support.S	standard
+sparc64/sparc64/support.S	standard				\
+	compile-with "${NORMAL_S} -mcpu=ultrasparc"
 sparc64/sparc64/sys_machdep.c	standard
 sparc64/sparc64/swtch.S		standard
 sparc64/sparc64/tick.c		standard

==== //depot/projects/usiii/conf/options.sparc64#2 (text+ko) ====

@@ -1,22 +1,30 @@
 # $FreeBSD: src/sys/conf/options.sparc64,v 1.14 2006/11/02 00:01:15 marius Exp $
 
-SUN4U			opt_global.h
-
 GFB_DEBUG		opt_gfb.h
 GFB_NO_FONT_LOADING	opt_gfb.h
 GFB_NO_MODE_CHANGE	opt_gfb.h
 
-PSYCHO_DEBUG		opt_psycho.h
-DEBUGGER_ON_POWERFAIL	opt_psycho.h
+SUN4U			opt_global.h
+
+ATKBD_DFLT_KEYMAP	opt_atkbd.h
+
+# Debug IOMMU inserts/removes using diagnostic accesses.  This is very loud.
+IOMMU_DIAG		opt_iommu.h
+
+OFWCONS_POLL_HZ		opt_ofw.h
+
 OFW_PCI_DEBUG		opt_ofw_pci.h
-OFWCONS_POLL_HZ		opt_ofw.h
-# Debug IOMMU inserts/removes using diagnostic accesses. Very loud.
-IOMMU_DIAG		opt_iommu.h
+
 PMAP_STATS		opt_pmap.h
 
-ATKBD_DFLT_KEYMAP	opt_atkbd.h
 PSM_DEBUG		opt_psm.h
 PSM_HOOKRESUME		opt_psm.h
 PSM_RESETAFTERSUSPEND	opt_psm.h
+
+DEBUGGER_ON_POWERFAIL	opt_psycho.h
+PSYCHO_DEBUG		opt_psycho.h
+
+SCHIZO_DEBUG		opt_schizo.h
+
 SUNKBD_DFLT_KEYMAP	opt_sunkbd.h
 SUNKBD_EMULATE_ATKBD	opt_sunkbd.h

==== //depot/projects/usiii/sparc64/include/cache.h#3 (text+ko) ====

@@ -45,10 +45,6 @@
 #ifndef _MACHINE_CACHE_H_
 #define	_MACHINE_CACHE_H_
 
-#ifndef LOCORE
-#include <dev/ofw/openfirm.h>
-#endif
-
 #define	DCACHE_COLOR_BITS	(1)
 #define	DCACHE_COLORS		(1 << DCACHE_COLOR_BITS)
 #define	DCACHE_COLOR_MASK	(DCACHE_COLORS - 1)
@@ -80,31 +76,27 @@
  * Cache control information
  */
 struct cacheinfo {
-	u_int	c_enabled;		/* true => cache is enabled */
 	u_int	ic_size;		/* instruction cache */
-	u_int	ic_set;
-	u_int	ic_l2set;
 	u_int	ic_assoc;
 	u_int	ic_linesize;
 	u_int	dc_size;		/* data cache */
-	u_int	dc_l2size;
 	u_int	dc_assoc;
 	u_int	dc_linesize;
 	u_int	ec_size;		/* external cache info */
 	u_int	ec_assoc;
-	u_int	ec_l2set;
 	u_int	ec_linesize;
-	u_int	ec_l2linesize;
 };
 
 #ifdef _KERNEL
 
+struct pcpu;
+
 typedef void cache_enable_t(void);
 typedef void cache_flush_t(void);
 typedef void dcache_page_inval_t(vm_paddr_t pa);
 typedef void icache_page_inval_t(vm_paddr_t pa);
 
-void	cache_init(phandle_t node);
+void cache_init(struct pcpu *pcpu);
 
 cache_enable_t cheetah_cache_enable;
 cache_flush_t cheetah_cache_flush;
@@ -121,8 +113,6 @@
 extern dcache_page_inval_t *dcache_page_inval;
 extern icache_page_inval_t *icache_page_inval;
 
-extern struct cacheinfo cache;
-
 #endif /* KERNEL */
 
 #endif /* !LOCORE */

==== //depot/projects/usiii/sparc64/include/clock.h#3 (text+ko) ====

@@ -29,8 +29,10 @@
 #ifndef	_MACHINE_CLOCK_H_
 #define	_MACHINE_CLOCK_H_
 
-extern u_long tick_increment;
-extern u_long tick_freq;
-extern u_long tick_MHz;
+extern void (*delay_func)(int usec);
+extern u_long clock_boot;
+
+void delay_boot(int usec);
+void delay_tick(int usec);
 
 #endif /* !_MACHINE_CLOCK_H_ */

==== //depot/projects/usiii/sparc64/include/cpu.h#2 (text+ko) ====

@@ -52,6 +52,7 @@
 extern	char btext[];
 extern	char etext[];
 
+void	cheetah_init(void);
 void	cpu_halt(void);
 void	cpu_reset(void);
 void	fork_trampoline(void);

==== //depot/projects/usiii/sparc64/include/cpufunc.h#3 (text+ko) ====

@@ -174,17 +174,28 @@
 } while (0)
 
 /*
+ * Trick GAS/GCC into compiling access to STICK/STICK_COMPARE independently
+ * of the selected instruction set.
+ */
+#define	rdstick()		rd(asr24)
+#define	rdstickcmpr()		rd(asr25)
+#define	wrstick(val, xor)	wr(asr24, (val), (xor))
+#define	wrstickcmpr(val, xor)	wr(asr25, (val), (xor))
+
+/*
  * Macro intended to be used instead of wr(asr23, val, xor) for writing to
  * the TICK_COMPARE register in order to avoid a bug in BlackBird CPUs that
  * can cause these writes to fail under certain condidtions which in turn
- * causes the hardclock to stop.  The workaround is to perform the write
- * at the beginning of an I-Cache line directly followed by a dummy read.
+ * causes the hardclock to stop.  The workaround is to read the TICK_COMPARE
+ * register back immediately after writing to it with these two instructions
+ * aligned to a quadword boundary in order to ensure that I$ misses won't
+ * split them up.
  */
 #define	wrtickcmpr(val, xor) ({						\
 	__asm __volatile(						\
 	"	ba,pt	%%xcc, 1f ;		"			\
 	"	 nop	 ;			"			\
-	"	.align	64 ;			"			\
+	"	.align	128 ;			"			\
 	"1:	wr	%0, %1, %%asr23 ;	"			\
 	"	rd	%%asr23, %%g0 ;		"			\
 	: : "r" (val), "rI" (xor));					\

==== //depot/projects/usiii/sparc64/include/pcpu.h#3 (text+ko) ====

@@ -33,6 +33,7 @@
 #ifdef _KERNEL
 
 #include <machine/asmacros.h>
+#include <machine/cache.h>
 #include <machine/frame.h>
 #include <machine/intr_machdep.h>
 
@@ -45,6 +46,7 @@
  * point at the globaldata structure.
  */
 #define	PCPU_MD_FIELDS							\
+	struct	cacheinfo pc_cache;					\
 	struct	intr_request pc_irpool[IR_FREE];			\
 	struct	intr_request *pc_irhead;				\
 	struct	intr_request **pc_irtail;				\
@@ -53,6 +55,7 @@
 	vm_offset_t pc_addr;						\
 	u_long	pc_tickref;						\
 	u_long	pc_tickadj;						\
+	u_int	pc_clock;						\
 	u_int	pc_mid;							\
 	u_int	pc_node;						\
 	u_int	pc_tlb_ctx;						\

==== //depot/projects/usiii/sparc64/include/smp.h#3 (text+ko) ====

@@ -29,9 +29,10 @@
 #ifndef	_MACHINE_SMP_H_
 #define	_MACHINE_SMP_H_
 
-#define	CPU_CLKSYNC		1
-#define	CPU_INIT		2
-#define	CPU_BOOTSTRAP		3
+#define	CPU_TICKSYNC		1
+#define	CPU_STICKSYNC		2
+#define	CPU_INIT		3
+#define	CPU_BOOTSTRAP		4
 
 #ifndef	LOCORE
 
@@ -62,6 +63,7 @@
 	u_int	csa_state;
 	vm_offset_t csa_pcpu;
 	u_long	csa_tick;
+	u_long	csa_stick;
 	u_long	csa_ver;
 	struct	tte csa_ttes[PCPU_PAGES];
 };

==== //depot/projects/usiii/sparc64/include/tick.h#2 (text+ko) ====

@@ -29,7 +29,7 @@
 #ifndef _MACHINE_TICK_H_
 #define	_MACHINE_TICK_H_
 
-void	tick_init(u_long clock);
+void	tick_clear(void);
 void	tick_start(void);
 void	tick_stop(void);
 

==== //depot/projects/usiii/sparc64/include/tlb.h#4 (text+ko) ====

@@ -51,6 +51,26 @@
 #define	TLB_TAR_VA(va)			((va) & ~TAR_CTX_MASK)
 #define	TLB_TAR_CTX(ctx)		((ctx) & TAR_CTX_MASK)
 
+#define	TLB_CXR_CTX_BITS		(13)
+#define	TLB_CXR_CTX_MASK						\
+	(((1UL << TLB_CXR_CTX_BITS) - 1) << TLB_CXR_CTX_SHIFT)
+#define	TLB_CXR_CTX_SHIFT		(0)
+#define	TLB_CXR_PGSZ_BITS		(3)
+#define	TLB_PCXR_PGSZ_MASK						\
+	((((1UL << TLB_CXR_PGSZ_BITS) - 1) << TLB_PCXR_N_PGSZ0_SHIFT) |	\
+	(((1UL << TLB_CXR_PGSZ_BITS) - 1) << TLB_PCXR_N_PGSZ1_SHIFT) |	\
+	(((1UL << TLB_CXR_PGSZ_BITS) - 1) << TLB_PCXR_P_PGSZ0_SHIFT) |	\
+	(((1UL << TLB_CXR_PGSZ_BITS) - 1) << TLB_PCXR_P_PGSZ1_SHIFT))
+#define	TLB_PCXR_N_PGSZ0_SHIFT		(61)
+#define	TLB_PCXR_N_PGSZ1_SHIFT		(58)
+#define	TLB_PCXR_P_PGSZ0_SHIFT		(16)
+#define	TLB_PCXR_P_PGSZ1_SHIFT		(19)
+#define	TLB_SCXR_PGSZ_MASK						\
+	((((1UL << TLB_CXR_PGSZ_BITS) - 1) << TLB_SCXR_S_PGSZ0_SHIFT) |	\
+	(((1UL << TLB_CXR_PGSZ_BITS) - 1) << TLB_SCXR_S_PGSZ1_SHIFT))
+#define	TLB_SCXR_S_PGSZ1_SHIFT		(19)
+#define	TLB_SCXR_S_PGSZ0_SHIFT		(16)
+
 #define	TLB_DEMAP_ID_SHIFT		(4)
 #define	TLB_DEMAP_ID_PRIMARY		(0)
 #define	TLB_DEMAP_ID_SECONDARY		(1)
@@ -59,8 +79,7 @@
 #define	TLB_DEMAP_TYPE_SHIFT		(6)
 #define	TLB_DEMAP_TYPE_PAGE		(0)
 #define	TLB_DEMAP_TYPE_CONTEXT		(1)
-/* US-III and greater only */
-#define	TLB_DEMAP_TYPE_ALL		(2)
+#define	TLB_DEMAP_TYPE_ALL		(2)	/* USIII and beyond only */
 
 #define	TLB_DEMAP_VA(va)		((va) & ~PAGE_MASK)
 #define	TLB_DEMAP_ID(id)		((id) << TLB_DEMAP_ID_SHIFT)

==== //depot/projects/usiii/sparc64/include/trap.h#2 (text+ko) ====

@@ -90,6 +90,7 @@
 #define	T_KERNEL			64
 
 #ifndef LOCORE
+void sun4u_set_traptable(void *tba_addr);
 extern const char *trap_msg[];
 #endif
 

==== //depot/projects/usiii/sparc64/include/tte.h#3 (text+ko) ====

@@ -36,21 +36,24 @@
 
 #define	TD_SIZE_SHIFT	(61)
 #define	TD_SOFT2_SHIFT	(50)
-#define	TD_DIAG_SHIFT	(41)
+#define	TD_DIAG_SF_SHIFT	(41)
+#define	TD_RSVD_CH_SHIFT	(43)
 #define	TD_PA_SHIFT	(13)
 #define	TD_SOFT_SHIFT	(7)
 
 #define	TD_SIZE_BITS	(2)
 #define	TD_SOFT2_BITS	(9)
-#define	TD_DIAG_BITS	(9)
+#define	TD_DIAG_SF_BITS	(9)
+#define	TD_RSVD_CH_BITS	(7)
 #define	TD_PA_CH_BITS	(30)
 #define	TD_PA_SF_BITS	(28)
-#define	TD_PA_BITS	TD_PA_SF_BITS
+#define	TD_PA_BITS	TD_PA_CH_BITS
 #define	TD_SOFT_BITS	(6)
 
 #define	TD_SIZE_MASK	((1UL << TD_SIZE_BITS) - 1)
 #define	TD_SOFT2_MASK	((1UL << TD_SOFT2_BITS) - 1)
-#define	TD_DIAG_MASK	((1UL << TD_DIAG_BITS) - 1)
+#define	TD_DIAG_SF_MASK	((1UL << TD_DIAG_SF_BITS) - 1)
+#define	TD_RSVD_CH_MASK	((1UL << TD_RSVD_CH_BITS) - 1)
 #define	TD_PA_CH_MASK	((1UL << TD_PA_CH_BITS) - 1)
 #define	TD_PA_SF_MASK	((1UL << TD_PA_SF_BITS) - 1)
 #define	TD_PA_MASK	((1UL << TD_PA_BITS) - 1)

==== //depot/projects/usiii/sparc64/include/ver.h#2 (text+ko) ====

@@ -41,6 +41,8 @@
 #define	VER_MAXTL_SIZE		(8)
 #define	VER_MAXWIN_SIZE		(5)
 
+#ifndef LOCORE
+
 #define	VER_MANUF_MASK		(((1L<<VER_MANUF_SIZE)-1)<<VER_MANUF_SHIFT)
 #define	VER_IMPL_MASK		(((1L<<VER_IMPL_SIZE)-1)<<VER_IMPL_SHIFT)
 #define	VER_MASK_MASK		(((1L<<VER_MASK_SIZE)-1)<<VER_MASK_SHIFT)
@@ -61,6 +63,8 @@
 extern int cpu_impl;
 extern char sparc64_model[];
 
+#endif /* !LOCORE */
+
 /* Known implementations. */
 #define	CPU_IMPL_SPARC64		0x01
 #define	CPU_IMPL_ULTRASPARCI		0x10

==== //depot/projects/usiii/sparc64/pci/ofw_pci.h#3 (text+ko) ====

@@ -32,7 +32,7 @@
  */
 
 #ifndef _SPARC64_PCI_OFW_PCI_H_
-#define _SPARC64_PCI_OFW_PCI_H_
+#define	_SPARC64_PCI_OFW_PCI_H_
 
 #include <machine/ofw_bus.h>
 
@@ -40,7 +40,7 @@
 
 /* PCI range child spaces. XXX: are these MI? */
 #define	OFW_PCI_CS_CONFIG	0x00
-#define	OFW_PCI_CS_IO	0x01
+#define	OFW_PCI_CS_IO		0x01
 #define	OFW_PCI_CS_MEM32	0x02
 #define	OFW_PCI_CS_MEM64	0x03
 
@@ -62,4 +62,7 @@
 	(((uint64_t)(r)->size_hi << 32) | (uint64_t)(r)->size_lo)
 #define	OFW_PCI_RANGE_CS(r)	(((r)->cspace >> 24) & 0x03)
 
+/* default values */
+#define	OFW_PCI_LATENCY	64
+
 #endif /* ! _SPARC64_PCI_OFW_PCI_H_ */

==== //depot/projects/usiii/sparc64/pci/ofw_pcibus.c#8 (text+ko) ====

@@ -60,10 +60,10 @@
 #include "pcib_if.h"
 #include "pci_if.h"
 
-/* Helper functions. */
+/* Helper functions */
 static void ofw_pcibus_setup_device(device_t, u_int, u_int, u_int);
 
-/* Methods. */
+/* Methods */
 static device_probe_t ofw_pcibus_probe;
 static device_attach_t ofw_pcibus_attach;
 static pci_assign_interrupt_t ofw_pcibus_assign_interrupt;
@@ -120,48 +120,82 @@
 static void
 ofw_pcibus_setup_device(device_t bridge, u_int busno, u_int slot, u_int func)
 {
+#ifndef SUN4V
 	uint32_t reg;
 
 	/*
-	 * Initialize the latency timer register for busmaster devices to work
-	 * properly. This is another task which the firmware does not always
-	 * perform. The Min_Gnt register can be used to compute it's recommended
-	 * value: it contains the desired latency in units of 1/4 us. To
-	 * calculate the correct latency timer value, the clock frequency of
-	 * the bus (defaulting to 33Mhz) should be used and no wait states
-	 * should be assumed.
+	 * Initialize the latency timer register for busmaster devices to
+	 * work properly.  This is another task which the firmware doesn't
+	 * always perform.  The Min_Gnt register can be used to compute its
+	 * recommended value: it contains the desired latency in units of
+	 * 1/4 us assuming a clock rate of 33MHz.  To calculate the correct
+	 * latency timer value, the clock frequency of the bus (defaulting
+	 * to 33MHz) should be used and no wait states assumed.
 	 */
-	if (OF_getprop(ofw_bus_get_node(bridge), "clock-frequency", &reg,
-	    sizeof(reg)) == -1)
-		reg = 33000000;
-	reg = PCIB_READ_CONFIG(bridge, busno, slot, func, PCIR_MINGNT, 1) *
-	    reg / 1000000 / 4;
-	if (reg != 0) {
+	if ((PCIB_READ_CONFIG(bridge, busno, slot, func, PCIR_HDRTYPE, 1) &
+	    PCIM_HDRTYPE) == PCIM_HDRTYPE_BRIDGE) {
+		reg = PCIB_READ_CONFIG(bridge, busno, slot, func,
+		    PCIR_BRIDGECTL_1, 1);
+		reg |= PCIB_BCR_MASTER_ABORT_MODE | PCIB_BCR_SERR_ENABLE |
+		    PCIB_BCR_PERR_ENABLE;
+#ifdef OFW_PCI_DEBUG
+		device_printf(bridge,
+		    "bridge %d/%d/%d: control 0x%x -> 0x%x\n",
+		    busno, slot, func, PCIB_READ_CONFIG(bridge, busno, slot,
+		    func, PCIR_SECLAT_1, 1), reg);
+#endif /* OFW_PCI_DEBUG */
+		PCIB_WRITE_CONFIG(bridge, busno, slot, func, PCIR_BRIDGECTL_1,
+		    reg, 1);
+
+		reg = OFW_PCI_LATENCY;
+#ifdef OFW_PCI_DEBUG
+		device_printf(bridge,
+		    "bridge %d/%d/%d: latency timer %d -> %d\n",
+		    busno, slot, func, PCIB_READ_CONFIG(bridge, busno, slot,
+		    func, PCIR_SECLAT_1, 1), reg);
+#endif /* OFW_PCI_DEBUG */
+		PCIB_WRITE_CONFIG(bridge, busno, slot, func, PCIR_SECLAT_1,
+		    reg, 1);
+	} else {
+		if (OF_getprop(ofw_bus_get_node(bridge), "clock-frequency",
+		    &reg, sizeof(reg)) == -1)
+			reg = 33000000;
+		switch (reg) {
+		case 33000000:
+			reg = 8;
+			break;
+		case 66000000:
+			reg = 4;
+			break;
+		}
+		reg *= PCIB_READ_CONFIG(bridge, busno, slot, func,
+		    PCIR_MINGNT, 1);
+		if (reg == 0)
+			reg = OFW_PCI_LATENCY;
 #ifdef OFW_PCI_DEBUG
-		device_printf(bridge, "device %d/%d/%d: latency timer %d -> "
-		    "%d\n", busno, slot, func,
-		    PCIB_READ_CONFIG(bridge, busno, slot, func,
-			PCIR_LATTIMER, 1), reg);
+		device_printf(bridge,
+		    "device %d/%d/%d: latency timer %d -> %d\n",
+		    busno, slot, func, PCIB_READ_CONFIG(bridge, busno, slot,
+		    func, PCIR_LATTIMER, 1), reg);
 #endif /* OFW_PCI_DEBUG */
 		PCIB_WRITE_CONFIG(bridge, busno, slot, func,
 		    PCIR_LATTIMER, min(reg, 255), 1);
 	}
 
-#ifndef SUN4V
 	/*
 	 * Compute a value to write into the cache line size register.
 	 * The role of the streaming cache is unclear in write invalidate
-	 * transfers, so it is made sure that it's line size is always reached.
-	 * Generally, the cache line size is fixed at 64 bytes by Fireplane/
-	 * Safari, JBus and UPA.
+	 * transfers, so it is made sure that it's line size is always
+	 * reached.  Generally, the cache line size is fixed at 64 bytes
+	 * by Fireplane/Safari, JBus and UPA.
 	 */
 	PCIB_WRITE_CONFIG(bridge, busno, slot, func, PCIR_CACHELNSZ,
 	    STRBUF_LINESZ / sizeof(uint32_t), 1);
 #endif
 
 	/*
-	 * The preset in the intline register is usually wrong. Reset it to 255,
-	 * so that the PCI code will reroute the interrupt if needed.
+	 * The preset in the intline register is usually wrong. Reset it to
+	 * 255, so that the PCI code will reroute the interrupt if needed.
 	 */
 	PCIB_WRITE_CONFIG(bridge, busno, slot, func, PCIR_INTLINE,
 	    PCI_INVALID_IRQ, 1);
@@ -237,7 +271,8 @@
 	} else if (intr >= 255) {
 		/*
 		 * A fully specified interrupt (including IGN), as present on
-		 * SPARCengine Ultra AX and e450. Extract the INO and return it.
+		 * SPARCengine Ultra AX and e450.  Extract the INO and return
+		 * it.
 		 */
 		return (INTINO(intr));
 #endif
@@ -245,11 +280,12 @@
 	/*
 	 * If we got intr from a property, it may or may not be an intpin.
 	 * For on-board devices, it frequently is not, and is completely out
-	 * of the valid intpin range. For PCI slots, it hopefully is, otherwise
-	 * we will have trouble interfacing with non-OFW buses such as cardbus.
+	 * of the valid intpin range.  For PCI slots, it hopefully is,
+	 * otherwise we will have trouble interfacing with non-OFW buses
+	 * such as cardbus.
 	 * Since we cannot tell which it is without violating layering, we
-	 * will always use the route_interrupt method, and treat exceptions on
-	 * the level they become apparent.
+	 * will always use the route_interrupt method, and treat exceptions
+	 * on the level they become apparent.
 	 */
 	return (PCIB_ROUTE_INTERRUPT(device_get_parent(dev), child, intr));
 }

==== //depot/projects/usiii/sparc64/pci/psycho.c#11 (text+ko) ====

@@ -281,7 +281,6 @@
 		device_set_desc(dev, "U2P UPA-PCI bridge");
 		return (0);
 	}
-
 	return (ENXIO);
 }
 
@@ -331,6 +330,7 @@
 		default:
 			panic("%s: bogus PCI control register location",
 			    __func__);
+			/* NOTREACHED */
 		}
 	} else {
 		rid = 0;
@@ -651,7 +651,7 @@
 	 * firmware.
 	 */
 	PCIB_WRITE_CONFIG(dev, sc->sc_pci_secbus, PCS_DEVICE, PCS_FUNC,
-	    PCIR_LATTIMER, 64, 1);
+	    PCIR_LATTIMER, OFW_PCI_LATENCY, 1);
 
 	for (n = PCIR_VENDOR; n < PCIR_STATUS; n += sizeof(uint16_t))
 		le16enc(&sc->sc_pci_hpbcfg[n], bus_space_read_2(
@@ -966,6 +966,7 @@
 		break;
 	default:
 		panic("%s: bad width", __func__);
+		/* NOTREACHED */
 	}

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list