Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 30 Jun 2009 21:42:27 -0700 (PDT)
From:      Neelkanth Natu <neelnatu@yahoo.com>
To:        freebsd-mips@freebsd.org
Subject:   Machine Check exception during bootup
Message-ID:  <14584.70267.qm@web34403.mail.mud.yahoo.com>

next in thread | raw e-mail | index | archive | help

Hi,

I was seeing machine check exception with the 'TLB Shutdown' bit
set in the Status register during bootup. This would happen about 30% of
the time at exactly the same place in Mips_TLBUpdate().

I was able to track this down to a bug in Mips_TLBFlush() which was
using whatever address happened to be in the EntryHi register to initialize
the TLB. If this address happened to be one that the system would 
subsequently instantiate in the TLB we would hit a machine check exception
in Mips_TLBUpdate().

At first glance it appears that the code in Mips_TLBUpdate() should deal
with this since it does a TLB probe and if the probe is successful it will
do a 'tlbwi' to avoid the machine check. But 'tlbp' can only look at the
'asid' and 'vpn2' fields to do its job - it does not know if you are
planning to install a TLB entry with 'Global' scope. IMO this is why
we trip up on a machine check exception at the 'tlbwr' instruction
in Mips_TLBUpdate().

I am attaching the diff to tlb.S that fixes this problem.

best
Neel

==== //depot/user/neelnatu/freebsd_sibyte/src/sys/mips/mips/tlb.S#1 - /amd/svlusr02.eng.netapp.com/vol/home24/neelnatu/p4/freebsd_sibyte/src/sys/mips/mips/tlb.S ====
@@ -81,14 +81,14 @@
 #define	_MFC0	dmfc0
 #define	_MTC0	dmtc0
 #define WIRED_SHIFT 34
-#define PAGE_SHIFT 34
+#define PAGE_SHIFT 12
 #else
 #define _SLL	sll
 #define	_SRL	srl
 #define	_MFC0	mfc0
 #define	_MTC0	mtc0
 #define WIRED_SHIFT 2
-#define PAGE_SHIFT 2
+#define PAGE_SHIFT 12
 #endif
 	.set	noreorder			# Noreorder is default style!
 #if defined(ISA_MIPS32)
@@ -232,22 +232,30 @@
 	mtc0	zero, COP_0_STATUS_REG		# Disable interrupts
 	ITLBNOPFIX
 	mfc0	t1, COP_0_TLB_WIRED
-	li	v0, MIPS_KSEG3_START + 0x0fff0000 # invalid address
 	_MFC0	t0, COP_0_TLB_HI		# Save the PID
 
-	_MTC0	v0, COP_0_TLB_HI		# Mark entry high as invalid
 	_MTC0	zero, COP_0_TLB_LO0		# Zero out low entry0.
 	_MTC0	zero, COP_0_TLB_LO1		# Zero out low entry1.
 	mtc0	zero, COP_0_TLB_PG_MASK 	# Zero out mask entry.
+
+	#
+	# Load invalid entry, each TLB entry should have it's own bogus 
+	# address calculated by following expression:
+	# MIPS_KSEG0_START + 0x0fff0000 + 2 * i * PAGE_SIZE;
+	# One bogus value for every TLB entry might cause MCHECK exception
+	#
+	sll	t3, t1, PAGE_SHIFT + 1
+	li	v0, MIPS_KSEG0_START + 0x0fff0000	# invalid address
+	addu	v0, t3
 /*
  * Align the starting value (t1) and the upper bound (a0).
  */
 1:
 	mtc0	t1, COP_0_TLB_INDEX		# Set the index register.
 	ITLBNOPFIX
-	_MTC0	t0, COP_0_TLB_HI		# Restore the PID
+	_MTC0	v0, COP_0_TLB_HI		# Mark entry high as invalid
 	addu	t1, t1, 1			# Increment index.
-	addu	t0, t0, 8 * 1024
+	addu	v0, v0, 8 * 1024
 	MIPS_CPU_NOP_DELAY
 	tlbwi					# Write the TLB entry.
 	MIPS_CPU_NOP_DELAY
@@ -473,7 +481,17 @@
 	_MFC0	t4, COP_0_TLB_HI		# Get current PID
 	move	t2, a0
 	mfc0	t1, COP_0_TLB_WIRED
+
+	#
+	# Load invalid entry, each TLB entry should have it's own bogus 
+	# address calculated by following expression:
+	# MIPS_KSEG0_START + 0x0fff0000 + 2 * i * PAGE_SIZE;
+	# One bogus value for every TLB entry might cause MCHECK exception
+	#
+	sll	t3, t1, PAGE_SHIFT + 1
 	li	v0, MIPS_KSEG0_START + 0x0fff0000	# invalid address
+	addu	v0, t3
+
 	mfc0	t3, COP_0_TLB_PG_MASK		# save current pgMask
 
 	# do {} while (t1 < t2)



      



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?14584.70267.qm>