pSeries iommu=off

Anton Blanchard anton at samba.org
Mon Mar 15 02:11:31 EST 2004


Hi,

Here is a patch to implement iommu=off on pSeries similar to how we
do it on g5. I moved the cmdline parsing into a common
early_cmdline_parse function and also made the memory limiting a little
more robust.

It should get some g5 testing to prove I didnt break things before
merging.

Anton

===== arch/ppc64/kernel/chrp_setup.c 1.58 vs edited =====
--- 1.58/arch/ppc64/kernel/chrp_setup.c	Tue Mar  2 00:40:28 2004
+++ edited/arch/ppc64/kernel/chrp_setup.c	Wed Mar 10 15:33:44 2004
@@ -205,15 +205,17 @@
 		fwnmi_active = 1;
 }

-
 /* Early initialization.  Relocation is on but do not reference unbolted pages */
 void __init pSeries_init_early(void)
 {
-#ifdef CONFIG_PPC_PSERIES	/* This ifdef should go away */
 	void *comport;

 	hpte_init_pSeries();
-	tce_init_pSeries();
+
+	if (ppc64_iommu_off)
+		pci_dma_init_direct();
+	else
+		tce_init_pSeries();

 #ifdef CONFIG_SMP
 	smp_init_pSeries();
@@ -226,7 +228,6 @@
 	ppc_md.udbg_putc = udbg_putc;
 	ppc_md.udbg_getc = udbg_getc;
 	ppc_md.udbg_getc_poll = udbg_getc_poll;
-#endif
 }

 void __init
===== arch/ppc64/kernel/pSeries_pci.c 1.38 vs edited =====
--- 1.38/arch/ppc64/kernel/pSeries_pci.c	Mon Mar  1 13:24:57 2004
+++ edited/arch/ppc64/kernel/pSeries_pci.c	Wed Mar 10 15:33:33 2004
@@ -699,7 +699,8 @@
 	phbs_fixup_io();
 	chrp_request_regions();
 	pci_fix_bus_sysdata();
-	iommu_setup_pSeries();
+	if (!ppc64_iommu_off)
+		iommu_setup_pSeries();
 }

 /***********************************************************************
===== arch/ppc64/kernel/prom.c 1.68 vs edited =====
--- 1.68/arch/ppc64/kernel/prom.c	Mon Mar  1 13:24:58 2004
+++ edited/arch/ppc64/kernel/prom.c	Wed Mar 10 17:19:53 2004
@@ -295,7 +295,6 @@
 	prom_print(RELOC("\n"));
 }

-
 static unsigned long
 prom_initialize_naca(unsigned long mem)
 {
@@ -311,7 +310,7 @@
 #ifdef DEBUG_PROM
 	prom_print(RELOC("prom_initialize_naca: start...\n"));
 #endif
-
+
 	_naca->pftSize = 0;	/* ilog2 of htab size.  computed below. */

         for (node = 0; prom_next_node(&node); ) {
@@ -516,25 +515,14 @@
 	return mem;
 }

-#ifdef CONFIG_PMAC_DART
-static int dart_force_on;
-#endif
+static int iommu_force_on;
+int ppc64_iommu_off;

