[OpenBIOS] [commit] r679 - in trunk/openbios-devel: drivers include/openbios

repository service svn at openbios.org
Mon Feb 22 19:52:27 CET 2010


Author: agraf
Date: Mon Feb 22 19:52:26 2010
New Revision: 679
URL: http://tracker.coreboot.org/trac/openbios/changeset/679

Log:
PPC: Create interrupt map for PCI

There is a draft spec that defines how interrupts are supposed to be mapped
from one bus to another, down to the PIC and CPU interrupt line.

So far we don't implement that spec. But PPC64 Linux requires us to for PCI
devices. So let's create a map here.

Draft: http://playground.sun.com/1275/practice/imap/imap0_9d.pdf

Signed-off-by: Alexander Graf <agraf at suse.de>

Modified:
   trunk/openbios-devel/drivers/macio.c
   trunk/openbios-devel/drivers/pci.c
   trunk/openbios-devel/include/openbios/pci.h

Modified: trunk/openbios-devel/drivers/macio.c
==============================================================================
--- trunk/openbios-devel/drivers/macio.c	Mon Feb 22 19:52:25 2010	(r678)
+++ trunk/openbios-devel/drivers/macio.c	Mon Feb 22 19:52:26 2010	(r679)
@@ -18,6 +18,7 @@
 #include "macio.h"
 #include "cuda.h"
 #include "escc.h"
+#include "openbios/pci.h"
 
 #define OW_IO_NVRAM_SIZE   0x00020000
 #define OW_IO_NVRAM_OFFSET 0x00060000
@@ -172,9 +173,13 @@
         fword("finish-device");
 
         if (is_newworld()) {
+            u32 *interrupt_map;
+            int len, i;
+
             /* patch in interrupt parent */
             dnode = find_dev(buf);
-            target_node = find_dev("/pci");
+
+            target_node = find_dev("/pci/mac-io");
             set_int_property(target_node, "interrupt-parent", dnode);
 
             target_node = find_dev("/pci/mac-io/escc/ch-a");
@@ -182,6 +187,15 @@
 
             target_node = find_dev("/pci/mac-io/escc/ch-b");
             set_int_property(target_node, "interrupt-parent", dnode);
+
+            target_node = find_dev("/pci");
+            set_int_property(target_node, "interrupt-parent", dnode);
+
+            interrupt_map = (u32 *)get_property(target_node, "interrupt-map", &len);
+            for (i = 0; i < 4; i++) {
+                interrupt_map[(i * 7) + PCI_INT_MAP_PIC_HANDLE] = (u32)dnode;
+            }
+            set_property(target_node, "interrupt-map", (char *)interrupt_map, len);
         }
 }
 

Modified: trunk/openbios-devel/drivers/pci.c
==============================================================================
--- trunk/openbios-devel/drivers/pci.c	Mon Feb 22 19:52:25 2010	(r678)
+++ trunk/openbios-devel/drivers/pci.c	Mon Feb 22 19:52:26 2010	(r679)
@@ -278,6 +278,47 @@
 	set_property(dev, "bus-range", (char *)props, 2 * sizeof(props[0]));
 }
 
+static void pci_host_set_interrupt_map(const pci_config_t *config)
+{
+/* XXX We currently have a hook in the MPIC init code to fill in its handle.
+ *     If you want to have interrupt maps for your PCI host bus, add your
+ *     architecture to the #if and make your bridge detect code fill in its
+ *     handle too.
+ *
+ *     It would be great if someone clever could come up with a more universal
+ *     mechanism here.
+ */
+#if defined(CONFIG_PPC)
+	phandle_t dev = get_cur_dev();
+	u32 props[7 * 4];
+	int i;
+
+#if defined(CONFIG_PPC)
+	/* Oldworld macs do interrupt maps differently */
+	if(!is_newworld())
+		return;
+#endif
+
+	for (i = 0; i < (7*4); i+=7) {
+		props[i+PCI_INT_MAP_PCI0] = 0;
+		props[i+PCI_INT_MAP_PCI1] = 0;
+		props[i+PCI_INT_MAP_PCI2] = 0;
+		props[i+PCI_INT_MAP_PCI_INT] = (i / 7) + 1; // starts at PINA=1
+		props[i+PCI_INT_MAP_PIC_HANDLE] = 0; // gets patched in later
+		props[i+PCI_INT_MAP_PIC_INT] = arch->irqs[i / 7];
+		props[i+PCI_INT_MAP_PIC_POL] = 3;
+	}
+	set_property(dev, "interrupt-map", (char *)props, 7 * 4 * sizeof(props[0]));
+
+	props[PCI_INT_MAP_PCI0] = 0;
+	props[PCI_INT_MAP_PCI1] = 0;
+	props[PCI_INT_MAP_PCI2] = 0;
+	props[PCI_INT_MAP_PCI_INT] = 0x7;
+
+	set_property(dev, "interrupt-map-mask", (char *)props, 4 * sizeof(props[0]));
+#endif
+}
+
 static void pci_host_set_reg(const pci_config_t *config)
 {
 	phandle_t dev = get_cur_dev();
@@ -344,6 +385,7 @@
 	pci_host_set_reg(config);
 	pci_host_set_ranges(config);
 	pci_set_bus_range(config);
+	pci_host_set_interrupt_map(config);
 
 	return 0;
 }

Modified: trunk/openbios-devel/include/openbios/pci.h
==============================================================================
--- trunk/openbios-devel/include/openbios/pci.h	Mon Feb 22 19:52:25 2010	(r678)
+++ trunk/openbios-devel/include/openbios/pci.h	Mon Feb 22 19:52:26 2010	(r679)
@@ -24,6 +24,16 @@
 
 extern const pci_arch_t *arch;
 
+/* Device tree offsets */
+
+#define PCI_INT_MAP_PCI0         0
+#define PCI_INT_MAP_PCI1         1
+#define PCI_INT_MAP_PCI2         2
+#define PCI_INT_MAP_PCI_INT      3
+#define PCI_INT_MAP_PIC_HANDLE   4
+#define PCI_INT_MAP_PIC_INT      5
+#define PCI_INT_MAP_PIC_POL      6
+
 /* Device classes and subclasses */
 
 #define PCI_BASE_CLASS_STORAGE           0x01



More information about the OpenBIOS mailing list