
From: Matt Porter <mporter@kernel.crashing.org>

Adds general Book E machine check exception support and PPC44x-specific
machine check exception implementation.


---

 25-akpm/arch/ppc/kernel/entry.S     |   85 +++++++++++++++
 25-akpm/arch/ppc/kernel/head_44x.S  |  197 +++++++++++++++++++++++++++---------
 25-akpm/arch/ppc/kernel/traps.c     |   31 +++++
 25-akpm/include/asm-ppc/ppc_asm.h   |    2 
 25-akpm/include/asm-ppc/reg_booke.h |   16 ++
 5 files changed, 283 insertions(+), 48 deletions(-)

diff -puN arch/ppc/kernel/entry.S~ppc32-add-book-e--ppc44x-specific-exception-support-2 arch/ppc/kernel/entry.S
--- 25/arch/ppc/kernel/entry.S~ppc32-add-book-e--ppc44x-specific-exception-support-2	2004-05-11 00:52:22.740762880 -0700
+++ 25-akpm/arch/ppc/kernel/entry.S	2004-05-11 00:52:22.750761360 -0700
@@ -56,6 +56,19 @@
 #define BOOKE_SAVE_COR
 #endif
 
+#ifdef CONFIG_BOOKE
+	.globl	mcheck_transfer_to_handler
+mcheck_transfer_to_handler:
+	mtspr	SPRG6W,r8
+	lis	r8,mcheck_save@ha
+	lwz	r0,mcheck_r10@l(r8)
+	stw	r0,GPR10(r11)
+	lwz	r0,mcheck_r11@l(r8)
+	stw	r0,GPR11(r11)
+	mfspr	r8,SPRG6R
+	b	transfer_to_handler_full
+#endif
+
 #if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
 	.globl	crit_transfer_to_handler
 crit_transfer_to_handler:
@@ -97,7 +110,7 @@ transfer_to_handler:
 	beq	2f			/* if from user, fix up THREAD.regs */
 	addi	r11,r1,STACK_FRAME_OVERHEAD
 	stw	r11,PT_REGS(r12)
-#ifdef CONFIG_4xx
+#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
 	lwz	r12,PTRACE-THREAD(r12)
 	andi.	r12,r12,PT_PTRACED
 	beq+	3f
@@ -738,8 +751,10 @@ ret_from_crit_exc:
 	mtspr	SPRN_SPRG4,r10
 	lwz	r10,crit_sprg5@l(COR)
 	mtspr	SPRN_SPRG5,r10
+#ifdef CONFIG_40x
 	lwz	r10,crit_sprg6@l(COR)
 	mtspr	SPRN_SPRG6,r10
+#endif
 	lwz	r10,crit_sprg7@l(COR)
 	mtspr	SPRN_SPRG7,r10
 	lwz	r10,crit_srr0@l(COR)
@@ -756,6 +771,74 @@ ret_from_crit_exc:
 	rfci
 	b	.		/* prevent prefetch past rfci */
 
