# Patch made against linuxppc_2_4_devel changeset 1.691
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux 2.4 for PowerPC development tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.140.1.551 -> 1.156  
#	include/asm-ppc/system.h	1.10.1.9 -> 1.14   
#	include/asm-ppc/machdep.h	1.11.1.22 -> 1.20   
#	  arch/ppc/config.in	1.50.1.46 -> 1.56   
#	arch/ppc/platforms/pmac_setup.c	1.21.1.37 -> 1.30   
#	arch/ppc/kernel/setup.c	1.44.1.40 -> 1.52   
#	include/asm-ppc/processor.h	1.31.1.20 -> 1.37   
#	arch/ppc/kernel/temp.c	1.2.1.4 -> 1.5    
#	include/asm-ppc/mpc10x.h	1.2.1.4 -> 1.6    
#	arch/ppc/kernel/Makefile	1.40.1.33 -> 1.45   
#	arch/ppc/kernel/head.S	1.24.1.31 -> 1.33   
#	arch/ppc/kernel/traps.c	1.11.1.21 -> 1.21   
#	arch/ppc/kernel/qspan_pci.c	1.5.1.3 -> 1.8    
#	               (new)	        -> 1.2     arch/ppc/kernel/mpc10x_errors.c
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 01/11/27	adrian@newt.marston	1.156
# Merged with upstream
# --------------------------------------------
#
diff --minimal -Nru a/arch/ppc/config.in b/arch/ppc/config.in
--- a/arch/ppc/config.in	Mon Dec  3 12:18:10 2001
+++ b/arch/ppc/config.in	Mon Dec  3 12:18:10 2001
@@ -146,6 +146,7 @@
   -o "$CONFIG_SANDPOINT" = "y" \
   -o "$CONFIG_ZX4500" = "y" ]; then
   bool 'Enable MPC10x store gathering' CONFIG_MPC10X_STORE_GATHERING
+  bool 'Enable MPC10x error detection' CONFIG_MPC10X_ERRORS
 fi
 
 if [ "$CONFIG_EV64260" = "y" ]; then
diff --minimal -Nru a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
--- a/arch/ppc/kernel/Makefile	Mon Dec  3 12:18:10 2001
+++ b/arch/ppc/kernel/Makefile	Mon Dec  3 12:18:10 2001
@@ -63,6 +63,7 @@
 obj-$(CONFIG_ALL_PPC)		+= prom.o open_pic.o indirect_pci.o i8259.o
 obj-$(CONFIG_PREP_RESIDUAL)	+= residual.o
 obj-$(CONFIG_PPC_RTAS)		+= error_log.o proc_rtas.o
+obj-$(CONFIG_MPC10X_ERRORS) 	+= mpc10x_errors.o
 obj-$(CONFIG_ADIR)		+= i8259.o indirect_pci.o pci_auto.o \
 					todc_time.o
 obj-$(CONFIG_EV64260)		+= gt64260_common.o gt64260_pic.o \
diff --minimal -Nru a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S
--- a/arch/ppc/kernel/head.S	Mon Dec  3 12:18:10 2001
+++ b/arch/ppc/kernel/head.S	Mon Dec  3 12:18:10 2001
@@ -1264,13 +1264,13 @@
 _GLOBAL(__setup_cpu_750)
 	mflr	r4
 	bl	setup_common_caches
-	bl	setup_750_7400_hid0
+	bl	setup_750_hid0
 	mtlr	r4
 	blr
 _GLOBAL(__setup_cpu_7400)
 	mflr	r4
 	bl	setup_common_caches
-	bl	setup_750_7400_hid0
+	bl	setup_7400_hid0
 	mtlr	r4
 	blr
 _GLOBAL(__setup_cpu_7450)
@@ -1315,16 +1315,39 @@
 	isync
 	blr
 
-/* 740/750/7400/7410
+/* 740/750
  * Enable Store Gathering (SGE), Address Brodcast (ABE),
  * Branch History Table (BHTE), Branch Target ICache (BTIC)
  * Dynamic Power Management (DPM), Speculative (SPD)
  * Clear Instruction cache throttling (ICTC)
  */
