/*
* Copyright (c) 2007 Mark Kettenis
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* fill in our softc with information from the prom
*/
sc->sc_intmap = NULL;
sc->sc_range = NULL;
error = prom_getprop(node, "interrupt-map",
sizeof(struct ebus_interrupt_map),
&sc->sc_nintmap, (void **)&sc->sc_intmap);
switch (error) {
case 0:
immp = &sc->sc_intmapmask;
nmapmask = 1;
error = prom_getprop(node, "interrupt-map-mask",
sizeof(struct ebus_interrupt_map_mask), &nmapmask,
(void **)&immp);
if (error)
panic("could not get ebus interrupt-map-mask: error %d",
error);
if (nmapmask != 1)
panic("ebus interrupt-map-mask is broken");
break;
case ENOENT:
break;
default:
panic("ebus interrupt-map: error %d", error);
break;
}
/*
* Ebus interrupts may be connected to any of the PCI Express
* leafs. Here we add the appropriate IGN to the interrupt
* mappings such that we can use it to distinguish between
* interrupts connected to PCIE-A and PCIE-B.
*/
for (i = 0; i < sc->sc_nintmap; i++) {
for (j = 0; j < pyro_cd.cd_ndevs; j++) {
device_t dt = device_lookup(&pyro_cd, j);
psc = device_private(dt);
if (psc && psc->sc_node == sc->sc_intmap[i].cnode) {
sc->sc_intmap[i].cintr |= psc->sc_ign;
break;
}
}
}
hi = offset >> 32UL;
lo = offset & 0xffffffff;
range = (struct ebus_mainbus_ranges *)sc->sc_range;
DPRINTF(EDB_BUSMAP, (" (hi %08x lo %08x)", (u_int)hi, (u_int)lo));
for (i = 0; i < sc->sc_nrange; i++) {
bus_addr_t addr;
if (hi != range[i].child_hi)
continue;
if (lo < range[i].child_lo ||
(lo + size) > (range[i].child_lo + range[i].size))
continue;
#if 0
/* Isolate address space and find the right tag */
ss = (range[i].phys_hi>>24)&3;
switch (ss) {
case 1: /* I/O space */
t = sc->sc_iotag;
break;
case 2: /* Memory space */
t = sc->sc_memtag;
break;
case 0: /* Config space */
case 3: /* 64-bit Memory space */
default: /* WTF? */
/* We don't handle these */
panic("ebus_mainbus_bus_map: illegal space %x", ss);
break;
}
#endif