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 - store the maximum [id]cache size ...
details: https://anonhg.NetBSD.org/src/rev/36f69339e658
branches: trunk
changeset: 752283:36f69339e658
user: mrg <mrg%NetBSD.org@localhost>
date: Mon Feb 22 00:16:31 2010 +0000
description:
- store the maximum [id]cache size / line size for each cpu
- remove patch_kernel() since it isn't necessary and has been patching
the wrong thing in general.
- implement USIII versions of blast_icache(), dcache_flush_page() and
cache_flush_phys(). use the newly recorded cache size/line sizes.
- in winfixsave, flush the D$ with the right size index and ops. this
kills one of the wrong tag->inval patches.
- for blast_dcache(), use the newly recorded dcache_size/line_size.
- for blast_icache(), use the newly recorded cache size/line sizes.
for the USIII verison, disable the I$ while writing to ASI_ICACHE_TAG.
these changes removed several hard coded cache sizes values, some very
wrong kernel patching, and seem to make the current failure modes for
USIII less common, but not gone.
diffstat:
sys/arch/sparc64/sparc64/autoconf.c | 64 +-------------
sys/arch/sparc64/sparc64/cache.h | 44 ++++++++-
sys/arch/sparc64/sparc64/cpu.c | 36 +++++--
sys/arch/sparc64/sparc64/locore.s | 166 ++++++++++++++++++++++++-----------
4 files changed, 180 insertions(+), 130 deletions(-)
diffs (truncated from 530 to 300 lines):
diff -r 398058e0b063 -r 36f69339e658 sys/arch/sparc64/sparc64/autoconf.c
--- a/sys/arch/sparc64/sparc64/autoconf.c Sun Feb 21 21:16:09 2010 +0000
+++ b/sys/arch/sparc64/sparc64/autoconf.c Mon Feb 22 00:16:31 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: autoconf.c,v 1.167 2010/02/15 07:56:51 mrg Exp $ */
+/* $NetBSD: autoconf.c,v 1.168 2010/02/22 00:16:31 mrg Exp $ */
/*
* Copyright (c) 1996
@@ -48,7 +48,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.167 2010/02/15 07:56:51 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.168 2010/02/22 00:16:31 mrg Exp $");
#include "opt_ddb.h"
#include "opt_kgdb.h"
@@ -183,7 +183,6 @@
#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);
@@ -335,65 +334,6 @@
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 398058e0b063 -r 36f69339e658 sys/arch/sparc64/sparc64/cache.h
--- a/sys/arch/sparc64/sparc64/cache.h Sun Feb 21 21:16:09 2010 +0000
+++ b/sys/arch/sparc64/sparc64/cache.h Mon Feb 22 00:16:31 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cache.h,v 1.11 2010/02/01 03:43:27 mrg Exp $ */
+/* $NetBSD: cache.h,v 1.12 2010/02/22 00:16:31 mrg Exp $ */
/*
* Copyright (c) 1996
@@ -73,12 +73,46 @@
*/
/* The following are for I$ and D$ flushes and are in locore.s */
-void dcache_flush_page(paddr_t); /* flush page from D$ */
+void dcache_flush_page_us(paddr_t); /* flush page from D$ */
+void dcache_flush_page_usiii(paddr_t); /* flush page from D$ */
void blast_dcache(void); /* Clear entire D$ */
-void blast_icache(void); /* Clear entire I$ */
+void blast_icache_us(void); /* Clear entire I$ */
+void blast_icache_usiii(void); /* Clear entire I$ */
/* The following flush a range from the D$ and I$ but not E$. */
-void cache_flush_phys(paddr_t, psize_t, int);
+void cache_flush_phys_us(paddr_t, psize_t, int);
+void cache_flush_phys_usiii(paddr_t, psize_t, int);
+
+static __inline__ void
+dcache_flush_page(paddr_t pa)
+{
+ if (CPU_IS_USIII_UP())
+ dcache_flush_page_usiii(pa);
+ else
+ dcache_flush_page_us(pa);
+}
-/* Smallest E$ line size. */
+static __inline__ void
+cache_flush_phys(paddr_t pa, psize_t size, int ecache)
+{
+ if (CPU_IS_USIII_UP())
+ cache_flush_phys_usiii(pa, size, ecache);
+ else
+ cache_flush_phys_us(pa, size, ecache);
+}
+
+static __inline__ void
+blast_icache(void)
+{
+ if (CPU_IS_USIII_UP())
+ blast_icache_usiii();
+ else
+ blast_icache_us();
+}
+
+/* Various cache size/line sizes */
extern int ecache_min_line_size;
+extern int dcache_line_size;
+extern int dcache_size;
+extern int icache_line_size;
+extern int icache_size;
diff -r 398058e0b063 -r 36f69339e658 sys/arch/sparc64/sparc64/cpu.c
--- a/sys/arch/sparc64/sparc64/cpu.c Sun Feb 21 21:16:09 2010 +0000
+++ b/sys/arch/sparc64/sparc64/cpu.c Mon Feb 22 00:16:31 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.88 2009/12/02 07:55:01 mrg Exp $ */
+/* $NetBSD: cpu.c,v 1.89 2010/02/22 00:16:31 mrg Exp $ */
/*
* Copyright (c) 1996
@@ -52,7 +52,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.88 2009/12/02 07:55:01 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.89 2010/02/22 00:16:31 mrg Exp $");
#include "opt_multiprocessor.h"
@@ -92,6 +92,12 @@
char cpu_model[100]; /* machine model (primary CPU) */
extern char machine_model[];
+/* These are used in locore.s, and are maximums */
+int dcache_line_size;
+int dcache_size;
+int icache_line_size;
+int icache_size;
+
#ifdef MULTIPROCESSOR
static const char *ipi_evcnt_names[IPI_EVCNT_NUM] = IPI_EVCNT_NAMES;
#endif
@@ -238,7 +244,7 @@
int bigcache, cachesize;
char buf[100];
int totalsize = 0;
- int linesize;
+ int linesize, dcachesize, icachesize;
/* tell them what we have */
node = ma->ma_node;
@@ -295,14 +301,18 @@
bigcache = 0;
- linesize = l =
- prom_getpropint(node, "icache-line-size", 0);
+ icachesize = prom_getpropint(node, "icache-size", 0);
+ if (icachesize > icache_size)
+ icache_size = icachesize;
+ linesize = l = prom_getpropint(node, "icache-line-size", 0);
+ if (linesize > icache_line_size)
+ icache_line_size = linesize;
+
for (i = 0; (1 << i) < l && l; i++)
/* void */;
if ((1 << i) != l && l)
panic("bad icache line size %d", l);
- totalsize =
- prom_getpropint(node, "icache-size", 0) *
+ totalsize = icachesize *
prom_getpropint(node, "icache-associativity", 1);
if (totalsize == 0)
totalsize = l *
@@ -321,14 +331,18 @@
sep = ", ";
}
- linesize = l =
- prom_getpropint(node, "dcache-line-size",0);
+ dcachesize = prom_getpropint(node, "dcache-size", 0);
+ if (dcachesize > dcache_size)
+ dcache_size = dcachesize;
+ linesize = l = prom_getpropint(node, "dcache-line-size", 0);
+ if (linesize > dcache_line_size)
+ dcache_line_size = linesize;
+
for (i = 0; (1 << i) < l && l; i++)
/* void */;
if ((1 << i) != l && l)
panic("bad dcache line size %d", l);
- totalsize =
- prom_getpropint(node, "dcache-size", 0) *
+ totalsize = dcachesize *
prom_getpropint(node, "dcache-associativity", 1);
if (totalsize == 0)
totalsize = l *
diff -r 398058e0b063 -r 36f69339e658 sys/arch/sparc64/sparc64/locore.s
--- a/sys/arch/sparc64/sparc64/locore.s Sun Feb 21 21:16:09 2010 +0000
+++ b/sys/arch/sparc64/sparc64/locore.s Mon Feb 22 00:16:31 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.s,v 1.317 2010/02/15 12:46:24 mrg Exp $ */
+/* $NetBSD: locore.s,v 1.318 2010/02/22 00:16:31 mrg Exp $ */
/*
* Copyright (c) 1996-2002 Eduardo Horvath
@@ -61,7 +61,6 @@
#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 */
@@ -202,20 +201,14 @@
* 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; \
- stxa %g0, [ t ] ASI_DCACHE_TAG_OR_INV; \
+ stxa %g0, [ t ] ASI_DCACHE_TAG; \
membar #Sync
/* The following can be used if the pointer is 16-byte aligned */
#define DLFLUSH2(t) \
- stxa %g0, [ t ] ASI_DCACHE_TAG_OR_INV; \
+ stxa %g0, [ t ] ASI_DCACHE_TAG; \
membar #Sync
#else
#define DLFLUSH(a,t)
@@ -2285,9 +2278,12 @@
/* Did we save a user or kernel window ? */
! srax %g3, 48, %g5 ! User or kernel store? (TAG TARGET)
sllx %g3, (64-13), %g5 ! User or kernel store? (TAG ACCESS)
- sethi %hi((2*NBPG)-8), %g7
+ sethi %hi(dcache_size), %g7
+ ld [%g7 + %lo(dcache_size)], %g7
+ sethi %hi(dcache_line_size), %g6
+ ld [%g6 + %lo(dcache_line_size)], %g6
brnz,pt %g5, 1f ! User fault -- save windows to pcb
- or %g7, %lo((2*NBPG)-8), %g7
+ sub %g7, %g6, %g7
and %g4, CWP, %g4 ! %g4 = %cwp of trap
wrpr %g4, 0, %cwp ! Kernel fault -- restore %cwp and force and trap to debugger
@@ -2316,10 +2312,9 @@
1:
#if 1
/* Now we need to blast away the D$ to make sure we're in sync */
-dlflush1:
stxa %g0, [%g7] ASI_DCACHE_TAG
brnz,pt %g7, 1b
Home |
Main Index |
Thread Index |
Old Index