patch-2.2.8 linux/arch/ppc/kernel/prep_pci.c

Next file: linux/arch/ppc/kernel/prep_setup.c
Previous file: linux/arch/ppc/kernel/prep_nvram.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.7/linux/arch/ppc/kernel/prep_pci.c linux/arch/ppc/kernel/prep_pci.c
@@ -1,5 +1,5 @@
 /*
- * $Id: prep_pci.c,v 1.25 1999/03/03 15:09:45 cort Exp $
+ * $Id: prep_pci.c,v 1.33 1999/05/09 20:15:54 cort Exp $
  * PReP pci functions.
  * Originally by Gary Thomas
  * rewritten and updated by Cort Dougan (cort@cs.nmt.edu)
@@ -11,11 +11,19 @@
 #include <linux/pci.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/openpic.h>
 
 #include <asm/byteorder.h>
 #include <asm/io.h>
 #include <asm/ptrace.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/residual.h>
 #include <asm/processor.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+
+#include "pci.h"
 
 #define MAX_DEVNR 22
 
@@ -27,6 +35,9 @@
 /* How is the 82378 PIRQ mapping setup? */
 unsigned char *Motherboard_routes;
 
+/* Used for Motorola to store system config register */
+static unsigned long	*ProcInfo;
+
 /* Tables for known hardware */   
 
 /* Motorola PowerStackII - Utah */
@@ -34,38 +45,39 @@
 {
         0,   /* Slot 0  - unused */
         0,   /* Slot 1  - unused */
-        4,   /* Slot 2  - SCSI - NCR825A  */
+        5,   /* Slot 2  - SCSI - NCR825A  */
         0,   /* Slot 3  - unused */
         1,   /* Slot 4  - Ethernet - DEC2114x */
         0,   /* Slot 5  - unused */
-        2,   /* Slot 6  - PCI Card slot #1 */
-        3,   /* Slot 7  - PCI Card slot #2 */
-        4,   /* Slot 8  - PCI Card slot #3 */
-        4,   /* Slot 9  - PCI Bridge */
+        3,   /* Slot 6  - PCI Card slot #1 */
+        4,   /* Slot 7  - PCI Card slot #2 */
+        5,   /* Slot 8  - PCI Card slot #3 */
+        5,   /* Slot 9  - PCI Bridge */
              /* added here in case we ever support PCI bridges */
              /* Secondary PCI bus cards are at slot-9,6 & slot-9,7 */
         0,   /* Slot 10 - unused */
         0,   /* Slot 11 - unused */
-        4,   /* Slot 12 - SCSI - NCR825A */
+        5,   /* Slot 12 - SCSI - NCR825A */
         0,   /* Slot 13 - unused */
-        2,   /* Slot 14 - enet */
+        3,   /* Slot 14 - enet */
         0,   /* Slot 15 - unused */
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
+        2,   /* Slot 16 - unused */
+        3,   /* Slot 17 - unused */
+        5,   /* Slot 18 - unused */
+        0,   /* Slot 19 - unused */
+        0,   /* Slot 20 - unused */
+        0,   /* Slot 21 - unused */
+        0,   /* Slot 22 - unused */
 };
 
 static char Utah_pci_IRQ_routes[] __prepdata =
 {
         0,   /* Line 0 - Unused */
         9,   /* Line 1 */
-        11,  /* Line 2 */
-        14,  /* Line 3 */
-        15,  /* Line 4 */
+	10,  /* Line 2 */
+        11,  /* Line 3 */
+        14,  /* Line 4 */
+        15,  /* Line 5 */
 };
 
 /* Motorola PowerStackII - Omaha */
@@ -125,9 +137,9 @@
   	0,	/* Slot 13 - unused */
   	1,	/* Slot 14 - Ethernet */
   	0,	/* Slot 15 - unused */
-  	1,	/* Slot P7 */
-  	2,	/* Slot P6 */
-  	3,	/* Slot P5 */
+ 	1,	/* Slot P7 */
+ 	2,	/* Slot P6 */
+ 	3,	/* Slot P5 */
 };
 
 static char Blackhawk_pci_IRQ_routes[] __prepdata =
@@ -139,6 +151,122 @@
    	15	/* Line 4 */
 };
    
