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);
}
Example #11
0
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);
	}
}