示例#1
0
int
gio_print_fb(void *aux, const char *pnp)
{
	struct gio_attach_args *ga = aux;
	const char *fbname;

	if (pnp != NULL) {
		switch (ga->ga_product) {
		case GIO_PRODUCT_FAKEID_GRTWO:
			fbname = "grtwo";
			break;
		case GIO_PRODUCT_FAKEID_LIGHT:
			fbname = "light";
			break;
		case GIO_PRODUCT_FAKEID_NEWPORT:
			fbname = "newport";
			break;
		default:
			if (GIO_PRODUCT_32BIT_ID(ga->ga_product) &&
			    GIO_PRODUCT_PRODUCTID(ga->ga_product) ==
			      GIO_PRODUCT_IMPACT)
				fbname = "impact";
			else	/* should never happen */
				fbname = "framebuffer";
			break;
		}
		printf("%s at %s", fbname, pnp);
	}

	printf(" addr 0x%lx", ga->ga_addr);

	return UNCONF;
}
示例#2
0
int
gio_is_framebuffer_id(uint32_t id)
{
	switch (id) {
	case GIO_PRODUCT_FAKEID_GRTWO:
	case GIO_PRODUCT_FAKEID_LIGHT:
	case GIO_PRODUCT_FAKEID_NEWPORT:
		return 1;
	default:
		if (GIO_PRODUCT_32BIT_ID(id) &&
		    GIO_PRODUCT_PRODUCTID(id) == GIO_PRODUCT_IMPACT)
			return 1;
		else
			return 0;
	}
}
示例#3
0
int
giofb_cnattach()
{
	struct gio_attach_args ga;

	ga.ga_addr = giofb_consaddr;
	ga.ga_iot = &imcbus_tag;
	ga.ga_ioh = PHYS_TO_XKPHYS(ga.ga_addr, CCA_NC);
	ga.ga_dmat = &imc_bus_dma_tag;
	ga.ga_slot = -1;
	ga.ga_product = giofb_consid;
	ga.ga_descr = NULL;

	switch (giofb_consid) {
	default:
#if NIMPACT_GIO > 0
		if (GIO_PRODUCT_32BIT_ID(giofb_consid) &&
		    GIO_PRODUCT_PRODUCTID(giofb_consid) == GIO_PRODUCT_IMPACT) {
			if (impact_gio_cnattach(&ga) == 0)
				return 0;
		}
#endif
		break;
	case GIO_PRODUCT_FAKEID_GRTWO:
#if NGRTWO > 0
		if (grtwo_cnattach(&ga) == 0)
			return 0;
#endif
		break;
	case GIO_PRODUCT_FAKEID_LIGHT:
#if NLIGHT > 0
		if (light_cnattach(&ga) == 0)
			return 0;
#endif
		break;
	case GIO_PRODUCT_FAKEID_NEWPORT:
#if NNEWPORT > 0
		if (newport_cnattach(&ga) == 0)
			return 0;
#endif
		break;
	}

	giofb_consaddr = 0;
	return ENXIO;
}
示例#4
0
static int
giopci_match(struct device *parent, struct cfdata *match, void *aux)
{
	struct gio_attach_args *ga = aux;
	int gprid;

	/*
	 * I think that these cards are all GIO32-bis or GIO64. Thus
	 * they work in either Indigo2/Challenge M or
	 * Indy/Challenge S/Indigo R4k, according to form factor. However,
	 * there are some exceptions (e.g. my Indigo R4k won't power 
	 * on with the Set Engineering card installed).
	 */
	if (mach_type != MACH_SGI_IP20 && mach_type != MACH_SGI_IP22)
		return (0);

	gprid = GIO_PRODUCT_PRODUCTID(ga->ga_product);
	if (gprid == PHOBOS_G100 || gprid == PHOBOS_G130 ||
	    gprid == PHOBOS_G160 || gprid == SETENG_GFE)
		return (1);

	return (0);
}
示例#5
0
int
gio_print(void *aux, const char *pnp)
{
	struct gio_attach_args *ga = aux;
	const char *descr;
	int product, revision;
	uint i;

	product = GIO_PRODUCT_PRODUCTID(ga->ga_product);
	if (GIO_PRODUCT_32BIT_ID(ga->ga_product))
		revision = GIO_PRODUCT_REVISION(ga->ga_product);
	else
		revision = 0;

	descr = "unknown GIO card";
	for (i = 0; gio_knowndevs[i].productid != 0; i++) {
		if (gio_knowndevs[i].productid == product) {
			descr = gio_knowndevs[i].product;
			break;
		}
	}

	if (pnp != NULL) {
		printf("%s", descr);
		if (ga->ga_product != -1)
			printf(" (product 0x%02x revision 0x%02x)",
			    product, revision);
		printf(" at %s", pnp);
	}

	if (ga->ga_slot != -1)
		printf(" slot %d", ga->ga_slot);
	printf(" addr 0x%lx", ga->ga_addr);

	return UNCONF;
}
示例#6
0
int
giofb_cnprobe()
{
	struct gio_attach_args ga;
	uint32_t id;
	int i;
	int sys_type;

	switch (sys_config.system_type) {
	case SGI_IP20:
		sys_type = SGI_IP20;
		break;
	default:
	case SGI_IP22:
	case SGI_IP26:
	case SGI_IP28:
		sys_type = SGI_IP22;
		break;
	}

	for (i = 0; gfx_bases[i].base != 0; i++) {
		if (giofb_consaddr != 0 &&
		    gfx_bases[i].base != giofb_consaddr)
			continue;

		/* skip bases that don't apply to us */
		if (gfx_bases[i].mach_type != sys_type)
			continue;

		if (gfx_bases[i].mach_subtype != -1 &&
		    gfx_bases[i].mach_subtype != sys_config.system_subtype)
			continue;

		ga.ga_addr = gfx_bases[i].base;
		ga.ga_iot = &imcbus_tag;
		ga.ga_ioh = PHYS_TO_XKPHYS(ga.ga_addr, CCA_NC);
		ga.ga_dmat = &imc_bus_dma_tag;
		ga.ga_slot = -1;
		ga.ga_descr = NULL;

		id = gio_id(ga.ga_ioh, ga.ga_addr, 1);
		if (!gio_is_framebuffer_id(id))
			continue;

		ga.ga_product = giofb_consid = id;
		switch (id) {
		default:
#if NIMPACT_GIO > 0
			if (GIO_PRODUCT_32BIT_ID(id) &&
			    GIO_PRODUCT_PRODUCTID(id) == GIO_PRODUCT_IMPACT) {
				if (impact_gio_cnprobe(&ga) != 0)
					return 0;
			}
#endif
			break;
		case GIO_PRODUCT_FAKEID_GRTWO:
#if NGRTWO > 0
			if (grtwo_cnprobe(&ga) != 0)
				return 0;
#endif
			break;
		case GIO_PRODUCT_FAKEID_LIGHT:
#if NLIGHT > 0
			if (light_cnprobe(&ga) != 0)
				return 0;
#endif
			break;
		case GIO_PRODUCT_FAKEID_NEWPORT:
#if NNEWPORT > 0
			if (newport_cnprobe(&ga) != 0)
				return 0;
#endif
			break;
		}
	}

	return ENXIO;
}
示例#7
0
/*
 * Try and figure out whether there is a device at the given slot address.
 */