+/* Motorola Mesquite */
+static char Mesquite_pci_IRQ_map[23] __prepdata =
+{
+	0,	/* Slot 0  - unused */
+	0,	/* Slot 1  - unused */
+	0,	/* Slot 2  - unused */
+	0,	/* Slot 3  - unused */
+	0,	/* Slot 4  - unused */
+	0,	/* Slot 5  - unused */
+	0,	/* Slot 6  - unused */
+	0,	/* Slot 7  - unused */
+	0,	/* Slot 8  - unused */
+	0,	/* Slot 9  - unused */
+	0,	/* Slot 10 - unxued */
+	0,	/* Slot 11 - unused */
+	0,	/* Slot 12 - unused */
+	0,	/* Slot 13 - unused */
+	2,	/* Slot 14 - Ethernet */
+	0,	/* Slot 15 - unused */
+	3,	/* Slot 16 - PMC */
+	0,	/* Slot 17 - unused */
+	0,	/* Slot 18 - unused */
+	0,	/* Slot 19 - unused */
+	0,	/* Slot 20 - unused */
+	0,	/* Slot 21 - unused */
+	0,	/* Slot 22 - unused */
+};
+
+/* Motorola Sitka */
+static char Sitka_pci_IRQ_map[21] __prepdata =
+{
+	0,      /* Slot 0  - unused */
+	0,      /* Slot 1  - unused */
+	0,      /* Slot 2  - unused */
+	0,      /* Slot 3  - unused */
+	0,      /* Slot 4  - unused */
+	0,      /* Slot 5  - unused */
+	0,      /* Slot 6  - unused */
+	0,      /* Slot 7  - unused */
+	0,      /* Slot 8  - unused */
+	0,      /* Slot 9  - unused */
+	0,      /* Slot 10 - unxued */
+	0,      /* Slot 11 - unused */
+	0,      /* Slot 12 - unused */
+	0,      /* Slot 13 - unused */
+	2,      /* Slot 14 - Ethernet */
+	0,      /* Slot 15 - unused */
+	9,      /* Slot 16 - PMC 1  */
+	12,     /* Slot 17 - PMC 2  */
+	0,      /* Slot 18 - unused */
+	0,      /* Slot 19 - unused */
+	4,      /* Slot 20 - NT P2P bridge */
+};
+
+/* Motorola MTX */
+static char MTX_pci_IRQ_map[23] __prepdata =
+{
+	0,	/* Slot 0  - unused */
+	0,	/* Slot 1  - unused */
+	0,	/* Slot 2  - unused */
+	0,	/* Slot 3  - unused */
+	0,	/* Slot 4  - unused */
+	0,	/* Slot 5  - unused */
+	0,	/* Slot 6  - unused */
+	0,	/* Slot 7  - unused */
+	0,	/* Slot 8  - unused */
+	0,	/* Slot 9  - unused */
+	0,	/* Slot 10 - unused */
+	0,	/* Slot 11 - unused */
+	3,	/* Slot 12 - SCSI */
+	0,	/* Slot 13 - unused */
+	2,	/* Slot 14 - Ethernet */
+	0,	/* Slot 15 - unused */
+	9,      /* Slot 16 - PCI/PMC slot 1 */
+	10,     /* Slot 17 - PCI/PMC slot 2 */
+	11,     /* Slot 18 - PCI slot 3 */
+	0,	/* Slot 19 - unused */
+	0,	/* Slot 20 - unused */
+	0,	/* Slot 21 - unused */
+	0,	/* Slot 22 - unused */
+};
+
+/* Motorola MTX Plus */
+/* Secondary bus interrupt routing is not supported yet */
+static char MTXplus_pci_IRQ_map[23] __prepdata =
+{
+        0,      /* Slot 0  - unused */
+        0,      /* Slot 1  - unused */
+        0,      /* Slot 2  - unused */
+        0,      /* Slot 3  - unused */
+        0,      /* Slot 4  - unused */
+        0,      /* Slot 5  - unused */
+        0,      /* Slot 6  - unused */
+        0,      /* Slot 7  - unused */
+        0,      /* Slot 8  - unused */
+        0,      /* Slot 9  - unused */
+        0,      /* Slot 10 - unused */
+        0,      /* Slot 11 - unused */
+        3,      /* Slot 12 - SCSI */
+        0,      /* Slot 13 - unused */
+        2,      /* Slot 14 - Ethernet 1 */
+        0,      /* Slot 15 - unused */
+        9,      /* Slot 16 - PCI slot 1P */
+        10,     /* Slot 17 - PCI slot 2P */
+        11,     /* Slot 18 - PCI slot 3P */
+        10,     /* Slot 19 - Ethernet 2 */
+        0,      /* Slot 20 - P2P Bridge */
+        0,      /* Slot 21 - unused */
+        0,      /* Slot 22 - unused */
+};
+
+static char Raven_pci_IRQ_routes[] __prepdata =
+{
+   	0,	/* This is a dummy structure */
+};
+   
 /* Motorola MVME16xx */
 static char Genesis_pci_IRQ_map[16] __prepdata =
 {
@@ -169,8 +297,35 @@
    	15	/* Line 4 */
 };
    
