static inline void rawhide_update_irq_hw(int hose, int mask) { *(vuip)MCPCIA_INT_MASK0(MCPCIA_HOSE2MID(hose)) = mask; mb(); *(vuip)MCPCIA_INT_MASK0(MCPCIA_HOSE2MID(hose)); }
static void __init rawhide_init_irq(void) { struct pci_controller *hose; long i; mcpcia_init_hoses(); /* Clear them all; only hoses that exist will be non-zero. */ for (i = 0; i < MCPCIA_MAX_HOSES; i++) cached_irq_masks[i] = 0; for (hose = hose_head; hose; hose = hose->next) { unsigned int h = hose->index; unsigned int mask = hose_irq_masks[h]; cached_irq_masks[h] = mask; *(vuip)MCPCIA_INT_MASK0(MCPCIA_HOSE2MID(h)) = mask; *(vuip)MCPCIA_INT_MASK1(MCPCIA_HOSE2MID(h)) = 0; } for (i = 16; i < 128; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; irq_desc[i].chip = &rawhide_irq_type; } init_i8259a_irqs(); common_init_isa_dma(); }
static void rawhide_mask_and_ack_irq(unsigned int irq) { unsigned int mask, mask1, hose; irq -= 16; hose = irq / 24; if (!hose_exists(hose)) /* if hose non-existent, exit */ return; irq -= hose * 24; mask1 = 1 << irq; mask = ~mask1 | hose_irq_masks[hose]; spin_lock(&rawhide_irq_lock); mask &= cached_irq_masks[hose]; cached_irq_masks[hose] = mask; rawhide_update_irq_hw(hose, mask); /* Clear the interrupt. */ *(vuip)MCPCIA_INT_REQ(MCPCIA_HOSE2MID(hose)) = mask1; spin_unlock(&rawhide_irq_lock); }
static int __init mcpcia_probe_hose(int h) { int cpu = smp_processor_id(); int mid = MCPCIA_HOSE2MID(h); unsigned int pci_rev; /* Gotta be REAL careful. If hose is absent, we get an mcheck. */ mb(); mb(); draina(); wrmces(7); mcheck_expected(cpu) = 2; /* indicates probing */ mcheck_taken(cpu) = 0; mcheck_extra(cpu) = mid; mb(); /* Access the bus revision word. */ pci_rev = *(vuip)MCPCIA_REV(mid); mb(); mb(); /* magic */ if (mcheck_taken(cpu)) { mcheck_taken(cpu) = 0; pci_rev = 0xffffffff; mb(); } mcheck_expected(cpu) = 0; mb(); return (pci_rev >> 16) == PCI_CLASS_BRIDGE_HOST; }
void mcpcia_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end) { wmb(); *(vuip)MCPCIA_SG_TBIA(MCPCIA_HOSE2MID(hose->index)) = 0; mb(); }
static void conf_write(unsigned long addr, unsigned int value, unsigned char type1, struct pci_controller *hose) { unsigned long flags; unsigned long mid = MCPCIA_HOSE2MID(hose->index); unsigned int stat0, temp, cpu; cpu = smp_processor_id(); local_irq_save(flags); /* avoid getting hit by machine check */ /* Reset status register to avoid losing errors. */ stat0 = *(vuip)MCPCIA_CAP_ERR(mid); *(vuip)MCPCIA_CAP_ERR(mid) = stat0; mb(); temp = *(vuip)MCPCIA_CAP_ERR(mid); DBG_CFG(("conf_write: MCPCIA CAP_ERR(%d) was 0x%x\n", mid, stat0)); draina(); mcheck_expected(cpu) = 1; mcheck_extra(cpu) = mid; mb(); /* Access configuration space. */ *((vuip)addr) = value; mb(); mb(); /* magic */ temp = *(vuip)MCPCIA_CAP_ERR(mid); /* read to force the write */ mcheck_expected(cpu) = 0; mb(); DBG_CFG(("conf_write(): finished\n")); local_irq_restore(flags); }
static unsigned int conf_read(unsigned long addr, unsigned char type1, struct pci_controller *hose) { unsigned long flags; unsigned long mid = MCPCIA_HOSE2MID(hose->index); <<<<<<< HEAD
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. */ }
static unsigned int conf_read(unsigned long addr, unsigned char type1, struct pci_controller *hose) { unsigned long flags; unsigned long mid = MCPCIA_HOSE2MID(hose->index); unsigned int stat0, value, temp, cpu; cpu = smp_processor_id(); local_irq_save(flags); DBG_CFG(("conf_read(addr=0x%lx, type1=%d, hose=%d)\n", addr, type1, mid)); /* Reset status register to avoid losing errors. */ stat0 = *(vuip)MCPCIA_CAP_ERR(mid); *(vuip)MCPCIA_CAP_ERR(mid) = stat0; mb(); temp = *(vuip)MCPCIA_CAP_ERR(mid); DBG_CFG(("conf_read: MCPCIA_CAP_ERR(%d) was 0x%x\n", mid, stat0)); mb(); draina(); mcheck_expected(cpu) = 1; mcheck_taken(cpu) = 0; mcheck_extra(cpu) = mid; mb(); /* Access configuration space. */ value = *((vuip)addr); mb(); mb(); /* magic */ if (mcheck_taken(cpu)) { mcheck_taken(cpu) = 0; value = 0xffffffffU; mb(); } mcheck_expected(cpu) = 0; mb(); DBG_CFG(("conf_read(): finished\n")); local_irq_restore(flags); return value; }
static void __init mcpcia_new_hose(int h) { struct pci_controller *hose; struct resource *io, *mem, *hae_mem; int mid = MCPCIA_HOSE2MID(h); hose = alloc_pci_controller(); if (h == 0) pci_isa_hose = hose; io = alloc_resource(); mem = alloc_resource(); hae_mem = alloc_resource(); hose->io_space = io; hose->mem_space = hae_mem; hose->sparse_mem_base = MCPCIA_SPARSE(mid) - IDENT_ADDR; hose->dense_mem_base = MCPCIA_DENSE(mid) - IDENT_ADDR; hose->sparse_io_base = MCPCIA_IO(mid) - IDENT_ADDR; hose->dense_io_base = 0; hose->config_space_base = MCPCIA_CONF(mid); hose->index = h; io->start = MCPCIA_IO(mid) - MCPCIA_IO_BIAS; io->end = io->start + 0xffff; io->name = pci_io_names[h]; io->flags = IORESOURCE_IO; mem->start = MCPCIA_DENSE(mid) - MCPCIA_MEM_BIAS; 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); }
void mcpcia_machine_check(unsigned long vector, unsigned long la_ptr, struct pt_regs * regs) { struct el_common *mchk_header; struct el_MCPCIA_uncorrected_frame_mcheck *mchk_logout; unsigned int cpu = smp_processor_id(); int expected; mchk_header = (struct el_common *)la_ptr; mchk_logout = (struct el_MCPCIA_uncorrected_frame_mcheck *)la_ptr; expected = mcheck_expected(cpu); mb(); mb(); /* magic */ draina(); switch (expected) { case 0: { /* FIXME: how do we figure out which hose the error was on? */ struct pci_controler *hose; for (hose = hose_head; hose; hose = hose->next) mcpcia_pci_clr_err(MCPCIA_HOSE2MID(hose->index)); break; } case 1: mcpcia_pci_clr_err(mcheck_extra(cpu)); break; default: /* Otherwise, we're being called from mcpcia_probe_hose and there's no hose clear an error from. */ break; } wrmces(0x7); mb(); process_mcheck_info(vector, la_ptr, regs, "MCPCIA", expected != 0); if (!expected && vector != 0x620 && vector != 0x630) { mcpcia_print_uncorrectable(mchk_logout); mcpcia_print_system_area(la_ptr); } }