1 /* $NetBSD: pci_machdep.c,v 1.79 2022/10/01 07:59:25 charlotte Exp $ */ 2 3 /* 4 * Copyright (c) 1999, 2000 Matthew R. Green 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 /* 30 * functions expected by the MI PCI code. 31 */ 32 33 #include <sys/cdefs.h> 34 __KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.79 2022/10/01 07:59:25 charlotte Exp $"); 35 36 #include <sys/types.h> 37 #include <sys/param.h> 38 #include <sys/time.h> 39 #include <sys/systm.h> 40 #include <sys/errno.h> 41 #include <sys/device.h> 42 #include <sys/malloc.h> 43 44 #define _SPARC_BUS_DMA_PRIVATE 45 #include <sys/bus.h> 46 #include <machine/autoconf.h> 47 #include <machine/openfirm.h> 48 #include <dev/pci/pcivar.h> 49 #include <dev/pci/pcireg.h> 50 51 #include <dev/ofw/ofw_pci.h> 52 53 #include <sparc64/dev/iommureg.h> 54 #include <sparc64/sparc64/cache.h> 55 56 #include "locators.h" 57 58 #ifdef DEBUG 59 #define SPDB_CONF 0x01 60 #define SPDB_INTR 0x04 61 #define SPDB_INTMAP 0x08 62 #define SPDB_PROBE 0x20 63 #define SPDB_TAG 0x40 64 int sparc_pci_debug = 0x0; 65 #define DPRINTF(l, s) do { if (sparc_pci_debug & l) printf s; } while (0) 66 #else 67 #define DPRINTF(l, s) 68 #endif 69 70 /* this is a base to be copied */ 71 struct sparc_pci_chipset _sparc_pci_chipset = { 72 .cookie = NULL, 73 }; 74 75 static pcitag_t 76 ofpci_make_tag(pci_chipset_tag_t pc, int node, int b, int d, int f) 77 { 78 pcitag_t tag; 79 pcireg_t reg; 80 81 tag = PCITAG_CREATE(node, b, d, f); 82 83 DPRINTF(SPDB_TAG, 84 ("%s: creating tag for node %x bus %d dev %d fn %d\n", 85 __func__, node, b, d, f)); 86 87 /* Enable all the different spaces for this device */ 88 reg = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 89 reg |= PCI_COMMAND_MEM_ENABLE|PCI_COMMAND_MASTER_ENABLE| 90 PCI_COMMAND_IO_ENABLE; 91 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, reg); 92 93 return (tag); 94 } 95 96 /* 97 * functions provided to the MI code. 98 */ 99 100 void 101 pci_attach_hook(device_t parent, device_t self, 102 struct pcibus_attach_args *pba) 103 { 104 } 105 106 int 107 pci_bus_maxdevs(pci_chipset_tag_t pc, int busno) 108 { 109 110 return 32; 111 } 112 113 pcitag_t 114 pci_make_tag(pci_chipset_tag_t pc, int b, int d, int f) 115 { 116 struct ofw_pci_register reg; 117 pcitag_t tag; 118 int (*valid)(void *); 119 int node, new_node, len; 120 #ifdef DEBUG 121 char name[80]; 122 memset(name, 0, sizeof(name)); 123 #endif 124 125 /* 126 * Refer to the PCI/CardBus bus node first. 127 * It returns a tag if node is present and bus is valid. 128 */ 129 if (0 <= b && b < 256) { 130 KASSERT(pc->spc_busnode != NULL); 131 node = (*pc->spc_busnode)[b].node; 132 valid = (*pc->spc_busnode)[b].valid; 133 if (node != 0 && d == 0 && 134 (valid == NULL || (*valid)((*pc->spc_busnode)[b].arg))) 135 return ofpci_make_tag(pc, node, b, d, f); 136 } 137 138 /* 139 * Hunt for the node that corresponds to this device 140 * 141 * We could cache this info in an array in the parent 142 * device... except then we have problems with devices 143 * attached below pci-pci bridges, and we would need to 144 * add special code to the pci-pci bridge to cache this 145 * info. 146 */ 147 148 tag = PCITAG_CREATE(-1, b, d, f); 149 node = pc->rootnode; 150 /* 151 * First make sure we're on the right bus. If our parent 152 * has a bus-range property and we're not in the range, 153 * then we're obviously on the wrong bus. So go up one 154 * level. 155 */ 156 DPRINTF(SPDB_PROBE, ("curnode %x %s\n", node, 157 prom_getpropstringA(node, "name", name, sizeof(name)))); 158 #if 0 159 while ((OF_getprop(OF_parent(node), "bus-range", (void *)&busrange, 160 sizeof(busrange)) == sizeof(busrange)) && 161 (b < busrange[0] || b > busrange[1])) { 162 /* Out of range, go up one */ 163 node = OF_parent(node); 164 DPRINTF(SPDB_PROBE, printf("going up to node %x %s\n", 165 node, 166 prom_getpropstringA(node, "name", name, sizeof(name)))); 167 } 168 #endif 169 node = prom_firstchild(node); 170 /* 171 * Now traverse all peers until we find the node or we find 172 * the right bridge. 173 * 174 * XXX We go up one and down one to make sure nobody's missed. 175 * but this should not be necessary. 176 */ 177 for (node = ((node)); node; node = prom_nextsibling(node)) { 178 179 DPRINTF(SPDB_PROBE, ("checking node %x %s\n", node, 180 prom_getpropstringA(node, "name", name, sizeof(name)))); 181 182 #if 1 183 /* 184 * Check for PCI-PCI bridges. If the device we want is 185 * in the bus-range for that bridge, work our way down. 186 */ 187 while (1) { 188 int busrange[2], *brp; 189 len = 2; 190 brp = busrange; 191 if (prom_getprop(node, "bus-range", sizeof(*brp), 192 &len, &brp) != 0) 193 break; 194 if (len != 2 || b < busrange[0] || b > busrange[1]) 195 break; 196 /* Go down 1 level, as long as we're able */ 197 new_node = prom_firstchild(node); 198 if (new_node == 0) 199 break; 200 node = new_node; 201 DPRINTF(SPDB_PROBE, ("going down to node %x %s\n", node, 202 prom_getpropstringA(node, "name", name, 203 sizeof(name)))); 204 } 205 #endif /*1*/ 206 /* 207 * We only really need the first `reg' property. 208 * 209 * For simplicity, we'll query the `reg' when we 210 * need it. Otherwise we could malloc() it, but 211 * that gets more complicated. 212 */ 213 len = prom_getproplen(node, "reg"); 214 if (len < sizeof(reg)) 215 continue; 216 if (OF_getprop(node, "reg", (void *)®, sizeof(reg)) != len) 217 panic("pci_probe_bus: OF_getprop len botch"); 218 219 if (b != OFW_PCI_PHYS_HI_BUS(reg.phys_hi)) 220 continue; 221 if (d != OFW_PCI_PHYS_HI_DEVICE(reg.phys_hi)) 222 continue; 223 if (f != OFW_PCI_PHYS_HI_FUNCTION(reg.phys_hi)) 224 continue; 225 226 /* Got a match */ 227 tag = ofpci_make_tag(pc, node, b, d, f); 228 229 return (tag); 230 } 231 /* No device found -- return a dead tag */ 232 return (tag); 233 } 234 235 void 236 pci_decompose_tag(pci_chipset_tag_t pc, pcitag_t tag, int *bp, int *dp, int *fp) 237 { 238 239 if (bp != NULL) 240 *bp = PCITAG_BUS(tag); 241 if (dp != NULL) 242 *dp = PCITAG_DEV(tag); 243 if (fp != NULL) 244 *fp = PCITAG_FUN(tag); 245 } 246 247 int 248 sparc64_pci_enumerate_bus(struct pci_softc *sc, const int *locators, 249 int (*match)(const struct pci_attach_args *), struct pci_attach_args *pap) 250 { 251 struct ofw_pci_register reg; 252 pci_chipset_tag_t pc = sc->sc_pc; 253 pcitag_t tag; 254 pcireg_t class, csr, bhlc, ic; 255 int node, b, d, f, ret; 256 int bus_frequency, lt, cl, cacheline; 257 char name[30]; 258 #if 0 259 extern int pci_config_dump; 260 #endif 261 262 if (sc->sc_bridgetag) 263 node = PCITAG_NODE(*sc->sc_bridgetag); 264 else 265 node = pc->rootnode; 266 267 bus_frequency = 268 prom_getpropint(node, "clock-frequency", 33000000) / 1000000; 269 270 /* 271 * Make sure the cache line size is at least as big as the 272 * ecache line and the streaming cache (64 byte). 273 */ 274 cacheline = uimax(ecache_min_line_size, 64); 275 KASSERT((cacheline/64)*64 == cacheline && 276 (cacheline/ecache_min_line_size)*ecache_min_line_size == cacheline && 277 (cacheline/4)*4 == cacheline); 278 279 #if 0 280 /* 281 * XXX this faults on Fire PCIe controllers. 282 * XXX move into the psycho and schizo driver front ends. 283 */ 284 /* Turn on parity for the bus. */ 285 tag = ofpci_make_tag(pc, node, sc->sc_bus, 0, 0); 286 csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 287 csr |= PCI_COMMAND_PARITY_ENABLE; 288 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, csr); 289 290 /* 291 * Initialize the latency timer register. 292 * The value 0x40 is from Solaris. 293 */ 294 bhlc = pci_conf_read(pc, tag, PCI_BHLC_REG); 295 bhlc &= ~(PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT); 296 bhlc |= 0x40 << PCI_LATTIMER_SHIFT; 297 pci_conf_write(pc, tag, PCI_BHLC_REG, bhlc); 298 299 if (pci_config_dump) 300 pci_conf_print(pc, tag, NULL); 301 #endif 302 303 for (node = prom_firstchild(node); node != 0 && node != -1; 304 node = prom_nextsibling(node)) { 305 name[0] = name[29] = 0; 306 prom_getpropstringA(node, "name", name, sizeof(name)); 307 308 if (OF_getprop(node, "class-code", &class, sizeof(class)) != 309 sizeof(class)) 310 continue; 311 if (OF_getprop(node, "reg", ®, sizeof(reg)) < sizeof(reg)) 312 panic("pci_enumerate_bus: \"%s\" regs too small", name); 313 314 b = OFW_PCI_PHYS_HI_BUS(reg.phys_hi); 315 d = OFW_PCI_PHYS_HI_DEVICE(reg.phys_hi); 316 f = OFW_PCI_PHYS_HI_FUNCTION(reg.phys_hi); 317 318 if (sc->sc_bus != b) { 319 aprint_error_dev(sc->sc_dev, "WARNING: incorrect " 320 "bus # for \"%s\" (%d/%d/%d)\n", name, b, d, f); 321 continue; 322 } 323 if ((locators[PCICF_DEV] != PCICF_DEV_DEFAULT) && 324 (locators[PCICF_DEV] != d)) 325 continue; 326 if ((locators[PCICF_FUNCTION] != PCICF_FUNCTION_DEFAULT) && 327 (locators[PCICF_FUNCTION] != f)) 328 continue; 329 330 tag = ofpci_make_tag(pc, node, b, d, f); 331 332 /* 333 * Turn on parity and fast-back-to-back for the device. 334 */ 335 csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 336 if (csr & PCI_STATUS_BACKTOBACK_SUPPORT) 337 csr |= PCI_COMMAND_BACKTOBACK_ENABLE; 338 csr |= PCI_COMMAND_PARITY_ENABLE; 339 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, csr); 340 341 /* 342 * Initialize the latency timer register for busmaster 343 * devices to work properly. 344 * latency-timer = min-grant * bus-freq / 4 (from FreeBSD) 345 * Also initialize the cache line size register. 346 * Solaris anytime sets this register to the value 0x10. 347 */ 348 bhlc = pci_conf_read(pc, tag, PCI_BHLC_REG); 349 ic = pci_conf_read(pc, tag, PCI_INTERRUPT_REG); 350 351 lt = uimin(PCI_MIN_GNT(ic) * bus_frequency / 4, 255); 352 if (lt == 0 || lt < PCI_LATTIMER(bhlc)) 353 lt = PCI_LATTIMER(bhlc); 354 355 cl = PCI_CACHELINE(bhlc); 356 if (cl == 0) 357 cl = cacheline; 358 359 bhlc &= ~((PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT) | 360 (PCI_CACHELINE_MASK << PCI_CACHELINE_SHIFT)); 361 bhlc |= (lt << PCI_LATTIMER_SHIFT) | 362 (cl << PCI_CACHELINE_SHIFT); 363 pci_conf_write(pc, tag, PCI_BHLC_REG, bhlc); 364 365 ret = pci_probe_device(sc, tag, match, pap); 366 if (match != NULL && ret != 0) 367 return (ret); 368 } 369 return (0); 370 } 371 372 const char * 373 pci_intr_string(pci_chipset_tag_t pc, pci_intr_handle_t ih, char *buf, 374 size_t len) 375 { 376 snprintf(buf, len, "ivec %x", ih); 377 DPRINTF(SPDB_INTR, ("pci_intr_string: returning %s\n", buf)); 378 379 return buf; 380 } 381 382 const struct evcnt * 383 pci_intr_evcnt(pci_chipset_tag_t pc, pci_intr_handle_t ih) 384 { 385 386 /* XXX for now, no evcnt parent reported */ 387 return NULL; 388 } 389 390 int 391 pci_intr_setattr(pci_chipset_tag_t pc, pci_intr_handle_t *ih, 392 int attr, uint64_t data) 393 { 394 395 switch (attr) { 396 case PCI_INTR_MPSAFE: 397 return 0; 398 default: 399 return ENODEV; 400 } 401 } 402 403 /* 404 * interrupt mapping foo. 405 * XXX: how does this deal with multiple interrupts for a device? 406 */ 407 int 408 pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *ihp) 409 { 410 pcitag_t tag = pa->pa_tag; 411 int interrupts[4], *intp, int_used; 412 int len, node = PCITAG_NODE(tag); 413 char devtype[30]; 414 415 intp = &interrupts[0]; 416 len = prom_getproplen(node, "interrupts"); 417 if (len > sizeof(interrupts)) { 418 DPRINTF(SPDB_INTMAP, 419 ("pci_intr_map: too many available interrupts\n")); 420 return (ENODEV); 421 } 422 if (prom_getprop(node, "interrupts", len, 423 &len, &intp) != 0 || len != 1) { 424 DPRINTF(SPDB_INTMAP, 425 ("pci_intr_map: could not read interrupts\n")); 426 return (ENODEV); 427 } 428 429 /* XXX We pick the first interrupt, but should do better */ 430 int_used = interrupts[0]; 431 if (OF_mapintr(node, &int_used, sizeof(int_used), 432 sizeof(int_used)) < 0) { 433 printf("OF_mapintr failed\n"); 434 if (pa->pa_pc->spc_find_ino) 435 pa->pa_pc->spc_find_ino(pa, &int_used); 436 } 437 DPRINTF(SPDB_INTMAP, ("OF_mapintr() gave %x\n", int_used)); 438 439 /* Try to find an IPL for this type of device. */ 440 prom_getpropstringA(node, "device_type", devtype, sizeof(devtype)); 441 for (len = 0; intrmap[len].in_class != NULL; len++) 442 if (strcmp(intrmap[len].in_class, devtype) == 0) { 443 int_used |= INTLEVENCODE(intrmap[len].in_lev); 444 DPRINTF(SPDB_INTMAP, ("reset to %x\n", int_used)); 445 break; 446 } 447 448 *ihp = int_used; 449 450 /* Call the sub-driver is necessary */ 451 if (pa->pa_pc->spc_intr_map) 452 (*pa->pa_pc->spc_intr_map)(pa, ihp); 453 454 return (0); 455 } 456 457 void 458 pci_intr_disestablish(pci_chipset_tag_t pc, void *cookie) 459 { 460 461 DPRINTF(SPDB_INTR, ("pci_intr_disestablish: cookie %p\n", cookie)); 462 463 /* XXX */ 464 /* panic("can't disestablish PCI interrupts yet"); */ 465 } 466 467 int 468 sparc_pci_childspace(int type) 469 { 470 int ss; 471 472 switch (type) { 473 case PCI_CONFIG_BUS_SPACE: 474 ss = 0x00; 475 break; 476 case PCI_IO_BUS_SPACE: 477 ss = 0x01; 478 break; 479 case PCI_MEMORY_BUS_SPACE: 480 ss = 0x02; 481 break; 482 #if 0 483 /* we don't do 64 bit memory space */ 484 case PCI_MEMORY64_BUS_SPACE: 485 ss = 0x03; 486 break; 487 #endif 488 default: 489 panic("get_childspace: unknown bus type: %d", type); 490 } 491 492 return (ss); 493 } 494