|  | @@ -193,3 +193,177 @@ wildfire_hardware_probe(void)
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	hard_qbb = (temp >> 8) & 7;
 | 
	
		
			
				|  |  | +	soft_qbb = (temp >> 4) & 7;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* Init the HW configuration variables. */
 | 
	
		
			
				|  |  | +	wildfire_hard_qbb_mask = (1 << hard_qbb);
 | 
	
		
			
				|  |  | +	wildfire_soft_qbb_mask = (1 << soft_qbb);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	wildfire_gp_mask = 0;
 | 
	
		
			
				|  |  | +	wildfire_hs_mask = 0;
 | 
	
		
			
				|  |  | +	wildfire_iop_mask = 0;
 | 
	
		
			
				|  |  | +	wildfire_ior_mask = 0;
 | 
	
		
			
				|  |  | +	wildfire_pca_mask = 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	wildfire_cpu_mask = 0;
 | 
	
		
			
				|  |  | +	wildfire_mem_mask = 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	memset(wildfire_hard_qbb_map, QBB_MAP_EMPTY, WILDFIRE_MAX_QBB);
 | 
	
		
			
				|  |  | +	memset(wildfire_soft_qbb_map, QBB_MAP_EMPTY, WILDFIRE_MAX_QBB);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* First, determine which QBBs are present. */
 | 
	
		
			
				|  |  | +	qsa = WILDFIRE_qsa(soft_qbb);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	temp = qsa->qsa_qbb_id.csr;
 | 
	
		
			
				|  |  | +#if 0
 | 
	
		
			
				|  |  | +	printk(KERN_ERR "QSA_QBB_ID at base %p is 0x%lx\n", qsa, temp);
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (temp & 0x40) /* Is there an HS? */
 | 
	
		
			
				|  |  | +		wildfire_hs_mask = 1;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (temp & 0x20) { /* Is there a GP? */
 | 
	
		
			
				|  |  | +		gp = WILDFIRE_gp(soft_qbb);
 | 
	
		
			
				|  |  | +		temp = 0;
 | 
	
		
			
				|  |  | +		for (i = 0; i < 4; i++) {
 | 
	
		
			
				|  |  | +			temp |= gp->gpa_qbb_map[i].csr << (i * 8);
 | 
	
		
			
				|  |  | +#if 0
 | 
	
		
			
				|  |  | +			printk(KERN_ERR "GPA_QBB_MAP[%d] at base %p is 0x%lx\n",
 | 
	
		
			
				|  |  | +			       i, gp, temp);
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		for (hard_qbb = 0; hard_qbb < WILDFIRE_MAX_QBB; hard_qbb++) {
 | 
	
		
			
				|  |  | +			if (temp & 8) { /* Is there a QBB? */
 | 
	
		
			
				|  |  | +				soft_qbb = temp & 7;
 | 
	
		
			
				|  |  | +				wildfire_hard_qbb_mask |= (1 << hard_qbb);
 | 
	
		
			
				|  |  | +				wildfire_soft_qbb_mask |= (1 << soft_qbb);
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +			temp >>= 4;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		wildfire_gp_mask = wildfire_soft_qbb_mask;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* Next determine each QBBs resources. */
 | 
	
		
			
				|  |  | +	for (soft_qbb = 0; soft_qbb < WILDFIRE_MAX_QBB; soft_qbb++) {
 | 
	
		
			
				|  |  | +	    if (WILDFIRE_QBB_EXISTS(soft_qbb)) {
 | 
	
		
			
				|  |  | +	        qsd = WILDFIRE_qsd(soft_qbb);
 | 
	
		
			
				|  |  | +		temp = qsd->qsd_whami.csr;
 | 
	
		
			
				|  |  | +#if 0
 | 
	
		
			
				|  |  | +	printk(KERN_ERR "QSD_WHAMI at base %p is 0x%lx\n", qsd, temp);
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +		hard_qbb = (temp >> 8) & 7;
 | 
	
		
			
				|  |  | +		wildfire_hard_qbb_map[hard_qbb] = soft_qbb;
 | 
	
		
			
				|  |  | +		wildfire_soft_qbb_map[soft_qbb] = hard_qbb;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		qsa = WILDFIRE_qsa(soft_qbb);
 | 
	
		
			
				|  |  | +		temp = qsa->qsa_qbb_pop[0].csr;
 | 
	
		
			
				|  |  | +#if 0
 | 
	
		
			
				|  |  | +	printk(KERN_ERR "QSA_QBB_POP_0 at base %p is 0x%lx\n", qsa, temp);
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +		wildfire_cpu_mask |= ((temp >> 0) & 0xf) << (soft_qbb << 2);
 | 
	
		
			
				|  |  | +		wildfire_mem_mask |= ((temp >> 4) & 0xf) << (soft_qbb << 2);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		temp = qsa->qsa_qbb_pop[1].csr;
 | 
	
		
			
				|  |  | +#if 0
 | 
	
		
			
				|  |  | +	printk(KERN_ERR "QSA_QBB_POP_1 at base %p is 0x%lx\n", qsa, temp);
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +		wildfire_iop_mask |= (1 << soft_qbb);
 | 
	
		
			
				|  |  | +		wildfire_ior_mask |= ((temp >> 4) & 0xf) << (soft_qbb << 2);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		temp = qsa->qsa_qbb_id.csr;
 | 
	
		
			
				|  |  | +#if 0
 | 
	
		
			
				|  |  | +	printk(KERN_ERR "QSA_QBB_ID at %p is 0x%lx\n", qsa, temp);
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +		if (temp & 0x20)
 | 
	
		
			
				|  |  | +		    wildfire_gp_mask |= (1 << soft_qbb);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		/* Probe for PCA existence here. */
 | 
	
		
			
				|  |  | +		for (i = 0; i < WILDFIRE_PCA_PER_QBB; i++) {
 | 
	
		
			
				|  |  | +		    iop = WILDFIRE_iop(soft_qbb);
 | 
	
		
			
				|  |  | +		    ne = WILDFIRE_ne(soft_qbb, i);
 | 
	
		
			
				|  |  | +		    fe = WILDFIRE_fe(soft_qbb, i);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		    if ((iop->iop_hose[i].init.csr & 1) == 1 &&
 | 
	
		
			
				|  |  | +			((ne->ne_what_am_i.csr & 0xf00000300UL) == 0x100000300UL) &&
 | 
	
		
			
				|  |  | +			((fe->fe_what_am_i.csr & 0xf00000300UL) == 0x100000200UL))
 | 
	
		
			
				|  |  | +		    {
 | 
	
		
			
				|  |  | +		        wildfire_pca_mask |= 1 << ((soft_qbb << 2) + i);
 | 
	
		
			
				|  |  | +		    }
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	    }
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +#if DEBUG_DUMP_CONFIG
 | 
	
		
			
				|  |  | +	wildfire_dump_hardware_config();
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void __init
 | 
	
		
			
				|  |  | +wildfire_init_arch(void)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	int qbbno;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* With multiple PCI buses, we play with I/O as physical addrs.  */
 | 
	
		
			
				|  |  | +	ioport_resource.end = ~0UL;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* Probe the hardware for info about configuration. */
 | 
	
		
			
				|  |  | +	wildfire_hardware_probe();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* Now init all the found QBBs. */
 | 
	
		
			
				|  |  | +	for (qbbno = 0; qbbno < WILDFIRE_MAX_QBB; qbbno++) {
 | 
	
		
			
				|  |  | +		wildfire_init_qbb(qbbno);
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	/* Normal direct PCI DMA mapping. */ 
 | 
	
		
			
				|  |  | +	__direct_map_base = 0x40000000UL;
 | 
	
		
			
				|  |  | +	__direct_map_size = 0x80000000UL;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void
 | 
	
		
			
				|  |  | +wildfire_machine_check(unsigned long vector, unsigned long la_ptr)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	mb();
 | 
	
		
			
				|  |  | +	mb();  /* magic */
 | 
	
		
			
				|  |  | +	draina();
 | 
	
		
			
				|  |  | +	/* FIXME: clear pci errors */
 | 
	
		
			
				|  |  | +	wrmces(0x7);
 | 
	
		
			
				|  |  | +	mb();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	process_mcheck_info(vector, la_ptr, "WILDFIRE",
 | 
	
		
			
				|  |  | +			    mcheck_expected(smp_processor_id()));
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void
 | 
	
		
			
				|  |  | +wildfire_kill_arch(int mode)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void
 | 
	
		
			
				|  |  | +wildfire_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	int qbbno = hose->index >> 3;
 | 
	
		
			
				|  |  | +	int hoseno = hose->index & 7;
 | 
	
		
			
				|  |  | +	wildfire_pci *pci = WILDFIRE_pci(qbbno, hoseno);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	mb();
 | 
	
		
			
				|  |  | +	pci->pci_flush_tlb.csr; /* reading does the trick */
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static int
 | 
	
		
			
				|  |  | +mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,
 | 
	
		
			
				|  |  | +	     unsigned long *pci_addr, unsigned char *type1)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	struct pci_controller *hose = pbus->sysdata;
 | 
	
		
			
				|  |  | +	unsigned long addr;
 | 
	
		
			
				|  |  | +	u8 bus = pbus->number;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, "
 | 
	
		
			
				|  |  | +		 "pci_addr=0x%p, type1=0x%p)\n",
 | 
	
		
			
				|  |  | +		 bus, device_fn, where, pci_addr, type1));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (!pbus->parent) /* No parent means peer PCI bus. */
 | 
	
		
			
				|  |  | +		bus = 0;
 | 
	
		
			
				|  |  | +	*type1 = (bus != 0);
 | 
	
		
			
				|  |  | +
 |