/*
* Copyright (c) 2006 Stephen M. Rumble
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Glue for PCI devices that are connected to the GIO bus by various little
* GIO<->PCI ASICs.
*
* We presently support the following boards:
* o Phobos G100/G130/G160 (if_tlp, lxtphy)
* o Set Engineering GFE (if_tl, nsphy)
*/
static int
giopci_match(device_t parent, cfdata_t 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);
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", device_xname(self));
return;
}
sc->sc_pci_len = pci_len;
static void
giopci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
{
struct giopci_softc *sc = pc->cookie;
int bus, dev, func;
if ((unsigned int)reg >= PCI_CONF_SIZE)
return;
pci_decompose_tag(pc, tag, &bus, &dev, &func);
if (bus != 0 || dev != 0 || func != 0)
return;
/* XXX - should just use bus_space_poke */
if (reg >= sc->sc_pci_len) {
DPRINTF(("giopci_conf_write: reg 0x%x out of bounds "
"(val = 0x%08x)\n", reg, data));
return;
}