changeset 303:afee673770bf

6253548 Backout Niagara workarounds 6301419 occasionally an idle CPU may suspend while there are runnable threads 6300289 Niagara virtual address space not fully utilizable
author girish
date Fri, 05 Aug 2005 13:40:45 -0700
parents b21b2a25a939
children 80feb3217668
files usr/src/uts/sun4v/Makefile.workarounds usr/src/uts/sun4v/cpu/niagara.c usr/src/uts/sun4v/cpu/niagara_asm.s usr/src/uts/sun4v/ml/hcall.s usr/src/uts/sun4v/ml/trap_table.s usr/src/uts/sun4v/os/mach_startup.c
diffstat 6 files changed, 49 insertions(+), 95 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/sun4v/Makefile.workarounds	Fri Aug 05 10:09:00 2005 -0700
+++ b/usr/src/uts/sun4v/Makefile.workarounds	Fri Aug 05 13:40:45 2005 -0700
@@ -34,5 +34,4 @@
 
 WORKAROUND_DEFS =
 WORKAROUND_DEFS	+= -DQCN_POLLING		# XXXQ
-WORKAROUND_DEFS	+= -DNIAGARA_ERRATUM_39		# XXXQ
-WORKAROUND_DEFS	+= -DNIAGARA_ERRATUM_42		# XXXQ
+WORKAROUND_DEFS	+= -DNIAGARA_CHK_VERSION	# XXXQ
--- a/usr/src/uts/sun4v/cpu/niagara.c	Fri Aug 05 10:09:00 2005 -0700
+++ b/usr/src/uts/sun4v/cpu/niagara.c	Fri Aug 05 13:40:45 2005 -0700
@@ -65,8 +65,7 @@
 
 uint_t root_phys_addr_lo_mask = 0xffffffffU;
 
-#ifdef NIAGARA_ERRATUM_39
-extern int	niagara_erratum_39;
+#ifdef NIAGARA_CHK_VERSION
 static uint64_t	cpu_ver;			/* Niagara CPU version reg */
 
 /* Niagara CPU version register */
@@ -77,7 +76,7 @@
 extern uint64_t	ni_getver();			/* HV code to get %hver */
 extern uint64_t	niagara_getver(uint64_t ni_getver_ra, uint64_t *cpu_version);
 
-#endif	/* NIAGARA_ERRATUM_39 */
+#endif	/* NIAGARA_CHK_VERSION */
 
 void
 cpu_setup(void)
@@ -88,19 +87,7 @@
 	extern int get_cpu_pagesizes(void);
 	extern int cpc_has_overflow_intr;
 
-#ifdef NIAGARA_ERRATUM_39
-	/*
-	 * Get CPU version and enable Niagara erratum 39 workaround only
-	 * on Niagara 1.x part. This workaround can also be enabled via
-	 * /etc/system.
-	 */
-	if (niagara_getver(va_to_pa((void *)ni_getver), &cpu_ver) == H_EOK &&
-	    ((cpu_ver >> VER_MASK_MAJOR_SHIFT) & VER_MASK_MAJOR_MASK) <= 1)
-		niagara_erratum_39 = 1;
-#endif
 	cache |= (CACHE_PTAG | CACHE_IOCOHERENT);
-
-	/* XXXQ */
 	at_flags = EF_SPARC_SUN_US3 | EF_SPARC_32PLUS | EF_SPARC_SUN_US1;
 
 	/*
@@ -147,16 +134,18 @@
 	cpu_hwcap_flags |= AV_SPARC_ASI_BLK_INIT;
 
 	/*
-	 * On Spitfire, there's a hole in the address space
-	 * that we must never map (the hardware only support 44-bits of
-	 * virtual address).  Later CPUs are expected to have wider
-	 * supported address ranges.
+	 * Niagara supports a 48-bit subset of the full 64-bit virtual
+	 * address space. Virtual addresses between 0x0000800000000000
+	 * and 0xffff.7fff.ffff.ffff inclusive lie within a "VA Hole"
+	 * and must never be mapped. In addition, software must not use
+	 * pages within 4GB of the VA hole as instruction pages to
+	 * avoid problems with prefetching into the VA hole.
 	 *
-	 * See address map on p23 of the UltraSPARC 1 user's manual.
+	 * VA hole information should be obtained from the machine
+	 * description.
 	 */
