mpc5200_pci.c revision 1.1 1 1.1 rkujawa /* $NetBSD: mpc5200_pci.c,v 1.1 2026/06/27 13:28:35 rkujawa Exp $ */
2 1.1 rkujawa
3 1.1 rkujawa /*-
4 1.1 rkujawa * Copyright (c) 2026 The NetBSD Foundation, Inc.
5 1.1 rkujawa * All rights reserved.
6 1.1 rkujawa *
7 1.1 rkujawa * This code is derived from software contributed to The NetBSD Foundation
8 1.1 rkujawa * by Radoslaw Kujawa.
9 1.1 rkujawa *
10 1.1 rkujawa * Redistribution and use in source and binary forms, with or without
11 1.1 rkujawa * modification, are permitted provided that the following conditions
12 1.1 rkujawa * are met:
13 1.1 rkujawa * 1. Redistributions of source code must retain the above copyright
14 1.1 rkujawa * notice, this list of conditions and the following disclaimer.
15 1.1 rkujawa * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 rkujawa * notice, this list of conditions and the following disclaimer in the
17 1.1 rkujawa * documentation and/or other materials provided with the distribution.
18 1.1 rkujawa *
19 1.1 rkujawa * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.1 rkujawa * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.1 rkujawa * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.1 rkujawa * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.1 rkujawa * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.1 rkujawa * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.1 rkujawa * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.1 rkujawa * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.1 rkujawa * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.1 rkujawa * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.1 rkujawa * POSSIBILITY OF SUCH DAMAGE.
30 1.1 rkujawa */
31 1.1 rkujawa
32 1.1 rkujawa /*
33 1.1 rkujawa * MPC5200B PCI host bridge.
34 1.1 rkujawa */
35 1.1 rkujawa
36 1.1 rkujawa /* Expose the powerpc _bus_dma* back-ends for the coherent SoC DMA tag. */
37 1.1 rkujawa #define _POWERPC_BUS_DMA_PRIVATE
38 1.1 rkujawa
39 1.1 rkujawa #include "opt_pci.h"
40 1.1 rkujawa
41 1.1 rkujawa #include <sys/cdefs.h>
42 1.1 rkujawa __KERNEL_RCSID(0, "$NetBSD: mpc5200_pci.c,v 1.1 2026/06/27 13:28:35 rkujawa Exp $");
43 1.1 rkujawa
44 1.1 rkujawa #include <sys/param.h>
45 1.1 rkujawa #include <sys/device.h>
46 1.1 rkujawa #include <sys/kmem.h>
47 1.1 rkujawa #include <sys/systm.h>
48 1.1 rkujawa
49 1.1 rkujawa #include <dev/pci/pcivar.h>
50 1.1 rkujawa #include <dev/pci/pcireg.h>
51 1.1 rkujawa #include <dev/pci/pcidevs.h>
52 1.1 rkujawa #include <dev/pci/pciconf.h>
53 1.1 rkujawa #include <dev/ofw/openfirm.h>
54 1.1 rkujawa #include <dev/ofw/ofw_pci.h>
55 1.1 rkujawa
56 1.1 rkujawa #include <machine/autoconf.h>
57 1.1 rkujawa #include <machine/pio.h>
58 1.1 rkujawa #include <machine/cpu.h> /* mapiodev() */
59 1.1 rkujawa
60 1.1 rkujawa #include <powerpc/mpc5200/mpc5200_pcivar.h>
61 1.1 rkujawa
62 1.1 rkujawa static int mpcpci_match(device_t, cfdata_t, void *);
63 1.1 rkujawa static void mpcpci_attach(device_t, device_t, void *);
64 1.1 rkujawa
65 1.1 rkujawa CFATTACH_DECL_NEW(mpcpci, sizeof(struct mpcpci_softc),
66 1.1 rkujawa mpcpci_match, mpcpci_attach, NULL, NULL);
67 1.1 rkujawa
68 1.1 rkujawa extern struct model_data modeldata;
69 1.1 rkujawa
70 1.1 rkujawa /* MPC5200 PCI Configuration Address Register: MBAR + PCI(0x0D00) + 0xF8. */
71 1.1 rkujawa #define MPC5200_PCICAR_PADDR 0xf0000df8
72 1.1 rkujawa
73 1.1 rkujawa /*
74 1.1 rkujawa * DMA tag for bus-mastering PCI devices. The MPC5200B XL bus does NOT snoop
75 1.1 rkujawa * bus-master traffic.
76 1.1 rkujawa */
77 1.1 rkujawa static struct powerpc_bus_dma_tag mpc5200_pci_bus_dma_tag = {
78 1.1 rkujawa ._dmamap_create = _bus_dmamap_create,
79 1.1 rkujawa ._dmamap_destroy = _bus_dmamap_destroy,
80 1.1 rkujawa ._dmamap_load = _bus_dmamap_load,
81 1.1 rkujawa ._dmamap_load_mbuf = _bus_dmamap_load_mbuf,
82 1.1 rkujawa ._dmamap_load_uio = _bus_dmamap_load_uio,
83 1.1 rkujawa ._dmamap_load_raw = _bus_dmamap_load_raw,
84 1.1 rkujawa ._dmamap_unload = _bus_dmamap_unload,
85 1.1 rkujawa ._dmamap_sync = _bus_dmamap_sync,
86 1.1 rkujawa ._dmamem_alloc = _bus_dmamem_alloc,
87 1.1 rkujawa ._dmamem_free = _bus_dmamem_free,
88 1.1 rkujawa ._dmamem_map = _bus_dmamem_map,
89 1.1 rkujawa ._dmamem_unmap = _bus_dmamem_unmap,
90 1.1 rkujawa ._dmamem_mmap = _bus_dmamem_mmap,
91 1.1 rkujawa };
92 1.1 rkujawa
93 1.1 rkujawa static pcireg_t
94 1.1 rkujawa mpcpci_conf_read(void *v, pcitag_t tag, int reg)
95 1.1 rkujawa {
96 1.1 rkujawa pci_chipset_tag_t pc = v;
97 1.1 rkujawa pcireg_t data;
98 1.1 rkujawa int s;
99 1.1 rkujawa
100 1.1 rkujawa if ((unsigned int)reg >= PCI_CONF_SIZE)
101 1.1 rkujawa return (pcireg_t)-1;
102 1.1 rkujawa
103 1.1 rkujawa s = splhigh();
104 1.1 rkujawa out32(pc->pc_addr, tag | reg); /* PCICAR: big-endian */
105 1.1 rkujawa data = in32rb(pc->pc_data); /* config data: little-endian */
106 1.1 rkujawa out32(pc->pc_addr, 0); /* clear E: restore I/O window */
107 1.1 rkujawa splx(s);
108 1.1 rkujawa
109 1.1 rkujawa return data;
110 1.1 rkujawa }
111 1.1 rkujawa
112 1.1 rkujawa static void
113 1.1 rkujawa mpcpci_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
114 1.1 rkujawa {
115 1.1 rkujawa pci_chipset_tag_t pc = v;
116 1.1 rkujawa int s;
117 1.1 rkujawa
118 1.1 rkujawa if ((unsigned int)reg >= PCI_CONF_SIZE)
119 1.1 rkujawa return;
120 1.1 rkujawa
121 1.1 rkujawa s = splhigh();
122 1.1 rkujawa out32(pc->pc_addr, tag | reg); /* PCICAR: big-endian */
123 1.1 rkujawa out32rb(pc->pc_data, data); /* config data: little-endian */
124 1.1 rkujawa out32(pc->pc_addr, 0); /* clear E: restore I/O window */
125 1.1 rkujawa splx(s);
126 1.1 rkujawa }
127 1.1 rkujawa
128 1.1 rkujawa /*
129 1.1 rkujawa * The on-chip host bridge answers configuration cycles (as device 28 via its
130 1.1 rkujawa * IDSEL on AD28).
131 1.1 rkujawa */
132 1.1 rkujawa static int
133 1.1 rkujawa mpcpci_conf_hook(void *v, int bus, int dev, int func, pcireg_t id)
134 1.1 rkujawa {
135 1.1 rkujawa pci_chipset_tag_t pc = v;
136 1.1 rkujawa pcireg_t class;
137 1.1 rkujawa
138 1.1 rkujawa class = pci_conf_read(pc, pci_make_tag(pc, bus, dev, func),
139 1.1 rkujawa PCI_CLASS_REG);
140 1.1 rkujawa
141 1.1 rkujawa if (PCI_CLASS(class) == PCI_CLASS_BRIDGE &&
142 1.1 rkujawa (PCI_SUBCLASS(class) == PCI_SUBCLASS_BRIDGE_HOST ||
143 1.1 rkujawa PCI_SUBCLASS(class) == PCI_SUBCLASS_BRIDGE_MISC))
144 1.1 rkujawa return 0;
145 1.1 rkujawa
146 1.1 rkujawa return PCI_CONF_DEFAULT;
147 1.1 rkujawa }
148 1.1 rkujawa
149 1.1 rkujawa /*
150 1.1 rkujawa * Build the PCI interrupt-map property dictionary from the host bridge's
151 1.1 rkujawa * OpenFirmware "interrupt-map"...
152 1.1 rkujawa */
153 1.1 rkujawa static void
154 1.1 rkujawa mpcpci_setup_intrmap(pci_chipset_tag_t pc,
155 1.1 rkujawa struct genppc_pci_chipset_businfo *pbi, int pcinode)
156 1.1 rkujawa {
157 1.1 rkujawa uint32_t map[160];
158 1.1 rkujawa prop_dictionary_t dict, sub = NULL;
159 1.1 rkujawa uint32_t acells, icells, pcells;
160 1.1 rkujawa int parent, len, reclen, ndevs, curdev, i;
161 1.1 rkujawa
162 1.1 rkujawa len = OF_getprop(pcinode, "interrupt-map", map, sizeof(map));
163 1.1 rkujawa if (len <= 0) {
164 1.1 rkujawa /* No interrupt-map; leave an empty dict (intr_map will fail). */
165 1.1 rkujawa dict = prop_dictionary_create();
166 1.1 rkujawa KASSERT(dict != NULL);
167 1.1 rkujawa prop_dictionary_set(pbi->pbi_properties, "ofw-pci-intrmap", dict);
168 1.1 rkujawa prop_object_release(dict);
169 1.1 rkujawa return;
170 1.1 rkujawa }
171 1.1 rkujawa
172 1.1 rkujawa if (OF_getprop(pcinode, "#address-cells", &acells, sizeof(acells)) == -1)
173 1.1 rkujawa acells = 1;
174 1.1 rkujawa if (OF_getprop(pcinode, "#interrupt-cells", &icells, sizeof(icells))
175 1.1 rkujawa == -1)
176 1.1 rkujawa icells = 1;
177 1.1 rkujawa parent = map[acells + icells];
178 1.1 rkujawa if (OF_getprop(parent, "#interrupt-cells", &pcells, sizeof(pcells)) == -1)
179 1.1 rkujawa pcells = 1;
180 1.1 rkujawa
181 1.1 rkujawa reclen = acells + pcells + icells + 1;
182 1.1 rkujawa ndevs = len / (reclen * sizeof(uint32_t));
183 1.1 rkujawa
184 1.1 rkujawa dict = prop_dictionary_create_with_capacity(ndevs * 2);
185 1.1 rkujawa KASSERT(dict != NULL);
186 1.1 rkujawa prop_dictionary_set(pbi->pbi_properties, "ofw-pci-intrmap", dict);
187 1.1 rkujawa
188 1.1 rkujawa curdev = -1;
189 1.1 rkujawa for (i = 0; i < ndevs; i++) {
190 1.1 rkujawa prop_number_t intr_num;
191 1.1 rkujawa uint32_t tier, source, line;
192 1.1 rkujawa int dev, func, pin;
193 1.1 rkujawa char key[20];
194 1.1 rkujawa
195 1.1 rkujawa dev = (map[i * reclen] >> 8) / 0x8;
196 1.1 rkujawa func = (map[i * reclen] >> 8) % 0x8;
197 1.1 rkujawa pin = map[i * reclen + acells];
198 1.1 rkujawa if (curdev != dev)
199 1.1 rkujawa sub = prop_dictionary_create_with_capacity(4);
200 1.1 rkujawa
201 1.1 rkujawa tier = map[i * reclen + acells + icells + 1];
202 1.1 rkujawa source = (pcells >= 2) ? map[i * reclen + acells + icells + 2] : 0;
203 1.1 rkujawa line = (tier << 5) + source;
204 1.1 rkujawa
205 1.1 rkujawa intr_num = prop_number_create_integer(line);
206 1.1 rkujawa snprintf(key, sizeof(key), "pin-%c", 'A' + (pin - 1));
207 1.1 rkujawa prop_dictionary_set(sub, key, intr_num);
208 1.1 rkujawa prop_object_release(intr_num);
209 1.1 rkujawa
210 1.1 rkujawa snprintf(key, sizeof(key), "devfunc-%d", dev * 0x8 + func);
211 1.1 rkujawa prop_dictionary_set(dict, key, sub);
212 1.1 rkujawa if (curdev != dev) {
213 1.1 rkujawa prop_object_release(sub);
214 1.1 rkujawa curdev = dev;
215 1.1 rkujawa }
216 1.1 rkujawa }
217 1.1 rkujawa prop_object_release(dict);
218 1.1 rkujawa aprint_debug("%s\n", prop_dictionary_externalize(pbi->pbi_properties));
219 1.1 rkujawa }
220 1.1 rkujawa
221 1.1 rkujawa /*
222 1.1 rkujawa * Resolve a PCI interrupt to a flat IRQ via the interrupt-map dictionary built
223 1.1 rkujawa * above.
224 1.1 rkujawa */
225 1.1 rkujawa static int
226 1.1 rkujawa mpcpci_pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ihp)
227 1.1 rkujawa {
228 1.1 rkujawa struct genppc_pci_chipset_businfo *pbi;
229 1.1 rkujawa prop_dictionary_t dict, devsub;
230 1.1 rkujawa prop_object_t pinsub;
231 1.1 rkujawa prop_number_t pbus;
232 1.1 rkujawa int busno, pin, line, dev, origdev, func, i;
233 1.1 rkujawa char key[20];
234 1.1 rkujawa
235 1.1 rkujawa pin = pa->pa_intrpin;
236 1.1 rkujawa line = pa->pa_intrline;
237 1.1 rkujawa busno = pa->pa_bus;
238 1.1 rkujawa origdev = dev = pa->pa_device;
239 1.1 rkujawa func = pa->pa_function;
240 1.1 rkujawa i = 0;
241 1.1 rkujawa
242 1.1 rkujawa pbi = SIMPLEQ_FIRST(&pa->pa_pc->pc_pbi);
243 1.1 rkujawa while (busno--)
244 1.1 rkujawa pbi = SIMPLEQ_NEXT(pbi, next);
245 1.1 rkujawa KASSERT(pbi != NULL);
246 1.1 rkujawa
247 1.1 rkujawa dict = prop_dictionary_get(pbi->pbi_properties, "ofw-pci-intrmap");
248 1.1 rkujawa if (dict != NULL)
249 1.1 rkujawa i = prop_dictionary_count(dict);
250 1.1 rkujawa
251 1.1 rkujawa if (dict == NULL || i == 0) {
252 1.1 rkujawa /* Unmapped bus (behind a PCI-PCI bridge): walk to the parent. */
253 1.1 rkujawa pbus = prop_dictionary_get(pbi->pbi_properties,
254 1.1 rkujawa "ofw-pcibus-parent");
255 1.1 rkujawa if (pbus == NULL)
256 1.1 rkujawa goto bad;
257 1.1 rkujawa busno = prop_number_integer_value(pbus);
258 1.1 rkujawa pbus = prop_dictionary_get(pbi->pbi_properties,
259 1.1 rkujawa "ofw-pcibus-rawdevnum");
260 1.1 rkujawa dev = prop_number_integer_value(pbus);
261 1.1 rkujawa
262 1.1 rkujawa pbi = SIMPLEQ_FIRST(&pa->pa_pc->pc_pbi);
263 1.1 rkujawa while (busno--)
264 1.1 rkujawa pbi = SIMPLEQ_NEXT(pbi, next);
265 1.1 rkujawa KASSERT(pbi != NULL);
266 1.1 rkujawa
267 1.1 rkujawa pin = ((pin + origdev - 1) & 3) + 1; /* swizzle the pin */
268 1.1 rkujawa
269 1.1 rkujawa dict = prop_dictionary_get(pbi->pbi_properties,
270 1.1 rkujawa "ofw-pci-intrmap");
271 1.1 rkujawa if (dict == NULL)
272 1.1 rkujawa goto bad;
273 1.1 rkujawa }
274 1.1 rkujawa
275 1.1 rkujawa if (pin == 0) /* no interrupt used */
276 1.1 rkujawa goto bad;
277 1.1 rkujawa if (pin > 4) {
278 1.1 rkujawa aprint_error("mpcpci_pci_intr_map: bad interrupt pin %d\n", pin);
279 1.1 rkujawa goto bad;
280 1.1 rkujawa }
281 1.1 rkujawa
282 1.1 rkujawa snprintf(key, sizeof(key), "devfunc-%d", dev * 0x8 + func);
283 1.1 rkujawa devsub = prop_dictionary_get(dict, key);
284 1.1 rkujawa if (devsub == NULL)
285 1.1 rkujawa goto bad;
286 1.1 rkujawa snprintf(key, sizeof(key), "pin-%c", 'A' + (pin - 1));
287 1.1 rkujawa pinsub = prop_dictionary_get(devsub, key);
288 1.1 rkujawa if (pinsub == NULL)
289 1.1 rkujawa goto bad;
290 1.1 rkujawa line = prop_number_integer_value(pinsub);
291 1.1 rkujawa
292 1.1 rkujawa if (line == 255) { /* 0xff == PCI "unrouted" */
293 1.1 rkujawa aprint_error("mpcpci_pci_intr_map: no mapping for pin %c\n",
294 1.1 rkujawa '@' + pin);
295 1.1 rkujawa goto bad;
296 1.1 rkujawa }
297 1.1 rkujawa
298 1.1 rkujawa *ihp = line; /* a real line, including flat IRQ 0 */
299 1.1 rkujawa return 0;
300 1.1 rkujawa
301 1.1 rkujawa bad:
302 1.1 rkujawa *ihp = -1;
303 1.1 rkujawa return 1;
304 1.1 rkujawa }
305 1.1 rkujawa
306 1.1 rkujawa static void
307 1.1 rkujawa mpcpci_get_chipset_tag(pci_chipset_tag_t pc)
308 1.1 rkujawa {
309 1.1 rkujawa pc->pc_conf_v = (void *)pc;
310 1.1 rkujawa
311 1.1 rkujawa pc->pc_attach_hook = genppc_pci_indirect_attach_hook;
312 1.1 rkujawa pc->pc_bus_maxdevs = genppc_pci_bus_maxdevs;
313 1.1 rkujawa pc->pc_make_tag = genppc_pci_indirect_make_tag;
314 1.1 rkujawa pc->pc_conf_read = mpcpci_conf_read;
315 1.1 rkujawa pc->pc_conf_write = mpcpci_conf_write;
316 1.1 rkujawa
317 1.1 rkujawa pc->pc_intr_v = (void *)pc;
318 1.1 rkujawa
319 1.1 rkujawa pc->pc_intr_map = mpcpci_pci_intr_map;
320 1.1 rkujawa pc->pc_intr_string = genppc_pci_intr_string;
321 1.1 rkujawa pc->pc_intr_evcnt = genppc_pci_intr_evcnt;
322 1.1 rkujawa pc->pc_intr_establish = genppc_pci_intr_establish;
323 1.1 rkujawa pc->pc_intr_disestablish = genppc_pci_intr_disestablish;
324 1.1 rkujawa pc->pc_intr_setattr = genppc_pci_intr_setattr;
325 1.1 rkujawa pc->pc_intr_type = genppc_pci_intr_type;
326 1.1 rkujawa pc->pc_intr_alloc = genppc_pci_intr_alloc;
327 1.1 rkujawa pc->pc_intr_release = genppc_pci_intr_release;
328 1.1 rkujawa pc->pc_intx_alloc = genppc_pci_intx_alloc;
329 1.1 rkujawa
330 1.1 rkujawa pc->pc_msi_v = (void *)pc;
331 1.1 rkujawa genppc_pci_chipset_msi_init(pc);
332 1.1 rkujawa
333 1.1 rkujawa pc->pc_msix_v = (void *)pc;
334 1.1 rkujawa genppc_pci_chipset_msix_init(pc);
335 1.1 rkujawa
336 1.1 rkujawa pc->pc_conf_interrupt = genppc_pci_conf_interrupt;
337 1.1 rkujawa pc->pc_decompose_tag = genppc_pci_indirect_decompose_tag;
338 1.1 rkujawa pc->pc_conf_hook = mpcpci_conf_hook;
339 1.1 rkujawa
340 1.1 rkujawa pc->pc_addr = 0;
341 1.1 rkujawa pc->pc_data = 0;
342 1.1 rkujawa pc->pc_bus = 0;
343 1.1 rkujawa pc->pc_node = 0;
344 1.1 rkujawa pc->pc_memt = 0;
345 1.1 rkujawa pc->pc_iot = 0;
346 1.1 rkujawa pc->pc_ihandle = 0;
347 1.1 rkujawa }
348 1.1 rkujawa
349 1.1 rkujawa static int
350 1.1 rkujawa mpcpci_match(device_t parent, cfdata_t cf, void *aux)
351 1.1 rkujawa {
352 1.1 rkujawa struct confargs *ca = aux;
353 1.1 rkujawa char name[32];
354 1.1 rkujawa
355 1.1 rkujawa if (strcmp(ca->ca_name, "pci") != 0)
356 1.1 rkujawa return 0;
357 1.1 rkujawa
358 1.1 rkujawa memset(name, 0, sizeof(name));
359 1.1 rkujawa OF_getprop(ca->ca_node, "device_type", name, sizeof(name));
360 1.1 rkujawa if (strcmp(name, "pci") != 0)
361 1.1 rkujawa return 0;
362 1.1 rkujawa
363 1.1 rkujawa return 1;
364 1.1 rkujawa }
365 1.1 rkujawa
366 1.1 rkujawa static void
367 1.1 rkujawa mpcpci_attach(device_t parent, device_t self, void *aux)
368 1.1 rkujawa {
369 1.1 rkujawa struct mpcpci_softc *sc = device_private(self);
370 1.1 rkujawa pci_chipset_tag_t pc = &sc->sc_pc;
371 1.1 rkujawa struct confargs *ca = aux;
372 1.1 rkujawa struct pcibus_attach_args pba;
373 1.1 rkujawa struct genppc_pci_chipset_businfo *pbi;
374 1.1 rkujawa int node = ca->ca_node;
375 1.1 rkujawa uint32_t busrange[2];
376 1.1 rkujawa
377 1.1 rkujawa aprint_normal(": MPC5200B PCI host bridge\n");
378 1.1 rkujawa
379 1.1 rkujawa sc->sc_dev = self;
380 1.1 rkujawa
381 1.1 rkujawa if (OF_getprop(node, "bus-range", busrange, sizeof(busrange)) != 8) {
382 1.1 rkujawa aprint_error_dev(self, "no bus-range property\n");
383 1.1 rkujawa return;
384 1.1 rkujawa }
385 1.1 rkujawa
386 1.1 rkujawa /* PCI I/O and memory windows come from the firmware's /pci ranges. */
387 1.1 rkujawa sc->sc_iot.pbs_flags = _BUS_SPACE_LITTLE_ENDIAN | _BUS_SPACE_IO_TYPE;
388 1.1 rkujawa sc->sc_iot.pbs_base = 0x00000000;
389 1.1 rkujawa if (ofwoea_map_space(RANGE_TYPE_PCI, RANGE_IO, node, &sc->sc_iot,
390 1.1 rkujawa "mpcpci io-space") != 0)
391 1.1 rkujawa panic("mpcpci: can't init PCI io tag");
392 1.1 rkujawa
393 1.1 rkujawa sc->sc_memt.pbs_flags = _BUS_SPACE_LITTLE_ENDIAN | _BUS_SPACE_MEM_TYPE;
394 1.1 rkujawa sc->sc_memt.pbs_base = 0x00000000;
395 1.1 rkujawa if (ofwoea_map_space(RANGE_TYPE_PCI, RANGE_MEM, node, &sc->sc_memt,
396 1.1 rkujawa "mpcpci mem-space") != 0)
397 1.1 rkujawa panic("mpcpci: can't init PCI mem tag");
398 1.1 rkujawa
399 1.1 rkujawa /*
400 1.1 rkujawa * Record the OFW interrupt-controller nodes (the SIU) so the PCI
401 1.1 rkujawa * interrupt-map routing below can resolve them. The SIU hardware was
402 1.1 rkujawa * already programmed by the mpc5200pic device, this is bookkeeping.
403 1.1 rkujawa */
404 1.1 rkujawa init_ofppc_interrupt();
405 1.1 rkujawa
406 1.1 rkujawa mpcpci_get_chipset_tag(pc);
407 1.1 rkujawa pc->pc_node = node;
408 1.1 rkujawa pc->pc_bus = busrange[0];
409 1.1 rkujawa pc->pc_iot = &sc->sc_iot;
410 1.1 rkujawa pc->pc_memt = &sc->sc_memt;
411 1.1 rkujawa
412 1.1 rkujawa pc->pc_addr = mapiodev(MPC5200_PCICAR_PADDR, 4, false);
413 1.1 rkujawa pc->pc_data = mapiodev(sc->sc_iot.pbs_offset, 4, false);
414 1.1 rkujawa if (pc->pc_addr == NULL || pc->pc_data == NULL)
415 1.1 rkujawa panic("mpcpci: can't map PCI config registers");
416 1.1 rkujawa
417 1.1 rkujawa pbi = kmem_alloc(sizeof(struct genppc_pci_chipset_businfo), KM_SLEEP);
418 1.1 rkujawa pbi->pbi_properties = prop_dictionary_create();
419 1.1 rkujawa KASSERT(pbi->pbi_properties != NULL);
420 1.1 rkujawa SIMPLEQ_INIT(&pc->pc_pbi);
421 1.1 rkujawa SIMPLEQ_INSERT_TAIL(&pc->pc_pbi, pbi, next);
422 1.1 rkujawa
423 1.1 rkujawa mpcpci_setup_intrmap(pc, pbi, pc->pc_node);
424 1.1 rkujawa
425 1.1 rkujawa #ifdef PCI_NETBSD_CONFIGURE
426 1.1 rkujawa struct pciconf_resources *pcires = pciconf_resource_init();
427 1.1 rkujawa
428 1.1 rkujawa pciconf_resource_add(pcires, PCICONF_RESOURCE_IO,
429 1.1 rkujawa modeldata.pciiodata[device_unit(self)].start,
430 1.1 rkujawa (modeldata.pciiodata[device_unit(self)].limit -
431 1.1 rkujawa modeldata.pciiodata[device_unit(self)].start) + 1);
432 1.1 rkujawa
433 1.1 rkujawa pciconf_resource_add(pcires, PCICONF_RESOURCE_MEM,
434 1.1 rkujawa sc->sc_memt.pbs_base,
435 1.1 rkujawa (sc->sc_memt.pbs_limit - sc->sc_memt.pbs_base) + 1);
436 1.1 rkujawa
437 1.1 rkujawa if (pci_configure_bus(pc, pcires, 0, CACHELINESIZE))
438 1.1 rkujawa aprint_error_dev(self, "pci_configure_bus() failed\n");
439 1.1 rkujawa
440 1.1 rkujawa pciconf_resource_fini(pcires);
441 1.1 rkujawa #endif /* PCI_NETBSD_CONFIGURE */
442 1.1 rkujawa
443 1.1 rkujawa memset(&pba, 0, sizeof(pba));
444 1.1 rkujawa pba.pba_memt = pc->pc_memt;
445 1.1 rkujawa pba.pba_iot = pc->pc_iot;
446 1.1 rkujawa pba.pba_dmat = &mpc5200_pci_bus_dma_tag;
447 1.1 rkujawa pba.pba_dmat64 = NULL;
448 1.1 rkujawa pba.pba_bus = pc->pc_bus;
449 1.1 rkujawa pba.pba_bridgetag = NULL;
450 1.1 rkujawa pba.pba_pc = pc;
451 1.1 rkujawa pba.pba_flags = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY;
452 1.1 rkujawa config_found(self, &pba, pcibusprint,
453 1.1 rkujawa CFARGS(.devhandle = device_handle(self)));
454 1.1 rkujawa }
455