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