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