Module Name:    src
Committed By:   mrg
Date:           Mon Feb 15 07:56:51 UTC 2010

Modified Files:
        src/sys/arch/sparc64/sparc64: autoconf.c locore.s

Log Message:
introduce a new patch_kernel() and call it from the end of bootstrap().
use it to patch up TLB flush instructions that don't match for USI/II
and later.  we can also hopefully use this to make GENERIC.MP minimally
expensive on single CPU machines as well.

this is the last piece needed to get GENERIC/GENERIC.MP to boot on the
USIII* machines.

idea and some initial code from openbsd.


To generate a diff of this commit:
cvs rdiff -u -r1.166 -r1.167 src/sys/arch/sparc64/sparc64/autoconf.c
cvs rdiff -u -r1.313 -r1.314 src/sys/arch/sparc64/sparc64/locore.s

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/sparc64/sparc64/autoconf.c
diff -u src/sys/arch/sparc64/sparc64/autoconf.c:1.166 src/sys/arch/sparc64/sparc64/autoconf.c:1.167
--- src/sys/arch/sparc64/sparc64/autoconf.c:1.166	Thu Jan 21 15:58:32 2010
+++ src/sys/arch/sparc64/sparc64/autoconf.c	Mon Feb 15 07:56:51 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: autoconf.c,v 1.166 2010/01/21 15:58:32 martin Exp $ */
+/*	$NetBSD: autoconf.c,v 1.167 2010/02/15 07:56:51 mrg Exp $ */
 
 /*
  * Copyright (c) 1996
@@ -48,7 +48,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.166 2010/01/21 15:58:32 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.167 2010/02/15 07:56:51 mrg Exp $");
 
 #include "opt_ddb.h"
 #include "opt_kgdb.h"
@@ -183,6 +183,7 @@
 #endif
 
 int console_node, console_instance;
+static void patch_kernel(void);
 struct genfb_colormap_callback gfb_cb;
 static void of_set_palette(void *, int, int, int, int);
 static void copyprops(struct device *busdev, int, prop_dictionary_t);
@@ -334,6 +335,65 @@
 
 	get_ncpus();
 	pmap_bootstrap(KERNBASE, bi_kend->addr);
+
+	patch_kernel();
+}
+
+/*
+ * Now that we've stopped using the prom mappings, we need to handle any
+ * text fixups.
+ *
+ * For the USIII and newer cpus, convert ASI_DCACHE_TAG into
+ * ASI_DCACHE_INVALIDATE.
+ *
+ * For the older CPUs, we need to convert a branch to a nop in
+ * cache_flush_phys().
+ */
+static void
+patch_kernel(void)
+{
+	paddr_t pa;
+	vaddr_t *pva;
+
+	if (CPU_IS_USIII_UP()) {
+		extern vaddr_t dlflush_start;
+		uint32_t insn, oinsn;
+
+		for (pva = &dlflush_start; *pva; pva++) {
+			oinsn = insn = *(uint32_t *)(*pva);
+			insn &= ~(ASI_DCACHE_TAG << 5);
+			insn |= (ASI_DCACHE_INVALIDATE << 5);
+
+			if (pmap_extract(pmap_kernel(), *pva, &pa)) {
+				sta(pa, ASI_PHYS_CACHED, insn);
+				flush((void *)(*pva));
+#ifdef PATCH_KERNEL_DEBUG
+				printf("patched %p for USIII ASI_DCACHE_INVALIDATE"
+				       ": old insn %08x ew insn %08x\n",
+				    (void *)(intptr_t)*pva, oinsn, insn);
+			} else {
+				printf("could not pmap_extract() to patch %p\n",
+				    (void *)(intptr_t)*pva);
+#endif
+			}
+		}
+	} else {
+		extern vaddr_t nop_on_us_1_start;
+
+		for (pva = &nop_on_us_1_start; *pva; pva++) {
+			if (pmap_extract(pmap_kernel(), *pva, &pa)) {
+				sta(pa, ASI_PHYS_CACHED, 0x01000000);
+				flush((void *)(*pva));
+#ifdef PATCH_KERNEL_DEBUG
+				printf("patched %p for USI/II cache_flush_phys\n",
+				    (void *)(intptr_t)*pva);
+			} else {
+				printf("could not pmap_extract() to patch %p\n",
+				    (void *)(intptr_t)*pva);
+#endif
+			}
+		}
+	}
 }
 
 /*

Index: src/sys/arch/sparc64/sparc64/locore.s
diff -u src/sys/arch/sparc64/sparc64/locore.s:1.313 src/sys/arch/sparc64/sparc64/locore.s:1.314
--- src/sys/arch/sparc64/sparc64/locore.s:1.313	Sat Feb 13 22:29:55 2010
+++ src/sys/arch/sparc64/sparc64/locore.s	Mon Feb 15 07:56:51 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: locore.s,v 1.313 2010/02/13 22:29:55 mrg Exp $	*/
+/*	$NetBSD: locore.s,v 1.314 2010/02/15 07:56:51 mrg Exp $	*/
 
 /*
  * Copyright (c) 1996-2002 Eduardo Horvath
@@ -55,15 +55,13 @@
  *	@(#)locore.s	8.4 (Berkeley) 12/10/93
  */
 