+static char Genesis2_pci_IRQ_map[23] __prepdata =
+{
+	0,	/* Slot 0  - unused */
+	0,	/* Slot 1  - unused */
+	0,	/* Slot 2  - unused */
+	0,	/* Slot 3  - unused */
+	0,	/* Slot 4  - unused */
+	0,	/* Slot 5  - unused */
+	0,	/* Slot 6  - unused */
+	0,	/* Slot 7  - unused */
+	0,	/* Slot 8  - unused */
+	0,	/* Slot 9  - unused */
+	0,	/* Slot 10 - Ethernet */
+	0,	/* Slot 11 - Universe PCI - VME Bridge */
+	3,	/* Slot 12 - unused */
+	0,	/* Slot 13 - unused */
+	2,	/* Slot 14 - SCSI */
+	0,	/* Slot 15 - graphics on 3600 */
+	9,	/* Slot 16 - PMC */
+	12,	/* Slot 17 - pci */
+	11,	/* Slot 18 - pci */
+	10,	/* Slot 19 - pci */
+	0,	/* Slot 20 - pci */
+	0,	/* Slot 21 - unused */
+	0,	/* Slot 22 - unused */
+};
+
 /* Motorola Series-E */
-static char Comet_pci_IRQ_map[16] __prepdata =
+static char Comet_pci_IRQ_map[23] __prepdata =
 {
   	0,	/* Slot 0  - unused */
   	0,	/* Slot 1  - unused */
@@ -188,6 +343,13 @@
   	0,	/* Slot 13 - unused */
   	1,	/* Slot 14 - Ethernet */
   	0,	/* Slot 15 - unused */
+	1,	/* Slot 16 - PCI slot 1 */
+	2,	/* Slot 17 - PCI slot 2 */
+	3,	/* Slot 18 - PCI slot 3 */
+	4,	/* Slot 19 - PCI bridge */
+	0,
+	0,
+	0,
 };
 
 static char Comet_pci_IRQ_routes[] __prepdata =
@@ -199,6 +361,43 @@
    	15	/* Line 4 */
 };
 