-setup_750_7400_hid0:
+setup_750_hid0:
 	mfspr	r11,HID0
 	ori	r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC
 	oris	r11,r11,HID0_DPM@h	/* enable dynamic power mgmt */
+	li	r3,HID0_SPD
+	andc	r11,r11,r3		/* clear SPD: enable speculative */
+ 	li	r3,0
+ 	mtspr	ICTC,r3			/* Instruction Cache Throttling off */
+	isync
+	mtspr	HID0,r11
+	sync
+	isync
+	blr
+
+/* 7400/7410
+ * Enable Store Gathering (SGE), Address Brodcast (ABE),
+ * Branch History Table (BHTE), Branch Target ICache (BTIC)
+ * Dynamic Power Management (DPM), Speculative (SPD),
+ * Internal Error Checking (EIEC)
+
+
+ * Clear Instruction cache throttling (ICTC)
+ */
+setup_7400_hid0:
+	mfspr	r11,HID0
+	ori	r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC
+	oris	r11,r11,(HID0_DPM | HID0_EIEC)@h /* enable dynamic power mgmt */
 	li	r3,HID0_SPD
 	andc	r11,r11,r3		/* clear SPD: enable speculative */
  	li	r3,0
diff --minimal -Nru a/arch/ppc/kernel/mpc10x_errors.c b/arch/ppc/kernel/mpc10x_errors.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ppc/kernel/mpc10x_errors.c	Mon Dec  3 12:18:10 2001
@@ -0,0 +1,159 @@
+/*
+ * arch/ppc/kernel/mpc10x_errors.c
+ * 
+ * Error handling for the MPC107.
+ *
+ * Author: Adrian Cox <adrian@humboldt.co.uk>
+ *
+ * Copyright 2001 Humboldt Solutions Ltd.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/malloc.h>
+
+#include <asm/machdep.h>
+#include <asm/system.h>
+#include <asm/ptrace.h>
+#include <asm/pci-bridge.h>
+
+#include "mpc10x.h"
+
+static u32 eumb;
+
+static int mpc10x_error_handler(struct pt_regs *regs)
+{
+    u8 ErrDr1;
+    u8 ErrDr2;
+    u16 PciStat;
+    u32 address;
+    int pci_error = 0;
+    int fatal = 1;
+    
+    pcibios_read_config_word(0, 0, PCI_STATUS, &PciStat);
+    pcibios_read_config_byte(0, 0, MPC10X_ERRDR1_REG, &ErrDr1);
+    pcibios_read_config_byte(0, 0, MPC10X_ERRDR2_REG, &ErrDr2);
+    pcibios_read_config_dword(0, 0, MPC10X_ERRADDR_REG, &address);
+    /* Address is stored (un)byteswapped */
+    address = le32_to_cpu(address);
+    
+    if (ErrDr1 & 0x80)
+    {
+	printk("PCI SERR detected as initiator\n");
+	pci_error = 1;
+    }
+    else if (ErrDr2 & 0x40)
+    {
+	printk("PCI SERR detected\n");
+	pci_error = 1;
+    }
+    if (ErrDr1 & 0x40)
+    {
+	printk("PCI PERR detected\n");
+	pci_error = 1;
+    }
+    
+    if (pci_error)
+    {
+	if (! (ErrDr2 & 0x80))
+	{
+	    u8 codes;
+    	    pcibios_read_config_byte(0, 0, MPC10X_PCIBES_REG, &codes);
+	    printk("Host was %s, CBE codes 0x%x, address 0x%08x\n",
+		    (codes & 0x10) ? "target" : "master",
+		    codes & 0xf, address);
+	}
+	else
+	    printk("No valid PCI address\n");
+	return 0;
+    }
+    
+    if (ErrDr1 & 0x20)
+    {
+	printk("Memory select error\n");
+	fatal = 0;
+    }
+    if (ErrDr1 & 0x10)
+	printk("Memory refresh overflow\n");
+    if (ErrDr1 & 0x04)
+	printk("Memory parity error\n");
+    if (ErrDr1 & 0x03)
+	printk("Processor transaction error\n");
+    if (ErrDr2 & 0x08)
+    {
+        u32 dh, dl;
+        u32 par;
+	printk("ECC multi-bit error: ");
+        dh = readl(eumb + MPC10X_MDP_ERR_CAP_MON_DH);
+        dl = readl(eumb + MPC10X_MDP_ERR_CAP_MON_DL);
+        par = readl(eumb + MPC10X_MDP_ERR_CAP_MON_PAR);
+        printk("DH=0x%08x DL=0x%08x PAR=0x%03x\n", dh, dl, par);
+    }
+    if (ErrDr2 & 0x04)
+	printk("Processor write parity error\n");
+    if (ErrDr2 & 0x01)
+    {
+	printk("Flash write error\n");
+	fatal = 0;
+    }
+    
+    if (! (ErrDr2 & 0x80))
+	printk("Cycle initiated by %s, error at physical address 0x%08x\n",
+		(ErrDr1 & 0x08) ? "PCI" : "processor",
+		address);
+    
+    /* PCI initiated foulups are always fatal */
+    if (! (ErrDr1 & 0x08) && ! fatal)
+    {
+	if (user_mode(regs)) {
+		_exception(SIGSEGV, regs);	
+		return 1;
+	}
+	
+	bad_page_fault(regs, regs->dar, SIGBUS);
+	return 1;
+    }
+    return 0;
+}
+
+int __init mpc10x_errors_init(void)
+{
+    u32 devvenid;
+    u32 picr1;
+    u32 mccr2;
+    
+    pcibios_read_config_dword(0, 0, PCI_VENDOR_ID, &devvenid);
+    if (devvenid != MPC10X_BRIDGE_107 && devvenid != MPC10X_BRIDGE_8240)
+    {
+	printk("Error detection not supported on this bridge\n");
+	return -1;
+    }
+    
+    printk("Enabling MPC107 error reporting\n");
+    ppc_md.machine_check = mpc10x_error_handler;
+	
+    /* Enable TEA and MCP delivery */
+    pcibios_read_config_dword(0, 0, MPC10X_CFG_PICR1_REG, &picr1);
+    pcibios_write_config_dword(0, 0, MPC10X_CFG_PICR1_REG, picr1 | 0xc00);
+    /* ErrEn1 */
+    pcibios_write_config_byte(0, 0, MPC10X_ERREN1_REG, 0xf1);
+    /* ErrEn2 */
+    pcibios_write_config_byte(0, 0, MPC10X_ERREN2_REG, 0xc1);
+    
+    pcibios_read_config_dword(0, 0, MPC10X_CFG_EUMBBAR, &eumb);
+    pcibios_read_config_dword(0, 0, 0xf4, &mccr2);
+    if ((mccr2 & 0x00140000) == 0x00040000)
+    {
+	printk("Enabling ECC memory\n");
+    	pcibios_write_config_byte(0, 0, MPC10X_ERREN2_REG, 0xc9);
+    }
+    
+    
+}
+__initcall(mpc10x_errors_init);
diff --minimal -Nru a/arch/ppc/kernel/qspan_pci.c b/arch/ppc/kernel/qspan_pci.c
--- a/arch/ppc/kernel/qspan_pci.c	Mon Dec  3 12:18:10 2001
+++ b/arch/ppc/kernel/qspan_pci.c	Mon Dec  3 12:18:10 2001
@@ -27,6 +27,7 @@
 
 #include <asm/io.h>
 #include <asm/mpc8xx.h>