+#ifdef CONFIG_BOOKE
+/*
+ * Return from a machine check interrupt, similar to a critical
+ * interrupt.
+ */
+	.globl	ret_from_mcheck_exc
+ret_from_mcheck_exc:
+	REST_NVGPRS(r1)
+	lwz	r3,_MSR(r1)
+	andi.	r3,r3,MSR_PR
+	LOAD_MSR_KERNEL(r10,MSR_KERNEL)
+	bne	user_exc_return
+
+	lwz	r0,GPR0(r1)
+	lwz	r2,GPR2(r1)
+	REST_4GPRS(3, r1)
+	REST_2GPRS(7, r1)
+
+	lwz	r10,_XER(r1)
+	lwz	r11,_CTR(r1)
+	mtspr	XER,r10
+	mtctr	r11
+
+	stwcx.	r0,0,r1			/* to clear the reservation */
+
+	lwz	r11,_LINK(r1)
+	mtlr	r11
+	lwz	r10,_CCR(r1)
+	mtcrf	0xff,r10
+	lwz	r9,_DEAR(r1)
+	lwz	r10,_ESR(r1)
+	mtspr	SPRN_DEAR,r9
+	mtspr	SPRN_ESR,r10
+	lwz	r11,_NIP(r1)
+	lwz	r12,_MSR(r1)
+	mtspr	MCSRR0,r11
+	mtspr	MCSRR1,r12
+	lwz	r9,GPR9(r1)
+	lwz	r12,GPR12(r1)
+	mtspr	SPRG6W,r8
+	lis	r8,mcheck_save@ha
+	lwz	r10,mcheck_sprg0@l(r8)
+	mtspr	SPRN_SPRG0,r10
+	lwz	r10,mcheck_sprg1@l(r8)
+	mtspr	SPRN_SPRG1,r10
+	lwz	r10,mcheck_sprg4@l(r8)
+	mtspr	SPRN_SPRG4,r10
+	lwz	r10,mcheck_sprg5@l(r8)
+	mtspr	SPRN_SPRG5,r10
+	lwz	r10,mcheck_sprg7@l(r8)
+	mtspr	SPRN_SPRG7,r10
+	lwz	r10,mcheck_srr0@l(r8)
+	mtspr	SRR0,r10
+	lwz	r10,mcheck_srr1@l(r8)
+	mtspr	SRR1,r10
+	lwz	r10,mcheck_csrr0@l(r8)
+	mtspr	CSRR0,r10
+	lwz	r10,mcheck_csrr1@l(r8)
+	mtspr	CSRR1,r10
+	lwz	r10,mcheck_pid@l(r8)
+	mtspr	SPRN_PID,r10
+	lwz	r10,GPR10(r1)
+	lwz	r11,GPR11(r1)
+	lwz	r1,GPR1(r1)
+	mfspr	r8,SPRG6R
+	RFMCI
+#endif /* CONFIG_BOOKE */
+
 /*
  * Load the DBCR0 value for a task that is being ptraced,
  * having first saved away the global DBCR0.
diff -puN arch/ppc/kernel/head_44x.S~ppc32-add-book-e--ppc44x-specific-exception-support-2 arch/ppc/kernel/head_44x.S
--- 25/arch/ppc/kernel/head_44x.S~ppc32-add-book-e--ppc44x-specific-exception-support-2	2004-05-11 00:52:22.742762576 -0700
+++ 25-akpm/arch/ppc/kernel/head_44x.S	2004-05-11 00:52:22.752761056 -0700
@@ -367,8 +367,6 @@ skpinv:	addi	r4,r4,1				/* Increment */
 	stw	r10,crit_sprg4@l(r8);					     \
 	mfspr	r10,SPRG5R;						     \
 	stw	r10,crit_sprg5@l(r8);					     \
-	mfspr	r10,SPRG6R;						     \
-	stw	r10,crit_sprg6@l(r8);					     \
 	mfspr	r10,SPRG7R;						     \
 	stw	r10,crit_sprg7@l(r8);					     \
 	mfspr	r10,SPRN_PID;						     \