+/* Motorola Series-EX */
+static char Comet2_pci_IRQ_map[23] __prepdata =
+{
+	0,	/* Slot 0  - unused */
+	0,	/* Slot 1  - unused */
+	3,	/* Slot 2  - SCSI - NCR825A */
+	0,	/* Slot 3  - unused */
+	1,	/* Slot 4  - Ethernet - DEC2104X */
+	0,	/* Slot 5  - unused */
+	1,	/* Slot 6  - PCI slot 1 */
+	2,	/* Slot 7  - PCI slot 2 */
+	3,	/* Slot 8  - PCI slot 3 */
+	4,	/* Slot 9  - PCI bridge  */
+	0,	/* Slot 10 - unused */
+	0,	/* Slot 11 - unused */
+	3,	/* Slot 12 - SCSI - NCR825A */
+	0,	/* Slot 13 - unused */
+	1,	/* Slot 14 - Ethernet - DEC2104X */
+	0,	/* Slot 15 - unused */
+	1,	/* Slot 16 - PCI slot 1 */
+	2,	/* Slot 17 - PCI slot 2 */
+	3,	/* Slot 18 - PCI slot 3 */
+	4,	/* Slot 19 - PCI bridge */
+	0,
+	0,
+	0,
+};
+
+static char Comet2_pci_IRQ_routes[] __prepdata =
+{
+	0,	/* Line 0 - Unused */
+	10,	/* Line 1 */
+	11,	/* Line 2 */
+	14,	/* Line 3 */
+	15,	/* Line 4 */
+};
+
 /*
  * ibm 830 (and 850?).
  * This is actually based on the Carolina motherboard
@@ -328,106 +527,24 @@
 #define ELCRM_INT7_LVL          0x80
 #define ELCRM_INT5_LVL          0x20
 
-/*
- * Mechanism 1 configuration space access as defined in the PCI spec.
- */
-#define CFG_ADDR (volatile u_int *)0x80000cf8
-#define CFG_DATA 0x80000cfc
-
-#define CFG_DEV_ADDR(b, d, o)	(0x80000000 |	\
-				 ((b) << 16) |	\
-				 ((d) << 8) |	\
-				 ((o) & ~3))
-
-unsigned char max_bus=255;
-
-int mech1_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
-				     unsigned char offset, unsigned char *val)
-{
-	*val = 0xff;
-	if (bus > max_bus)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	out_le32(CFG_ADDR, CFG_DEV_ADDR(bus, dev_fn, offset));
-	*val = in_8((unsigned char *)CFG_DATA + (offset & 3));
-	return PCIBIOS_SUCCESSFUL;
-}
-
-int mech1_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
-				     unsigned char offset, unsigned short *val)
-{
-	*val = 0xffff;
-	if (bus > max_bus)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	if ((offset & 1) != 0)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	out_le32(CFG_ADDR, CFG_DEV_ADDR(bus, dev_fn, offset));
-	*val = in_le16((volatile unsigned short *)(CFG_DATA + (offset&3)));
-	return PCIBIOS_SUCCESSFUL;
-}
-
-int mech1_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
-				      unsigned char offset, unsigned int *val)
-{
-	*val = 0xffffffff;
-	if (bus > max_bus)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	if ((offset & 3) != 0)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	out_le32(CFG_ADDR, CFG_DEV_ADDR(bus, dev_fn, offset));
-	*val = in_le32((volatile unsigned int *)CFG_DATA);
-	return PCIBIOS_SUCCESSFUL;
-}
-
-int mech1_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
-				      unsigned char offset, unsigned char val)
-{
-	if (bus > max_bus)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	out_le32(CFG_ADDR, CFG_DEV_ADDR(bus, dev_fn, offset));
-	out_8((unsigned char *)CFG_DATA + (offset & 3), val);
-	return PCIBIOS_SUCCESSFUL;
-}
-
-int mech1_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
-				      unsigned char offset, unsigned short val)
-{
-	if (bus > max_bus)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	if ((offset & 1) != 0)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	out_le32(CFG_ADDR, CFG_DEV_ADDR(bus, dev_fn, offset));
-	out_le16((volatile unsigned short *)(CFG_DATA + (offset&3)), val);
-	return PCIBIOS_SUCCESSFUL;
-}
-
-int mech1_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
-				    unsigned char offset, unsigned int val)
-{
-	if (bus > max_bus)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	if ((offset & 1) != 0)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	out_le32(CFG_ADDR, CFG_DEV_ADDR(bus, dev_fn, offset));
-	out_le32((volatile unsigned int *)CFG_DATA, val);
-	return PCIBIOS_SUCCESSFUL;
-}
+#define CFGPTR(dev) (0x80800000 | (1<<(dev>>3)) | ((dev&7)<<8) | offset)
+#define DEVNO(dev)  (dev>>3)                                  
 
 __prep
 int
 prep_pcibios_read_config_dword (unsigned char bus,
 			   unsigned char dev, unsigned char offset, unsigned int *val)
 {
-	unsigned long _val;
+	unsigned long _val;                                          
 	unsigned long *ptr;
-	dev >>= 3;
-	
-	if ((bus != 0) || (dev > MAX_DEVNR))
-	{
+
+	if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR))
+	{                   
 		*val = 0xFFFFFFFF;
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	} else
+		return PCIBIOS_DEVICE_NOT_FOUND;    
+	} else                                                                
 	{
-		ptr = (unsigned long *)(0x80800000 | (1<<dev) | offset);
+		ptr = (unsigned long *)CFGPTR(dev);
 		_val = le32_to_cpu(*ptr);
 	}
 	*val = _val;
@@ -439,16 +556,16 @@
 prep_pcibios_read_config_word (unsigned char bus,
 			  unsigned char dev, unsigned char offset, unsigned short *val)
 {
-	unsigned short _val;
+	unsigned short _val;                                          
 	unsigned short *ptr;
-	dev >>= 3;
-	if ((bus != 0) || (dev > MAX_DEVNR))
-	{
-		*val = (unsigned short)0xFFFFFFFF;
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	} else
+
+	if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR))
+	{                   
+		*val = 0xFFFF;
+		return PCIBIOS_DEVICE_NOT_FOUND;    
+	} else                                                                
 	{
-		ptr = (unsigned short *)(0x80800000 | (1<<dev) | offset);
+		ptr = (unsigned short *)CFGPTR(dev);
 		_val = le16_to_cpu(*ptr);
 	}
 	*val = _val;
@@ -460,16 +577,16 @@
 prep_pcibios_read_config_byte (unsigned char bus,
 			  unsigned char dev, unsigned char offset, unsigned char *val)
 {
-	unsigned char _val;
-	volatile unsigned char *ptr;
-	dev >>= 3;
-	if ((bus != 0) || (dev > MAX_DEVNR))
-	{
-		*(unsigned long *)val = (unsigned long) 0xFFFFFFFF;
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	} else
+	unsigned char _val;                                          
+	unsigned char *ptr;
+
+	if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR))
+	{                   
+		*val = 0xFF;
+		return PCIBIOS_DEVICE_NOT_FOUND;    
+	} else                                                                
 	{
-		ptr = (unsigned char *)(0x80800000 | (1<<dev) | (offset ^ 1));
+		ptr = (unsigned char *)CFGPTR(dev);
 		_val = *ptr;
 	}
 	*val = _val;