-/* XXXQ get from machine description */
-	hole_start = (caddr_t)0x80000000000ull;
-	hole_end = (caddr_t)0xfffff80000000000ull;
+	hole_start = (caddr_t)(0x800000000000ul - (1ul << 32));
+	hole_end = (caddr_t)(0xffff800000000000ul + (1ul << 32));
 
 	/*
 	 * The kpm mapping window.
@@ -238,6 +227,20 @@
 {
 	extern int niagara_kstat_init(void);
 
+#ifdef NIAGARA_CHK_VERSION
+	/*
+	 * Prevent booting on a Niagara 1.x processor as it is no longer
+	 * supported.
+	 *
+	 * This is a temporary hack until everyone has switched to the
+	 * firmware which prevents booting on a Niagara 1.x processor.
+	 */
+	if (niagara_getver(va_to_pa((void *)ni_getver), &cpu_ver) == H_EOK &&
+	    ((cpu_ver >> VER_MASK_MAJOR_SHIFT) & VER_MASK_MAJOR_MASK) <= 1)
+		cmn_err(CE_PANIC, "CPU%d: Niagara 1.x no longer supported.",
+		    cp->cpu_id);
+#endif	/* NIAGARA_CHK_VERSION */
+
 	/*
 	 * This code change assumes that the virtual cpu ids are identical
 	 * to the physical cpu ids which is true for ontario but not for
--- a/usr/src/uts/sun4v/cpu/niagara_asm.s	Fri Aug 05 10:09:00 2005 -0700
+++ b/usr/src/uts/sun4v/cpu/niagara_asm.s	Fri Aug 05 13:40:45 2005 -0700
@@ -144,7 +144,7 @@
 	SET_SIZE(cpu_inv_tsb)
 #endif /* lint */
 
-#ifdef NIAGARA_ERRATUM_39
+#ifdef NIAGARA_CHK_VERSION
 
 /*
  * This workaround will be removed prior to the FCS release.
@@ -201,4 +201,4 @@
 
 #endif	/* lint */
 
-#endif NIAGARA_ERRATUM_39
+#endif /* NIAGARA_CHK_VERSION */
--- a/usr/src/uts/sun4v/ml/hcall.s	Fri Aug 05 10:09:00 2005 -0700
+++ b/usr/src/uts/sun4v/ml/hcall.s	Fri Aug 05 13:40:45 2005 -0700
@@ -1085,32 +1085,6 @@
 	 * hv_cpu_yield(void)
 	 */
 	ENTRY(hv_cpu_yield)
-#ifdef NIAGARA_ERRATUM_39
-	/*
-	 * If niagara_erratum_39 is set, then we need to halt the strand by
-	 * executing a synthetic "halt" instruction which maps to a
-	 * wrasr %asr26 with a data value which has bit 0 clear.
-	 *
-	 * Note that we don't halt the strand if there are any pending
-	 * soft interrupts (%asr22).
-	 */
-	set	niagara_erratum_39, %o0
-	ld	[%o0], %o1
-	brz	%o1, 2f
-	nop
-
-	rd	%asr26, %o0
-	andn	%o0, 1, %o0
-	rd	%asr22, %o1		! don't halt if soft interrupts pending
-	brnz	%o1, 1f
-	nop
-	wr	%o0, %asr26		! halt the strand
-1:
-	mov	%g0, %o0
-	retl
-	nop
-2:
-#endif /* NIAGARA_ERRATUM_39 */
 	mov	HV_CPU_YIELD, %o5
 	ta	FAST_TRAP
 	retl
@@ -1325,13 +1299,4 @@
 	retl
 	nop
 	SET_SIZE(hv_ncs_request)
-
-#ifdef NIAGARA_ERRATUM_39
-	.seg	".data"
-	.align	4
-	.global	niagara_erratum_39
-niagara_erratum_39:
-	.word	0
-	.seg	".text"
-#endif
 #endif	/* lint || __lint */