@@ -409,6 +407,71 @@ skpinv:	addi	r4,r4,1				/* Increment */
 	SAVE_2GPRS(7, r11)
 
 /*
+ * Exception prolog for machine check exceptions.  This is similar to
+ * the critical exception prolog, except that machine check exceptions
+ * have their own save area.  For Book E processors, we also have a
+ * reserved register (SPRG6) that is only used in machine check exceptions
+ * so we can free up a GPR to use as the base for indirect access to the
+ * machine check exception save area.  This is necessary since the MMU
+ * is always on and the save area is offset from KERNELBASE.
+ */
+#define MCHECK_EXCEPTION_PROLOG					     \
+	mtspr	SPRG6W,r8;		/* SPRG6 used in machine checks */   \
+	lis	r8,mcheck_save@ha;					     \
+	stw	r10,mcheck_r10@l(r8);					     \
+	stw	r11,mcheck_r11@l(r8);					     \
+	mfspr	r10,SPRG0;						     \
+	stw	r10,mcheck_sprg0@l(r8);					     \
+	mfspr	r10,SPRG1;						     \
+	stw	r10,mcheck_sprg1@l(r8);					     \
+	mfspr	r10,SPRG4R;						     \
+	stw	r10,mcheck_sprg4@l(r8);					     \
+	mfspr	r10,SPRG5R;						     \
+	stw	r10,mcheck_sprg5@l(r8);					     \
+	mfspr	r10,SPRG7R;						     \
+	stw	r10,mcheck_sprg7@l(r8);					     \
+	mfspr	r10,SPRN_PID;						     \
+	stw	r10,mcheck_pid@l(r8);					     \
+	mfspr	r10,SRR0;						     \
+	stw	r10,mcheck_srr0@l(r8);					     \
+	mfspr	r10,SRR1;						     \
+	stw	r10,mcheck_srr1@l(r8);					     \
+	mfspr	r10,CSRR0;						     \
+	stw	r10,mcheck_csrr0@l(r8);					     \
+	mfspr	r10,CSRR1;						     \
+	stw	r10,mcheck_csrr1@l(r8);					     \
+	mfspr	r8,SPRG6R;		/* SPRG6 used in machine checks */   \
+	mfcr	r10;			/* save CR in r10 for now	   */\
+	mfspr	r11,SPRN_MCSRR1;	/* check whether user or kernel    */\
+	andi.	r11,r11,MSR_PR;						     \
+	lis	r11,mcheck_stack_top@h;					     \
+	ori	r11,r11,mcheck_stack_top@l;				     \
+	beq	1f;							     \
+	/* COMING FROM USER MODE */					     \
+	mfspr	r11,SPRG3;		/* if from user, start at top of   */\
+	lwz	r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
+	addi	r11,r11,THREAD_SIZE;					     \
+1:	subi	r11,r11,INT_FRAME_SIZE;	/* Allocate an exception frame     */\
+	stw	r10,_CCR(r11);          /* save various registers	   */\
+	stw	r12,GPR12(r11);						     \
+	stw	r9,GPR9(r11);						     \
+	mflr	r10;							     \
+	stw	r10,_LINK(r11);						     \
+	mfspr	r12,SPRN_DEAR;		/* save DEAR and ESR in the frame  */\
+	stw	r12,_DEAR(r11);		/* since they may have had stuff   */\
+	mfspr	r9,SPRN_ESR;		/* in them at the point where the  */\
+	stw	r9,_ESR(r11);		/* exception was taken		   */\
+	mfspr	r12,MCSRR0;						     \
+	stw	r1,GPR1(r11);						     \
+	mfspr	r9,MCSRR1;						     \
+	stw	r1,0(r11);						     \
+	tovirt(r1,r11);							     \
+	rlwinm	r9,r9,0,14,12;		/* clear MSR_WE (necessary?)	   */\
+	stw	r0,GPR0(r11);						     \
+	SAVE_4GPRS(3, r11);						     \
+	SAVE_2GPRS(7, r11)
+
+/*
  * Exception vectors.
  */
 #define	START_EXCEPTION(label)						     \
@@ -434,6 +497,18 @@ label:
 			  NOCOPY, transfer_to_handler_full, \
 			  ret_from_except_full)
 
+#define MCHECK_EXCEPTION(n, label, hdlr)			\
+	START_EXCEPTION(label);					\
+	MCHECK_EXCEPTION_PROLOG;				\
+	lis	r4,MCSR_MCS@h;					\
+	mtspr	SPRN_MCSR,r4;					\
+	mfspr	r5,SPRN_ESR;					\
+	stw	r5,_ESR(r11);					\
+	addi	r3,r1,STACK_FRAME_OVERHEAD;			\
+	EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
+			  NOCOPY, mcheck_transfer_to_handler,   \
+			  ret_from_mcheck_exc)
+
 #define EXC_XFER_TEMPLATE(hdlr, trap, msr, copyee, tfer, ret)	\
 	li	r10,trap;					\
 	stw	r10,TRAP(r11);					\
@@ -468,7 +543,11 @@ interrupt_base:
 	CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException)
 
 	/* Machine Check Interrupt */
+#ifdef CONFIG_440A
+	MCHECK_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
+#else
 	CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
+#endif
 
 	/* Data Storage Interrupt */
 	START_EXCEPTION(DataStorage)
