Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/sparc64/sparc64 introduce a new patch_kernel() and ...
details: https://anonhg.NetBSD.org/src/rev/c05b4f9d6f42
branches: trunk
changeset: 752106:c05b4f9d6f42
user: mrg <mrg%NetBSD.org@localhost>
date: Mon Feb 15 07:56:51 2010 +0000
description:
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.
diffstat:
sys/arch/sparc64/sparc64/autoconf.c | 64 +++++++++++++++++++++++++++++++++++-
sys/arch/sparc64/sparc64/locore.s | 49 +++++++++++++++++++---------
2 files changed, 95 insertions(+), 18 deletions(-)
diffs (215 lines):
diff -r a92c12045d2f -r c05b4f9d6f42 sys/arch/sparc64/sparc64/autoconf.c
--- a/sys/arch/sparc64/sparc64/autoconf.c Mon Feb 15 07:55:33 2010 +0000
+++ b/sys/arch/sparc64/sparc64/autoconf.c Mon Feb 15 07:56:51 2010 +0000
@@ -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
+ }
+ }
+ }
}
/*
diff -r a92c12045d2f -r c05b4f9d6f42 sys/arch/sparc64/sparc64/locore.s
--- a/sys/arch/sparc64/sparc64/locore.s Mon Feb 15 07:55:33 2010 +0000
+++ b/sys/arch/sparc64/sparc64/locore.s Mon Feb 15 07:56:51 2010 +0000
@@ -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
Home |
Main Index |
Thread Index |
Old Index