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