1139825Simp/*-
286232Stmm * Copyright (c) 1999, 2000 Matthew R. Green
386232Stmm * All rights reserved.
486232Stmm *
586232Stmm * Redistribution and use in source and binary forms, with or without
686232Stmm * modification, are permitted provided that the following conditions
786232Stmm * are met:
886232Stmm * 1. Redistributions of source code must retain the above copyright
986232Stmm *    notice, this list of conditions and the following disclaimer.
1086232Stmm * 2. Redistributions in binary form must reproduce the above copyright
1186232Stmm *    notice, this list of conditions and the following disclaimer in the
1286232Stmm *    documentation and/or other materials provided with the distribution.
1386232Stmm * 3. The name of the author may not be used to endorse or promote products
1486232Stmm *    derived from this software without specific prior written permission.
1586232Stmm *
1686232Stmm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1786232Stmm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1886232Stmm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1986232Stmm * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2086232Stmm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2186232Stmm * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2286232Stmm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
2386232Stmm * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2486232Stmm * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2586232Stmm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2686232Stmm * SUCH DAMAGE.
2786232Stmm *
28219567Smarius *	from: NetBSD: ebus.c,v 1.52 2008/05/29 14:51:26 mrg Exp
2986232Stmm */
30219567Smarius/*-
31219567Smarius * Copyright (c) 2001, 2003 Thomas Moestl <tmm@FreeBSD.org>
32219567Smarius * All rights reserved.
33219567Smarius *
34219567Smarius * Redistribution and use in source and binary forms, with or without
35219567Smarius * modification, are permitted provided that the following conditions
36219567Smarius * are met:
37219567Smarius * 1. Redistributions of source code must retain the above copyright
38219567Smarius *    notice, this list of conditions and the following disclaimer.
39219567Smarius * 2. Redistributions in binary form must reproduce the above copyright
40219567Smarius *    notice, this list of conditions and the following disclaimer in the
41219567Smarius *    documentation and/or other materials provided with the distribution.
42219567Smarius * 3. The name of the author may not be used to endorse or promote products
43219567Smarius *    derived from this software without specific prior written permission.
44219567Smarius *
45219567Smarius * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
46219567Smarius * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
47219567Smarius * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
48219567Smarius * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
49219567Smarius * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
50219567Smarius * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51219567Smarius * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
52219567Smarius * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
53219567Smarius * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54219567Smarius * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55219567Smarius * SUCH DAMAGE.
56219567Smarius */
5786232Stmm
58153057Smarius#include <sys/cdefs.h>
59153057Smarius__FBSDID("$FreeBSD$");
60153057Smarius
6186232Stmm/*
6286232Stmm * Helper functions which can be used in both ISA and EBus code.
6386232Stmm */
6486232Stmm
6586232Stmm#include <sys/param.h>
6691966Stmm#include <sys/systm.h>
6786232Stmm#include <sys/bus.h>
6886232Stmm
69190110Smarius#include <dev/ofw/ofw_bus_subr.h>
70119338Simp#include <dev/ofw/openfirm.h>
7186232Stmm
72117119Stmm#include <machine/bus.h>
7386232Stmm#include <machine/resource.h>
7486232Stmm
75117119Stmm#include <sparc64/pci/ofw_pci.h>
7686232Stmm#include <sparc64/isa/ofw_isa.h>
7786232Stmm
78117119Stmm#include "pcib_if.h"
79117119Stmm
80128712Stmmint
81128712Stmmofw_isa_range_restype(struct isa_ranges *range)
82128712Stmm{
83128712Stmm	int ps = ISA_RANGE_PS(range);
84128712Stmm
85128712Stmm	switch (ps) {
86153061Smarius	case OFW_PCI_CS_IO:
87128712Stmm		return (SYS_RES_IOPORT);
88153061Smarius	case OFW_PCI_CS_MEM32:
89128712Stmm		return (SYS_RES_MEMORY);
90128712Stmm	default:
91128712Stmm		panic("ofw_isa_range_restype: illegal space %x", ps);
92128712Stmm	}
93128712Stmm
94128712Stmm}
95128712Stmm
9686232Stmm/* XXX: this only supports PCI as parent bus right now. */
9786232Stmmint
98128712Stmmofw_isa_range_map(struct isa_ranges *range, int nrange, u_long *start,
99128712Stmm    u_long *end, int *which)
10086232Stmm{
101128712Stmm	struct isa_ranges *r;
102153057Smarius	uint64_t offs, cstart, cend;
10386232Stmm	int i;
10486232Stmm
10586232Stmm	for (i = 0; i < nrange; i++) {
106128712Stmm		r = &range[i];
107128712Stmm		cstart = ISA_RANGE_CHILD(r);
108200880Smarius		cend = cstart + r->size - 1;
10986232Stmm		if (*start < cstart || *start > cend)
11086232Stmm			continue;
11186232Stmm		if (*end < cstart || *end > cend) {
112200880Smarius			panic("ofw_isa_map_iorange: iorange crosses PCI "
11386232Stmm			    "ranges (%#lx not in %#lx - %#lx)", *end, cstart,
11486232Stmm			    cend);
11586232Stmm		}
116128712Stmm		offs = ISA_RANGE_PHYS(r);
11786232Stmm		*start = *start + offs - cstart;
11886232Stmm		*end  = *end + offs - cstart;
119128712Stmm		if (which != NULL)
120128712Stmm			*which = i;
121128712Stmm		return (ofw_isa_range_restype(r));
12286232Stmm	}
12386232Stmm	panic("ofw_isa_map_iorange: could not map range %#lx - %#lx",
12486232Stmm	    *start, *end);
12586232Stmm}
126117119Stmm
127117119Stmmofw_pci_intr_t
128117119Stmmofw_isa_route_intr(device_t bridge, phandle_t node, struct ofw_bus_iinfo *ii,
129117119Stmm    ofw_isa_intr_t intr)
130117119Stmm{
131117119Stmm	struct isa_regs reg;
132117119Stmm	device_t pbridge;
133117119Stmm	ofw_isa_intr_t mintr;
134117119Stmm
135117119Stmm	pbridge = device_get_parent(device_get_parent(bridge));
136117119Stmm	/*
137117119Stmm	 * If we get a match from using the map, the resulting INO is
138117119Stmm	 * fully specified, so we may not continue to map.
139117119Stmm	 */
140117119Stmm	if (!ofw_bus_lookup_imap(node, ii, &reg, sizeof(reg),
141259516Snwhitehorn	    &intr, sizeof(intr), &mintr, sizeof(mintr), NULL)) {
142117119Stmm		/* Try routing at the parent bridge. */
143117119Stmm		mintr = PCIB_ROUTE_INTERRUPT(pbridge, bridge, intr);
144117119Stmm	}
145117119Stmm	return (mintr);
146117119Stmm}
147