@@ -483,14 +600,14 @@
 {
 	unsigned long _val;
 	unsigned long *ptr;
-	dev >>= 3;
+
 	_val = le32_to_cpu(val);
-	if ((bus != 0) || (dev > MAX_DEVNR))
+	if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR))
 	{
 		return PCIBIOS_DEVICE_NOT_FOUND;
 	} else
 	{
-		ptr = (unsigned long *)(0x80800000 | (1<<dev) | offset);
+		ptr = (unsigned long *)CFGPTR(dev);
 		*ptr = _val;
 	}
 	return PCIBIOS_SUCCESSFUL;
@@ -503,14 +620,14 @@
 {
 	unsigned short _val;
 	unsigned short *ptr;
-	dev >>= 3;
+
 	_val = le16_to_cpu(val);
-	if ((bus != 0) || (dev > MAX_DEVNR))
+	if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR))
 	{
 		return PCIBIOS_DEVICE_NOT_FOUND;
 	} else
 	{
-		ptr = (unsigned short *)(0x80800000 | (1<<dev) | offset);
+		ptr = (unsigned short *)CFGPTR(dev);
 		*ptr = _val;
 	}
 	return PCIBIOS_SUCCESSFUL;
@@ -523,20 +640,151 @@
 {
 	unsigned char _val;
 	unsigned char *ptr;
-	dev >>= 3;
+
 	_val = val;
-	if ((bus != 0) || (dev > MAX_DEVNR))
+	if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR))
 	{
 		return PCIBIOS_DEVICE_NOT_FOUND;
 	} else
 	{
-		ptr = (unsigned char *)(0x80800000 | (1<<dev) | (offset^1));
+		ptr = (unsigned char *)CFGPTR(dev);
 		*ptr = _val;
 	}
 	return PCIBIOS_SUCCESSFUL;
 }
 
