[PATCH] PPC64: Fix non-LPAR IOMMU table allocation on pSeries

Olof Johansson olof at lixom.net
Wed Aug 10 13:24:37 EST 2005


Hi,

This is for the 2.6.14 feed. I wouldn't recommend pushing it into
2.6.13 due to risk of regressing some box that I don't have access to
for testing.

I'd appreciate it if people with pre-POWER5, non-LPAR machines would give
this a go on their boxes and let me know if something falls apart. It's
been tested on an F80 and a p650 (SMP mode) here. p615 and p630 have
been sore spots in the past.

---

Some RS64 systems (such as F80) have non-python host bridges with EADS.
However, they have two EADS with 4 buses each under them, so the logic
that assumed no more than 7 busses per PHB failed miserably.

Try to be a bit smarter at detecting the need for a PHB-level IOMMU table
by checking for the presence of an ISA bus. Only PHBs with ISA bridges should
need the PHB-level table.

Signed-off-by: Olof Johansson <olof at lixom.net>

Index: 2.6/arch/ppc64/kernel/pSeries_iommu.c
===================================================================
--- 2.6.orig/arch/ppc64/kernel/pSeries_iommu.c	2005-08-09 03:20:04.000000000 -0500
+++ 2.6/arch/ppc64/kernel/pSeries_iommu.c	2005-08-09 03:25:54.000000000 -0500
@@ -311,6 +311,7 @@ static void iommu_bus_setup_pSeries(stru
 {
 	struct device_node *dn, *pdn;
 	struct iommu_table *tbl;
+	struct device_node *isa_dn;
 
 	DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self);
 
@@ -328,18 +329,22 @@ static void iommu_bus_setup_pSeries(stru
 	if (!bus->self) {
 		/* Root bus */
 		if (is_python(dn)) {
-			unsigned int *iohole;
-
 			DBG("Python root bus %s\n", bus->name);
 
-			iohole = (unsigned int *)get_property(dn, "io-hole", 0);
+			/* Check if the ISA bus on the system is under
+			 * this PHB.
+			 */
+			isa_dn = of_find_node_by_type(NULL, "isa");
+			
+			while (isa_dn && isa_dn != dn)
+				isa_dn = isa_dn->parent;
 
-			if (iohole) {
+			if (isa_dn) {
 				/* On first bus we need to leave room for the
 				 * ISA address space. Just skip the first 256MB
 				 * alltogether. This leaves 768MB for the window.
 				 */
-				DBG("PHB has io-hole, reserving 256MB\n");
+				DBG("PHB has isa bus, reserving 256MB\n");
 				dn->phb->dma_window_size = 3 << 28;
 				dn->phb->dma_window_base_cur = 1 << 28;
 			} else {
@@ -353,15 +358,36 @@ static void iommu_bus_setup_pSeries(stru
 			iommu_table_setparms(dn->phb, dn, tbl);
 			dn->iommu_table = iommu_init_table(tbl);
 		} else {
-			/* Do a 128MB table at root. This is used for the IDE
-			 * controller on some SMP-mode POWER4 machines. It
-			 * doesn't hurt to allocate it on other machines
-			 * -- it'll just be unused since new tables are
-			 * allocated on the EADS level.
+			/* Do a 128MB table at root if there is an ISA bus
+			 * under our PHB. This is used for the IDE
+			 * controller on some SMP-mode POWER4 machines.
 			 *
 			 * Allocate at offset 128MB to avoid having to deal
 			 * with ISA holes; 128MB table for IDE is plenty.
 			 */
+			/* Check if the ISA bus on the system is under
+			 * this PHB.
+			 */
+			isa_dn = of_find_node_by_type(NULL, "isa");
+			
+			while (isa_dn && isa_dn != dn)
+				isa_dn = isa_dn->parent;
+
+			if (!isa_dn) {
+				/* No ISA/IDE, no table needed. All I/O is under
+				 * EADS bridges. All we need to do is set
+				 * base values.
+				 */
+				dn->phb->dma_window_size = 1 << 28;
+				dn->phb->dma_window_base_cur = 0;
+				return;
+			}
+
+			/* If we have ISA, then we probably have an IDE
+			 * controller too. Allocate a 128MB table but
+			 * skip the first 128MB to avoid stepping on ISA
+			 * space.
+			 */
 			dn->phb->dma_window_size = 1 << 27;
 			dn->phb->dma_window_base_cur = 1 << 27;
 



More information about the Linuxppc64-dev mailing list