+#include <asm/ptrace.h>
 #include <asm/system.h>
 #include <asm/machdep.h>
 #include <asm/pci-bridge.h>
@@ -366,6 +367,18 @@
     return PCIBIOS_DEVICE_NOT_FOUND;
 }
 
+static int qspan_machine_check(struct pt_regs *regs)
+{
+	if (user_mode(regs)) {
+		_exception(SIGSEGV, regs);	
+		return 1;
+	}
+	
+	/* the qspan pci read routines can cause machine checks -- Cort */
+	bad_page_fault(regs, regs->dar, SIGBUS);
+	return 1;
+}
+
 void __init
 m8xx_pcibios_fixup(void))
 {
@@ -378,5 +391,6 @@
 	set_config_access_method(qspan);
 
 	ppc_md.pcibios_fixup = m8xx_pcibios_fixup;
+	ppc_md.machine_check = qspan_machine_check;
 }
 
diff --minimal -Nru a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
--- a/arch/ppc/kernel/traps.c	Mon Dec  3 12:18:10 2001
+++ b/arch/ppc/kernel/traps.c	Mon Dec  3 12:18:10 2001
@@ -32,7 +32,11 @@
 #include <linux/interrupt.h>
 #include <linux/config.h>
 #include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
 
+#include <asm/machdep.h>
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -123,105 +127,157 @@
 	force_sig(signr, current);
 }
 
