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