iopte_val(*iopte) = val;
 }
 
-void pci_iommu_table_init(struct pci_iommu *iommu, int tsbsize)
+void pci_iommu_table_init(struct pci_iommu *iommu, int tsbsize, u32 dma_offset, u32 dma_addr_mask)
 {
-       int i;
+       unsigned long i, tsbbase, order;
+
+       /* Setup initial software IOMMU state. */
+       spin_lock_init(&iommu->lock);
+       iommu->ctx_lowest_free = 1;
+       iommu->page_table_map_base = dma_offset;
+       iommu->dma_addr_mask = dma_addr_mask;
+
+       switch (tsbsize / (8 * 1024)) {
+       case 64:
+               iommu->page_table_sz_bits = 16;
+               break;
+       case 128:
+               iommu->page_table_sz_bits = 17;
+               break;
+       default:
+               prom_printf("PCI_IOMMU: Illegal TSB size %d\n",
+                           tsbsize / (8 * 1024));
+               prom_halt();
+               break;
+       };
+
+       iommu->lowest_consistent_map =
+               1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS);
+
+       for (i = 0; i < PBM_NCLUSTERS; i++) {
+               iommu->alloc_info[i].flush = 0;
+               iommu->alloc_info[i].next = 0;
+       }
 
-       tsbsize /= sizeof(iopte_t);
+       /* Allocate and initialize the dummy page which we
+        * set inactive IO PTEs to point to.
+        */
+       iommu->dummy_page = __get_free_pages(GFP_KERNEL, 0);
+       if (!iommu->dummy_page) {
+               prom_printf("PCI_IOMMU: Error, gfp(dummy_page) failed.\n");
+               prom_halt();
+       }
+       memset((void *)iommu->dummy_page, 0, PAGE_SIZE);
+       iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page);
+
+       /* Now allocate and setup the IOMMU page table itself.  */
+       order = get_order(tsbsize);
+       tsbbase = __get_free_pages(GFP_KERNEL, order);
+       if (!tsbbase) {
+               prom_printf("PCI_IOMMU: Error, gfp(tsb) failed.\n");
+               prom_halt();
+       }
+       iommu->page_table = (iopte_t *)tsbbase;
 
-       for (i = 0; i < tsbsize; i++)
+       for (i = 0; i < tsbsize / sizeof(iopte_t); i++)
                iopte_make_dummy(iommu, &iommu->page_table[i]);
 }
 
 
 static void psycho_iommu_init(struct pci_controller_info *p)
 {
        struct pci_iommu *iommu = p->pbm_A.iommu;
-       unsigned long tsbbase, i;
+       unsigned long i;
        u64 control;
 
-       /* Setup initial software IOMMU state. */
-       spin_lock_init(&iommu->lock);
-       iommu->ctx_lowest_free = 1;
-
        /* Register addresses. */
        iommu->iommu_control  = p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL;
        iommu->iommu_tsbbase  = p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE;
        /* Leave diag mode enabled for full-flushing done
         * in pci_iommu.c
         */
+       pci_iommu_table_init(iommu, IO_TSB_SIZE, 0xc0000000, 0xffffffff);
 
-       iommu->dummy_page = __get_free_pages(GFP_KERNEL, 0);
-       if (!iommu->dummy_page) {
-               prom_printf("PSYCHO_IOMMU: Error, gfp(dummy_page) failed.\n");
-               prom_halt();
-       }
-       memset((void *)iommu->dummy_page, 0, PAGE_SIZE);
-       iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page);
-
-       /* Using assumed page size 8K with 128K entries we need 1MB iommu page
-        * table (128K ioptes * 8 bytes per iopte).  This is
-        * page order 7 on UltraSparc.
-        */
-       tsbbase = __get_free_pages(GFP_KERNEL, get_order(IO_TSB_SIZE));
-       if (!tsbbase) {
-               prom_printf("PSYCHO_IOMMU: Error, gfp(tsb) failed.\n");
-               prom_halt();
-       }
-       iommu->page_table = (iopte_t *)tsbbase;
-       iommu->page_table_sz_bits = 17;
-       iommu->page_table_map_base = 0xc0000000;
-       iommu->dma_addr_mask = 0xffffffff;
-       pci_iommu_table_init(iommu, IO_TSB_SIZE);
-
-       /* We start with no consistent mappings. */
-       iommu->lowest_consistent_map =
-               1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS);
-
-       for (i = 0; i < PBM_NCLUSTERS; i++) {
-               iommu->alloc_info[i].flush = 0;
-               iommu->alloc_info[i].next = 0;
-       }
-
-       psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE, __pa(tsbbase));
+       psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE,
+                    __pa(iommu->page_table));
 
        control = psycho_read(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL);
        control &= ~(PSYCHO_IOMMU_CTRL_TSBSZ | PSYCHO_IOMMU_CTRL_TBWSZ);
        psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL, control);
 
        /* If necessary, hook us up for starfire IRQ translations. */