uint32_t
gio_id(vaddr_t va, paddr_t pa, int maybe_gfx)
{
	uint32_t id32, mystery;
	uint16_t id16 = 0;
	uint8_t id8 = 0;

	/*
	 * First, attempt to read the address with various sizes.
	 *
	 * - GIO32 devices will only support reads from 32-bit aligned
	 *   addresses, in all sizes (at least for the ID register).
	 * - frame buffers will support aligned reads from any size at
	 *   any address, but will actually return the access width if
	 *   the slot is pipelined.
	 */

	if (guarded_read_4(va, &id32) != 0)
		return 0;

	/*
	 * If the address doesn't match a base slot address, then we are
	 * only probing for a light(4) frame buffer.
	 */

	if (pa != GIO_ADDR_GFX && pa != GIO_ADDR_EXP0 && pa != GIO_ADDR_EXP1) {
		if (maybe_gfx == 0)
			return 0;
		else {
			if (pa == LIGHT_ADDR_0 || pa == LIGHT_ADDR_1) {
				if (guarded_read_4(va + REX_PAGE1_SET +
				    REX_P1REG_XYOFFSET, &id32) != 0)
					return 0;
				if (id32 == 0x08000800)
					return GIO_PRODUCT_FAKEID_LIGHT;
			}
			return 0;
		}
	}

	/*
	 * GIO32 devices with a 32-bit ID register will not necessarily
	 * answer to addresses not aligned on 32 bit boundaries.
	 */

	if (guarded_read_2(va | 2, &id16) != 0 ||
	    guarded_read_1(va | 3, &id8) != 0) {
		if (GIO_PRODUCT_32BIT_ID(id32))
			return id32;
		else /* not a frame buffer anyway */
			return GIO_PRODUCT_PRODUCTID(id32);
	}

	/*
	 * Of course, GIO32 devices with a 8-bit ID register can use the
	 * other bytes in the first 32-bit word for other purposes.
	 */

	if ((id32 & 0xffff) == id16 && (id32 & 0xff) == id8) {
		if (GIO_PRODUCT_32BIT_ID(id32))
			return id32;
		else if (!GIO_PRODUCT_32BIT_ID(id8) && id8 != 0x00)
			return /*GIO_PRODUCT_PRODUCTID*/(id8);
	}

	/*
	 * If there is a frame buffer device, then either we have hit a
	 * device register (grtwo), or we did not fault because the slot
	 * is pipelined (newport).
	 * In the latter case, we attempt to probe a known register offset.
	 */

	if (maybe_gfx) {
		/*
		 * On (at least) Indy systems with newport graphics, the
		 * presence of a SCSI Expansion board (030-8133) in either
		 * slot will cause extra bits to be set in the topmost byte
		 * of the 32-bit access to the pipelined slot (i.e. the
		 * value of id32 is 0x18000004, not 0x00000004).
		 *
		 * This would prevent newport from being recognized
		 * properly.
		 *
		 * This behaviour seems to be specific to the SCSI board,
		 * since the E++ board does not trigger it. This would
		 * rule out an HPC1.x-specific cause.
		 * 
		 * We work around this by ignoring the topmost byte of id32
		 * from this point on, but it's ugly and isaish...
		 *
		 * Note that this is not necessary on Indigo 2 since this
		 * troublesome board can not be installed on such a system.
		 * Indigo are probably safe from this issues, for they can't
		 * use newport graphics; but the issue at hand might be
		 * HPC 1.x related, so better play safe.
		 */
		if (sys_config.system_type == SGI_IP20 ||
		    (sys_config.system_type == SGI_IP22 &&
		     sys_config.system_subtype != IP22_INDIGO2))
			id32 &= ~0xff000000;

		if (id32 != 4 || id16 != 2 || id8 != 1) {
			if (guarded_read_4(va + HQ2_MYSTERY, &mystery) == 0 &&
			    mystery == HQ2_MYSTERY_VALUE)
				return GIO_PRODUCT_FAKEID_GRTWO;
			else
				return 0;
		}

		/* could be newport(4) */
		if (pa == GIO_ADDR_GFX || pa == GIO_ADDR_EXP0) {
			va += NEWPORT_REX3_OFFSET;
			if (guarded_read_4(va, &id32) == 0 &&
			    guarded_read_2(va | 2, &id16) == 0 &&
			    guarded_read_1(va | 3, &id8) == 0) {
				if (id32 != 4 || id16 != 2 || id8 != 1)
					return GIO_PRODUCT_FAKEID_NEWPORT;
			}
		}

		return 0;
	}

	return 0;
}
示例#8
0
static void 
giopci_attach(struct device *parent, struct device *self, void *aux)
{
	struct giopci_softc *sc = (void *)self;
	pci_chipset_tag_t pc = &sc->sc_pc;
	struct gio_attach_args *ga = aux;
	uint32_t pci_off, pci_len, arb;
	struct pcibus_attach_args pba;
	u_long m_start, m_end;
#ifdef PCI_NETBSD_CONFIGURE
	extern int pci_conf_debug;

	pci_conf_debug = giopci_debug;
#endif

	sc->sc_iot	= ga->ga_iot;
	sc->sc_slot	= ga->ga_slot;
	sc->sc_gprid	= GIO_PRODUCT_PRODUCTID(ga->ga_product);

	if (mach_type == MACH_SGI_IP22 &&
	    mach_subtype == MACH_SGI_IP22_FULLHOUSE)
		arb = GIO_ARB_RT | GIO_ARB_MST | GIO_ARB_PIPE;
	else
		arb = GIO_ARB_RT | GIO_ARB_MST;

	if (gio_arb_config(ga->ga_slot, arb)) {
		printf(": failed to configure GIO bus arbiter\n");
		return;
	}

#if (NIMC > 0)
	imc_disable_sysad_parity();
#endif

	switch (sc->sc_gprid) {
	case PHOBOS_G100:
	case PHOBOS_G130:
	case PHOBOS_G160:
		pci_off = PHOBOS_PCI_OFFSET;
		pci_len = PHOBOS_PCI_LENGTH;
		m_start = MIPS_KSEG1_TO_PHYS(ga->ga_addr + PHOBOS_TULIP_START);
		m_end = MIPS_KSEG1_TO_PHYS(ga->ga_addr + PHOBOS_TULIP_END);
		break;

	case SETENG_GFE:
		/*
		 * NB: The SetEng board does not allow the ThunderLAN's DMA
		 *     engine to properly transfer segments that span page
		 *     boundaries. See sgimips/autoconf.c where we catch a
		 *     tl(4) device attachment and create an appropriate
		 *     proplib entry to enable the workaround.
		 */
		pci_off = SETENG_PCI_OFFSET;
		pci_len = SETENG_PCI_LENGTH;
		m_start = MIPS_KSEG1_TO_PHYS(ga->ga_addr + SETENG_TLAN_START);
		m_end = MIPS_KSEG1_TO_PHYS(ga->ga_addr + SETENG_TLAN_END);
		bus_space_write_4(ga->ga_iot, ga->ga_ioh,
		    SETENG_MAGIC_OFFSET, SETENG_MAGIC_VALUE);
		break;

	default:
		panic("giopci_attach: unsupported GIO product id 0x%02x",
		    sc->sc_gprid);
	}

	if (bus_space_subregion(ga->ga_iot, ga->ga_ioh, pci_off, pci_len,
	    &sc->sc_ioh)) {
		printf("%s: unable to map PCI registers\n",sc->sc_dev.dv_xname);
		return;
	}
	sc->sc_pci_len = pci_len;

	pc->pc_bus_maxdevs	= giopci_bus_maxdevs;
	pc->pc_conf_read	= giopci_conf_read;
	pc->pc_conf_write	= giopci_conf_write;
	pc->pc_conf_hook	= giopci_conf_hook;
	pc->pc_intr_map		= giopci_intr_map;
	pc->pc_intr_string	= giopci_intr_string;
	pc->intr_establish	= giopci_intr_establish;
	pc->intr_disestablish	= giopci_intr_disestablish;
	pc->iot			= ga->ga_iot;
	pc->ioh			= ga->ga_ioh;
	pc->cookie		= sc;

	printf(": %s\n", gio_product_string(sc->sc_gprid));

#ifdef PCI_NETBSD_CONFIGURE
	pc->pc_memext = extent_create("giopcimem", m_start, m_end,
	    M_DEVBUF, NULL, 0, EX_NOWAIT);
	pci_configure_bus(pc, NULL, pc->pc_memext, NULL, 0, mips_dcache_align);
#endif

	memset(&pba, 0, sizeof(pba));
	pba.pba_memt	= SGIMIPS_BUS_SPACE_MEM;
	pba.pba_dmat	= ga->ga_dmat;
	pba.pba_pc	= pc;
	pba.pba_flags	= PCI_FLAGS_MEM_ENABLED;
	/* NB: do not set PCI_FLAGS_{MRL,MRM,MWI}_OKAY  -- true ?! */

	config_found_ia(self, "pcibus", &pba, pcibusprint);
}