-__initfunc(unsigned long route_pci_interrupts(void))
+#define MOTOROLA_CPUTYPE_REG	0x800
+#define MOTOROLA_BASETYPE_REG	0x803
+#define MPIC_RAVEN_ID		0x48010000
+#define	MPIC_HAWK_ID		0x48030000
+#define	MOT_PROC2_BIT		0x800
+
+static u_char mvme2600_openpic_initsenses[] __initdata = {
+    1,	/* MVME2600_INT_SIO */
+    0,	/* MVME2600_INT_FALCN_ECC_ERR */
+    1,	/* MVME2600_INT_PCI_ETHERNET */
+    1,	/* MVME2600_INT_PCI_SCSI */
+    1,	/* MVME2600_INT_PCI_GRAPHICS */
+    1,	/* MVME2600_INT_PCI_VME0 */
+    1,	/* MVME2600_INT_PCI_VME1 */
+    1,	/* MVME2600_INT_PCI_VME2 */
+    1,	/* MVME2600_INT_PCI_VME3 */
+    1,	/* MVME2600_INT_PCI_INTA */
+    1,	/* MVME2600_INT_PCI_INTB */
+    1,	/* MVME2600_INT_PCI_INTC */
+    1,	/* MVME2600_INT_PCI_INTD */
+    1,	/* MVME2600_INT_LM_SIG0 */
+    1,	/* MVME2600_INT_LM_SIG1 */
+};
+
+#define MOT_RAVEN_PRESENT	0x1
+#define MOT_HAWK_PRESENT	0x2
+
+int prep_keybd_present = 1;
+int MotMPIC = 0;
+
+__initfunc(int raven_init(void))
+{
+	unsigned int	devid;
+	unsigned int	pci_membase;
+	unsigned char	base_mod;
+
+	/* Check to see if the Raven chip exists. */
+	if ( _prep_type != _PREP_Motorola) {
+		OpenPIC = NULL;
+		return 0;
+	}
+
+	/* Check to see if this board is a type that might have a Raven. */
+	if ((inb(MOTOROLA_CPUTYPE_REG) & 0xF0) != 0xE0) {
+		OpenPIC = NULL;
+		return 0;
+	}
+
+	/* Check the first PCI device to see if it is a Raven. */
+	pcibios_read_config_dword(0, 0, PCI_VENDOR_ID, &devid);
+
+	switch (devid & 0xffff0000) {
+	case MPIC_RAVEN_ID:
+		MotMPIC = MOT_RAVEN_PRESENT;
+		break;
+	case MPIC_HAWK_ID:
+		MotMPIC = MOT_HAWK_PRESENT;
+		break;
+	default:
+		OpenPIC = NULL;
+		return 0;
+	}
+
+
+	/* Read the memory base register. */
+	pcibios_read_config_dword(0, 0, PCI_BASE_ADDRESS_1, &pci_membase);
+
+	if (pci_membase == 0) {
+		OpenPIC = NULL;
+		return 0;
+	}
+
+	/* Map the Raven MPIC registers to virtual memory. */
+	OpenPIC = (struct OpenPIC *)ioremap(pci_membase+0xC0000000, 0x22000);
+
+	OpenPIC_InitSenses = mvme2600_openpic_initsenses;
+	OpenPIC_NumInitSenses = sizeof(mvme2600_openpic_initsenses);
+
+	/* If raven is present on Motorola store the system config register
+	 * for later use.
+	 */
+	ProcInfo = (unsigned long *)ioremap(0xfef80400, 4);
+
+	/* This is a hack.  If this is a 2300 or 2400 mot board then there is
+	 * no keyboard controller and we have to indicate that.
+	 */
+	base_mod = inb(MOTOROLA_BASETYPE_REG);
+	if ((MotMPIC == MOT_HAWK_PRESENT) || (base_mod == 0xF9) ||
+	    (base_mod == 0xFA) || (base_mod == 0xE1))
+		prep_keybd_present = 0;
+
+	return 1;
+}
+
+struct mot_info {
+	int		cpu_type;	/* 0x100 mask assumes for Raven and Hawk boards that the level/edge are set */
+					/* 0x200 if this board has a Hawk chip. */
+	int		base_type;
+	int		max_cpu;	/* ored with 0x80 if this board should be checked for multi CPU */
+	const char	*name;
+	unsigned char	*map;
+	unsigned char	*routes;
+} mot_info[] = {
+	{0x300, 0x00, 0x00, "MVME 2400",			Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes},
+	{0x010, 0x00, 0x00, "Genesis",				Genesis_pci_IRQ_map,	Genesis_pci_IRQ_routes},
+	{0x020, 0x00, 0x00, "Powerstack (Series E)",		Comet_pci_IRQ_map,	Comet_pci_IRQ_routes},
+	{0x040, 0x00, 0x00, "Blackhawk (Powerstack)",		Blackhawk_pci_IRQ_map,	Blackhawk_pci_IRQ_routes},
+	{0x050, 0x00, 0x00, "Omaha (PowerStack II Pro3000)",	Omaha_pci_IRQ_map,	Omaha_pci_IRQ_routes},
+	{0x060, 0x00, 0x00, "Utah (Powerstack II Pro4000)",	Utah_pci_IRQ_map,	Utah_pci_IRQ_routes},
+	{0x0A0, 0x00, 0x00, "Powerstack (Series EX)",		Comet2_pci_IRQ_map,	Comet2_pci_IRQ_routes},
+	{0x1E0, 0xE0, 0x00, "Mesquite cPCI (MCP750)",		Mesquite_pci_IRQ_map,	Raven_pci_IRQ_routes},
+	{0x1E0, 0xE1, 0x00, "Sitka cPCI (MCPN750)",		Sitka_pci_IRQ_map,	Raven_pci_IRQ_routes},
+	{0x1E0, 0xE2, 0x00, "Mesquite cPCI (MCP750) w/ HAC",	Mesquite_pci_IRQ_map,	Raven_pci_IRQ_routes},
+	{0x1E0, 0xF6, 0x80, "MTX Plus",				MTXplus_pci_IRQ_map,	Raven_pci_IRQ_routes},
+	{0x1E0, 0xF6, 0x81, "Dual MTX Plus",			MTXplus_pci_IRQ_map,	Raven_pci_IRQ_routes},
+	{0x1E0, 0xF7, 0x80, "MTX wo/ Parallel Port",		MTX_pci_IRQ_map,	Raven_pci_IRQ_routes},
+	{0x1E0, 0xF7, 0x81, "Dual MTX wo/ Parallel Port",	MTX_pci_IRQ_map,	Raven_pci_IRQ_routes},
+	{0x1E0, 0xF8, 0x80, "MTX w/ Parallel Port",		MTX_pci_IRQ_map,	Raven_pci_IRQ_routes},
+	{0x1E0, 0xF8, 0x81, "Dual MTX w/ Parallel Port",	MTX_pci_IRQ_map,	Raven_pci_IRQ_routes},
+	{0x1E0, 0xF9, 0x00, "MVME 2300",			Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes},
+	{0x1E0, 0xFA, 0x00, "MVME 2300SC/2600",			Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes},
+	{0x1E0, 0xFB, 0x00, "MVME 2600 with MVME712M",		Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes},
+	{0x1E0, 0xFC, 0x00, "MVME 2600/2700 with MVME761",	Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes},
+	{0x1E0, 0xFD, 0x80, "MVME 3600 with MVME712M",		Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes},
+	{0x1E0, 0xFD, 0x81, "MVME 4600 with MVME712M",		Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes},
+	{0x1E0, 0xFE, 0x80, "MVME 3600 with MVME761",		Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes},
+	{0x1E0, 0xFE, 0x81, "MVME 4600 with MVME761",		Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes},
+	{0x1E0, 0xFF, 0x00, "MVME 1600-001 or 1600-011",	Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes},
+	{0x000, 0x00, 0x00, "",					NULL,			NULL}
+};
+
+__initfunc(unsigned long prep_route_pci_interrupts(void))
 {
 	unsigned char *ibc_pirq = (unsigned char *)0x80800860;
 	unsigned char *ibc_pcicon = (unsigned char *)0x80800840;
@@ -545,49 +793,66 @@
 	if ( _prep_type == _PREP_Motorola)
 	{
 		unsigned short irq_mode;
+		unsigned char  cpu_type;
+		unsigned char  base_mod;
+		int	       entry;
+		int	       mot_entry = -1;
+
+		cpu_type = inb(MOTOROLA_CPUTYPE_REG) & 0xF0;
+		base_mod = inb(MOTOROLA_BASETYPE_REG);
+
+		for (entry = 0; mot_info[entry].cpu_type != 0; entry++) {
+			if (mot_info[entry].cpu_type & 0x200) {		 	/* Check for Hawk chip */
+				if (!(MotMPIC & MOT_HAWK_PRESENT))
+					continue;
+			} else {						/* Check non hawk boards */
+				if ((mot_info[entry].cpu_type & 0xff) != cpu_type)
+					continue;
+
+				if (mot_info[entry].base_type == 0) {
+					mot_entry = entry;
+					break;
+				}
 
-		switch (inb(0x800) & 0xF0)
-		{
-		case 0x10: /* MVME16xx */
-			Motherboard_map_name = "Genesis";
-			Motherboard_map = Genesis_pci_IRQ_map;
-			Motherboard_routes = Genesis_pci_IRQ_routes;
-			break;
-		case 0x20: /* Series E */
-			Motherboard_map_name = "Powerstack (Series E)";
-			Motherboard_map = Comet_pci_IRQ_map;
-			Motherboard_routes = Comet_pci_IRQ_routes;
-			break;
-		case 0x50: /* PowerStackII Pro3000 */
-			Motherboard_map_name = "Omaha (PowerStack II Pro3000)";
-			Motherboard_map = Omaha_pci_IRQ_map;
-			Motherboard_routes = Omaha_pci_IRQ_routes;
-			break;
-		case 0x60: /* PowerStackII Pro4000 */
-			Motherboard_map_name = "Utah (Powerstack II Pro4000)";
-			Motherboard_map = Utah_pci_IRQ_map;
-			Motherboard_routes = Utah_pci_IRQ_routes;
-			break;
-                case 0xE0: /* MTX -- close enough?? to Genesis, so reuse it */
-                        Motherboard_map_name = "Motorola MTX";
-                        Motherboard_map = Genesis_pci_IRQ_map;
-                        Motherboard_routes = Genesis_pci_IRQ_routes;
-                        break;
-		case 0x40: /* PowerStack */
-		default: /* Can't hurt, can it? */
-			Motherboard_map_name = "Blackhawk (Powerstack)";
-			Motherboard_map = Blackhawk_pci_IRQ_map;
-			Motherboard_routes = Blackhawk_pci_IRQ_routes;
-			break;
+				if (mot_info[entry].base_type != base_mod)
+					continue;
+			}
+
+			if (!(mot_info[entry].max_cpu & 0x80)) {
+				mot_entry = entry;
+				break;
+			}
+
+			/* processor 1 not present and max processor zero indicated */
+			if ((*ProcInfo & MOT_PROC2_BIT) && !(mot_info[entry].max_cpu & 0x7f)) {
+				mot_entry = entry;
+				break;
+			}
+
+			/* processor 1 present and max processor zero indicated */
+			if (!(*ProcInfo & MOT_PROC2_BIT) && (mot_info[entry].max_cpu & 0x7f)) {
+				mot_entry = entry;
+				break;
+			}
 		}
-		/* AJF adjust level/edge control according to routes */
-		irq_mode = 0;
-		for (i = 1;  i <= 4;  i++)
-		{
-			irq_mode |= ( 1 << Motherboard_routes[i] );
+
+		if (mot_entry == -1) 	/* No particular cpu type found - assume Blackhawk */
+			mot_entry = 3;
+
+		Motherboard_map_name = (unsigned char *)mot_info[mot_entry].name;
+		Motherboard_map = mot_info[mot_entry].map;
+		Motherboard_routes = mot_info[mot_entry].routes;
+
+		if (!(mot_info[entry].cpu_type & 0x100)) {
+			/* AJF adjust level/edge control according to routes */
+			irq_mode = 0;
+			for (i = 1;  i <= 4;  i++)
+			{
+				irq_mode |= ( 1 << Motherboard_routes[i] );
+			}
+			outb( irq_mode & 0xff, 0x4d0 );
+			outb( (irq_mode >> 8) & 0xff, 0x4d1 );
 		}
-		outb( irq_mode & 0xff, 0x4d0 );
-		outb( (irq_mode >> 8) & 0xff, 0x4d1 );
 	} else if ( _prep_type == _PREP_IBM )
 	{
 		unsigned char pl_id;
@@ -705,5 +970,119 @@
 	/* Enable PCI interrupts */
 	*ibc_pcicon |= 0x20;
 	return 0;
+}
+
+__initfunc(
+void
+prep_pcibios_fixup(void))
+{
+        struct pci_dev *dev;
+        extern unsigned char *Motherboard_map;
+        extern unsigned char *Motherboard_routes;
+        unsigned char i;
+
+        if ( _prep_type == _PREP_Radstone )
+        {
+                printk("Radstone boards require no PCI fixups\n");
+		return;
+        }
+
+	prep_route_pci_interrupts();
+
+	printk("Setting PCI interrupts for a \"%s\"\n", Motherboard_map_name);
+	if (OpenPIC) {
+		/* PCI interrupts are controlled by the OpenPIC */
+		for(dev=pci_devices; dev; dev=dev->next) {
+			if (dev->bus->number == 0) {
+                       		dev->irq = openpic_to_irq(Motherboard_map[PCI_SLOT(dev->devfn)]);
+				pcibios_write_config_byte(dev->bus->number, dev->devfn, PCI_INTERRUPT_PIN, dev->irq);
+			}
+		}
+		return;
+	}
+
+	for(dev=pci_devices; dev; dev=dev->next)
+	{
+		/*
+		 * Use our old hard-coded kludge to figure out what
+		 * irq this device uses.  This is necessary on things
+		 * without residual data. -- Cort
+		 */
+		unsigned char d = PCI_SLOT(dev->devfn);
+		dev->irq = Motherboard_routes[Motherboard_map[d]];
+
+		for ( i = 0 ; i <= 5 ; i++ )
+		{
+		        if ( dev->base_address[i] > 0x10000000 )
+		        {
+		                printk("Relocating PCI address %lx -> %lx\n",
+		                       dev->base_address[i],
+		                       (dev->base_address[i] & 0x00FFFFFF)
+		                       | 0x01000000);
+		                dev->base_address[i] =
+		                  (dev->base_address[i] & 0x00FFFFFF) | 0x01000000;
+		                pci_write_config_dword(dev,
+		                        PCI_BASE_ADDRESS_0+(i*0x4),
+		                       dev->base_address[i] );
+		        }
+		}
+#if 0
+		/*
+		 * If we have residual data and if it knows about this
+		 * device ask it what the irq is.
+		 *  -- Cort
+		 */
+		ppcd = residual_find_device_id( ~0L, dev->device,
+		                                -1,-1,-1, 0);
+#endif
+	}
+}
+
+decl_config_access_method(indirect);
+
+__initfunc(
+void
+prep_setup_pci_ptrs(void))
+{
+	PPC_DEVICE *hostbridge;
+
+        printk("PReP architecture\n");
+        if ( _prep_type == _PREP_Radstone )
+        {
+		pci_config_address = (unsigned *)0x80000cf8;
+		pci_config_data = (char *)0x80000cfc;
+                set_config_access_method(indirect);		
+        }
+        else
+        {
+                hostbridge = residual_find_device(PROCESSORDEVICE, NULL,
+		       BridgeController, PCIBridge, -1, 0);
+                if (hostbridge &&
+                    hostbridge->DeviceId.Interface == PCIBridgeIndirect) {
+                        PnP_TAG_PACKET * pkt;
+                        set_config_access_method(indirect);
+                        pkt = PnP_find_large_vendor_packet(
+				res->DevicePnPHeap+hostbridge->AllocatedOffset,
+				3, 0);
+                        if(pkt)
+			{
+#define p pkt->L4_Pack.L4_Data.L4_PPCPack
+                                pci_config_address= (unsigned *)ld_le32((unsigned *) p.PPCData);
+				pci_config_data= (unsigned char *)ld_le32((unsigned *) (p.PPCData+8));
+                        }
+			else
+			{
+                                pci_config_address= (unsigned *) 0x80000cf8;
+                                pci_config_data= (unsigned char *) 0x80000cfc;
+                        }
+                }
+		else
+		{
+                        set_config_access_method(prep);
+                }
+
+        }
+
+	ppc_md.pcibios_fixup = prep_pcibios_fixup;
 }
 

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