ofw_isa.c revision 128712
10Sduke/* 210369Sdholmes * Copyright (c) 1999, 2000 Matthew R. Green 30Sduke * Copyright (c) 2001, 2003 Thomas Moestl <tmm@FreeBSD.org> 40Sduke * All rights reserved. 50Sduke * 60Sduke * Redistribution and use in source and binary forms, with or without 70Sduke * modification, are permitted provided that the following conditions 80Sduke * are met: 90Sduke * 1. Redistributions of source code must retain the above copyright 100Sduke * notice, this list of conditions and the following disclaimer. 110Sduke * 2. Redistributions in binary form must reproduce the above copyright 120Sduke * notice, this list of conditions and the following disclaimer in the 130Sduke * documentation and/or other materials provided with the distribution. 140Sduke * 3. The name of the author may not be used to endorse or promote products 150Sduke * derived from this software without specific prior written permission. 160Sduke * 170Sduke * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 180Sduke * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 191472Strims * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 201472Strims * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 211472Strims * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 220Sduke * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 230Sduke * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 240Sduke * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 251879Sstefank * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2611857Sdholmes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2711254Sgoetz * SUCH DAMAGE. 281879Sstefank * 296402Sgoetz * from: NetBSD: ebus.c,v 1.26 2001/09/10 16:27:53 eeh Exp 301879Sstefank * 313864Sstefank * $FreeBSD: head/sys/sparc64/isa/ofw_isa.c 128712 2004-04-28 13:06:46Z tmm $ 321879Sstefank */ 3311658Sgoetz 340Sduke/* 350Sduke * Helper functions which can be used in both ISA and EBus code. 360Sduke */ 370Sduke 380Sduke#include "opt_ofw_pci.h" 390Sduke 400Sduke#include <sys/param.h> 410Sduke#include <sys/systm.h> 420Sduke#include <sys/bus.h> 430Sduke 440Sduke#include <dev/ofw/openfirm.h> 450Sduke#include <dev/ofw/ofw_pci.h> 460Sduke 470Sduke#include <machine/bus.h> 480Sduke#include <machine/resource.h> 490Sduke#include <machine/ofw_bus.h> 500Sduke 510Sduke#include <sparc64/pci/ofw_pci.h> 520Sduke#include <sparc64/isa/ofw_isa.h> 530Sduke 540Sduke#include "pcib_if.h" 550Sduke 560Sdukeint 570Sdukeofw_isa_range_restype(struct isa_ranges *range) 580Sduke{ 590Sduke int ps = ISA_RANGE_PS(range); 600Sduke 610Sduke switch (ps) { 620Sduke case PCI_CS_IO: 630Sduke return (SYS_RES_IOPORT); 640Sduke case PCI_CS_MEM32: 650Sduke return (SYS_RES_MEMORY); 660Sduke default: 670Sduke panic("ofw_isa_range_restype: illegal space %x", ps); 680Sduke } 690Sduke 700Sduke} 710Sduke 720Sduke/* XXX: this only supports PCI as parent bus right now. */ 730Sdukeint 740Sdukeofw_isa_range_map(struct isa_ranges *range, int nrange, u_long *start, 750Sduke u_long *end, int *which) 760Sduke{ 770Sduke struct isa_ranges *r; 780Sduke u_int64_t offs, cstart, cend; 790Sduke int i; 800Sduke 810Sduke for (i = 0; i < nrange; i++) { 820Sduke r = &range[i]; 830Sduke cstart = ISA_RANGE_CHILD(r); 840Sduke cend = cstart + r->size; 850Sduke if (*start < cstart || *start > cend) 860Sduke continue; 870Sduke if (*end < cstart || *end > cend) { 880Sduke panic("ofw_isa_map_iorange: iorange crosses pci " 890Sduke "ranges (%#lx not in %#lx - %#lx)", *end, cstart, 900Sduke cend); 910Sduke } 920Sduke offs = ISA_RANGE_PHYS(r); 930Sduke *start = *start + offs - cstart; 940Sduke *end = *end + offs - cstart; 950Sduke if (which != NULL) 960Sduke *which = i; 970Sduke return (ofw_isa_range_restype(r)); 980Sduke } 990Sduke panic("ofw_isa_map_iorange: could not map range %#lx - %#lx", 1000Sduke *start, *end); 1010Sduke} 1020Sduke 1030Sduke#ifdef OFW_NEWPCI 1040Sdukeofw_pci_intr_t 1050Sdukeofw_isa_route_intr(device_t bridge, phandle_t node, struct ofw_bus_iinfo *ii, 1060Sduke ofw_isa_intr_t intr) 1070Sduke{ 1080Sduke struct isa_regs reg; 1090Sduke u_int8_t maskbuf[sizeof(reg) + sizeof(intr)]; 1100Sduke device_t pbridge; 1110Sduke ofw_isa_intr_t mintr; 1120Sduke 1130Sduke pbridge = device_get_parent(device_get_parent(bridge)); 1140Sduke /* 1150Sduke * If we get a match from using the map, the resulting INO is 1160Sduke * fully specified, so we may not continue to map. 1170Sduke */ 1180Sduke if (!ofw_bus_lookup_imap(node, ii, ®, sizeof(reg), 1190Sduke &intr, sizeof(intr), &mintr, sizeof(mintr), maskbuf)) { 1200Sduke /* Try routing at the parent bridge. */ 1210Sduke mintr = PCIB_ROUTE_INTERRUPT(pbridge, bridge, intr); 1220Sduke } 1230Sduke return (mintr); 1240Sduke} 1250Sduke#endif /* OFW_NEWPCI */ 1260Sduke