--- a/usr/src/uts/sun4v/ml/trap_table.s	Fri Aug 05 10:09:00 2005 -0700
+++ b/usr/src/uts/sun4v/ml/trap_table.s	Fri Aug 05 13:40:45 2005 -0700
@@ -111,21 +111,6 @@
 
 #endif
 
-#ifdef NIAGARA_ERRATUM_42
-
-#define	NI_GL_RESET_TT0	\
-	wrpr	%g0, 2, %gl			;\
-	wrpr	%g0, 1, %gl
-
-#define	NI_GL_RESET_TT0_INS	2
-
-#else /* NIAGARA_ERRATUM_42 */
-
-#define	NI_GL_RESET_TT0
-#define	NI_GL_RESET_TT0_INS	0
-
-#endif /* NIAGARA_ERRATUM_42 */
-
 /*
  * This macro is used to update per cpu mmu stats in perf critical
  * paths. It is only enabled in debug kernels or if SFMMU_STAT_GATHER
@@ -319,7 +304,6 @@
  * though this code only needs it to be four-byte aligned.
  */
 #define	SPILL_32bit(tail)					\
-	NI_GL_RESET_TT0						;\
 	srl	%sp, 0, %sp					;\
 1:	st	%l0, [%sp + 0]					;\
 	st	%l1, [%sp + 4]					;\
@@ -340,7 +324,7 @@
 	TT_TRACE_L(trace_win)					;\
 	saved							;\
 	retry							;\
-	SKIP(31-19-NI_GL_RESET_TT0_INS-TT_TRACE_L_INS)		;\
+	SKIP(31-19-TT_TRACE_L_INS)				;\
 	ba,a,pt	%xcc, fault_32bit_/**/tail			;\
 	.empty
 
@@ -352,7 +336,6 @@
  * aligned.
  */
 #define	SPILL_32bit_asi(asi_num, tail)				\
-	NI_GL_RESET_TT0						;\
 	srl	%sp, 0, %sp					;\
 1:	sta	%l0, [%sp + %g0]asi_num				;\
 	mov	4, %g1						;\
@@ -379,7 +362,7 @@
 	TT_TRACE_L(trace_win)					;\
 	saved							;\
 	retry							;\
-	SKIP(31-25-NI_GL_RESET_TT0_INS-TT_TRACE_L_INS)		;\
+	SKIP(31-25-TT_TRACE_L_INS)				;\
 	ba,a,pt %xcc, fault_32bit_/**/tail			;\
 	.empty
 
@@ -465,7 +448,6 @@
  * same.  The stack pointer is required to be eight-byte aligned.
  */
 #define	SPILL_64bit(tail)					\
-	NI_GL_RESET_TT0						;\
 2:	stx	%l0, [%sp + V9BIAS64 + 0]			;\
 	stx	%l1, [%sp + V9BIAS64 + 8]			;\
 	stx	%l2, [%sp + V9BIAS64 + 16]			;\
@@ -485,7 +467,7 @@
 	TT_TRACE_L(trace_win)					;\
 	saved							;\
 	retry							;\
-	SKIP(31-18-NI_GL_RESET_TT0_INS-TT_TRACE_L_INS)		;\
+	SKIP(31-18-TT_TRACE_L_INS)				;\
 	ba,a,pt	%xcc, fault_64bit_/**/tail			;\
 	.empty
 
@@ -509,7 +491,6 @@
  * aligned.
  */
 #define	SPILL_64bit_asi(asi_num, tail)				\
-	NI_GL_RESET_TT0						;\
 	mov	0 + V9BIAS64, %g1				;\
 2:	stxa	%l0, [%sp + %g1]asi_num				;\
 	mov	8 + V9BIAS64, %g2				;\
@@ -536,7 +517,7 @@
 	TT_TRACE_L(trace_win)					;\
 	saved							;\
 	retry							;\
-	SKIP(31-25-NI_GL_RESET_TT0_INS-TT_TRACE_L_INS)		;\
+	SKIP(31-25-TT_TRACE_L_INS)				;\
 	ba,a,pt %xcc, fault_64bit_/**/tail			;\
 	.empty
 
