|
@@ -316,3 +316,147 @@ mcpcia_new_hose(int h)
|
|
|
mem->end = mem->start + 0xffffffff;
|
|
|
mem->name = pci_mem_names[h];
|
|
|
mem->flags = IORESOURCE_MEM;
|
|
|
+
|
|
|
+ hae_mem->start = mem->start;
|
|
|
+ hae_mem->end = mem->start + MCPCIA_MEM_MASK;
|
|
|
+ hae_mem->name = pci_hae0_name;
|
|
|
+ hae_mem->flags = IORESOURCE_MEM;
|
|
|
+
|
|
|
+ if (request_resource(&ioport_resource, io) < 0)
|
|
|
+ printk(KERN_ERR "Failed to request IO on hose %d\n", h);
|
|
|
+ if (request_resource(&iomem_resource, mem) < 0)
|
|
|
+ printk(KERN_ERR "Failed to request MEM on hose %d\n", h);
|
|
|
+ if (request_resource(mem, hae_mem) < 0)
|
|
|
+ printk(KERN_ERR "Failed to request HAE_MEM on hose %d\n", h);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+mcpcia_pci_clr_err(int mid)
|
|
|
+{
|
|
|
+ *(vuip)MCPCIA_CAP_ERR(mid);
|
|
|
+ *(vuip)MCPCIA_CAP_ERR(mid) = 0xffffffff; /* Clear them all. */
|
|
|
+ mb();
|
|
|
+ *(vuip)MCPCIA_CAP_ERR(mid); /* Re-read for force write. */
|
|
|
+}
|
|
|
+
|
|
|
+static void __init
|
|
|
+mcpcia_startup_hose(struct pci_controller *hose)
|
|
|
+{
|
|
|
+ int mid = MCPCIA_HOSE2MID(hose->index);
|
|
|
+ unsigned int tmp;
|
|
|
+
|
|
|
+ mcpcia_pci_clr_err(mid);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Set up error reporting.
|
|
|
+ */
|
|
|
+ tmp = *(vuip)MCPCIA_CAP_ERR(mid);
|
|
|
+ tmp |= 0x0006; /* master/target abort */
|
|
|
+ *(vuip)MCPCIA_CAP_ERR(mid) = tmp;
|
|
|
+ mb();
|
|
|
+ tmp = *(vuip)MCPCIA_CAP_ERR(mid);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Set up the PCI->physical memory translation windows.
|
|
|
+ *
|
|
|
+ * Window 0 is scatter-gather 8MB at 8MB (for isa)
|
|
|
+ * Window 1 is scatter-gather (up to) 1GB at 1GB (for pci)
|
|
|
+ * Window 2 is direct access 2GB at 2GB
|
|
|
+ */
|
|
|
+ hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0);
|
|
|
+ hose->sg_pci = iommu_arena_new(hose, 0x40000000,
|
|
|
+ size_for_memory(0x40000000), 0);
|
|
|
+
|
|
|
+ __direct_map_base = 0x80000000;
|
|
|
+ __direct_map_size = 0x80000000;
|
|
|
+
|
|
|
+ *(vuip)MCPCIA_W0_BASE(mid) = hose->sg_isa->dma_base | 3;
|
|
|
+ *(vuip)MCPCIA_W0_MASK(mid) = (hose->sg_isa->size - 1) & 0xfff00000;
|
|
|
+ *(vuip)MCPCIA_T0_BASE(mid) = virt_to_phys(hose->sg_isa->ptes) >> 8;
|
|
|
+
|
|
|
+ *(vuip)MCPCIA_W1_BASE(mid) = hose->sg_pci->dma_base | 3;
|
|
|
+ *(vuip)MCPCIA_W1_MASK(mid) = (hose->sg_pci->size - 1) & 0xfff00000;
|
|
|
+ *(vuip)MCPCIA_T1_BASE(mid) = virt_to_phys(hose->sg_pci->ptes) >> 8;
|
|
|
+
|
|
|
+ *(vuip)MCPCIA_W2_BASE(mid) = __direct_map_base | 1;
|
|
|
+ *(vuip)MCPCIA_W2_MASK(mid) = (__direct_map_size - 1) & 0xfff00000;
|
|
|
+ *(vuip)MCPCIA_T2_BASE(mid) = 0;
|
|
|
+
|
|
|
+ *(vuip)MCPCIA_W3_BASE(mid) = 0x0;
|
|
|
+
|
|
|
+ mcpcia_pci_tbi(hose, 0, -1);
|
|
|
+
|
|
|
+ *(vuip)MCPCIA_HBASE(mid) = 0x0;
|
|
|
+ mb();
|
|
|
+
|
|
|
+ *(vuip)MCPCIA_HAE_MEM(mid) = 0U;
|
|
|
+ mb();
|
|
|
+ *(vuip)MCPCIA_HAE_MEM(mid); /* read it back. */
|
|
|
+ *(vuip)MCPCIA_HAE_IO(mid) = 0;
|
|
|
+ mb();
|
|
|
+ *(vuip)MCPCIA_HAE_IO(mid); /* read it back. */
|
|
|
+}
|
|
|
+
|
|
|
+void __init
|
|
|
+mcpcia_init_arch(void)
|
|
|
+{
|
|
|
+ /* With multiple PCI busses, we play with I/O as physical addrs. */
|
|
|
+ ioport_resource.end = ~0UL;
|
|
|
+
|
|
|
+ /* Allocate hose 0. That's the one that all the ISA junk hangs
|
|
|
+ off of, from which we'll be registering stuff here in a bit.
|
|
|
+ Other hose detection is done in mcpcia_init_hoses, which is
|
|
|
+ called from init_IRQ. */
|
|
|
+
|
|
|
+ mcpcia_new_hose(0);
|
|
|
+}
|
|
|
+
|
|
|
+/* This is called from init_IRQ, since we cannot take interrupts
|
|
|
+ before then. Which means we cannot do this in init_arch. */
|
|
|
+
|
|
|
+void __init
|
|
|
+mcpcia_init_hoses(void)
|
|
|
+{
|
|
|
+ struct pci_controller *hose;
|
|
|
+ int hose_count;
|
|
|
+ int h;
|
|
|
+
|
|
|
+ /* First, find how many hoses we have. */
|
|
|
+ hose_count = 0;
|
|
|
+ for (h = 0; h < MCPCIA_MAX_HOSES; ++h) {
|
|
|
+ if (mcpcia_probe_hose(h)) {
|
|
|
+ if (h != 0)
|
|
|
+ mcpcia_new_hose(h);
|
|
|
+ hose_count++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ printk("mcpcia_init_hoses: found %d hoses\n", hose_count);
|
|
|
+
|
|
|
+ /* Now do init for each hose. */
|
|
|
+ for (hose = hose_head; hose; hose = hose->next)
|
|
|
+ mcpcia_startup_hose(hose);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+mcpcia_print_uncorrectable(struct el_MCPCIA_uncorrected_frame_mcheck *logout)
|
|
|
+{
|
|
|
+ struct el_common_EV5_uncorrectable_mcheck *frame;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ frame = &logout->procdata;
|
|
|
+
|
|
|
+ /* Print PAL fields */
|
|
|
+ for (i = 0; i < 24; i += 2) {
|
|
|
+ printk(" paltmp[%d-%d] = %16lx %16lx\n",
|
|
|
+ i, i+1, frame->paltemp[i], frame->paltemp[i+1]);
|
|
|
+ }
|
|
|
+ for (i = 0; i < 8; i += 2) {
|
|
|
+ printk(" shadow[%d-%d] = %16lx %16lx\n",
|
|
|
+ i, i+1, frame->shadow[i],
|
|
|
+ frame->shadow[i+1]);
|
|
|
+ }
|
|
|
+ printk(" Addr of excepting instruction = %16lx\n",
|
|
|
+ frame->exc_addr);
|
|
|
+ printk(" Summary of arithmetic traps = %16lx\n",
|
|
|
+ frame->exc_sum);
|