POWER3 TCE updates

Anton Blanchard anton at samba.org
Mon Mar 15 01:59:05 EST 2004


Hi,

We currently always allocate a TCE table that maps 2GB. Unfortunately
there is at least one pSeries machine that has a 3GB IO hole, the
nighthawk2 node. The following patch checks where the IO hole starts
and will only use 1GB of the TCE table if it starts below 2GB.

While I was in the area, I upped the maximum number of PHBs to give us
some breathing room (it would be nice to make of_tce_table[] initdata
but its currently referenced in IOMMU functions not marked __init).

We also now only allocate a 4MB tce table on POWER3/RS64, we were only
allocating an 8MB due to a firmware/hardware interaction on POWER4.

Does it look OK? I havent tested it yet but I hope to tomorrow.

Anton

---

 forakpm-anton/arch/ppc64/kernel/pSeries_iommu.c |   13 ++++++++++++-
 forakpm-anton/arch/ppc64/kernel/prom.c          |   17 +++++++++--------
 2 files changed, 21 insertions(+), 9 deletions(-)

diff -puN arch/ppc64/kernel/prom.c~power3_pci arch/ppc64/kernel/prom.c
--- forakpm/arch/ppc64/kernel/prom.c~power3_pci	2004-03-15 01:44:39.173340849 +1100
+++ forakpm-anton/arch/ppc64/kernel/prom.c	2004-03-15 01:46:13.348758313 +1100
@@ -138,8 +138,8 @@ extern struct rtas_t rtas;
 extern unsigned long klimit;
 extern struct lmb lmb;

-#define MAX_PHB 16 * 3  // 16 Towers * 3 PHBs/tower
-struct _of_tce_table of_tce_table[MAX_PHB + 1] = {{0, 0, 0}};
+#define MAX_PHB 24 * 6  /* 24 drawers * 6 PHBs/drawer */
+struct _of_tce_table of_tce_table[MAX_PHB + 1];

 char *bootpath = 0;
 char *bootdevice = 0;
@@ -848,20 +848,21 @@ prom_initialize_tce_table(void)
 			minsize = 4UL << 20;
 		}

-		/* Even though we read what OF wants, we just set the table
+		/*
+		 * Even though we read what OF wants, we just set the table
 		 * size to 4 MB.  This is enough to map 2GB of PCI DMA space.
 		 * By doing this, we avoid the pitfalls of trying to DMA to
 		 * MMIO space and the DMA alias hole.
-		 */
-		/*
+		 *
 		 * On POWER4, firmware sets the TCE region by assuming
 		 * each TCE table is 8MB. Using this memory for anything
 		 * else will impact performance, so we always allocate 8MB.
 		 * Anton
-		 *
-		 * XXX FIXME use a cpu feature here
 		 */
-		minsize = 8UL << 20;
+		if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p))
+			minsize = 8UL << 20;
+		else
+			minsize = 4UL << 20;

 		/* Align to the greater of the align or size */
 		align = max(minalign, minsize);
diff -puN arch/ppc64/kernel/pSeries_iommu.c~power3_pci arch/ppc64/kernel/pSeries_iommu.c
--- forakpm/arch/ppc64/kernel/pSeries_iommu.c~power3_pci	2004-03-15 01:36:23.063897211 +1100
+++ forakpm-anton/arch/ppc64/kernel/pSeries_iommu.c	2004-03-15 01:41:39.493396173 +1100
@@ -104,6 +104,17 @@ static void iommu_buses_init(void)
 	struct device_node *dn, *first_dn;
 	int num_slots, num_slots_ilog2;
 	int first_phb = 1;
+	unsigned long tcetable_ilog2;
+
+	/*
+	 * We default to a TCE table that maps 2GB (4MB table, 22 bits),
+	 * however some machines have a 3GB IO hole and for these we
+	 * create a table that maps 1GB (2MB table, 21 bits)
+	 */
+	if (io_hole_start < 0x80000000UL)
+		tcetable_ilog2 = 21;
+	else
+		tcetable_ilog2 = 22;

 	/* XXX Should we be using pci_root_buses instead?  -ojn
 	 */
@@ -119,7 +130,7 @@ static void iommu_buses_init(void)
 		if ((1<<num_slots_ilog2) != num_slots)
 			num_slots_ilog2++;

-		phb->dma_window_size = 1 << (22 - num_slots_ilog2);
+		phb->dma_window_size = 1 << (tcetable_ilog2 - num_slots_ilog2);

 		/* Reserve 16MB of DMA space on the first PHB.
 		 * We should probably be more careful and use firmware props.

_

** Sent via the linuxppc64-dev mail list. See http://lists.linuxppc.org/





More information about the Linuxppc64-dev mailing list