[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