acpipci.c revision 1.36
1/* $OpenBSD: acpipci.c,v 1.36 2022/08/29 15:42:25 kettenis Exp $ */ 2/* 3 * Copyright (c) 2018 Mark Kettenis 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18#include <sys/param.h> 19#include <sys/device.h> 20#include <sys/extent.h> 21#include <sys/malloc.h> 22#include <sys/systm.h> 23 24#include <machine/bus.h> 25 26#include <dev/acpi/acpireg.h> 27#include <dev/acpi/acpivar.h> 28#include <dev/acpi/acpidev.h> 29#include <dev/acpi/amltypes.h> 30#include <dev/acpi/dsdt.h> 31 32#include <dev/pci/pcidevs.h> 33#include <dev/pci/pcireg.h> 34#include <dev/pci/pcivar.h> 35#include <dev/pci/ppbreg.h> 36 37#include <arm64/dev/acpiiort.h> 38 39struct acpipci_mcfg { 40 SLIST_ENTRY(acpipci_mcfg) am_list; 41 42 uint16_t am_segment; 43 uint8_t am_min_bus; 44 uint8_t am_max_bus; 45 46 bus_space_tag_t am_iot; 47 bus_space_handle_t am_ioh; 48 49 struct machine_pci_chipset am_pc; 50}; 51 52struct acpipci_trans { 53 struct acpipci_trans *at_next; 54 bus_space_tag_t at_iot; 55 bus_addr_t at_base; 56 bus_size_t at_size; 57 bus_size_t at_offset; 58}; 59 60struct acpipci_softc { 61 struct device sc_dev; 62 struct acpi_softc *sc_acpi; 63 struct aml_node *sc_node; 64 bus_space_tag_t sc_iot; 65 pci_chipset_tag_t sc_pc; 66 67 struct bus_space sc_bus_iot; 68 struct bus_space sc_bus_memt; 69 struct acpipci_trans *sc_io_trans; 70 struct acpipci_trans *sc_mem_trans; 71 72 struct extent *sc_busex; 73 struct extent *sc_memex; 74 struct extent *sc_ioex; 75 char sc_busex_name[32]; 76 char sc_ioex_name[32]; 77 char sc_memex_name[32]; 78 int sc_bus; 79 uint32_t sc_seg; 80 81 struct interrupt_controller *sc_msi_ic; 82}; 83 84struct acpipci_intr_handle { 85 struct machine_intr_handle aih_ih; 86 bus_dma_tag_t aih_dmat; 87 bus_dmamap_t aih_map; 88}; 89 90int acpipci_match(struct device *, void *, void *); 91void acpipci_attach(struct device *, struct device *, void *); 92 93const struct cfattach acpipci_ca = { 94 sizeof(struct acpipci_softc), acpipci_match, acpipci_attach 95}; 96 97struct cfdriver acpipci_cd = { 98 NULL, "acpipci", DV_DULL 99}; 100 101const char *acpipci_hids[] = { 102 "PNP0A08", 103 NULL 104}; 105 106int acpipci_parse_resources(int, union acpi_resource *, void *); 107int acpipci_bs_map(bus_space_tag_t, bus_addr_t, bus_size_t, int, 108 bus_space_handle_t *); 109paddr_t acpipci_bs_mmap(bus_space_tag_t, bus_addr_t, off_t, int, int); 110 111void acpipci_attach_hook(struct device *, struct device *, 112 struct pcibus_attach_args *); 113int acpipci_bus_maxdevs(void *, int); 114pcitag_t acpipci_make_tag(void *, int, int, int); 115void acpipci_decompose_tag(void *, pcitag_t, int *, int *, int *); 116int acpipci_conf_size(void *, pcitag_t); 117pcireg_t acpipci_conf_read(void *, pcitag_t, int); 118void acpipci_conf_write(void *, pcitag_t, int, pcireg_t); 119int acpipci_probe_device_hook(void *, struct pci_attach_args *); 120 121int acpipci_intr_map(struct pci_attach_args *, pci_intr_handle_t *); 122const char *acpipci_intr_string(void *, pci_intr_handle_t); 123void *acpipci_intr_establish(void *, pci_intr_handle_t, int, 124 struct cpu_info *, int (*)(void *), void *, char *); 125void acpipci_intr_disestablish(void *, void *); 126 127uint32_t acpipci_iort_map_msi(pci_chipset_tag_t, pcitag_t); 128 129int 130acpipci_match(struct device *parent, void *match, void *aux) 131{ 132 struct acpi_attach_args *aaa = aux; 133 struct cfdata *cf = match; 134 135 return acpi_matchhids(aaa, acpipci_hids, cf->cf_driver->cd_name); 136} 137 138void 139acpipci_attach(struct device *parent, struct device *self, void *aux) 140{ 141 struct acpi_attach_args *aaa = aux; 142 struct acpipci_softc *sc = (struct acpipci_softc *)self; 143 struct interrupt_controller *ic; 144 struct pcibus_attach_args pba; 145 struct aml_value res; 146 uint64_t bbn = 0; 147 uint64_t seg = 0; 148 pcitag_t tag; 149 pcireg_t id; 150 151 sc->sc_acpi = (struct acpi_softc *)parent; 152 sc->sc_node = aaa->aaa_node; 153 printf(" %s", sc->sc_node->name); 154 155 if (aml_evalname(sc->sc_acpi, sc->sc_node, "_CRS", 0, NULL, &res)) { 156 printf(": can't find resources\n"); 157 return; 158 } 159 160 aml_evalinteger(sc->sc_acpi, sc->sc_node, "_BBN", 0, NULL, &bbn); 161 sc->sc_bus = bbn; 162 163 aml_evalinteger(sc->sc_acpi, sc->sc_node, "_SEG", 0, NULL, &seg); 164 sc->sc_seg = seg; 165 166 sc->sc_iot = aaa->aaa_memt; 167 168 printf("\n"); 169 170 /* Create extents for our address spaces. */ 171 snprintf(sc->sc_busex_name, sizeof(sc->sc_busex_name), 172 "%s pcibus", sc->sc_dev.dv_xname); 173 snprintf(sc->sc_ioex_name, sizeof(sc->sc_ioex_name), 174 "%s pciio", sc->sc_dev.dv_xname); 175 snprintf(sc->sc_memex_name, sizeof(sc->sc_memex_name), 176 "%s pcimem", sc->sc_dev.dv_xname); 177 sc->sc_busex = extent_create(sc->sc_busex_name, 0, 255, 178 M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED); 179 sc->sc_ioex = extent_create(sc->sc_ioex_name, 0, 0xffffffff, 180 M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED); 181 sc->sc_memex = extent_create(sc->sc_memex_name, 0, (u_long)-1, 182 M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED); 183 184 aml_parse_resource(&res, acpipci_parse_resources, sc); 185 186 memcpy(&sc->sc_bus_iot, sc->sc_iot, sizeof(sc->sc_bus_iot)); 187 sc->sc_bus_iot.bus_private = sc->sc_io_trans; 188 sc->sc_bus_iot._space_map = acpipci_bs_map; 189 sc->sc_bus_iot._space_mmap = acpipci_bs_mmap; 190 memcpy(&sc->sc_bus_memt, sc->sc_iot, sizeof(sc->sc_bus_memt)); 191 sc->sc_bus_memt.bus_private = sc->sc_mem_trans; 192 sc->sc_bus_memt._space_map = acpipci_bs_map; 193 sc->sc_bus_memt._space_mmap = acpipci_bs_mmap; 194 195 extern LIST_HEAD(, interrupt_controller) interrupt_controllers; 196 LIST_FOREACH(ic, &interrupt_controllers, ic_list) { 197 if (ic->ic_establish_msi) 198 break; 199 } 200 sc->sc_msi_ic = ic; 201 202 sc->sc_pc = pci_lookup_segment(seg); 203 KASSERT(sc->sc_pc->pc_intr_v == NULL); 204 205 sc->sc_pc->pc_probe_device_hook = acpipci_probe_device_hook; 206 207 sc->sc_pc->pc_intr_v = sc; 208 sc->sc_pc->pc_intr_map = acpipci_intr_map; 209 sc->sc_pc->pc_intr_map_msi = _pci_intr_map_msi; 210 sc->sc_pc->pc_intr_map_msix = _pci_intr_map_msix; 211 sc->sc_pc->pc_intr_string = acpipci_intr_string; 212 sc->sc_pc->pc_intr_establish = acpipci_intr_establish; 213 sc->sc_pc->pc_intr_disestablish = acpipci_intr_disestablish; 214 215 memset(&pba, 0, sizeof(pba)); 216 pba.pba_busname = "pci"; 217 pba.pba_iot = &sc->sc_bus_iot; 218 pba.pba_memt = &sc->sc_bus_memt; 219 pba.pba_dmat = aaa->aaa_dmat; 220 pba.pba_pc = sc->sc_pc; 221 pba.pba_busex = sc->sc_busex; 222 pba.pba_ioex = sc->sc_ioex; 223 pba.pba_memex = sc->sc_memex; 224 pba.pba_pmemex = sc->sc_memex; 225 pba.pba_domain = pci_ndomains++; 226 pba.pba_bus = sc->sc_bus; 227 if (sc->sc_msi_ic) 228 pba.pba_flags |= PCI_FLAGS_MSI_ENABLED; 229 230 /* 231 * Qualcomm SC8280XP uses a non-standard MSI implementation. 232 */ 233 tag = pci_make_tag(sc->sc_pc, sc->sc_bus, 0, 0); 234 id = pci_conf_read(sc->sc_pc, tag, PCI_ID_REG); 235 if (PCI_VENDOR(id) == PCI_VENDOR_QUALCOMM && 236 PCI_PRODUCT(id) == PCI_PRODUCT_QUALCOMM_SC8280XP_PCIE) 237 pba.pba_flags &= ~PCI_FLAGS_MSI_ENABLED; 238 239 config_found(self, &pba, NULL); 240} 241 242int 243acpipci_parse_resources(int crsidx, union acpi_resource *crs, void *arg) 244{ 245 struct acpipci_softc *sc = arg; 246 struct acpipci_trans *at; 247 int type = AML_CRSTYPE(crs); 248 int restype, tflags; 249 u_long min, len = 0, tra; 250 251 switch (type) { 252 case LR_WORD: 253 restype = crs->lr_word.type; 254 tflags = crs->lr_word.tflags; 255 min = crs->lr_word._min; 256 len = crs->lr_word._len; 257 tra = crs->lr_word._tra; 258 break; 259 case LR_DWORD: 260 restype = crs->lr_dword.type; 261 tflags = crs->lr_dword.tflags; 262 min = crs->lr_dword._min; 263 len = crs->lr_dword._len; 264 tra = crs->lr_dword._tra; 265 break; 266 case LR_QWORD: 267 restype = crs->lr_qword.type; 268 tflags = crs->lr_qword.tflags; 269 min = crs->lr_qword._min; 270 len = crs->lr_qword._len; 271 tra = crs->lr_qword._tra; 272 break; 273 case LR_MEM32FIXED: 274 restype = LR_TYPE_MEMORY; 275 tflags = 0; 276 min = crs->lr_m32fixed._bas; 277 len = crs->lr_m32fixed._len; 278 tra = 0; 279 break; 280 } 281 282 if (len == 0) 283 return 0; 284 285 switch (restype) { 286 case LR_TYPE_MEMORY: 287 if (tflags & LR_MEMORY_TTP) 288 return 0; 289 extent_free(sc->sc_memex, min, len, EX_WAITOK); 290 at = malloc(sizeof(struct acpipci_trans), M_DEVBUF, M_WAITOK); 291 at->at_iot = sc->sc_iot; 292 at->at_base = min; 293 at->at_size = len; 294 at->at_offset = tra; 295 at->at_next = sc->sc_mem_trans; 296 sc->sc_mem_trans = at; 297 break; 298 case LR_TYPE_IO: 299 /* 300 * Don't check _TTP as various firmwares don't set it, 301 * even though they should!! 302 */ 303 extent_free(sc->sc_ioex, min, len, EX_WAITOK); 304 at = malloc(sizeof(struct acpipci_trans), M_DEVBUF, M_WAITOK); 305 at->at_iot = sc->sc_iot; 306 at->at_base = min; 307 at->at_size = len; 308 at->at_offset = tra; 309 at->at_next = sc->sc_io_trans; 310 sc->sc_io_trans = at; 311 break; 312 case LR_TYPE_BUS: 313 extent_free(sc->sc_busex, min, len, EX_WAITOK); 314 /* 315 * Let _CRS minimum bus number override _BBN. 316 */ 317 sc->sc_bus = min; 318 break; 319 } 320 321 return 0; 322} 323 324void 325acpipci_attach_hook(struct device *parent, struct device *self, 326 struct pcibus_attach_args *pba) 327{ 328} 329 330int 331acpipci_bus_maxdevs(void *v, int bus) 332{ 333 return 32; 334} 335 336pcitag_t 337acpipci_make_tag(void *v, int bus, int device, int function) 338{ 339 return ((bus << 20) | (device << 15) | (function << 12)); 340} 341 342void 343acpipci_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp) 344{ 345 if (bp != NULL) 346 *bp = (tag >> 20) & 0xff; 347 if (dp != NULL) 348 *dp = (tag >> 15) & 0x1f; 349 if (fp != NULL) 350 *fp = (tag >> 12) & 0x7; 351} 352 353int 354acpipci_conf_size(void *v, pcitag_t tag) 355{ 356 return PCIE_CONFIG_SPACE_SIZE; 357} 358 359pcireg_t 360acpipci_conf_read(void *v, pcitag_t tag, int reg) 361{ 362 struct acpipci_mcfg *am = v; 363 364 if (tag < (am->am_min_bus << 20) || 365 tag >= ((am->am_max_bus + 1) << 20)) 366 return 0xffffffff; 367 368 return bus_space_read_4(am->am_iot, am->am_ioh, tag | reg); 369} 370 371void 372acpipci_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data) 373{ 374 struct acpipci_mcfg *am = v; 375 376 if (tag < (am->am_min_bus << 20) || 377 tag >= ((am->am_max_bus + 1) << 20)) 378 return; 379 380 bus_space_write_4(am->am_iot, am->am_ioh, tag | reg, data); 381} 382 383int 384acpipci_probe_device_hook(void *v, struct pci_attach_args *pa) 385{ 386 struct acpipci_mcfg *am = v; 387 struct acpipci_trans *at; 388 struct acpi_table_header *hdr; 389 struct acpi_iort *iort = NULL; 390 struct acpi_iort_node *node; 391 struct acpi_iort_mapping *map; 392 struct acpi_iort_rc_node *rc; 393 struct acpi_q *entry; 394 uint32_t rid, offset; 395 int i; 396 397 rid = pci_requester_id(pa->pa_pc, pa->pa_tag); 398 399 /* Look for IORT table. */ 400 SIMPLEQ_FOREACH(entry, &acpi_softc->sc_tables, q_next) { 401 hdr = entry->q_table; 402 if (strncmp(hdr->signature, IORT_SIG, 403 sizeof(hdr->signature)) == 0) { 404 iort = entry->q_table; 405 break; 406 } 407 } 408 if (iort == NULL) 409 return 0; 410 411 /* Find our root complex. */ 412 offset = iort->offset; 413 for (i = 0; i < iort->number_of_nodes; i++) { 414 node = (struct acpi_iort_node *)((char *)iort + offset); 415 if (node->type == ACPI_IORT_ROOT_COMPLEX) { 416 rc = (struct acpi_iort_rc_node *)&node[1]; 417 if (rc->segment == am->am_segment) 418 break; 419 } 420 offset += node->length; 421 } 422 423 /* No RC found? Weird. */ 424 if (i >= iort->number_of_nodes) 425 return 0; 426 427 /* Find our output base towards SMMU. */ 428 map = (struct acpi_iort_mapping *)((char *)node + node->mapping_offset); 429 for (i = 0; i < node->number_of_mappings; i++) { 430 offset = map[i].output_reference; 431 432 if (map[i].flags & ACPI_IORT_MAPPING_SINGLE) { 433 rid = map[i].output_base; 434 break; 435 } 436 437 /* Mapping encodes number of IDs in the range minus one. */ 438 if (map[i].input_base <= rid && 439 rid <= map[i].input_base + map[i].number_of_ids) { 440 rid = map[i].output_base + (rid - map[i].input_base); 441 break; 442 } 443 } 444 445 /* No mapping found? Even weirder. */ 446 if (i >= node->number_of_mappings) 447 return 0; 448 449 node = (struct acpi_iort_node *)((char *)iort + offset); 450 if (node->type == ACPI_IORT_SMMU) { 451 pa->pa_dmat = acpiiort_smmu_map(node, rid, pa->pa_dmat); 452 for (at = pa->pa_iot->bus_private; at; at = at->at_next) { 453 acpiiort_smmu_reserve_region(node, rid, 454 at->at_base, at->at_size); 455 } 456 for (at = pa->pa_memt->bus_private; at; at = at->at_next) { 457 acpiiort_smmu_reserve_region(node, rid, 458 at->at_base, at->at_size); 459 } 460 } 461 462 return 0; 463} 464 465int 466acpipci_intr_swizzle(struct pci_attach_args *pa, pci_intr_handle_t *ihp) 467{ 468 int dev, swizpin; 469 pcireg_t id; 470 471 if (pa->pa_bridgeih == NULL) 472 return -1; 473 474 pci_decompose_tag(pa->pa_pc, pa->pa_tag, NULL, &dev, NULL); 475 swizpin = PPB_INTERRUPT_SWIZZLE(pa->pa_rawintrpin, dev); 476 477 /* 478 * Qualcomm SC8280XP Root Complex violates PCI bridge 479 * interrupt swizzling rules. 480 */ 481 if (pa->pa_bridgetag) { 482 id = pci_conf_read(pa->pa_pc, *pa->pa_bridgetag, PCI_ID_REG); 483 if (PCI_VENDOR(id) == PCI_VENDOR_QUALCOMM && 484 PCI_PRODUCT(id) == PCI_PRODUCT_QUALCOMM_SC8280XP_PCIE) { 485 swizpin = (((swizpin - 1) + 3) % 4) + 1; 486 } 487 } 488 489 if (pa->pa_bridgeih[swizpin - 1].ih_type == PCI_NONE) 490 return -1; 491 492 *ihp = pa->pa_bridgeih[swizpin - 1]; 493 return 0; 494} 495 496int 497acpipci_getirq(int crsidx, union acpi_resource *crs, void *arg) 498{ 499 int *irq = arg; 500 501 switch (AML_CRSTYPE(crs)) { 502 case SR_IRQ: 503 *irq = ffs(letoh16(crs->sr_irq.irq_mask)) - 1; 504 break; 505 case LR_EXTIRQ: 506 *irq = letoh32(crs->lr_extirq.irq[0]); 507 break; 508 default: 509 break; 510 } 511 512 return 0; 513} 514 515int 516acpipci_intr_link(struct acpipci_softc *sc, struct aml_value *val) 517{ 518 struct aml_value res; 519 int64_t sta; 520 int irq = -1; 521 522 if (val->type == AML_OBJTYPE_OBJREF) 523 val = val->v_objref.ref; 524 if (val->type != AML_OBJTYPE_DEVICE) 525 return -1; 526 527 sta = acpi_getsta(sc->sc_acpi, val->node); 528 if ((sta & STA_PRESENT) == 0) 529 return -1; 530 531 if (aml_evalname(sc->sc_acpi, val->node, "_CRS", 0, NULL, &res)) 532 return -1; 533 aml_parse_resource(&res, acpipci_getirq, &irq); 534 aml_freevalue(&res); 535 536 return irq; 537} 538 539int 540acpipci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) 541{ 542 struct acpipci_softc *sc = pa->pa_pc->pc_intr_v; 543 struct aml_node *node = sc->sc_node; 544 struct aml_value res; 545 uint64_t addr, pin, source, index; 546 int i; 547 548 /* 549 * If we're behind a bridge, we need to look for a _PRT for 550 * it. If we don't find a _PRT, we need to swizzle. If we're 551 * not behind a bridge we need to look for a _PRT on the host 552 * bridge node itself. 553 */ 554 if (pa->pa_bridgetag) { 555 node = acpi_find_pci(pa->pa_pc, *pa->pa_bridgetag); 556 if (node == NULL) 557 return acpipci_intr_swizzle(pa, ihp); 558 } 559 560 if (aml_evalname(sc->sc_acpi, node, "_PRT", 0, NULL, &res)) 561 return acpipci_intr_swizzle(pa, ihp); 562 563 if (res.type != AML_OBJTYPE_PACKAGE) 564 return -1; 565 566 for (i = 0; i < res.length; i++) { 567 struct aml_value *val = res.v_package[i]; 568 569 if (val->type != AML_OBJTYPE_PACKAGE) 570 continue; 571 if (val->length != 4) 572 continue; 573 if (val->v_package[0]->type != AML_OBJTYPE_INTEGER || 574 val->v_package[1]->type != AML_OBJTYPE_INTEGER || 575 val->v_package[3]->type != AML_OBJTYPE_INTEGER) 576 continue; 577 578 addr = val->v_package[0]->v_integer; 579 pin = val->v_package[1]->v_integer; 580 if (ACPI_ADR_PCIDEV(addr) != pa->pa_device || 581 ACPI_ADR_PCIFUN(addr) != 0xffff || 582 pin != pa->pa_intrpin - 1) 583 continue; 584 585 if (val->v_package[2]->type == AML_OBJTYPE_INTEGER) { 586 source = val->v_package[2]->v_integer; 587 index = val->v_package[3]->v_integer; 588 } else { 589 source = 0; 590 index = acpipci_intr_link(sc, val->v_package[2]); 591 } 592 if (source != 0 || index == -1) 593 continue; 594 595 ihp->ih_pc = pa->pa_pc; 596 ihp->ih_tag = pa->pa_tag; 597 ihp->ih_intrpin = index; 598 ihp->ih_type = PCI_INTX; 599 600 return 0; 601 } 602 603 return -1; 604} 605 606const char * 607acpipci_intr_string(void *v, pci_intr_handle_t ih) 608{ 609 static char irqstr[32]; 610 611 switch (ih.ih_type) { 612 case PCI_MSI: 613 return "msi"; 614 case PCI_MSIX: 615 return "msix"; 616 } 617 618 snprintf(irqstr, sizeof(irqstr), "irq %d", ih.ih_intrpin); 619 return irqstr; 620} 621 622void * 623acpipci_intr_establish(void *v, pci_intr_handle_t ih, int level, 624 struct cpu_info *ci, int (*func)(void *), void *arg, char *name) 625{ 626 struct acpipci_softc *sc = v; 627 struct acpipci_intr_handle *aih; 628 void *cookie; 629 630 KASSERT(ih.ih_type != PCI_NONE); 631 632 if (ih.ih_type != PCI_INTX) { 633 struct interrupt_controller *ic = sc->sc_msi_ic; 634 bus_dma_segment_t seg; 635 uint64_t addr, data; 636 637 KASSERT(ic); 638 639 /* Map Requester ID through IORT to get sideband data. */ 640 data = acpipci_iort_map_msi(ih.ih_pc, ih.ih_tag); 641 cookie = ic->ic_establish_msi(ic->ic_cookie, &addr, 642 &data, level, ci, func, arg, name); 643 if (cookie == NULL) 644 return NULL; 645 646 aih = malloc(sizeof(*aih), M_DEVBUF, M_WAITOK); 647 aih->aih_ih.ih_ic = ic; 648 aih->aih_ih.ih_ih = cookie; 649 aih->aih_dmat = ih.ih_dmat; 650 651 if (bus_dmamap_create(aih->aih_dmat, sizeof(uint32_t), 1, 652 sizeof(uint32_t), 0, BUS_DMA_WAITOK, &aih->aih_map)) { 653 free(aih, M_DEVBUF, sizeof(*aih)); 654 ic->ic_disestablish(cookie); 655 return NULL; 656 } 657 658 memset(&seg, 0, sizeof(seg)); 659 seg.ds_addr = addr; 660 seg.ds_len = sizeof(uint32_t); 661 662 if (bus_dmamap_load_raw(aih->aih_dmat, aih->aih_map, 663 &seg, 1, sizeof(uint32_t), BUS_DMA_WAITOK)) { 664 bus_dmamap_destroy(aih->aih_dmat, aih->aih_map); 665 free(aih, M_DEVBUF, sizeof(*aih)); 666 ic->ic_disestablish(cookie); 667 return NULL; 668 } 669 670 addr = aih->aih_map->dm_segs[0].ds_addr; 671 if (ih.ih_type == PCI_MSIX) { 672 pci_msix_enable(ih.ih_pc, ih.ih_tag, 673 &sc->sc_bus_memt, ih.ih_intrpin, addr, data); 674 } else 675 pci_msi_enable(ih.ih_pc, ih.ih_tag, addr, data); 676 677 cookie = aih; 678 } else { 679 if (ci != NULL && !CPU_IS_PRIMARY(ci)) 680 return NULL; 681 cookie = acpi_intr_establish(ih.ih_intrpin, 0, level, 682 func, arg, name); 683 } 684 685 return cookie; 686} 687 688void 689acpipci_intr_disestablish(void *v, void *cookie) 690{ 691 struct acpipci_intr_handle *aih = cookie; 692 struct interrupt_controller *ic = aih->aih_ih.ih_ic; 693 694 if (ic->ic_establish_msi) { 695 ic->ic_disestablish(aih->aih_ih.ih_ih); 696 bus_dmamap_unload(aih->aih_dmat, aih->aih_map); 697 bus_dmamap_destroy(aih->aih_dmat, aih->aih_map); 698 free(aih, M_DEVBUF, sizeof(*aih)); 699 } else 700 acpi_intr_disestablish(cookie); 701} 702 703/* 704 * Translate memory address if needed. 705 */ 706int 707acpipci_bs_map(bus_space_tag_t t, bus_addr_t addr, bus_size_t size, 708 int flags, bus_space_handle_t *bshp) 709{ 710 struct acpipci_trans *at; 711 712 for (at = t->bus_private; at; at = at->at_next) { 713 if (addr >= at->at_base && addr < at->at_base + at->at_size) { 714 return bus_space_map(at->at_iot, 715 addr + at->at_offset, size, flags, bshp); 716 } 717 } 718 719 return ENXIO; 720} 721 722paddr_t 723acpipci_bs_mmap(bus_space_tag_t t, bus_addr_t addr, off_t off, 724 int prot, int flags) 725{ 726 struct acpipci_trans *at; 727 728 for (at = t->bus_private; at; at = at->at_next) { 729 if (addr >= at->at_base && addr < at->at_base + at->at_size) { 730 return bus_space_mmap(at->at_iot, 731 addr + at->at_offset, off, prot, flags); 732 } 733 } 734 735 return -1; 736} 737 738SLIST_HEAD(,acpipci_mcfg) acpipci_mcfgs = 739 SLIST_HEAD_INITIALIZER(acpipci_mcfgs); 740 741void 742pci_mcfg_init(bus_space_tag_t iot, bus_addr_t addr, int segment, 743 int min_bus, int max_bus) 744{ 745 struct acpipci_mcfg *am; 746 747 am = malloc(sizeof(struct acpipci_mcfg), M_DEVBUF, M_WAITOK | M_ZERO); 748 am->am_segment = segment; 749 am->am_min_bus = min_bus; 750 am->am_max_bus = max_bus; 751 752 am->am_iot = iot; 753 if (bus_space_map(iot, addr, (max_bus + 1) << 20, 0, &am->am_ioh)) 754 panic("%s: can't map config space", __func__); 755 756 am->am_pc.pc_conf_v = am; 757 am->am_pc.pc_attach_hook = acpipci_attach_hook; 758 am->am_pc.pc_bus_maxdevs = acpipci_bus_maxdevs; 759 am->am_pc.pc_make_tag = acpipci_make_tag; 760 am->am_pc.pc_decompose_tag = acpipci_decompose_tag; 761 am->am_pc.pc_conf_size = acpipci_conf_size; 762 am->am_pc.pc_conf_read = acpipci_conf_read; 763 am->am_pc.pc_conf_write = acpipci_conf_write; 764 SLIST_INSERT_HEAD(&acpipci_mcfgs, am, am_list); 765} 766 767pcireg_t 768acpipci_dummy_conf_read(void *v, pcitag_t tag, int reg) 769{ 770 return 0xffffffff; 771} 772 773void 774acpipci_dummy_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data) 775{ 776} 777 778struct machine_pci_chipset acpipci_dummy_chipset = { 779 .pc_attach_hook = acpipci_attach_hook, 780 .pc_bus_maxdevs = acpipci_bus_maxdevs, 781 .pc_make_tag = acpipci_make_tag, 782 .pc_decompose_tag = acpipci_decompose_tag, 783 .pc_conf_size = acpipci_conf_size, 784 .pc_conf_read = acpipci_dummy_conf_read, 785 .pc_conf_write = acpipci_dummy_conf_write, 786}; 787 788pci_chipset_tag_t 789pci_lookup_segment(int segment) 790{ 791 struct acpipci_mcfg *am; 792 793 SLIST_FOREACH(am, &acpipci_mcfgs, am_list) { 794 if (am->am_segment == segment) 795 return &am->am_pc; 796 } 797 798 return &acpipci_dummy_chipset; 799} 800 801/* 802 * IORT support. 803 */ 804 805uint32_t acpipci_iort_map(struct acpi_iort *, uint32_t, uint32_t); 806 807uint32_t 808acpipci_iort_map_node(struct acpi_iort *iort, 809 struct acpi_iort_node *node, uint32_t id) 810{ 811 struct acpi_iort_mapping *map = 812 (struct acpi_iort_mapping *)((char *)node + node->mapping_offset); 813 int i; 814 815 for (i = 0; i < node->number_of_mappings; i++) { 816 uint32_t offset = map[i].output_reference; 817 818 if (map[i].flags & ACPI_IORT_MAPPING_SINGLE) { 819 id = map[i].output_base; 820 return acpipci_iort_map(iort, offset, id); 821 } 822 823 /* Mapping encodes number of IDs in the range minus one. */ 824 if (map[i].input_base <= id && 825 id <= map[i].input_base + map[i].number_of_ids) { 826 id = map[i].output_base + (id - map[i].input_base); 827 return acpipci_iort_map(iort, offset, id); 828 } 829 } 830 831 return id; 832} 833 834uint32_t 835acpipci_iort_map(struct acpi_iort *iort, uint32_t offset, uint32_t id) 836{ 837 struct acpi_iort_node *node = 838 (struct acpi_iort_node *)((char *)iort + offset); 839 840 switch (node->type) { 841 case ACPI_IORT_ITS: 842 return id; 843 case ACPI_IORT_SMMU: 844 return acpipci_iort_map_node(iort, node, id); 845 } 846 847 return id; 848} 849 850uint32_t 851acpipci_iort_map_msi(pci_chipset_tag_t pc, pcitag_t tag) 852{ 853 struct acpipci_softc *sc = pc->pc_intr_v; 854 struct acpi_table_header *hdr; 855 struct acpi_iort *iort = NULL; 856 struct acpi_iort_node *node; 857 struct acpi_iort_rc_node *rc; 858 struct acpi_q *entry; 859 uint32_t rid, offset; 860 int i; 861 862 rid = pci_requester_id(pc, tag); 863 864 /* Look for IORT table. */ 865 SIMPLEQ_FOREACH(entry, &sc->sc_acpi->sc_tables, q_next) { 866 hdr = entry->q_table; 867 if (strncmp(hdr->signature, IORT_SIG, 868 sizeof(hdr->signature)) == 0) { 869 iort = entry->q_table; 870 break; 871 } 872 } 873 if (iort == NULL) 874 return rid; 875 876 /* Find our root complex and map. */ 877 offset = iort->offset; 878 for (i = 0; i < iort->number_of_nodes; i++) { 879 node = (struct acpi_iort_node *)((char *)iort + offset); 880 switch (node->type) { 881 case ACPI_IORT_ROOT_COMPLEX: 882 rc = (struct acpi_iort_rc_node *)&node[1]; 883 if (rc->segment == sc->sc_seg) 884 return acpipci_iort_map_node(iort, node, rid); 885 break; 886 } 887 offset += node->length; 888 } 889 890 return rid; 891} 892