-static unsigned long __init
-prom_initialize_lmb(unsigned long mem)
+static void early_cmdline_parse(void)
 {
-	phandle node;
-	char type[64];
-        unsigned long i, offset = reloc_offset();
-	struct prom_t *_prom = PTRRELOC(&prom);
-        struct systemcfg *_systemcfg = RELOC(systemcfg);
-	union lmb_reg_property reg;
-	unsigned long lmb_base, lmb_size;
-	unsigned long num_regs, bytes_per_reg = (_prom->encode_phys_size*2)/8;
-	int nodart = 0;
-
-#ifdef CONFIG_PMAC_DART
+	unsigned long offset = reloc_offset();
 	char *opt;
+	struct systemcfg *_systemcfg = RELOC(systemcfg);

 	opt = strstr(RELOC(cmd_line), RELOC("iommu="));
 	if (opt) {
@@ -545,16 +533,30 @@
 		while (*opt && *opt == ' ')
 			opt++;
 		if (!strncmp(opt, RELOC("off"), 3))
-			nodart = 1;
+			RELOC(ppc64_iommu_off) = 1;
 		else if (!strncmp(opt, RELOC("force"), 5))
-			RELOC(dart_force_on) = 1;
+			RELOC(iommu_force_on) = 1;
 	}
-#else
-	nodart = 1;
-#endif /* CONFIG_PMAC_DART */

-	if (nodart)
+#ifndef CONFIG_PMAC_DART
+	if (_systemcfg->platform == PLATFORM_POWERMAC) {
+		RELOC(ppc64_iommu_off) = 1;
 		prom_print(RELOC("DART disabled on PowerMac !\n"));
+	}
+#endif
+}
+
+static unsigned long __init
+prom_initialize_lmb(unsigned long mem)
+{
+	phandle node;
+	char type[64];
+        unsigned long i, offset = reloc_offset();
+	struct prom_t *_prom = PTRRELOC(&prom);
+        struct systemcfg *_systemcfg = RELOC(systemcfg);
+	union lmb_reg_property reg;
+	unsigned long lmb_base, lmb_size;
+	unsigned long num_regs, bytes_per_reg = (_prom->encode_phys_size*2)/8;

 	lmb_init();

@@ -580,11 +582,6 @@
 				lmb_base = ((unsigned long)reg.addrPM[i].address_hi) << 32;
 				lmb_base |= (unsigned long)reg.addrPM[i].address_lo;
 				lmb_size = reg.addrPM[i].size;
-				if (nodart && lmb_base > 0x80000000ull) {
-					prom_print(RELOC("Skipping memory above 2Gb for "
-							 "now, DART support disabled\n"));
-					continue;
-				}
 			} else if (_prom->encode_phys_size == 32) {
 				lmb_base = reg.addr32[i].address;
 				lmb_size = reg.addr32[i].size;
@@ -593,7 +590,16 @@
 				lmb_size = reg.addr64[i].size;
 			}

-			if ( lmb_add(lmb_base, lmb_size) < 0 )
+			/* We limit memory to 2GB if the IOMMU is off */
+			if (RELOC(ppc64_iommu_off)) {
+				if (lmb_base >= 0x80000000UL)
+					continue;
+
+				if ((lmb_base + lmb_size) > 0x80000000UL)
+					lmb_size = 0x80000000UL - lmb_base;
+			}
+
+			if (lmb_add(lmb_base, lmb_size) < 0)
 				prom_print(RELOC("Too many LMB's, discarding this one...\n"));
 		}

@@ -788,7 +794,6 @@
 }
 #endif /* CONFIG_PMAC_DART */

-
 void
 prom_initialize_tce_table(void)
 {
@@ -802,6 +807,9 @@
 	struct _of_tce_table *prom_tce_table = RELOC(of_tce_table);
 	unsigned long tce_entry, *tce_entryp;

+	if (RELOC(ppc64_iommu_off))
+		return;
+
 #ifdef DEBUG_PROM
 	prom_print(RELOC("starting prom_initialize_tce_table\n"));
 #endif
@@ -1563,6 +1571,8 @@
 		if (p != NULL && p[0] != 0)
 			strlcpy(RELOC(cmd_line), p, sizeof(cmd_line));
 	}
+
+	early_cmdline_parse();

 	mem = prom_initialize_lmb(mem);

===== include/asm-ppc64/iommu.h 1.2 vs edited =====
--- 1.2/include/asm-ppc64/iommu.h	Thu Mar  4 00:26:24 2004
+++ edited/include/asm-ppc64/iommu.h	Wed Mar 10 15:37:25 2004
@@ -152,4 +152,6 @@
 extern void pci_iommu_init(void);
 extern void pci_dma_init_direct(void);

+extern int ppc64_iommu_off;
+
 #endif

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





More information about the Linuxppc64-dev mailing list