-void
-MachineCheckException(struct pt_regs *regs)
-{
-#ifdef CONFIG_ALL_PPC
-	unsigned long fixup;
-#endif /* CONFIG_ALL_PPC */
-	unsigned long msr = regs->msr;
+/* This routine incorporates the safe components of panic(), but does not
+   risk syncing disks */
 
-	if (user_mode(regs)) {
-		_exception(SIGSEGV, regs);	
-		return;
-	}
+static NORET_TYPE void fatal_machine_check(const char *str, struct pt_regs *regs)
+{
+        extern int panic_timeout;
+	
+    	console_verbose();
+	spin_lock_irq(&oops_lock);
+	if (str)
+            printk(KERN_EMERG "%s error, SRR1=0x%lx\n", str, regs->msr);
+	show_regs(regs);
+	print_backtrace((unsigned long *)regs->gpr[1]);
+	printk(KERN_EMERG "Fatal Machine Check\n");
 
-#if defined(CONFIG_8xx) && defined(CONFIG_PCI)
-	/* the qspan pci read routines can cause machine checks -- Cort */
-	bad_page_fault(regs, regs->dar, SIGBUS);
-	return;
+#ifdef CONFIG_SMP
+	smp_send_stop();
 #endif
-	if (debugger_fault_handler) {
-		debugger_fault_handler(regs);
-		return;
-	}
 
-#ifdef CONFIG_ALL_PPC
-	/*
-	 * I/O accesses can cause machine checks on powermacs.
-	 * Check if the NIP corresponds to the address of a sync
-	 * instruction for which there is an entry in the exception
-	 * table.
-	 * Note that the 601 only takes a machine check on TEA
-	 * (transfer error ack) signal assertion, and does not
-	 * set any of the top 16 bits of SRR1.
-	 *  -- paulus.
-	 */
-	if (((msr & 0xffff0000) == 0 || (msr & (0x80000 | 0x40000)))
-	    && (fixup = search_exception_table(regs->nip)) != 0) {
+	notifier_call_chain(&panic_notifier_list, 0, NULL);
+
+	if (panic_timeout > 0)
+	{
 		/*
-		 * Check that it's a sync instruction, or somewhere
-		 * in the twi; isync; nop sequence that inb/inw/inl uses.
-		 * As the address is in the exception table
-		 * we should be able to read the instr there.
-		 * For the debug message, we look at the preceding
-		 * load or store.
+	 	 * Delay timeout seconds before rebooting the machine. 
+		 * We can't use the "normal" timers since we just panicked..
+	 	 */
+		printk(KERN_EMERG "Rebooting in %d seconds..",panic_timeout);
+		mdelay(panic_timeout*1000);
+		/*
+		 *	Should we run the reboot notifier. For the moment Im
+		 *	choosing not too. It might crash, be corrupt or do
+		 *	more harm than good for other reasons.
 		 */
-		unsigned int *nip = (unsigned int *)regs->nip;
-		if (*nip == 0x60000000)		/* nop */
-			nip -= 2;
-		else if (*nip == 0x4c00012c)	/* isync */
-			--nip;
-		if (*nip == 0x7c0004ac || (*nip >> 26) == 3) {
-			/* sync or twi */
-			unsigned int rb;
-
-			--nip;
-			rb = (*nip >> 11) & 0x1f;
-			printk(KERN_DEBUG "%s bad port %lx at %p\n",
-			       (*nip & 0x100)? "OUT to": "IN from",
-			       regs->gpr[rb] - _IO_BASE, nip);
-			regs->nip = fixup;
-			return;
-		}
+		machine_restart(NULL);
 	}
-#endif /* CONFIG_ALL_PPC */
-	printk("Machine check in kernel mode.\n");
-	printk("Caused by (from SRR1=%lx): ", msr);
-	switch (msr & 0x601F0000) {
-	case 0x80000:
-		printk("Machine check signal\n");
-		break;
-	case 0:		/* for 601 */
-	case 0x40000:
-	case 0x140000:	/* 7450 MSS error and TEA */
-		printk("Transfer error ack signal\n");
+	sti();
+	for(;;) { }
+}
+
+void
+MachineCheckException(struct pt_regs *regs)
+{
+#ifdef CONFIG_6xx
+	unsigned mask = 0;
+	unsigned pvr = mfspr(SPRN_PVR);
+	unsigned hid0;
+
+    	/* First check for fatal internal errors. We should not
+	   attempt to recover from these. */
+	switch (PVR_VER(pvr))
+	{
+	case 0x0001: /* 601 */
+		hid0 = mfspr(SPRN_HID0);
+		if (hid0 & 0x40000000)
+			fatal_machine_check("Microcode", regs);
+		if (hid0 & 0x20000000)
+			fatal_machine_check("Double machine check", regs);
+		if (hid0 & 0x10000000)
+			fatal_machine_check("Multiple TLB hit", regs);
+		if (hid0 & 0x08000000)
+			fatal_machine_check("Multiple cache hit", regs);
+		if (hid0 & 0x04000000)
+			fatal_machine_check("Sequencer timeout", regs);
+		if (hid0 & 0x02000000)
+			fatal_machine_check("Dispatch timeout", regs);
+		if (hid0 & 0x01000000)
+			fatal_machine_check("Address parity", regs);
+		if (hid0 & 0x00800000)
+			fatal_machine_check("Data parity", regs);
+		if (hid0 & 0x00400000)
+			fatal_machine_check("Cache parity", regs);
+		if (hid0 & 0x00200000)
+			fatal_machine_check("Invalid microcode", regs);
+		if (hid0 & 0x00100000)
+			fatal_machine_check("I/O controller interface access protocol", regs);
 		break;
-	case 0x20000:
-		printk("Data parity error signal\n");
+	case 0x0003: /* 603 */
+	case 0x0006: /* 603e */
+	case 0x0007: /* 603r/ev */
+		mask = 0x00030000;
 		break;
-	case 0x10000:
-		printk("Address parity error signal\n");
+	case 0x0004: /* 604 */
+	case 0x0009: /* 604e */
+	case 0x000a: /* 604r */
+		if (regs->msr & 0x00100000)
+			fatal_machine_check("L1 Data cache", regs);
+		if (regs->msr & 0x00200000)
+			fatal_machine_check("L1 Instruction cache", regs);
+		mask = 0x00330000;
 		break;
-	case 0x20000000:
-		printk("L1 Data Cache error\n");
+	case 0x0008: /* 740/750 */
+	case 0x1008: /* 740/750p */
+		mask = 0x00130000;
 		break;
-	case 0x40000000:
-		printk("L1 Instruction Cache error\n");
+	case 0x000c: /* 7400 */
+	case 0x800c: /* 7410 */
+		if (regs->msr & 0x10000000)
+			fatal_machine_check("L2 cache tag", regs);
+		if (regs->msr & 0x08000000)
+			fatal_machine_check("TLB array", regs);
+		if (regs->msr & 0x04000000)
+			fatal_machine_check("Internal", regs);
+		mask = 0x7c130000;
 		break;
-	case 0x00100000:
-		printk("L2 data cache parity error\n");
+	case 0x8000: /* 7450 */
+		if (regs->msr & 0x00100000)
+			fatal_machine_check("L2 or L3 cache parity or tag", regs);
+		mask = 0x60130000;
 		break;
-	default:
-		printk("Unknown values in msr\n");
+	}
+	
+	/* Now handle fields common to several 60x/7xxx processors */
+	mask &= regs->msr;
+	if (regs->msr & 0x40000000)
+		fatal_machine_check("L1 Instruction cache", regs);
+	if (regs->msr & 0x20000000)
+		fatal_machine_check("L1 Data cache", regs);
+	if (regs->msr & 0x00100000)
+		fatal_machine_check("L2 cache parity", regs);
+	if (mask & 0x00020000)
+		fatal_machine_check("Data bus parity", regs);
+	if (mask & 0x00010000)
+		fatal_machine_check("Address bus parity", regs);
+	if (mask)
+		fatal_machine_check("Unknown internal", regs);
+#endif /* CONFIG_6xx */
+	
+	/* Call board specific handler for external causes. Some of
+	   these will be recoverable */
+	if (ppc_md.machine_check && ppc_md.machine_check(regs))
+	    return;
+	
+	/* At this point we have an exception of unknown cause. */
+	if (debugger_fault_handler) {
+		debugger_fault_handler(regs);
+		return;
 	}
 	debugger(regs);
-	die("machine check", regs, SIGBUS);
+
+        fatal_machine_check(NULL, regs);
 }
 
 void
 SMIException(struct pt_regs *regs)
 {
+    	if (ppc_md.SMI)
+	{
+	    ppc_md.SMI(regs);
+	    return;
+	}
 	debugger(regs);
 #if !(defined(CONFIG_XMON) || defined(CONFIG_KGDB))
 	show_regs(regs);
diff --minimal -Nru a/arch/ppc/platforms/pmac_setup.c b/arch/ppc/platforms/pmac_setup.c
--- a/arch/ppc/platforms/pmac_setup.c	Mon Dec  3 12:18:10 2001
+++ b/arch/ppc/platforms/pmac_setup.c	Mon Dec  3 12:18:10 2001
@@ -295,6 +295,40 @@
 }
 #endif /* CONFIG_VT */
 
+static int pmac_machine_check(struct pt_regs *regs)
+{
+	unsigned long fixup;
+	
+	if (user_mode(regs)) {
+		_exception(SIGSEGV, regs);	
+		return 1;
+	}
+	
+	/*
+	 * I/O accesses can cause machine checks on powermacs.
+	 * Check if the NIP corresponds to the address of a sync
+	 * instruction for which there is an entry in the exception
+	 * table.
+	 */
+nc	if (fixup = search_exception_table(regs->nip)) != 0) {
+		/*
+		 * Check that it's a sync instruction.
+		 * As the address is in the exception table
+		 * we should be able to read the instr there.
+		 */
+		if (*(unsigned int *)regs->nip == 0x7c0004ac) {
+			unsigned int lsi = ((unsigned int *)regs->nip)[-1];
+			int rb = (lsi >> 11) & 0x1f;
+			printk(KERN_DEBUG "%s bad port %lx at %lx\n",
+			       (lsi & 0x100)? "OUT to": "IN from",
+			       regs->gpr[rb] - _IO_BASE, regs->nip);
+			regs->nip = fixup;
+			return 1;
+		}
+	}
+	return 0;
+}
+
 static volatile u32 *sysctrl_regs;
 
 void __init
@@ -834,6 +868,8 @@
 #ifdef CONFIG_BOOTX_TEXT
 	ppc_md.progress = pmac_progress;
 #endif /* CONFIG_BOOTX_TEXT */
+
+	ppc_md.machine_check = pmac_machine_check;
 
 	if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0);
 	
diff --minimal -Nru a/include/asm-ppc/machdep.h b/include/asm-ppc/machdep.h
--- a/include/asm-ppc/machdep.h	Mon Dec  3 12:18:10 2001
+++ b/include/asm-ppc/machdep.h	Mon Dec  3 12:18:10 2001
@@ -100,6 +100,11 @@
 	/* this is for modules, since _machine can be a define -- Cort */
 	int ppc_machine;
 
+	/* This is called by the machine check handler - return non-zero if
+	   it has handled the condition */
+	int (*machine_check)(struct pt_regs *regs);
+	void (*SMI)(struct pt_regs *regs);
+
 	/* Motherboard/chipset features. This is a kind of general purpose
 	 * hook used to control some machine specific features (like reset
 	 * lines, chip power control, etc...).
diff --minimal -Nru a/include/asm-ppc/mpc10x.h b/include/asm-ppc/mpc10x.h
--- a/include/asm-ppc/mpc10x.h	Mon Dec  3 12:18:10 2001
+++ b/include/asm-ppc/mpc10x.h	Mon Dec  3 12:18:10 2001
@@ -155,6 +155,17 @@
 #define	MPC10X_MAPA_EUMB_BASE		(ioremap_base - MPC10X_EUMB_SIZE)
 #define	MPC10X_MAPB_EUMB_BASE		MPC10X_MAPA_EUMB_BASE
 
+#define MPC10X_ERREN1_REG   	    	0xc0
+#define MPC10X_ERRDR1_REG   	    	0xc1
+#define MPC10X_PROCBES_REG     	    	0xc3
+#define MPC10X_ERREN2_REG   	    	0xc4
+#define MPC10X_ERRDR2_REG   	    	0xc5
+#define MPC10X_PCIBES_REG     	    	0xc7
+#define MPC10X_ERRADDR_REG  	    	0xc8
+
+#define MPC10X_MDP_ERR_CAP_MON_DH   	0xff00c
+#define MPC10X_MDP_ERR_CAP_MON_DL   	0xff010
+#define MPC10X_MDP_ERR_CAP_MON_PAR   	0xff014
 
 int mpc10x_bridge_init(struct pci_controller *hose,
 		       uint current_map,
diff --minimal -Nru a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h
--- a/include/asm-ppc/processor.h	Mon Dec  3 12:18:10 2001
+++ b/include/asm-ppc/processor.h	Mon Dec  3 12:18:10 2001
@@ -221,6 +221,7 @@
 #define	  HID0_NAP	(1<<22)
 #define	  HID0_SLEEP	(1<<21)
 #define	  HID0_DPM	(1<<20)
+#define	  HID0_EIEC	(1<<18)     	/* 7400 Internal Error Checking */
 #define	  HID0_BHTCLR	(1<<18)		/* Clear branch history table - 7450 */
 #define	  HID0_XAEN	(1<<17)		/* Extended addressing enable - 7450 */
 #define   HID0_NHR	(1<<16)		/* Not hard reset (software bit-7450)*/
diff --minimal -Nru a/include/asm-ppc/system.h b/include/asm-ppc/system.h
--- a/include/asm-ppc/system.h	Mon Dec  3 12:18:10 2001
+++ b/include/asm-ppc/system.h	Mon Dec  3 12:18:10 2001
@@ -56,9 +56,11 @@
 extern void hard_reset_now(void);
 extern void poweroff_now(void);
 #ifdef CONFIG_6xx
+extern int _get_HID0(void);
 extern long _get_L2CR(void);
 extern void _set_L2CR(unsigned long);
 #else
+#define _get_HID0() 	0
 #define _get_L2CR()	0
 #define _set_L2CR(val)	do { } while(0)
 #endif
@@ -75,6 +77,7 @@
 extern int call_rtas(const char *, int, int, unsigned long *, ...);
 extern int abs(int);
 extern void cacheable_memzero(void *p, unsigned int nb);
+extern void bad_page_fault(struct pt_regs *, unsigned long, int sig);
 
 struct device_node;
 extern void note_scsi_host(struct device_node *, void *);