@@ -623,7 +604,6 @@
  * We won't need to clear them in 64 bit kernel.
  */
 #define	SPILL_mixed						\
-	NI_GL_RESET_TT0						;\
 	btst	1, %sp						;\
 	bz,a,pt	%xcc, 1b					;\
 	srl	%sp, 0, %sp					;\
@@ -668,7 +648,6 @@
  * window that didn't get a cleanwin trap.
  */
 #define	SPILL_32clean(asi_num, tail)				\
-	NI_GL_RESET_TT0						;\
 	srl	%sp, 0, %sp					;\
 	sta	%l0, [%sp + %g0]asi_num				;\
 	mov	4, %g1						;\
@@ -695,12 +674,11 @@
 	TT_TRACE_L(trace_win)					;\
 	b	.spill_clean					;\
 	  mov	WSTATE_USER32, %g7				;\
-	SKIP(31-25-NI_GL_RESET_TT0_INS-TT_TRACE_L_INS)		;\
+	SKIP(31-25-TT_TRACE_L_INS)				;\
 	ba,a,pt	%xcc, fault_32bit_/**/tail			;\
 	.empty
 
 #define	SPILL_64clean(asi_num, tail)				\
-	NI_GL_RESET_TT0						;\
 	mov	0 + V9BIAS64, %g1				;\
 	stxa	%l0, [%sp + %g1]asi_num				;\
 	mov	8 + V9BIAS64, %g2				;\
@@ -727,7 +705,7 @@
 	TT_TRACE_L(trace_win)					;\
 	b	.spill_clean					;\
 	  mov	WSTATE_USER64, %g7				;\
-	SKIP(31-25-NI_GL_RESET_TT0_INS-TT_TRACE_L_INS)		;\
+	SKIP(31-25-TT_TRACE_L_INS)				;\
 	ba,a,pt	%xcc, fault_64bit_/**/tail			;\
 	.empty
 
@@ -745,14 +723,12 @@
  * Floating point exceptions.
  */
 #define	FP_IEEE_TRAP			\
-	NI_GL_RESET_TT0			;\
 	TT_TRACE(trace_gen)		;\
 	ba,pt	%xcc,.fp_ieee_exception	;\
 	nop				;\
 	.align	32
 
 #define	FP_TRAP				\
-	NI_GL_RESET_TT0			;\
 	TT_TRACE(trace_gen)		;\
 	ba,pt	%xcc,.fp_exception	;\
 	nop				;\
--- a/usr/src/uts/sun4v/os/mach_startup.c	Fri Aug 05 10:09:00 2005 -0700
+++ b/usr/src/uts/sun4v/os/mach_startup.c	Fri Aug 05 13:40:45 2005 -0700
@@ -101,9 +101,16 @@
 
 	/*
 	 * Add ourselves to the partition's halted CPUs bitmask
-	 * if necessary.
+	 * and set our HALTED flag, if necessary.
+	 *
+	 * Note that the memory barrier after updating the HALTED flag
+	 * is needed to ensure that the HALTED flag has reached global
+	 * visibility before scanning the run queue for the last time
+	 * (via disp_anywork) and halting ourself.
 	 */
 	if (hset_update) {
+		cpup->cpu_disp_flags |= CPU_DISP_HALTED;
+		membar_producer();
 		cp = cpup->cpu_part;
 		CPUSET_ATOMIC_ADD(cp->cp_haltset, cpun);
 	}
@@ -116,8 +123,10 @@
 	 * ...which will pop us right back out of the halted state.
 	 */
 	if (disp_anywork()) {
-		if (hset_update)
+		if (hset_update) {
+			cpup->cpu_disp_flags &= ~CPU_DISP_HALTED;
 			CPUSET_ATOMIC_DEL(cp->cp_haltset, cpun);
+		}
 		enable_vec_intr(s);
 		return;
 	}
@@ -131,8 +140,10 @@
 	 * We're no longer halted
 	 */
 	enable_vec_intr(s);
-	if (hset_update)
+	if (hset_update) {
+		cpup->cpu_disp_flags &= ~CPU_DISP_HALTED;
 		CPUSET_ATOMIC_DEL(cp->cp_haltset, cpun);
+	}
 }
 
 /*