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>