1 /* $OpenBSD: acpipci.c,v 1.22 2020/12/06 21:20:41 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 struct acpipci_mcfg { 38 SLIST_ENTRY(acpipci_mcfg) am_list; 39 40 uint16_t am_segment; 41 uint8_t am_min_bus; 42 uint8_t am_max_bus; 43 44 bus_space_tag_t am_iot; 45 bus_space_handle_t am_ioh; 46 47 struct arm64_pci_chipset am_pc; 48 }; 49 50 struct acpipci_trans { 51 struct acpipci_trans *at_next; 52 bus_space_tag_t at_iot; 53 bus_addr_t at_base; 54 bus_size_t at_size; 55 bus_size_t at_offset; 56 }; 57 58 struct acpipci_softc { 59 struct device sc_dev; 60 struct acpi_softc *sc_acpi; 61 struct aml_node *sc_node; 62 bus_space_tag_t sc_iot; 63 pci_chipset_tag_t sc_pc; 64 65 struct bus_space sc_bus_iot; 66 struct bus_space sc_bus_memt; 67 struct acpipci_trans *sc_io_trans; 68 struct acpipci_trans *sc_mem_trans; 69 70 struct extent *sc_busex; 71 struct extent *sc_memex; 72 struct extent *sc_ioex; 73 char sc_busex_name[32]; 74 char sc_ioex_name[32]; 75 char sc_memex_name[32]; 76 int sc_bus; 77 uint32_t sc_seg; 78 }; 79 80 int acpipci_match(struct device *, void *, void *); 81 void acpipci_attach(struct device *, struct device *, void *); 82 83 struct cfattach acpipci_ca = { 84 sizeof(struct acpipci_softc), acpipci_match, acpipci_attach 85 }; 86 87 struct cfdriver acpipci_cd = { 88 NULL, "acpipci", DV_DULL 89 }; 90 91 const char *acpipci_hids[] = { 92 "PNP0A08", 93 NULL 94 }; 95 96 int acpipci_parse_resources(int, union acpi_resource *, void *); 97 int acpipci_bs_map(bus_space_tag_t, bus_addr_t, bus_size_t, int, 98 bus_space_handle_t *); 99 paddr_t acpipci_bs_mmap(bus_space_tag_t, bus_addr_t, off_t, int, int); 100 101 void acpipci_attach_hook(struct device *, struct device *, 102 struct pcibus_attach_args *); 103 int acpipci_bus_maxdevs(void *, int); 104 pcitag_t acpipci_make_tag(void *, int, int, int); 105 void acpipci_decompose_tag(void *, pcitag_t, int *, int *, int *); 106 int acpipci_conf_size(void *, pcitag_t); 107 pcireg_t acpipci_conf_read(void *, pcitag_t, int); 108 void acpipci_conf_write(void *, pcitag_t, int, pcireg_t); 109 110 int acpipci_intr_map(struct pci_attach_args *, pci_intr_handle_t *); 111 const char *acpipci_intr_string(void *, pci_intr_handle_t); 112 void *acpipci_intr_establish(void *, pci_intr_handle_t, int, 113 struct cpu_info *, int (*)(void *), void *, char *); 114 void acpipci_intr_disestablish(void *, void *); 115 116 uint32_t acpipci_iort_map_msi(pci_chipset_tag_t, pcitag_t); 117 118 int 119 acpipci_match(struct device *parent, void *match, void *aux) 120 { 121 struct acpi_attach_args *aaa = aux; 122 struct cfdata *cf = match; 123 124 return acpi_matchhids(aaa, acpipci_hids, cf->cf_driver->cd_name); 125 } 126 127 void 128 acpipci_attach(struct device *parent, struct device *self, void *aux) 129 { 130 struct acpi_attach_args *aaa = aux; 131 struct acpipci_softc *sc = (struct acpipci_softc *)self; 132 struct pcibus_attach_args pba; 133 struct aml_value res; 134 uint64_t bbn = 0; 135 uint64_t seg = 0; 136 137 sc->sc_acpi = (struct acpi_softc *)parent; 138 sc->sc_node = aaa->aaa_node; 139 printf(" %s", sc->sc_node->name); 140 141 if (aml_evalname(sc->sc_acpi, sc->sc_node, "_CRS", 0, NULL, &res)) { 142 printf(": can't find resources\n"); 143 return; 144 } 145 146 aml_evalinteger(sc->sc_acpi, sc->sc_node, "_BBN", 0, NULL, &bbn); 147 sc->sc_bus = bbn; 148 149 aml_evalinteger(sc->sc_acpi, sc->sc_node, "_SEG", 0, NULL, &seg); 150 sc->sc_seg = seg; 151 152 sc->sc_iot = aaa->aaa_memt; 153 154 printf("\n"); 155 156 /* Create extents for our address spaces. */ 157 snprintf(sc->sc_busex_name, sizeof(sc->sc_busex_name), 158 "%s pcibus", sc->sc_dev.dv_xname); 159 snprintf(sc->sc_ioex_name, sizeof(sc->sc_ioex_name), 160 "%s pciio", sc->sc_dev.dv_xname); 161 snprintf(sc->sc_memex_name, sizeof(sc->sc_memex_name), 162 "%s pcimem", sc->sc_dev.dv_xname); 163 sc->sc_busex = extent_create(sc->sc_busex_name, 0, 255, 164 M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED); 165 sc->sc_ioex = extent_create(sc->sc_ioex_name, 0, 0xffffffff, 166 M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED); 167 sc->sc_memex = extent_create(sc->sc_memex_name, 0, (u_long)-1, 168 M_DEVBUF, NULL, 0, EX_WAITOK | EX_FILLED); 169 170 aml_parse_resource(&res, acpipci_parse_resources, sc); 171 172 memcpy(&sc->sc_bus_iot, sc->sc_iot, sizeof(sc->sc_bus_iot)); 173 sc->sc_bus_iot.bus_private = sc->sc_io_trans; 174 sc->sc_bus_iot._space_map = acpipci_bs_map; 175 sc->sc_bus_iot._space_mmap = acpipci_bs_mmap; 176 memcpy(&sc->sc_bus_memt, sc->sc_iot, sizeof(sc->sc_bus_memt)); 177 sc->sc_bus_memt.bus_private = sc->sc_mem_trans; 178 sc->sc_bus_memt._space_map = acpipci_bs_map; 179 sc->sc_bus_memt._space_mmap = acpipci_bs_mmap; 180 181 sc->sc_pc = pci_lookup_segment(seg); 182 KASSERT(sc->sc_pc->pc_intr_v == NULL); 183 184 sc->sc_pc->pc_intr_v = sc; 185 sc->sc_pc->pc_intr_map = acpipci_intr_map; 186 sc->sc_pc->pc_intr_map_msi = _pci_intr_map_msi; 187 sc->sc_pc->pc_intr_map_msix = _pci_intr_map_msix; 188 sc->sc_pc->pc_intr_string = acpipci_intr_string; 189 sc->sc_pc->pc_intr_establish = acpipci_intr_establish; 190 sc->sc_pc->pc_intr_disestablish = acpipci_intr_disestablish; 191 192 memset(&pba, 0, sizeof(pba)); 193 pba.pba_busname = "pci"; 194 pba.pba_iot = &sc->sc_bus_iot; 195 pba.pba_memt = &sc->sc_bus_memt; 196 pba.pba_dmat = aaa->aaa_dmat; 197 pba.pba_pc = sc->sc_pc; 198 pba.pba_busex = sc->sc_busex; 199 pba.pba_ioex = sc->sc_ioex; 200 pba.pba_memex = sc->sc_memex; 201 pba.pba_pmemex = sc->sc_memex; 202 pba.pba_domain = pci_ndomains++; 203 pba.pba_bus = sc->sc_bus; 204 pba.pba_flags |= PCI_FLAGS_MSI_ENABLED; 205 206 config_found(self, &pba, NULL); 207 } 208 209 int 210 acpipci_parse_resources(int crsidx, union acpi_resource *crs, void *arg) 211 { 212 struct acpipci_softc *sc = arg; 213 struct acpipci_trans *at; 214 int type = AML_CRSTYPE(crs); 215 int restype, tflags; 216 u_long min, len = 0, tra; 217 218 switch (type) { 219 case LR_WORD: 220 restype = crs->lr_word.type; 221 tflags = crs->lr_word.tflags; 222 min = crs->lr_word._min; 223 len = crs->lr_word._len; 224 tra = crs->lr_word._tra; 225 break; 226 case LR_DWORD: 227 restype = crs->lr_dword.type; 228 tflags = crs->lr_dword.tflags; 229 min = crs->lr_dword._min; 230 len = crs->lr_dword._len; 231 tra = crs->lr_dword._tra; 232 break; 233 case LR_QWORD: 234 restype = crs->lr_qword.type; 235 tflags = crs->lr_qword.tflags; 236 min = crs->lr_qword._min; 237 len = crs->lr_qword._len; 238 tra = crs->lr_qword._tra; 239 break; 240 } 241 242 if (len == 0) 243 return 0; 244 245 switch (restype) { 246 case LR_TYPE_MEMORY: 247 if (tflags & LR_MEMORY_TTP) 248 return 0; 249 extent_free(sc->sc_memex, min, len, EX_WAITOK); 250 at = malloc(sizeof(struct acpipci_trans), M_DEVBUF, M_WAITOK); 251 at->at_iot = sc->sc_iot; 252 at->at_base = min; 253 at->at_size = len; 254 at->at_offset = tra; 255 at->at_next = sc->sc_mem_trans; 256 sc->sc_mem_trans = at; 257 break; 258 case LR_TYPE_IO: 259 /* 260 * Don't check _TTP as various firmwares don't set it, 261 * even though they should!! 262 */ 263 extent_free(sc->sc_ioex, min, len, EX_WAITOK); 264 at = malloc(sizeof(struct acpipci_trans), M_DEVBUF, M_WAITOK); 265 at->at_iot = sc->sc_iot; 266 at->at_base = min; 267 at->at_size = len; 268 at->at_offset = tra; 269 at->at_next = sc->sc_io_trans; 270 sc->sc_io_trans = at; 271 break; 272 case LR_TYPE_BUS: 273 extent_free(sc->sc_busex, min, len, EX_WAITOK); 274 /* 275 * Let _CRS minimum bus number override _BBN. 276 */ 277 sc->sc_bus = min; 278 break; 279 } 280 281 return 0; 282 } 283 284 void 285 acpipci_attach_hook(struct device *parent, struct device *self, 286 struct pcibus_attach_args *pba) 287 { 288 } 289 290 int 291 acpipci_bus_maxdevs(void *v, int bus) 292 { 293 return 32; 294 } 295 296 pcitag_t 297 acpipci_make_tag(void *v, int bus, int device, int function) 298 { 299 return ((bus << 20) | (device << 15) | (function << 12)); 300 } 301 302 void 303 acpipci_decompose_tag(void *v, pcitag_t tag, int *bp, int *dp, int *fp) 304 { 305 if (bp != NULL) 306 *bp = (tag >> 20) & 0xff; 307 if (dp != NULL) 308 *dp = (tag >> 15) & 0x1f; 309 if (fp != NULL) 310 *fp = (tag >> 12) & 0x7; 311 } 312 313 int 314 acpipci_conf_size(void *v, pcitag_t tag) 315 { 316 return PCIE_CONFIG_SPACE_SIZE; 317 } 318 319 pcireg_t 320 acpipci_conf_read(void *v, pcitag_t tag, int reg) 321 { 322 struct acpipci_mcfg *am = v; 323 324 if (tag < (am->am_min_bus << 20) || 325 tag >= ((am->am_max_bus + 1) << 20)) 326 return 0xffffffff; 327 328 return bus_space_read_4(am->am_iot, am->am_ioh, tag | reg); 329 } 330 331 void 332 acpipci_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data) 333 { 334 struct acpipci_mcfg *am = v; 335 336 if (tag < (am->am_min_bus << 20) || 337 tag >= ((am->am_max_bus + 1) << 20)) 338 return; 339 340 bus_space_write_4(am->am_iot, am->am_ioh, tag | reg, data); 341 } 342 343 int 344 acpipci_intr_swizzle(struct pci_attach_args *pa, pci_intr_handle_t *ihp) 345 { 346 int dev, swizpin; 347 348 if (pa->pa_bridgeih == NULL) 349 return -1; 350 351 pci_decompose_tag(pa->pa_pc, pa->pa_tag, NULL, &dev, NULL); 352 swizpin = PPB_INTERRUPT_SWIZZLE(pa->pa_rawintrpin, dev); 353 if (pa->pa_bridgeih[swizpin - 1].ih_type == PCI_NONE) 354 return -1; 355 356 *ihp = pa->pa_bridgeih[swizpin - 1]; 357 return 0; 358 } 359 360 int 361 acpipci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) 362 { 363 struct acpipci_softc *sc = pa->pa_pc->pc_intr_v; 364 struct aml_node *node = sc->sc_node; 365 struct aml_value res; 366 uint64_t addr, pin, source, index; 367 int i; 368 369 /* 370 * If we're behind a bridge, we need to look for a _PRT for 371 * it. If we don't find a _PRT, we need to swizzle. If we're 372 * not behind a bridge we need to look for a _PRT on the host 373 * bridge node itself. 374 */ 375 if (pa->pa_bridgetag) { 376 node = acpi_find_pci(pa->pa_pc, *pa->pa_bridgetag); 377 if (node == NULL) 378 return acpipci_intr_swizzle(pa, ihp); 379 } 380 381 if (aml_evalname(sc->sc_acpi, node, "_PRT", 0, NULL, &res)) 382 return acpipci_intr_swizzle(pa, ihp); 383 384 if (res.type != AML_OBJTYPE_PACKAGE) 385 return -1; 386 387 for (i = 0; i < res.length; i++) { 388 struct aml_value *val = res.v_package[i]; 389 390 if (val->type != AML_OBJTYPE_PACKAGE) 391 continue; 392 if (val->length != 4) 393 continue; 394 if (val->v_package[0]->type != AML_OBJTYPE_INTEGER || 395 val->v_package[1]->type != AML_OBJTYPE_INTEGER || 396 val->v_package[2]->type != AML_OBJTYPE_INTEGER || 397 val->v_package[3]->type != AML_OBJTYPE_INTEGER) 398 continue; 399 400 addr = val->v_package[0]->v_integer; 401 pin = val->v_package[1]->v_integer; 402 source = val->v_package[2]->v_integer; 403 index = val->v_package[3]->v_integer; 404 if (ACPI_ADR_PCIDEV(addr) != pa->pa_device || 405 ACPI_ADR_PCIFUN(addr) != 0xffff || 406 pin != pa->pa_intrpin - 1 || source != 0) 407 continue; 408 409 ihp->ih_pc = pa->pa_pc; 410 ihp->ih_tag = pa->pa_tag; 411 ihp->ih_intrpin = index; 412 ihp->ih_type = PCI_INTX; 413 414 return 0; 415 } 416 417 return -1; 418 } 419 420 const char * 421 acpipci_intr_string(void *v, pci_intr_handle_t ih) 422 { 423 static char irqstr[32]; 424 425 switch (ih.ih_type) { 426 case PCI_MSI: 427 return "msi"; 428 case PCI_MSIX: 429 return "msix"; 430 } 431 432 snprintf(irqstr, sizeof(irqstr), "irq %d", ih.ih_intrpin); 433 return irqstr; 434 } 435 436 void * 437 acpipci_intr_establish(void *v, pci_intr_handle_t ih, int level, 438 struct cpu_info *ci, int (*func)(void *), void *arg, char *name) 439 { 440 struct acpipci_softc *sc = v; 441 struct interrupt_controller *ic; 442 struct arm_intr_handle *aih; 443 void *cookie; 444 445 extern LIST_HEAD(, interrupt_controller) interrupt_controllers; 446 LIST_FOREACH(ic, &interrupt_controllers, ic_list) { 447 if (ic->ic_establish_msi) 448 break; 449 } 450 if (ic == NULL) 451 return NULL; 452 453 KASSERT(ih.ih_type != PCI_NONE); 454 455 if (ih.ih_type != PCI_INTX) { 456 uint64_t addr, data; 457 458 /* Map Requester ID through IORT to get sideband data. */ 459 data = acpipci_iort_map_msi(ih.ih_pc, ih.ih_tag); 460 cookie = ic->ic_establish_msi(ic->ic_cookie, &addr, 461 &data, level, ci, func, arg, name); 462 if (cookie == NULL) 463 return NULL; 464 465 /* TODO: translate address to the PCI device's view */ 466 467 if (ih.ih_type == PCI_MSIX) { 468 pci_msix_enable(ih.ih_pc, ih.ih_tag, 469 &sc->sc_bus_memt, ih.ih_intrpin, addr, data); 470 } else 471 pci_msi_enable(ih.ih_pc, ih.ih_tag, addr, data); 472 473 aih = malloc(sizeof(*aih), M_DEVBUF, M_WAITOK); 474 aih->ih_ic = ic; 475 aih->ih_ih = cookie; 476 cookie = aih; 477 } else { 478 if (ci != NULL && !CPU_IS_PRIMARY(ci)) 479 return NULL; 480 cookie = acpi_intr_establish(ih.ih_intrpin, 0, level, 481 func, arg, name); 482 } 483 484 return cookie; 485 } 486 487 void 488 acpipci_intr_disestablish(void *v, void *cookie) 489 { 490 struct arm_intr_handle *aih = cookie; 491 struct interrupt_controller *ic = aih->ih_ic; 492 493 if (ic->ic_establish_msi) 494 ic->ic_disestablish(aih->ih_ih); 495 else 496 acpi_intr_disestablish(cookie); 497 } 498 499 /* 500 * Translate memory address if needed. 501 */ 502 int 503 acpipci_bs_map(bus_space_tag_t t, bus_addr_t addr, bus_size_t size, 504 int flags, bus_space_handle_t *bshp) 505 { 506 struct acpipci_trans *at; 507 508 for (at = t->bus_private; at; at = at->at_next) { 509 if (addr >= at->at_base && addr < at->at_base + at->at_size) { 510 return bus_space_map(at->at_iot, 511 addr + at->at_offset, size, flags, bshp); 512 } 513 } 514 515 return ENXIO; 516 } 517 518 paddr_t 519 acpipci_bs_mmap(bus_space_tag_t t, bus_addr_t addr, off_t off, 520 int prot, int flags) 521 { 522 struct acpipci_trans *at; 523 524 for (at = t->bus_private; at; at = at->at_next) { 525 if (addr >= at->at_base && addr < at->at_base + at->at_size) { 526 return bus_space_mmap(at->at_iot, 527 addr + at->at_offset, off, prot, flags); 528 } 529 } 530 531 return -1; 532 } 533 534 SLIST_HEAD(,acpipci_mcfg) acpipci_mcfgs = 535 SLIST_HEAD_INITIALIZER(acpipci_mcfgs); 536 537 void 538 pci_mcfg_init(bus_space_tag_t iot, bus_addr_t addr, int segment, 539 int min_bus, int max_bus) 540 { 541 struct acpipci_mcfg *am; 542 543 am = malloc(sizeof(struct acpipci_mcfg), M_DEVBUF, M_WAITOK | M_ZERO); 544 am->am_segment = segment; 545 am->am_min_bus = min_bus; 546 am->am_max_bus = max_bus; 547 548 am->am_iot = iot; 549 if (bus_space_map(iot, addr, (max_bus + 1) << 20, 0, &am->am_ioh)) 550 panic("%s: can't map config space", __func__); 551 552 am->am_pc.pc_conf_v = am; 553 am->am_pc.pc_attach_hook = acpipci_attach_hook; 554 am->am_pc.pc_bus_maxdevs = acpipci_bus_maxdevs; 555 am->am_pc.pc_make_tag = acpipci_make_tag; 556 am->am_pc.pc_decompose_tag = acpipci_decompose_tag; 557 am->am_pc.pc_conf_size = acpipci_conf_size; 558 am->am_pc.pc_conf_read = acpipci_conf_read; 559 am->am_pc.pc_conf_write = acpipci_conf_write; 560 SLIST_INSERT_HEAD(&acpipci_mcfgs, am, am_list); 561 } 562 563 pcireg_t 564 acpipci_dummy_conf_read(void *v, pcitag_t tag, int reg) 565 { 566 return 0xffffffff; 567 } 568 569 void 570 acpipci_dummy_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data) 571 { 572 } 573 574 struct arm64_pci_chipset acpipci_dummy_chipset = { 575 .pc_attach_hook = acpipci_attach_hook, 576 .pc_bus_maxdevs = acpipci_bus_maxdevs, 577 .pc_make_tag = acpipci_make_tag, 578 .pc_decompose_tag = acpipci_decompose_tag, 579 .pc_conf_size = acpipci_conf_size, 580 .pc_conf_read = acpipci_dummy_conf_read, 581 .pc_conf_write = acpipci_dummy_conf_write, 582 }; 583 584 pci_chipset_tag_t 585 pci_lookup_segment(int segment) 586 { 587 struct acpipci_mcfg *am; 588 589 SLIST_FOREACH(am, &acpipci_mcfgs, am_list) { 590 if (am->am_segment == segment) 591 return &am->am_pc; 592 } 593 594 return &acpipci_dummy_chipset; 595 } 596 597 /* 598 * IORT support. 599 */ 600 601 struct acpi_iort { 602 struct acpi_table_header hdr; 603 #define IORT_SIG "IORT" 604 uint32_t number_of_nodes; 605 uint32_t offset; 606 uint32_t reserved; 607 } __packed; 608 609 struct acpi_iort_node { 610 uint8_t type; 611 #define ACPI_IORT_ITS 0 612 #define ACPI_IORT_ROOT_COMPLEX 2 613 #define ACPI_IORT_SMMU 3 614 uint16_t length; 615 uint8_t revision; 616 uint32_t reserved1; 617 uint32_t number_of_mappings; 618 uint32_t mapping_offset; 619 uint64_t memory_access_properties; 620 uint32_t atf_attributes; 621 uint32_t segment; 622 uint8_t memory_address_size_limit; 623 uint8_t reserved2[3]; 624 } __packed; 625 626 struct acpi_iort_mapping { 627 uint32_t input_base; 628 uint32_t number_of_ids; 629 uint32_t output_base; 630 uint32_t output_reference; 631 uint32_t flags; 632 #define ACPI_IORT_MAPPING_SINGLE 0x00000001 633 } __packed; 634 635 uint32_t acpipci_iort_map(struct acpi_iort *, uint32_t, uint32_t); 636 637 uint32_t 638 acpipci_iort_map_node(struct acpi_iort *iort, 639 struct acpi_iort_node *node, uint32_t id) 640 { 641 struct acpi_iort_mapping *map = 642 (struct acpi_iort_mapping *)((char *)node + node->mapping_offset); 643 int i; 644 645 for (i = 0; i < node->number_of_mappings; i++) { 646 uint32_t offset = map[i].output_reference; 647 648 if (map[i].flags & ACPI_IORT_MAPPING_SINGLE) { 649 id = map[i].output_base; 650 return acpipci_iort_map(iort, offset, id); 651 } 652 653 /* Mapping encodes number of IDs in the range minus one. */ 654 if (map[i].input_base <= id && 655 id <= map[i].input_base + map[i].number_of_ids) { 656 id = map[i].output_base + (id - map[i].input_base); 657 return acpipci_iort_map(iort, offset, id); 658 } 659 } 660 661 return id; 662 } 663 664 uint32_t 665 acpipci_iort_map(struct acpi_iort *iort, uint32_t offset, uint32_t id) 666 { 667 struct acpi_iort_node *node = 668 (struct acpi_iort_node *)((char *)iort + offset); 669 670 switch (node->type) { 671 case ACPI_IORT_ITS: 672 return id; 673 case ACPI_IORT_SMMU: 674 return acpipci_iort_map_node(iort, node, id); 675 } 676 677 return id; 678 } 679 680 uint32_t 681 acpipci_iort_map_msi(pci_chipset_tag_t pc, pcitag_t tag) 682 { 683 struct acpipci_softc *sc = pc->pc_intr_v; 684 struct acpi_table_header *hdr; 685 struct acpi_iort *iort = NULL; 686 struct acpi_iort_node *node; 687 struct acpi_q *entry; 688 uint32_t rid, offset; 689 int i; 690 691 rid = pci_requester_id(pc, tag); 692 693 /* Look for IORT table. */ 694 SIMPLEQ_FOREACH(entry, &sc->sc_acpi->sc_tables, q_next) { 695 hdr = entry->q_table; 696 if (strncmp(hdr->signature, IORT_SIG, 697 sizeof(hdr->signature)) == 0) { 698 iort = entry->q_table; 699 break; 700 } 701 } 702 if (iort == NULL) 703 return rid; 704 705 /* Find our root complex and map. */ 706 offset = iort->offset; 707 for (i = 0; i < iort->number_of_nodes; i++) { 708 node = (struct acpi_iort_node *)((char *)iort + offset); 709 switch (node->type) { 710 case ACPI_IORT_ROOT_COMPLEX: 711 if (node->segment == sc->sc_seg) 712 return acpipci_iort_map_node(iort, node, rid); 713 break; 714 } 715 offset += node->length; 716 } 717 718 return rid; 719 } 720