-#ifndef CHEETAH
-#define	SPITFIRE
-#endif
 #undef	PARANOID		/* Extremely expensive consistency checks */
 #undef	NO_VCACHE		/* Map w/D$ disabled */
 #undef	TRAPSTATS		/* Count traps */
 #undef	TRAPS_USE_IG		/* Use Interrupt Globals for all traps */
 #define	HWREF			/* Track ref/mod bits in trap handlers */
 #undef	DCACHE_BUG		/* Flush D$ around ASI_PHYS accesses */
+#undef	SPITFIRE		/* Only used in DLFLUSH* now, see DCACHE_BUG */
 #undef	NO_TSB			/* Don't use TSB */
 #define	USE_BLOCK_STORE_LOAD	/* enable block load/store ops */
 #define	BB_ERRATA_1		/* writes to TICK_CMPR may fail */
@@ -195,12 +193,6 @@
 /* Give this real authority: reset the machine */
 #define NOTREACHED	sir
 
-#ifdef SPITFIRE
-#define ASI_DCACHE_TAG_OR_INV	ASI_DCACHE_TAG
-#else
-#define ASI_DCACHE_TAG_OR_INV	ASI_DCACHE_INVALIDATE
-#endif
-
 /*
  * This macro will clear out a cache line before an explicit
  * access to that location.  It's mostly used to make certain
@@ -209,6 +201,12 @@
  * It uses a register with the address to clear and a temporary
  * which is destroyed.
  */
+#ifdef SPITFIRE
+#define ASI_DCACHE_TAG_OR_INV	ASI_DCACHE_TAG
+#else
+#define ASI_DCACHE_TAG_OR_INV	ASI_DCACHE_INVALIDATE
+#endif
+
 #ifdef DCACHE_BUG
 #define DLFLUSH(a,t) \
 	andn	a, 0x1f, t; \
@@ -2317,7 +2315,8 @@
 1:
 #if 1
 	/* Now we need to blast away the D$ to make sure we're in sync */
-	stxa	%g0, [%g7] ASI_DCACHE_TAG_OR_INV
+dlflush1:
+	stxa	%g0, [%g7] ASI_DCACHE_TAG
 	brnz,pt	%g7, 1b
 	 dec	8, %g7
 #endif
@@ -5313,7 +5312,8 @@
 	andn	%o3, PSTATE_IE, %o4			! Turn off PSTATE_IE bit
 	wrpr	%o4, 0, %pstate
 1:
-	stxa	%g0, [%o1] ASI_DCACHE_TAG_OR_INV
+dlflush2:
+	stxa	%g0, [%o1] ASI_DCACHE_TAG
 	brnz,pt	%o1, 1b
 	 dec	32, %o1
 	sethi	%hi(KERNBASE), %o2
@@ -5386,7 +5386,8 @@
 	bne,pt	%xcc, 1b
 	 membar	#LoadStore
 
-	stxa	%g0, [%o0] ASI_DCACHE_TAG_OR_INV
+dlflush3:
+	stxa	%g0, [%o0] ASI_DCACHE_TAG
 	ba,pt	%icc, 1b
 	 membar	#StoreLoad
 2:
@@ -5444,9 +5445,13 @@
 	 nop
 
 	membar	#LoadStore
-	stxa	%g0, [%o4] ASI_DCACHE_TAG_OR_INV ! Just right
+dlflush4:
+	stxa	%g0, [%o4] ASI_DCACHE_TAG ! Just right
+	membar	#Sync
 2:
-#ifdef SPITFIRE
+nop_on_us_1:
+	b	3f
+	 nop					! XXXMRG put something useful here?
 	ldda	[%o4] ASI_ICACHE_TAG, %g0	! Tag goes in %g1
 	sllx	%g1, 40-35, %g1			! Shift I$ tag into place
 	and	%g1, %o2, %g1			! Mask out trash
@@ -5457,7 +5462,6 @@
 	 nop
 	stxa	%g0, [%o4] ASI_ICACHE_TAG
 3:
-#endif
 	membar	#StoreLoad
 	dec	32, %o5
 	brgz,pt	%o5, 1b
@@ -9702,3 +9706,16 @@
 	.comm	_C_LABEL(trapdebug), 4
 	.comm	_C_LABEL(pmapdebug), 4
 #endif
+
+	.globl  _C_LABEL(dlflush_start)
+_C_LABEL(dlflush_start):
+	.xword	dlflush1
+	.xword	dlflush2
+	.xword	dlflush3
+	.xword	dlflush4
+	.xword	0
+
+	.globl  _C_LABEL(nop_on_us_1_start)
+_C_LABEL(nop_on_us_1_start):
+	.xword	nop_on_us_1
+	.xword	0

Reply via email to