patch-2.4.22 linux-2.4.22/arch/ppc/kernel/head_8xx.S

Next file: linux-2.4.22/arch/ppc/kernel/i8259.c
Previous file: linux-2.4.22/arch/ppc/kernel/head_4xx.S
Back to the patch index
Back to the overall index

diff -urN linux-2.4.21/arch/ppc/kernel/head_8xx.S linux-2.4.22/arch/ppc/kernel/head_8xx.S
@@ -1,7 +1,7 @@
 /*
  *  arch/ppc/kernel/except_8xx.S
  *
- *  PowerPC version 
+ *  PowerPC version
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
  *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
@@ -74,6 +74,20 @@
  * I used to use SPRG2 for a temporary register in the TLB handler, but it
  * has since been put to other uses.  I now use a hack to save a register
  * and the CCR at memory location 0.....Someday I'll fix this.....
+ *
+ * With regard to resetting the CPM. The UART console has a number of subtle
+ * assumptions built around the initialization to support kgdb/xmon debugging.
+ * The quick answer is we don't want to reset the CPM so we can proper support
+ * this debugging.
+ *
+ * When the kernel is first booted, kgdb/xmon use the CPM as it was set up by
+ * the boot rom.  There is a second initialization of the UART driver, but
+ * before the console is initialized.  This changes the BDs, but the UART
+ * still operates for kgdb/xmon.  The final stage initialization occurs when
+ * the console is initialized, and all of the "normal path" debugging and
+ * messages can occur after this point.  So the only time we want to do a CPM
+ * is in the case of a microcode patch.
+ *
  *	-- Dan
  */
 
@@ -470,7 +484,16 @@
 #endif
 	rfi
 
-2:	mfspr	r20, M_TW	/* Restore registers */
+2:
+	/* Copy 20 msb from MD_EPN to DAR since the dcxx instructions fail
+	 * to update DAR when they cause a DTLB miss.
+	 */
+	mfspr	r21, MD_EPN
+	mfspr	r20, DAR
+	rlwimi	r20, r21, 0, 0, 19
+	mtspr	DAR, r20
+
+	mfspr	r20, M_TW	/* Restore registers */
 	lwz	r21, 0(r0)
 	mtcr	r21
 	lwz	r21, 4(r0)
@@ -514,20 +537,20 @@
 	andis.	r21, r20, 0x0200	/* If set, indicates store op */
 	beq	2f
 
-	/* The EA of a data TLB miss is automatically stored in the MD_EPN 
-	 * register.  The EA of a data TLB error is automatically stored in 
-	 * the DAR, but not the MD_EPN register.  We must copy the 20 most 
-	 * significant bits of the EA from the DAR to MD_EPN before we 
-	 * start walking the page tables.  We also need to copy the CASID 
+	/* The EA of a data TLB miss is automatically stored in the MD_EPN
+	 * register.  The EA of a data TLB error is automatically stored in
+	 * the DAR, but not the MD_EPN register.  We must copy the 20 most
+	 * significant bits of the EA from the DAR to MD_EPN before we
+	 * start walking the page tables.  We also need to copy the CASID
 	 * value from the M_CASID register.
-	 * Addendum:  The EA of a data TLB error is _supposed_ to be stored 
-	 * in DAR, but it seems that this doesn't happen in some cases, such 
-	 * as when the error is due to a dcbi instruction to a page with a 
-	 * TLB that doesn't have the changed bit set.  In such cases, there 
-	 * does not appear to be any way  to recover the EA of the error 
-	 * since it is neither in DAR nor MD_EPN.  As a workaround, the 
-	 * _PAGE_HWWRITE bit is set for all kernel data pages when the PTEs 
-	 * are initialized in mapin_ram().  This will avoid the problem, 
+	 * Addendum:  The EA of a data TLB error is _supposed_ to be stored
+	 * in DAR, but it seems that this doesn't happen in some cases, such
+	 * as when the error is due to a dcbi instruction to a page with a
+	 * TLB that doesn't have the changed bit set.  In such cases, there
+	 * does not appear to be any way  to recover the EA of the error
+	 * since it is neither in DAR nor MD_EPN.  As a workaround, the
+	 * _PAGE_HWWRITE bit is set for all kernel data pages when the PTEs
+	 * are initialized in mapin_ram().  This will avoid the problem,
 	 * assuming we only use the dcbi instruction on kernel addresses.
 	 */
 	mfspr	r20, DAR

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)