#include "pci.h"
-/* Only used to pass OF initialization data set in prom.c into the main
- * kernel code -- data ultimately copied into regular tce tables.
- */
-extern struct _of_tce_table of_tce_table[];
-
-
-extern struct pci_controller *hose_head;
-extern struct pci_controller **hose_tail;
-
-
static void tce_build_pSeries(struct iommu_table *tbl, long index,
long npages, unsigned long uaddr,
int direction)
}
-
static void iommu_buses_init(void)
{
struct pci_controller* phb;
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
*/
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.
{
phandle node;
unsigned long i;
- struct _of_tce_table *oft;
+ struct of_tce_table *oft;
node = ((struct device_node *)(phb->arch_data))->node;
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 (32 * 6) /* 32 drawers * 6 PHBs/drawer */
+struct of_tce_table of_tce_table[MAX_PHB + 1];
char *bootpath = 0;
char *bootdevice = 0;
unsigned long i, table = 0;
unsigned long base, vbase, align;
unsigned int minalign, minsize;
- struct _of_tce_table *prom_tce_table = RELOC(of_tce_table);
+ struct of_tce_table *prom_tce_table = RELOC(of_tce_table);
unsigned long tce_entry, *tce_entryp;
#ifdef DEBUG_PROM
/* Search all nodes looking for PHBs. */
for (node = 0; prom_next_node(&node); ) {
+ if (table == MAX_PHB) {
+ prom_print(RELOC("WARNING: PCI host bridge ignored, "
+ "need to increase MAX_PHB\n"));
+ continue;
+ }
+
compatible[0] = 0;
type[0] = 0;
model[0] = 0;
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);