pba.pba_iot = &sc->sc_bus_space; pba.pba_memt = &sc->sc_bus_space;
pba.pba_iot = &sc->sc_iobus_space; pba.pba_memt = &sc->sc_membus_space;
const char *mpc_intr_string __P((void *, pci_intr_handle_t));void     *mpc_intr_establish __P((void *, pci_intr_handle_t,            int, int (*func)(void *), void *, char *));void     mpc_intr_disestablish __P((void *, void *));int      mpc_ether_hw_addr __P((u_int8_t *));struct cfattach mpcpcibr_ca = {        sizeof(struct pcibr_softc), mpcpcibrmatch, mpcpcibrattach,};struct cfdriver mpcpcibr_cd = {	NULL, "mpcpcibr", DV_DULL,};static int      mpcpcibrprint __P((void *, const char *pnp));struct pcibr_config mpc_config;/* * Code from "pci/if_de.c" used to calculate crc32 of ether rom data. */#define      TULIP_CRC32_POLY  0xEDB88320ULstatic __inline__ unsignedsrom_crc32(    const unsigned char *databuf,    size_t datalen){    u_int idx, bit, data, crc = 0xFFFFFFFFUL;    for (idx = 0; idx < datalen; idx++)        for (data = *databuf++, bit = 0; bit < 8; bit++, data >>= 1)            crc = (crc >> 1) ^ (((crc ^ data) & 1) ? TULIP_CRC32_POLY : 0);    return crc;}intmpcpcibrmatch(parent, match, aux)	struct device *parent;	void *match, *aux;{	struct confargs *ca = aux;	if (strcmp(ca->ca_name, mpcpcibr_cd.cd_name) != 0)		return (0);	return (1);}voidmpcpcibrattach(parent, self, aux)	struct device *parent, *self;	void *aux;{	struct pcibr_softc *sc = (struct pcibr_softc *)self;	struct pcibr_config *lcp;	struct pcibus_attach_args pba;	switch(system_type) {	case POWER4e:		lcp = sc->sc_pcibr = &mpc_config;		sc->sc_bus_space.bus_base = MPC106_V_PCI_MEM_SPACE;		sc->sc_bus_space.bus_reverse = 1;		lcp->lc_pc.pc_conf_v = lcp;		lcp->lc_pc.pc_attach_hook = mpc_attach_hook;		lcp->lc_pc.pc_bus_maxdevs = mpc_bus_maxdevs;		lcp->lc_pc.pc_make_tag = mpc_make_tag;		lcp->lc_pc.pc_decompose_tag = mpc_decompose_tag;		lcp->lc_pc.pc_conf_read = mpc_conf_read;		lcp->lc_pc.pc_conf_write = mpc_conf_write;		lcp->lc_pc.pc_ether_hw_addr = mpc_ether_hw_addr;	        lcp->lc_pc.pc_intr_v = lcp;		lcp->lc_pc.pc_intr_map = mpc_intr_map;		lcp->lc_pc.pc_intr_string = mpc_intr_string;		lcp->lc_pc.pc_intr_establish = mpc_intr_establish;		lcp->lc_pc.pc_intr_disestablish = mpc_intr_disestablish;		printf(": MPC106, Revision %x.\n",				mpc_cfg_read_1(MPC106_PCI_REVID));		mpc_cfg_write_2(MPC106_PCI_STAT, 0xff80); /* Reset status */		break;	}	pba.pba_busname = "pci";	pba.pba_iot = &sc->sc_bus_space;	pba.pba_memt = &sc->sc_bus_space;	pba.pba_pc = &lcp->lc_pc;	pba.pba_bus = 0;	config_found(self, &pba, mpcpcibrprint);}static intmpcpcibrprint(aux, pnp)	void *aux;	const char *pnp;{	struct pcibus_attach_args *pba = aux;	if(pnp)		printf("%s at %s", pba->pba_busname, pnp);	printf(" bus %d", pba->pba_bus);	return(UNCONF);}/* *  Get PCI physical address from given viritual address. *  XXX Note that cross page boundarys are *not* garantueed to work! */vm_offset_tvtophys(p)	void *p;{	vm_offset_t pa;	vm_offset_t va;	va = (vm_offset_t)p;	if((vm_offset_t)va < VM_MIN_KERNEL_ADDRESS) {		pa = va;	}	else {		pa = pmap_extract(vm_map_pmap(phys_map), va);	}	return(pa | MPC106_PCI_CPUMEM);}voidmpc_attach_hook(parent, self, pba)	struct device *parent, *self;	struct pcibus_attach_args *pba;{}intmpc_ether_hw_addr(p)	u_int8_t *p;{	int i;	for(i = 0; i < 128; i++)		p[i] = 0x00;	p[18] = 0x03;	/* Srom version. */	p[19] = 0x01;	/* One chip. */	/* Next six, ethernet address. */	bcopy(ofw_eth_addr, &p[20], 6);	p[26] = 0x00;	/* Chip 0 device number */	p[27] = 30;		/* Descriptor offset */	p[28] = 00;	p[29] = 00;		/* MBZ */					/* Descriptor */	p[30] = 0x00;	/* Autosense. */	p[31] = 0x08;	p[32] = 0xff;	/* GP cntrl */	p[33] = 0x01;	/* Block cnt */#define GPR_LEN 0#define	RES_LEN 0	p[34] = 0x80 + 12 + GPR_LEN + RES_LEN;	p[35] = 0x01;	/* MII PHY type */	p[36] = 0x00;	/* PHY number 0 */	p[37] = 0x00;	/* GPR Length */	p[38] = 0x00;	/* Reset Length */	p[39] = 0x00;	/* Media capabilities */	p[40] = 0x78;	/* Media capabilities */	p[41] = 0x00;	/* Autoneg advertisment */	p[42] = 0x78;	/* Autoneg advertisment */	p[43] = 0x00;	/* Full duplex map */	p[44] = 0x50;	/* Full duplex map */	p[45] = 0x00;	/* Treshold map */	p[46] = 0x18;	/* Treshold map */	i = (srom_crc32(p, 126) & 0xFFFF) ^ 0xFFFF;	p[126] = i;	p[127] = i >> 8;	return(1);}intmpc_bus_maxdevs(cpv, busno)	void *cpv;	int busno;{	return(16);}pcitag_tmpc_make_tag(cpv, bus, dev, fnc)	void *cpv;	int bus, dev, fnc;{	return (bus << 16) | (dev << 11) | (fnc << 8);}voidmpc_decompose_tag(cpv, tag, busp, devp, fncp)	void *cpv;	pcitag_t tag;	int *busp, *devp, *fncp;{	if (busp != NULL)		*busp = (tag >> 16) & 0xff;	if (devp != NULL)		*devp = (tag >> 11) & 0x1f;	if (fncp != NULL)		*fncp = (tag >> 8) & 0x7;}pcireg_tmpc_conf_read(cpv, tag, offset)	void *cpv;	pcitag_t tag;	int offset;{	pcireg_t data;	u_int32_t addr;	int device;	int s;	if((tag >> 16) != 0)		return(~0);	if(offset & 3 || offset < 0 || offset >= 0x100) {		printf ("pci_conf_read: bad reg %x\n", offset);		return(~0);	}	device = (tag >> 11) & 0x1f;	if(device > 11)		return(~0);	/* Outside config space */	addr = (0x800 << device) | (tag & 0x380) | offset;	s = splhigh();	/* low 20 bits of address are in the actual address */	data = in32rb(MPC106_PCI_CONF_SPACE | addr);	splx(s);	return(data);}voidmpc_conf_write(cpv, tag, offset, data)	void *cpv;	pcitag_t tag;	int offset;	pcireg_t data;{	u_int32_t addr;	int device;	int s;	device = (tag >> 11) & 0x1f;	addr = (0x800 << device) | (tag & 0x380) | offset;	s = splhigh();	/* low 20 bits of address are in the actual address */	out32rb(MPC106_PCI_CONF_SPACE | addr, data);	splx(s);}intmpc_intr_map(lcv, bustag, buspin, line, ihp)	void *lcv;	pcitag_t bustag;	int buspin, line;	pci_intr_handle_t *ihp;{	int error = 0;	int route;	int lvl;	*ihp = -1;        if (buspin == 0) {                /* No IRQ used. */                error = 1;        }        else if (buspin > 4) {                printf("mpc_intr_map: bad interrupt pin %d\n", buspin);                error = 1;        }	if(system_type == POWER4e) {		route = in32rb(MPC106_PCI_CONF_SPACE + 0x860);		switch(line) {		case 14:			line = 9;			route &= ~0x000000ff;			route |= line;			break;		case 11:			line = 6;			route &= ~0x0000ff00;			route |= line << 8;			break;		case 12:			line = 14;			route &= ~0x00ff0000;			route |= line << 16;			break;		case 13:			line = 15;			route &= ~0xff000000;			route |= line << 24;			break;		}		lvl = isa_inb(0x04d0);		lvl |= isa_inb(0x04d1);		lvl |= 1L << line;		isa_outb(0x04d0, lvl);		isa_outb(0x04d1, lvl >> 8);		out32rb(MPC106_PCI_CONF_SPACE + 0x860, route);	}	if(!error)		*ihp = line;	return error;}const char *mpc_intr_string(lcv, ih)	void *lcv;	pci_intr_handle_t ih;{	static char str[16];	sprintf(str, "irq %d", ih);	return(str);}