@@ -476,7 +555,6 @@ interrupt_base:
 	mtspr	SPRG1, r11
 	mtspr	SPRG4W, r12
 	mtspr	SPRG5W, r13
-	mtspr	SPRG6W, r14
 	mfcr	r11
 	mtspr	SPRG7W, r11
 
@@ -549,15 +627,14 @@ interrupt_base:
 	rlwinm	r11,r11,0,20,15		/* Clear U0-U3 */
 
 	/* find the TLB index that caused the fault.  It has to be here. */
-	tlbsx	r14, 0, r10
+	tlbsx	r10, 0, r10
 
-	tlbwe	r11, r14, PPC44x_TLB_ATTRIB	/* Write ATTRIB */
+	tlbwe	r11, r10, PPC44x_TLB_ATTRIB	/* Write ATTRIB */
 
 	/* Done...restore registers and get out of here.
 	*/
 	mfspr	r11, SPRG7R
 	mtcr	r11
-	mfspr	r14, SPRG6R
 	mfspr	r13, SPRG5R
 	mfspr	r12, SPRG4R
 
@@ -572,7 +649,6 @@ interrupt_base:
 	 */
 	mfspr	r11, SPRG7R
 	mtcr	r11
-	mfspr	r14, SPRG6R
 	mfspr	r13, SPRG5R
 	mfspr	r12, SPRG4R
 
@@ -640,7 +716,6 @@ interrupt_base:
 	mtspr	SPRG1, r11
 	mtspr	SPRG4W, r12
 	mtspr	SPRG5W, r13
-	mtspr	SPRG6W, r14
 	mfcr	r11
 	mtspr	SPRG7W, r11
 	mfspr	r10, SPRN_DEAR		/* Get faulting address */
@@ -693,7 +768,6 @@ interrupt_base:
 	 */
 	mfspr	r11, SPRG7R
 	mtcr	r11
-	mfspr	r14, SPRG6R
 	mfspr	r13, SPRG5R
 	mfspr	r12, SPRG4R
 	mfspr	r11, SPRG1
@@ -711,7 +785,6 @@ interrupt_base:
 	mtspr	SPRG1, r11
 	mtspr	SPRG4W, r12
 	mtspr	SPRG5W, r13
-	mtspr	SPRG6W, r14
 	mfcr	r11
 	mtspr	SPRG7W, r11
 	mfspr	r10, SRR0		/* Get faulting address */
@@ -764,7 +837,6 @@ interrupt_base:
 	 */
 	mfspr	r11, SPRG7R
 	mtcr	r11
-	mfspr	r14, SPRG6R
 	mfspr	r13, SPRG5R
 	mfspr	r12, SPRG4R
 	mfspr	r11, SPRG1
@@ -854,7 +926,6 @@ data_access:
  * 	r11 - available to use
  *	r12 - Pointer to the 64-bit PTE
  *	r13 - available to use
- *	r14 - available to use
  *	MMUCR - loaded with proper value when we get here
  *	Upon exit, we reload everything and RFI.
  */
@@ -869,51 +940,50 @@ finish_tlb_load:
 
 	/* Load the next available TLB index */
 	lis	r13, tlb_44x_index@ha
-	lwz	r14, tlb_44x_index@l(r13)
+	lwz	r13, tlb_44x_index@l(r13)
 	/* Load the TLB high watermark */
-	lis	r13, tlb_44x_hwater@ha
-	lwz	r11, tlb_44x_hwater@l(r13)
+	lis	r11, tlb_44x_hwater@ha
+	lwz	r11, tlb_44x_hwater@l(r11)
 
 	/* Increment, rollover, and store TLB index */
-	addi	r14, r14, 1
-	cmpw	0, r14, r11			/* reserve entries */
+	addi	r13, r13, 1
+	cmpw	0, r13, r11			/* reserve entries */
 	ble	7f
-	li	r14, 0
+	li	r13, 0
 7:
 	/* Store the next available TLB index */
-	lis	r13, tlb_44x_index@ha
-	stw	r14, tlb_44x_index@l(r13)
+	lis	r11, tlb_44x_index@ha
+	stw	r13, tlb_44x_index@l(r11)
 