-       if(this_is_starfire)
+       if (this_is_starfire)
                p->starfire_cookie = starfire_hookup(p->pbm_A.portid);
        else
                p->starfire_cookie = NULL;
 
                             u32 dma_mask)
 {
        struct pci_iommu *iommu = p->pbm_A.iommu;
-       unsigned long tsbbase, i, order;
+       unsigned long i;
        u64 control;
 
-       /* Setup initial software IOMMU state. */
-       spin_lock_init(&iommu->lock);
-       iommu->ctx_lowest_free = 1;
-
        /* Register addresses. */
        iommu->iommu_control  = p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL;
        iommu->iommu_tsbbase  = p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE;
        /* Leave diag mode enabled for full-flushing done
         * in pci_iommu.c
         */
+       pci_iommu_table_init(iommu, tsbsize * 1024 * 8, dvma_offset, dma_mask);
 
-       iommu->dummy_page = __get_free_pages(GFP_KERNEL, 0);
-       if (!iommu->dummy_page) {
-               prom_printf("PSYCHO_IOMMU: Error, gfp(dummy_page) failed.\n");
-               prom_halt();
-       }
-       memset((void *)iommu->dummy_page, 0, PAGE_SIZE);
-       iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page);
-
-       tsbbase = __get_free_pages(GFP_KERNEL, order = get_order(tsbsize * 1024 * 8));
-       if (!tsbbase) {
-               prom_printf("SABRE_IOMMU: Error, gfp(tsb) failed.\n");
-               prom_halt();
-       }
-       iommu->page_table = (iopte_t *)tsbbase;
-       iommu->page_table_map_base = dvma_offset;
-       iommu->dma_addr_mask = dma_mask;
-       pci_iommu_table_init(iommu, PAGE_SIZE << order);
-
-       sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE, __pa(tsbbase));
+       sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE,
+                   __pa(iommu->page_table));
 
        control = sabre_read(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL);
        control &= ~(SABRE_IOMMUCTRL_TSBSZ | SABRE_IOMMUCTRL_TBWSZ);
        switch(tsbsize) {
        case 64:
                control |= SABRE_IOMMU_TSBSZ_64K;
-               iommu->page_table_sz_bits = 16;
                break;
        case 128:
                control |= SABRE_IOMMU_TSBSZ_128K;
-               iommu->page_table_sz_bits = 17;
                break;
        default:
                prom_printf("iommu_init: Illegal TSB size %d\n", tsbsize);
                break;
        }
        sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL, control);
-
-       /* We start with no consistent mappings. */
-       iommu->lowest_consistent_map =
-               1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS);
-
-       for (i = 0; i < PBM_NCLUSTERS; i++) {
-               iommu->alloc_info[i].flush = 0;
-               iommu->alloc_info[i].next = 0;
-       }
 }
 
 static void pbm_register_toplevel_resources(struct pci_controller_info *p,
 
 static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
 {
        struct pci_iommu *iommu = pbm->iommu;
-       unsigned long tsbbase, i, tagbase, database, order;
+       unsigned long i, tagbase, database;
        u32 vdma[2], dma_mask;
        u64 control;
        int err, tsbsize;
                        prom_halt();
        };
 
-       /* Setup initial software IOMMU state. */
-       spin_lock_init(&iommu->lock);
-       iommu->ctx_lowest_free = 1;
-
        /* Register addresses, SCHIZO has iommu ctx flushing. */
        iommu->iommu_control  = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL;
        iommu->iommu_tsbbase  = pbm->pbm_regs + SCHIZO_IOMMU_TSBBASE;
        /* Leave diag mode enabled for full-flushing done
         * in pci_iommu.c
         */
+       pci_iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask);
 
-       iommu->dummy_page = __get_free_pages(GFP_KERNEL, 0);
-       if (!iommu->dummy_page) {
-               prom_printf("PSYCHO_IOMMU: Error, gfp(dummy_page) failed.\n");
-               prom_halt();
-       }
-       memset((void *)iommu->dummy_page, 0, PAGE_SIZE);
-       iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page);
-
-       /* Using assumed page size 8K with 128K entries we need 1MB iommu page
-        * table (128K ioptes * 8 bytes per iopte).  This is
-        * page order 7 on UltraSparc.
-        */
-       order = get_order(tsbsize * 8 * 1024);
-       tsbbase = __get_free_pages(GFP_KERNEL, order);
-       if (!tsbbase) {
-               prom_printf("%s: Error, gfp(tsb) failed.\n", pbm->name);
-               prom_halt();
-       }
-
-       iommu->page_table = (iopte_t *)tsbbase;
-       iommu->page_table_map_base = vdma[0];
-       iommu->dma_addr_mask = dma_mask;
-       pci_iommu_table_init(iommu, PAGE_SIZE << order);
-
-       switch (tsbsize) {
-       case 64:
-               iommu->page_table_sz_bits = 16;
-               break;
-
-       case 128:
-               iommu->page_table_sz_bits = 17;
-               break;
-
-       default:
-               prom_printf("iommu_init: Illegal TSB size %d\n", tsbsize);
-               prom_halt();
-               break;
-       };
-
-       /* We start with no consistent mappings. */
-       iommu->lowest_consistent_map =
-               1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS);
-
-       for (i = 0; i < PBM_NCLUSTERS; i++) {
-               iommu->alloc_info[i].flush = 0;
-               iommu->alloc_info[i].next = 0;
-       }
-
-       schizo_write(iommu->iommu_tsbbase, __pa(tsbbase));
+       schizo_write(iommu->iommu_tsbbase, __pa(iommu->page_table));
 
        control = schizo_read(iommu->iommu_control);
        control &= ~(SCHIZO_IOMMU_CTRL_TSBSZ | SCHIZO_IOMMU_CTRL_TBWSZ);
 
        u32 dma_addr_mask;
 };
 
-extern void pci_iommu_table_init(struct pci_iommu *, int);
+extern void pci_iommu_table_init(struct pci_iommu *iommu, int tsbsize, u32 dma_offset, u32 dma_addr_mask);
 
 /* This describes a PCI bus module's streaming buffer. */
 struct pci_strbuf {