pci_machdep_ofw.c revision 1.1.8.1 1 1.1.8.1 yamt /* $NetBSD: pci_machdep_ofw.c,v 1.1.8.1 2007/10/18 08:32:42 yamt Exp $ */
2 1.1.8.1 yamt
3 1.1.8.1 yamt /*-
4 1.1.8.1 yamt * Copyright (c) 2007 The NetBSD Foundation, Inc.
5 1.1.8.1 yamt * All rights reserved.
6 1.1.8.1 yamt *
7 1.1.8.1 yamt * This code is derived from software contributed to The NetBSD Foundation
8 1.1.8.1 yamt * by Tim Rightnour
9 1.1.8.1 yamt *
10 1.1.8.1 yamt * Redistribution and use in source and binary forms, with or without
11 1.1.8.1 yamt * modification, are permitted provided that the following conditions
12 1.1.8.1 yamt * are met:
13 1.1.8.1 yamt * 1. Redistributions of source code must retain the above copyright
14 1.1.8.1 yamt * notice, this list of conditions and the following disclaimer.
15 1.1.8.1 yamt * 2. Redistributions in binary form must reproduce the above copyright
16 1.1.8.1 yamt * notice, this list of conditions and the following disclaimer in the
17 1.1.8.1 yamt * documentation and/or other materials provided with the distribution.
18 1.1.8.1 yamt * 3. All advertising materials mentioning features or use of this software
19 1.1.8.1 yamt * must display the following acknowledgement:
20 1.1.8.1 yamt * This product includes software developed by the NetBSD
21 1.1.8.1 yamt * Foundation, Inc. and its contributors.
22 1.1.8.1 yamt * 4. Neither the name of The NetBSD Foundation nor the names of its
23 1.1.8.1 yamt * contributors may be used to endorse or promote products derived
24 1.1.8.1 yamt * from this software without specific prior written permission.
25 1.1.8.1 yamt *
26 1.1.8.1 yamt * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 1.1.8.1 yamt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 1.1.8.1 yamt * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 1.1.8.1 yamt * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 1.1.8.1 yamt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 1.1.8.1 yamt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 1.1.8.1 yamt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 1.1.8.1 yamt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 1.1.8.1 yamt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 1.1.8.1 yamt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 1.1.8.1 yamt * POSSIBILITY OF SUCH DAMAGE.
37 1.1.8.1 yamt */
38 1.1.8.1 yamt
39 1.1.8.1 yamt /*
40 1.1.8.1 yamt * Generic OFW routines for pci_machdep
41 1.1.8.1 yamt */
42 1.1.8.1 yamt
43 1.1.8.1 yamt #include <sys/cdefs.h>
44 1.1.8.1 yamt __KERNEL_RCSID(0, "$NetBSD: pci_machdep_ofw.c,v 1.1.8.1 2007/10/18 08:32:42 yamt Exp $");
45 1.1.8.1 yamt
46 1.1.8.1 yamt #include <sys/types.h>
47 1.1.8.1 yamt #include <sys/param.h>
48 1.1.8.1 yamt #include <sys/time.h>
49 1.1.8.1 yamt #include <sys/systm.h>
50 1.1.8.1 yamt #include <sys/errno.h>
51 1.1.8.1 yamt #include <sys/device.h>
52 1.1.8.1 yamt #include <sys/malloc.h>
53 1.1.8.1 yamt
54 1.1.8.1 yamt #include <uvm/uvm_extern.h>
55 1.1.8.1 yamt
56 1.1.8.1 yamt #include <machine/bus.h>
57 1.1.8.1 yamt
58 1.1.8.1 yamt #include <machine/autoconf.h>
59 1.1.8.1 yamt #include <machine/pio.h>
60 1.1.8.1 yamt #include <machine/intr.h>
61 1.1.8.1 yamt
62 1.1.8.1 yamt #include <dev/pci/pcivar.h>
63 1.1.8.1 yamt #include <dev/pci/pcireg.h>
64 1.1.8.1 yamt #include <dev/pci/ppbreg.h>
65 1.1.8.1 yamt #include <dev/pci/pcidevs.h>
66 1.1.8.1 yamt #include <dev/pci/pciconf.h>
67 1.1.8.1 yamt
68 1.1.8.1 yamt #include <dev/ofw/openfirm.h>
69 1.1.8.1 yamt #include <dev/ofw/ofw_pci.h>
70 1.1.8.1 yamt
71 1.1.8.1 yamt pcitag_t genppc_pci_indirect_make_tag(void *, int, int, int);
72 1.1.8.1 yamt void genppc_pci_indirect_decompose_tag(void *, pcitag_t, int *, int *, int *);
73 1.1.8.1 yamt
74 1.1.8.1 yamt ofw_pic_node_t picnodes[8];
75 1.1.8.1 yamt int nrofpics = 0;
76 1.1.8.1 yamt
77 1.1.8.1 yamt int
78 1.1.8.1 yamt genofw_find_picnode(int node)
79 1.1.8.1 yamt {
80 1.1.8.1 yamt int i;
81 1.1.8.1 yamt
82 1.1.8.1 yamt for (i = 0; i < 8; i++)
83 1.1.8.1 yamt if (node == picnodes[i].node)
84 1.1.8.1 yamt return i;
85 1.1.8.1 yamt return -1;
86 1.1.8.1 yamt }
87 1.1.8.1 yamt
88 1.1.8.1 yamt void
89 1.1.8.1 yamt genofw_find_ofpics(int startnode)
90 1.1.8.1 yamt {
91 1.1.8.1 yamt int node, iparent, child, iranges[2];
92 1.1.8.1 yamt char name[32];
93 1.1.8.1 yamt
94 1.1.8.1 yamt for (node = startnode; node; node = OF_peer(node)) {
95 1.1.8.1 yamt if ((child = OF_child(node)) != 0)
96 1.1.8.1 yamt genofw_find_ofpics(child);
97 1.1.8.1 yamt memset(name, 0, sizeof(name));
98 1.1.8.1 yamt if (OF_getprop(node, "name", name, sizeof(name)) == -1)
99 1.1.8.1 yamt continue;
100 1.1.8.1 yamt if (strncmp(name, "interrupt-controller", 20) == 0)
101 1.1.8.1 yamt goto foundic;
102 1.1.8.1 yamt if (OF_getprop(node, "interrupt-controller", name,
103 1.1.8.1 yamt sizeof(name)) > -1)
104 1.1.8.1 yamt goto foundic;
105 1.1.8.1 yamt if (OF_getprop(node, "device-type", name, sizeof(name)) == -1)
106 1.1.8.1 yamt continue;
107 1.1.8.1 yamt if (strncmp(name, "interrupt-controller", 20) == 0)
108 1.1.8.1 yamt goto foundic;
109 1.1.8.1 yamt foundic:
110 1.1.8.1 yamt picnodes[nrofpics].node = node;
111 1.1.8.1 yamt if (OF_getprop(node, "interrupt-parent", &iparent,
112 1.1.8.1 yamt sizeof(iparent)) == sizeof(iparent))
113 1.1.8.1 yamt picnodes[nrofpics].parent = iparent;
114 1.1.8.1 yamt if (OF_getprop(node, "#interrupt-cells", &iparent,
115 1.1.8.1 yamt sizeof(iparent)) == sizeof(iparent))
116 1.1.8.1 yamt picnodes[nrofpics].cells = iparent;
117 1.1.8.1 yamt else
118 1.1.8.1 yamt picnodes[nrofpics].cells = 1;
119 1.1.8.1 yamt if (OF_getprop(node, "interrupt-ranges", iranges,
120 1.1.8.1 yamt sizeof(int)*2) == sizeof(int)*2)
121 1.1.8.1 yamt picnodes[nrofpics].intrs = iranges[1];
122 1.1.8.1 yamt else
123 1.1.8.1 yamt picnodes[nrofpics].intrs = 16;
124 1.1.8.1 yamt if (nrofpics > 0)
125 1.1.8.1 yamt picnodes[nrofpics].offset = picnodes[nrofpics-1].offset
126 1.1.8.1 yamt + picnodes[nrofpics-1].intrs;
127 1.1.8.1 yamt else
128 1.1.8.1 yamt picnodes[nrofpics].offset = 0;
129 1.1.8.1 yamt OF_getprop(node, "device-type", name, sizeof(name));
130 1.1.8.1 yamt if (strcmp(name, "open-pic") == 0)
131 1.1.8.1 yamt picnodes[nrofpics].type = PICNODE_TYPE_OPENPIC;
132 1.1.8.1 yamt if (strcmp(name, "interrupt-controller") == 0) {
133 1.1.8.1 yamt OF_getprop(node, "compatible", name, sizeof(name));
134 1.1.8.1 yamt if (strcmp(name, "heathrow") != 0)
135 1.1.8.1 yamt picnodes[nrofpics].type = PICNODE_TYPE_HEATHROW;
136 1.1.8.1 yamt if (strcmp(name, "chrp,iic") != 0)
137 1.1.8.1 yamt picnodes[nrofpics].type = PICNODE_TYPE_8259;
138 1.1.8.1 yamt }
139 1.1.8.1 yamt nrofpics++;
140 1.1.8.1 yamt }
141 1.1.8.1 yamt }
142 1.1.8.1 yamt
143 1.1.8.1 yamt /* Fix up the various picnode offsets */
144 1.1.8.1 yamt void
145 1.1.8.1 yamt genofw_fixup_picnode_offsets(void)
146 1.1.8.1 yamt {
147 1.1.8.1 yamt int i, curoff;
148 1.1.8.1 yamt
149 1.1.8.1 yamt curoff=0;
150 1.1.8.1 yamt
151 1.1.8.1 yamt for (i=0; i < nrofpics; i++) {
152 1.1.8.1 yamt if (picnodes[i].type == PICNODE_TYPE_8259) {
153 1.1.8.1 yamt picnodes[i].offset = 0;
154 1.1.8.1 yamt curoff = picnodes[i].intrs;
155 1.1.8.1 yamt }
156 1.1.8.1 yamt }
157 1.1.8.1 yamt for (i=0; i < nrofpics; i++) {
158 1.1.8.1 yamt /* now skip the 8259 */
159 1.1.8.1 yamt if (picnodes[i].type == PICNODE_TYPE_8259)
160 1.1.8.1 yamt continue;
161 1.1.8.1 yamt picnodes[i].offset = curoff;
162 1.1.8.1 yamt curoff += picnodes[i].intrs;
163 1.1.8.1 yamt }
164 1.1.8.1 yamt }
165 1.1.8.1 yamt
166 1.1.8.1 yamt /* we are given a pci devnode, and dig from there */
167 1.1.8.1 yamt void
168 1.1.8.1 yamt genofw_setup_pciintr_map(struct genppc_pci_chipset_businfo *pbi, int pcinode)
169 1.1.8.1 yamt {
170 1.1.8.1 yamt int node;
171 1.1.8.1 yamt u_int32_t map[160];
172 1.1.8.1 yamt int parent, len;
173 1.1.8.1 yamt int curdev;
174 1.1.8.1 yamt int i, reclen, nrofpcidevs=0;
175 1.1.8.1 yamt u_int32_t acells, icells, pcells;
176 1.1.8.1 yamt prop_dictionary_t dict;
177 1.1.8.1 yamt prop_dictionary_t sub=0;
178 1.1.8.1 yamt
179 1.1.8.1 yamt len = OF_getprop(pcinode, "interrupt-map", map, sizeof(map));
180 1.1.8.1 yamt if (len == -1)
181 1.1.8.1 yamt goto nomap;
182 1.1.8.1 yamt
183 1.1.8.1 yamt if (OF_getprop(pcinode, "#address-cells", &acells,
184 1.1.8.1 yamt sizeof(acells)) == -1)
185 1.1.8.1 yamt acells = 1;
186 1.1.8.1 yamt if (OF_getprop(pcinode, "#interrupt-cells", &icells,
187 1.1.8.1 yamt sizeof(icells)) == -1)
188 1.1.8.1 yamt icells = 1;
189 1.1.8.1 yamt
190 1.1.8.1 yamt parent = map[acells+icells+1];
191 1.1.8.1 yamt if (OF_getprop(parent, "#interrupt-cells", &pcells,
192 1.1.8.1 yamt sizeof(pcells)) == -1)
193 1.1.8.1 yamt pcells = 1;
194 1.1.8.1 yamt
195 1.1.8.1 yamt reclen = acells+pcells+icells+1;
196 1.1.8.1 yamt nrofpcidevs = len / (reclen * sizeof(int));
197 1.1.8.1 yamt
198 1.1.8.1 yamt dict = prop_dictionary_create_with_capacity(nrofpcidevs*2);
199 1.1.8.1 yamt KASSERT(dict != NULL);
200 1.1.8.1 yamt
201 1.1.8.1 yamt curdev = -1;
202 1.1.8.1 yamt prop_dictionary_set(pbi->pbi_properties, "ofw-pci-intrmap", dict);
203 1.1.8.1 yamt for (i = 0; i < nrofpcidevs; i++) {
204 1.1.8.1 yamt prop_number_t intr_num;
205 1.1.8.1 yamt int dev, pin, pic;
206 1.1.8.1 yamt char key[20];
207 1.1.8.1 yamt
208 1.1.8.1 yamt pic = genofw_find_picnode(map[i*reclen + acells + icells]);
209 1.1.8.1 yamt KASSERT(pic != -1);
210 1.1.8.1 yamt dev = (map[i*reclen] >> 8) / 0x8;
211 1.1.8.1 yamt if (curdev != dev)
212 1.1.8.1 yamt sub = prop_dictionary_create_with_capacity(4);
213 1.1.8.1 yamt pin = map[i*reclen + acells];
214 1.1.8.1 yamt intr_num = prop_number_create_integer(map[i*reclen + acells + icells + 1] + picnodes[pic].offset);
215 1.1.8.1 yamt sprintf(key, "pin-%c", 'A' + pin);
216 1.1.8.1 yamt prop_dictionary_set(sub, key, intr_num);
217 1.1.8.1 yamt prop_object_release(intr_num);
218 1.1.8.1 yamt /* should we care about level? */
219 1.1.8.1 yamt
220 1.1.8.1 yamt sprintf(key, "devfunc-%d", dev);
221 1.1.8.1 yamt prop_dictionary_set(dict, key, sub);
222 1.1.8.1 yamt if (curdev != dev) {
223 1.1.8.1 yamt prop_object_release(sub);
224 1.1.8.1 yamt curdev = dev;
225 1.1.8.1 yamt }
226 1.1.8.1 yamt }
227 1.1.8.1 yamt /* the mapping is complete */
228 1.1.8.1 yamt prop_object_release(dict);
229 1.1.8.1 yamt return;
230 1.1.8.1 yamt
231 1.1.8.1 yamt nomap:
232 1.1.8.1 yamt /* so, we have one of those annoying machines that doesn't provide
233 1.1.8.1 yamt * a nice simple map of interrupts. We get to do this the hard
234 1.1.8.1 yamt * way instead. Lucky us.
235 1.1.8.1 yamt */
236 1.1.8.1 yamt for (node = OF_child(pcinode), nrofpcidevs=0; node;
237 1.1.8.1 yamt node = OF_peer(node))
238 1.1.8.1 yamt nrofpcidevs++;
239 1.1.8.1 yamt dict = prop_dictionary_create_with_capacity(nrofpcidevs*2);
240 1.1.8.1 yamt KASSERT(dict != NULL);
241 1.1.8.1 yamt prop_dictionary_set(pbi->pbi_properties, "ofw-pci-intrmap", dict);
242 1.1.8.1 yamt
243 1.1.8.1 yamt for (node = OF_child(pcinode); node; node = OF_peer(node)) {
244 1.1.8.1 yamt uint32_t irqs[4], reg[5];
245 1.1.8.1 yamt prop_number_t intr_num;
246 1.1.8.1 yamt int dev, pin;
247 1.1.8.1 yamt char key[20];
248 1.1.8.1 yamt
249 1.1.8.1 yamt /* walk the bus looking for pci devices and map them */
250 1.1.8.1 yamt if (OF_getprop(node, "AAPL,interrupts", irqs, 4) > 0) {
251 1.1.8.1 yamt dev = 0;
252 1.1.8.1 yamt if (OF_getprop(node, "reg", reg, 5) > 0)
253 1.1.8.1 yamt dev = ((reg[0] & 0x0000ff00) >> 8) / 0x8;
254 1.1.8.1 yamt else if (OF_getprop(node, "assigned-addresses",
255 1.1.8.1 yamt reg, 5) > 0)
256 1.1.8.1 yamt dev = ((reg[0] & 0x0000ff00) >> 8) / 0x8;
257 1.1.8.1 yamt if (dev == 0) {
258 1.1.8.1 yamt aprint_error("cannot figure out device num "
259 1.1.8.1 yamt "for node 0x%x\n", node);
260 1.1.8.1 yamt continue;
261 1.1.8.1 yamt }
262 1.1.8.1 yamt sub = prop_dictionary_create_with_capacity(4);
263 1.1.8.1 yamt if (OF_getprop(node, "interrupts", &pin, 4) < 0)
264 1.1.8.1 yamt pin = 1;
265 1.1.8.1 yamt intr_num = prop_number_create_integer(irqs[0]);
266 1.1.8.1 yamt sprintf(key, "pin-%c", 'A' + pin);
267 1.1.8.1 yamt prop_dictionary_set(sub, key, intr_num);
268 1.1.8.1 yamt prop_object_release(intr_num);
269 1.1.8.1 yamt sprintf(key, "devfunc-%d", dev);
270 1.1.8.1 yamt prop_dictionary_set(dict, key, sub);
271 1.1.8.1 yamt prop_object_release(sub);
272 1.1.8.1 yamt }
273 1.1.8.1 yamt }
274 1.1.8.1 yamt aprint_normal("%s\n", prop_dictionary_externalize(pbi->pbi_properties));
275 1.1.8.1 yamt }
276 1.1.8.1 yamt
277 1.1.8.1 yamt int
278 1.1.8.1 yamt genofw_find_node_by_devfunc(int startnode, int bus, int dev, int func)
279 1.1.8.1 yamt {
280 1.1.8.1 yamt int node, sz, p=0;
281 1.1.8.1 yamt uint32_t reg;
282 1.1.8.1 yamt
283 1.1.8.1 yamt for (node = startnode; node; node = p) {
284 1.1.8.1 yamt sz = OF_getprop(node, "reg", ®, sizeof(reg));
285 1.1.8.1 yamt if (sz != sizeof(reg))
286 1.1.8.1 yamt continue;
287 1.1.8.1 yamt if (OFW_PCI_PHYS_HI_BUS(reg) == bus &&
288 1.1.8.1 yamt OFW_PCI_PHYS_HI_DEVICE(reg) == dev &&
289 1.1.8.1 yamt OFW_PCI_PHYS_HI_FUNCTION(reg) == func)
290 1.1.8.1 yamt return node;
291 1.1.8.1 yamt if ((p = OF_child(node)))
292 1.1.8.1 yamt continue;
293 1.1.8.1 yamt while (node) {
294 1.1.8.1 yamt if ((p = OF_peer(node)))
295 1.1.8.1 yamt break;
296 1.1.8.1 yamt node = OF_parent(node);
297 1.1.8.1 yamt }
298 1.1.8.1 yamt }
299 1.1.8.1 yamt /* couldn't find it */
300 1.1.8.1 yamt return -1;
301 1.1.8.1 yamt }
302 1.1.8.1 yamt
303 1.1.8.1 yamt int
304 1.1.8.1 yamt genofw_pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
305 1.1.8.1 yamt {
306 1.1.8.1 yamt struct genppc_pci_chipset_businfo *pbi;
307 1.1.8.1 yamt prop_dictionary_t dict, devsub;
308 1.1.8.1 yamt prop_object_t pinsub;
309 1.1.8.1 yamt prop_number_t pbus;
310 1.1.8.1 yamt int busno, bus, pin, line, swiz, dev, origdev, i;
311 1.1.8.1 yamt char key[20];
312 1.1.8.1 yamt
313 1.1.8.1 yamt pin = pa->pa_intrpin;
314 1.1.8.1 yamt line = pa->pa_intrline;
315 1.1.8.1 yamt bus = busno = pa->pa_bus;
316 1.1.8.1 yamt swiz = pa->pa_intrswiz;
317 1.1.8.1 yamt origdev = dev = pa->pa_device;
318 1.1.8.1 yamt i = 0;
319 1.1.8.1 yamt
320 1.1.8.1 yamt pbi = SIMPLEQ_FIRST(&pa->pa_pc->pc_pbi);
321 1.1.8.1 yamt while (busno--)
322 1.1.8.1 yamt pbi = SIMPLEQ_NEXT(pbi, next);
323 1.1.8.1 yamt KASSERT(pbi != NULL);
324 1.1.8.1 yamt
325 1.1.8.1 yamt dict = prop_dictionary_get(pbi->pbi_properties, "ofw-pci-intrmap");
326 1.1.8.1 yamt
327 1.1.8.1 yamt if (dict != NULL)
328 1.1.8.1 yamt i = prop_dictionary_count(dict);
329 1.1.8.1 yamt
330 1.1.8.1 yamt if (dict == NULL || i == 0) {
331 1.1.8.1 yamt /* We have an unmapped bus, now it gets hard */
332 1.1.8.1 yamt pbus = prop_dictionary_get(pbi->pbi_properties,
333 1.1.8.1 yamt "ofw-pcibus-parent");
334 1.1.8.1 yamt if (pbus == NULL)
335 1.1.8.1 yamt goto bad;
336 1.1.8.1 yamt busno = prop_number_integer_value(pbus);
337 1.1.8.1 yamt pbus = prop_dictionary_get(pbi->pbi_properties,
338 1.1.8.1 yamt "ofw-pcibus-rawdevnum");
339 1.1.8.1 yamt dev = prop_number_integer_value(pbus);
340 1.1.8.1 yamt
341 1.1.8.1 yamt /* now that we know the parent bus, we need to find it's pbi */
342 1.1.8.1 yamt pbi = SIMPLEQ_FIRST(&pa->pa_pc->pc_pbi);
343 1.1.8.1 yamt while (busno--)
344 1.1.8.1 yamt pbi = SIMPLEQ_NEXT(pbi, next);
345 1.1.8.1 yamt KASSERT(pbi != NULL);
346 1.1.8.1 yamt
347 1.1.8.1 yamt /* swizzle the pin */
348 1.1.8.1 yamt pin = ((pin + origdev - 1) & 3) + 1;
349 1.1.8.1 yamt
350 1.1.8.1 yamt /* now we have the pbi, ask for dict again */
351 1.1.8.1 yamt dict = prop_dictionary_get(pbi->pbi_properties,
352 1.1.8.1 yamt "ofw-pci-intrmap");
353 1.1.8.1 yamt if (dict == NULL)
354 1.1.8.1 yamt goto bad;
355 1.1.8.1 yamt }
356 1.1.8.1 yamt
357 1.1.8.1 yamt /* No IRQ used. */
358 1.1.8.1 yamt if (pin == 0)
359 1.1.8.1 yamt goto bad;
360 1.1.8.1 yamt if (pin > 4) {
361 1.1.8.1 yamt aprint_error("pci_intr_map: bad interrupt pin %d\n", pin);
362 1.1.8.1 yamt goto bad;
363 1.1.8.1 yamt }
364 1.1.8.1 yamt
365 1.1.8.1 yamt sprintf(key, "devfunc-%d", dev);
366 1.1.8.1 yamt devsub = prop_dictionary_get(dict, key);
367 1.1.8.1 yamt if (devsub == NULL)
368 1.1.8.1 yamt goto bad;
369 1.1.8.1 yamt sprintf(key, "pin-%c", 'A' + (pin-1));
370 1.1.8.1 yamt pinsub = prop_dictionary_get(devsub, key);
371 1.1.8.1 yamt if (pinsub == NULL)
372 1.1.8.1 yamt goto bad;
373 1.1.8.1 yamt line = prop_number_integer_value(pinsub);
374 1.1.8.1 yamt
375 1.1.8.1 yamt if (line == 0 || line == 255) {
376 1.1.8.1 yamt aprint_error("pci_intr_map: no mapping for pin %c\n",'@' + pin);
377 1.1.8.1 yamt goto bad;
378 1.1.8.1 yamt }
379 1.1.8.1 yamt
380 1.1.8.1 yamt *ihp = line;
381 1.1.8.1 yamt return 0;
382 1.1.8.1 yamt
383 1.1.8.1 yamt bad:
384 1.1.8.1 yamt *ihp = -1;
385 1.1.8.1 yamt return 1;
386 1.1.8.1 yamt }
387 1.1.8.1 yamt
388 1.1.8.1 yamt int
389 1.1.8.1 yamt genofw_pci_conf_hook(pci_chipset_tag_t pct, int bus, int dev, int func,
390 1.1.8.1 yamt pcireg_t id)
391 1.1.8.1 yamt {
392 1.1.8.1 yamt struct genppc_pci_chipset_businfo *pbi;
393 1.1.8.1 yamt prop_number_t pbus;
394 1.1.8.1 yamt pcitag_t tag;
395 1.1.8.1 yamt pcireg_t class;
396 1.1.8.1 yamt int node;
397 1.1.8.1 yamt
398 1.1.8.1 yamt /* We have already mapped MPIC's if we have them, so leave them alone */
399 1.1.8.1 yamt if (PCI_VENDOR(id) == PCI_VENDOR_IBM &&
400 1.1.8.1 yamt PCI_PRODUCT(id) == PCI_PRODUCT_IBM_MPIC2)
401 1.1.8.1 yamt return 0;
402 1.1.8.1 yamt
403 1.1.8.1 yamt if (PCI_VENDOR(id) == PCI_VENDOR_IBM &&
404 1.1.8.1 yamt PCI_PRODUCT(id) == PCI_PRODUCT_IBM_MPIC)
405 1.1.8.1 yamt return 0;
406 1.1.8.1 yamt
407 1.1.8.1 yamt /* I highly doubt there are any CHRP ravens, but just in case */
408 1.1.8.1 yamt if (PCI_VENDOR(id) == PCI_VENDOR_MOT &&
409 1.1.8.1 yamt PCI_PRODUCT(id) == PCI_PRODUCT_MOT_RAVEN)
410 1.1.8.1 yamt return (PCI_CONF_ALL & ~PCI_CONF_MAP_MEM);
411 1.1.8.1 yamt
412 1.1.8.1 yamt /* NOTE, all device specific stuff must be above this line */
413 1.1.8.1 yamt /* don't do this on the primary host bridge */
414 1.1.8.1 yamt if (bus == 0 && dev == 0 && func == 0)
415 1.1.8.1 yamt return PCI_CONF_DEFAULT;
416 1.1.8.1 yamt
417 1.1.8.1 yamt tag = genppc_pci_indirect_make_tag(pct, bus, dev, func);
418 1.1.8.1 yamt class = genppc_pci_indirect_conf_read(pct, tag, PCI_CLASS_REG);
419 1.1.8.1 yamt
420 1.1.8.1 yamt /*
421 1.1.8.1 yamt * PCI bridges have special needs. We need to discover where they
422 1.1.8.1 yamt * came from, and wire them appropriately.
423 1.1.8.1 yamt */
424 1.1.8.1 yamt if (PCI_CLASS(class) == PCI_CLASS_BRIDGE &&
425 1.1.8.1 yamt PCI_SUBCLASS(class) == PCI_SUBCLASS_BRIDGE_PCI) {
426 1.1.8.1 yamt pbi = malloc(sizeof(struct genppc_pci_chipset_businfo),
427 1.1.8.1 yamt M_DEVBUF, M_NOWAIT);
428 1.1.8.1 yamt KASSERT(pbi != NULL);
429 1.1.8.1 yamt pbi->pbi_properties = prop_dictionary_create();
430 1.1.8.1 yamt KASSERT(pbi->pbi_properties != NULL);
431 1.1.8.1 yamt node = genofw_find_node_by_devfunc(pct->pc_node, bus, dev,
432 1.1.8.1 yamt func);
433 1.1.8.1 yamt if (node == -1) {
434 1.1.8.1 yamt aprint_error("Cannot find node for device "
435 1.1.8.1 yamt "bus %d dev %d func %d\n", bus, dev, func);
436 1.1.8.1 yamt prop_object_release(pbi->pbi_properties);
437 1.1.8.1 yamt free(pbi, M_DEVBUF);
438 1.1.8.1 yamt return (PCI_CONF_DEFAULT);
439 1.1.8.1 yamt }
440 1.1.8.1 yamt genofw_setup_pciintr_map(pbi, node);
441 1.1.8.1 yamt
442 1.1.8.1 yamt /* record the parent bus, and the parent device number */
443 1.1.8.1 yamt pbus = prop_number_create_integer(bus);
444 1.1.8.1 yamt prop_dictionary_set(pbi->pbi_properties, "ofw-pcibus-parent",
445 1.1.8.1 yamt pbus);
446 1.1.8.1 yamt prop_object_release(pbus);
447 1.1.8.1 yamt pbus = prop_number_create_integer(dev);
448 1.1.8.1 yamt prop_dictionary_set(pbi->pbi_properties, "ofw-pcibus-rawdevnum",
449 1.1.8.1 yamt pbus);
450 1.1.8.1 yamt prop_object_release(pbus);
451 1.1.8.1 yamt
452 1.1.8.1 yamt SIMPLEQ_INSERT_TAIL(&pct->pc_pbi, pbi, next);
453 1.1.8.1 yamt }
454 1.1.8.1 yamt
455 1.1.8.1 yamt return (PCI_CONF_DEFAULT);
456 1.1.8.1 yamt }
457