-	lwz	r13, 0(r12)			/* Get MS word of PTE */
-	lwz	r11, 4(r12)			/* Get LS word of PTE */
-	rlwimi	r13, r11, 0, 0 , 19		/* Insert RPN */
-	tlbwe	r13, r14, PPC44x_TLB_XLAT	/* Write XLAT */
+	lwz	r11, 0(r12)			/* Get MS word of PTE */
+	lwz	r12, 4(r12)			/* Get LS word of PTE */
+	rlwimi	r11, r12, 0, 0 , 19		/* Insert RPN */
+	tlbwe	r11, r13, PPC44x_TLB_XLAT	/* Write XLAT */
 
 	/*
 	 * Create PAGEID. This is the faulting address,
 	 * page size, and valid flag.
 	 */
-	li	r12, PPC44x_TLB_VALID | PPC44x_TLB_4K
-	rlwimi	r10, r12, 0, 20, 31		/* Insert valid and page size */
-	tlbwe	r10, r14, PPC44x_TLB_PAGEID	/* Write PAGEID */
-
-	li	r13, PPC44x_TLB_SR@l		/* Set SR */
-	rlwimi	r13, r11, 0, 30, 30		/* Set SW = _PAGE_RW */
-	rlwimi	r13, r11, 29, 29, 29		/* SX = _PAGE_HWEXEC */
-	rlwimi	r13, r11, 29, 28, 28		/* UR = _PAGE_USER */
-	rlwimi	r12, r11, 31, 26, 26		/* (_PAGE_USER>>1)->r12 */
-	and	r12, r12, r11			/* HWEXEC & USER */
-	rlwimi	r13, r12, 0, 26, 26		/* UX = HWEXEC & USER */
-
-	rlwimi	r11, r13, 0, 26, 31		/* Insert static perms */
-	rlwinm	r11, r11, 0, 20, 15		/* Clear U0-U3 */
-	tlbwe	r11, r14, PPC44x_TLB_ATTRIB	/* Write ATTRIB */
+	li	r11, PPC44x_TLB_VALID | PPC44x_TLB_4K
+	rlwimi	r10, r11, 0, 20, 31		/* Insert valid and page size */
+	tlbwe	r10, r13, PPC44x_TLB_PAGEID	/* Write PAGEID */
+
+	li	r10, PPC44x_TLB_SR@l		/* Set SR */
+	rlwimi	r10, r12, 0, 30, 30		/* Set SW = _PAGE_RW */
+	rlwimi	r10, r12, 29, 29, 29		/* SX = _PAGE_HWEXEC */
+	rlwimi	r10, r12, 29, 28, 28		/* UR = _PAGE_USER */
+	rlwimi	r11, r12, 31, 26, 26		/* (_PAGE_USER>>1)->r12 */
+	and	r11, r12, r11			/* HWEXEC & USER */
+	rlwimi	r10, r11, 0, 26, 26		/* UX = HWEXEC & USER */
+
+	rlwimi	r12, r10, 0, 26, 31		/* Insert static perms */
+	rlwinm	r12, r12, 0, 20, 15		/* Clear U0-U3 */
+	tlbwe	r12, r13, PPC44x_TLB_ATTRIB	/* Write ATTRIB */
 
 	/* Done...restore registers and get out of here.
 	*/
 	mfspr	r11, SPRG7R
 	mtcr	r11
-	mfspr	r14, SPRG6R
 	mfspr	r13, SPRG5R
 	mfspr	r12, SPRG4R
 	mfspr	r11, SPRG1
@@ -979,19 +1049,28 @@ _GLOBAL(empty_zero_page)
 _GLOBAL(swapper_pg_dir)
 	.space	8192
 
-/* Stack for handling critical exceptions from kernel mode */
 	.section .bss
+/* Stack for handling critical exceptions from kernel mode */
 critical_stack_bottom:
 	.space 4096
 critical_stack_top:
 	.previous
 
+/* Stack for handling machine check exceptions from kernel mode */
+mcheck_stack_bottom:
+	.space 4096
+mcheck_stack_top:
+	.previous
+
 /*
  * This area is used for temporarily saving registers during the
- * critical exception prolog. It must always follow the page
- * aligned allocations, so it starts on a page boundary, ensuring
- * that all crit_save areas are in a single page.
+ * critical and machine check exception prologs. It must always
+ * follow the page aligned allocations, so it starts on a page
+ * boundary, ensuring that all crit_save areas are in a single
+ * page.
  */
+
+/* crit_save */
 _GLOBAL(crit_save)
 	.space  4
 _GLOBAL(crit_r10)
@@ -1006,8 +1085,6 @@ _GLOBAL(crit_sprg4)
 	.space	4
 _GLOBAL(crit_sprg5)
 	.space	4
-_GLOBAL(crit_sprg6)
-	.space	4
 _GLOBAL(crit_sprg7)
 	.space	4
 _GLOBAL(crit_pid)
@@ -1017,6 +1094,34 @@ _GLOBAL(crit_srr0)
 _GLOBAL(crit_srr1)
 	.space	4
 
+/* mcheck_save */
+_GLOBAL(mcheck_save)
+	.space  4
+_GLOBAL(mcheck_r10)
+	.space	4
+_GLOBAL(mcheck_r11)
+	.space	4
+_GLOBAL(mcheck_sprg0)
+	.space	4
+_GLOBAL(mcheck_sprg1)
+	.space	4
+_GLOBAL(mcheck_sprg4)
+	.space	4
+_GLOBAL(mcheck_sprg5)
+	.space	4
+_GLOBAL(mcheck_sprg7)
+	.space	4
+_GLOBAL(mcheck_pid)
+	.space	4
+_GLOBAL(mcheck_srr0)
+	.space	4
+_GLOBAL(mcheck_srr1)
+	.space	4
+_GLOBAL(mcheck_csrr0)
+	.space	4
+_GLOBAL(mcheck_csrr1)
+	.space	4
+
 /*
  * This space gets a copy of optional info passed to us by the bootstrap
  * which is used to pass parameters into the kernel like root=/dev/sda1, etc.
diff -puN arch/ppc/kernel/traps.c~ppc32-add-book-e--ppc44x-specific-exception-support-2 arch/ppc/kernel/traps.c
--- 25/arch/ppc/kernel/traps.c~ppc32-add-book-e--ppc44x-specific-exception-support-2	2004-05-11 00:52:22.743762424 -0700
+++ 25-akpm/arch/ppc/kernel/traps.c	2004-05-11 00:52:22.753760904 -0700
@@ -222,14 +222,43 @@ MachineCheckException(struct pt_regs *re
 	if (check_io_access(regs))
 		return;
 
-#ifdef CONFIG_4xx
+#if defined(CONFIG_4xx) && !defined(CONFIG_440A)
 	if (reason & ESR_IMCP) {
 		printk("Instruction");
 		mtspr(SPRN_ESR, reason & ~ESR_IMCP);
 	} else
 		printk("Data");
 	printk(" machine check in kernel mode.\n");
+#elif defined(CONFIG_440A)
+	printk("Machine check in kernel mode.\n");
+	if (reason & ESR_IMCP){
+		printk("Instruction Synchronous Machine Check exception\n");
+		mtspr(SPRN_ESR, reason & ~ESR_IMCP);
+	}
+	else {
+		u32 mcsr = mfspr(SPRN_MCSR);
+		if (mcsr & MCSR_IB)
+			printk("Instruction Read PLB Error\n");
+		if (mcsr & MCSR_DRB)
+			printk("Data Read PLB Error\n");
+		if (mcsr & MCSR_DWB)
+			printk("Data Write PLB Error\n");
+		if (mcsr & MCSR_TLBP)
+			printk("TLB Parity Error\n");
+		if (mcsr & MCSR_ICP){
+			flush_instruction_cache();
+			printk("I-Cache Parity Error\n");
+		}
+		if (mcsr & MCSR_DCSP)
+			printk("D-Cache Search Parity Error\n");
+		if (mcsr & MCSR_DCFP)
+			printk("D-Cache Flush Parity Error\n");
+		if (mcsr & MCSR_IMPE)
+			printk("Machine Check exception is imprecise\n");
 
+		/* Clear MCSR */
+		mtspr(SPRN_MCSR, mcsr);
+	}
 #else /* !CONFIG_4xx */
 	printk("Machine check in kernel mode.\n");
 	printk("Caused by (from SRR1=%lx): ", reason);
diff -puN include/asm-ppc/ppc_asm.h~ppc32-add-book-e--ppc44x-specific-exception-support-2 include/asm-ppc/ppc_asm.h
--- 25/include/asm-ppc/ppc_asm.h~ppc32-add-book-e--ppc44x-specific-exception-support-2	2004-05-11 00:52:22.744762272 -0700
+++ 25-akpm/include/asm-ppc/ppc_asm.h	2004-05-11 00:52:22.753760904 -0700
@@ -161,6 +161,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601)
 #define CLR_TOP32(r)
 #endif /* CONFIG_PPC64BRIDGE */
 
+#define RFMCI		.long 0x4c00004c	/* rfmci instruction */
+
 #ifdef CONFIG_IBM405_ERR77
 #define PPC405_ERR77(ra,rb)	dcbt	ra, rb;
 #define	PPC405_ERR77_SYNC	sync;
diff -puN include/asm-ppc/reg_booke.h~ppc32-add-book-e--ppc44x-specific-exception-support-2 include/asm-ppc/reg_booke.h
--- 25/include/asm-ppc/reg_booke.h~ppc32-add-book-e--ppc44x-specific-exception-support-2	2004-05-11 00:52:22.746761968 -0700
+++ 25-akpm/include/asm-ppc/reg_booke.h	2004-05-11 00:52:22.754760752 -0700
@@ -86,6 +86,20 @@ do {						\
 #define SPRN_IVOR13	0x19D	/* Interrupt Vector Offset Register 13 */
 #define SPRN_IVOR14	0x19E	/* Interrupt Vector Offset Register 14 */
 #define SPRN_IVOR15	0x19F	/* Interrupt Vector Offset Register 15 */
+#define SPRN_MCSRR0	0x23A	/* Machine Check Save and Restore Register 0 */
+#define SPRN_MCSRR1	0x23B	/* Machine Check Save and Restore Register 1 */
+#define SPRN_MCSR	0x23C	/* Machine Check Status Register */
+#ifdef CONFIG_440A
+#define  MCSR_MCS	0x80000000 /* Machine Check Summary */
+#define  MCSR_IB	0x40000000 /* Instruction PLB Error */
+#define  MCSR_DRB	0x20000000 /* Data Read PLB Error */
+#define  MCSR_DWB	0x10000000 /* Data Write PLB Error */
+#define  MCSR_TLBP	0x08000000 /* TLB Parity Error */
+#define  MCSR_ICP	0x04000000 /* I-Cache Parity Error */
+#define  MCSR_DCSP	0x02000000 /* D-Cache Search Parity Error */
+#define  MCSR_DCFP	0x01000000 /* D-Cache Flush Parity Error */
+#define  MCSR_IMPE	0x00800000 /* Imprecise Machine Check Exception */
+#endif
 #define SPRN_ZPR	0x3B0	/* Zone Protection Register (40x) */
 #define SPRN_MMUCR	0x3B2	/* MMU Control Register */
 #define SPRN_CCR0	0x3B3	/* Core Configuration Register */
@@ -251,6 +265,8 @@ do {						\
 #define CSRR0	SPRN_SRR2	/* Logically and functionally equivalent. */
 #define CSRR1	SPRN_SRR3	/* Logically and functionally equivalent. */
 #endif
+#define MCSRR0	SPRN_MCSRR0	/* Machine Check Save and Restore Register 0 */
+#define MCSRR1	SPRN_MCSRR1	/* Machine Check Save and Restore Register 1 */
 #define DCMP	SPRN_DCMP	/* Data TLB Compare Register */
 #define SPRG4R	SPRN_SPRG4R	/* Supervisor Private Registers */
 #define SPRG5R	SPRN_SPRG5R

_
