1 /*-
2 * Copyright (c) 2015, 2020 Ruslan Bukin <br@bsdpad.com>
3 * Copyright (c) 2014 The FreeBSD Foundation
4 * All rights reserved.
5 *
6 * This software was developed by Semihalf under
7 * the sponsorship of the FreeBSD Foundation.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31 /* Generic ECAM PCIe driver */
32
33 #include <sys/cdefs.h>
34 #include "opt_platform.h"
35
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/malloc.h>
39 #include <sys/kernel.h>
40 #include <sys/rman.h>
41 #include <sys/module.h>
42 #include <sys/bus.h>
43 #include <sys/endian.h>
44
45 #include <dev/pci/pcivar.h>
46 #include <dev/pci/pcireg.h>
47 #include <dev/pci/pcib_private.h>
48 #include <dev/pci/pci_host_generic.h>
49
50 #include <machine/bus.h>
51 #include <machine/intr.h>
52
53 #include "pcib_if.h"
54
55 #if defined(VM_MEMATTR_DEVICE_NP)
56 #define PCI_UNMAPPED
57 #define PCI_RF_FLAGS RF_UNMAPPED
58 #else
59 #define PCI_RF_FLAGS 0
60 #endif
61
62 /*
63 * We allocate "ranges" specified mappings higher up in the rid space to avoid
64 * conflicts with various definitions in the wild that may have other registers
65 * attributed to the controller besides just the config space.
66 */
67 #define RANGE_RID(idx) ((idx) + 100)
68
69 /* Forward prototypes */
70
71 static uint32_t generic_pcie_read_config(device_t dev, u_int bus, u_int slot,
72 u_int func, u_int reg, int bytes);
73 static void generic_pcie_write_config(device_t dev, u_int bus, u_int slot,
74 u_int func, u_int reg, uint32_t val, int bytes);
75 static int generic_pcie_maxslots(device_t dev);
76 static int generic_pcie_write_ivar(device_t dev, device_t child, int index,
77 uintptr_t value);
78
79 int
pci_host_generic_core_attach(device_t dev)80 pci_host_generic_core_attach(device_t dev)
81 {
82 #ifdef PCI_UNMAPPED
83 struct resource_map_request req;
84 struct resource_map map;
85 #endif
86 struct generic_pcie_core_softc *sc;
87 struct rman *rm;
88 uint64_t phys_base;
89 uint64_t pci_base;
90 uint64_t size;
91 const char *range_descr;
92 char buf[64];
93 int domain, error;
94 int flags, rid, tuple;
95
96 sc = device_get_softc(dev);
97 sc->dev = dev;
98
99 /* Create the parent DMA tag to pass down the coherent flag */
100 error = bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
101 1, 0, /* alignment, bounds */
102 BUS_SPACE_MAXADDR, /* lowaddr */
103 BUS_SPACE_MAXADDR, /* highaddr */
104 NULL, NULL, /* filter, filterarg */
105 BUS_SPACE_MAXSIZE, /* maxsize */
106 BUS_SPACE_UNRESTRICTED, /* nsegments */
107 BUS_SPACE_MAXSIZE, /* maxsegsize */
108 sc->coherent ? BUS_DMA_COHERENT : 0, /* flags */
109 NULL, NULL, /* lockfunc, lockarg */
110 &sc->dmat);
111 if (error != 0)
112 return (error);
113
114 /*
115 * Attempt to set the domain. If it's missing, or we are unable to
116 * set it then memory allocations may be placed in the wrong domain.
117 */
118 if (bus_get_domain(dev, &domain) == 0)
119 (void)bus_dma_tag_set_domain(sc->dmat, domain);
120
121 if ((sc->quirks & PCIE_CUSTOM_CONFIG_SPACE_QUIRK) == 0) {
122 rid = 0;
123 sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
124 PCI_RF_FLAGS | RF_ACTIVE);
125 if (sc->res == NULL) {
126 device_printf(dev, "could not allocate memory.\n");
127 error = ENXIO;
128 goto err_resource;
129 }
130 #ifdef PCI_UNMAPPED
131 resource_init_map_request(&req);
132 req.memattr = VM_MEMATTR_DEVICE_NP;
133 error = bus_map_resource(dev, SYS_RES_MEMORY, sc->res, &req,
134 &map);
135 if (error != 0) {
136 device_printf(dev, "could not map memory.\n");
137 return (error);
138 }
139 rman_set_mapping(sc->res, &map);
140 #endif
141 }
142
143 sc->has_pmem = false;
144 sc->pmem_rman.rm_type = RMAN_ARRAY;
145 snprintf(buf, sizeof(buf), "%s prefetch window",
146 device_get_nameunit(dev));
147 sc->pmem_rman.rm_descr = strdup(buf, M_DEVBUF);
148
149 sc->mem_rman.rm_type = RMAN_ARRAY;
150 snprintf(buf, sizeof(buf), "%s memory window",
151 device_get_nameunit(dev));
152 sc->mem_rman.rm_descr = strdup(buf, M_DEVBUF);
153
154 sc->io_rman.rm_type = RMAN_ARRAY;
155 snprintf(buf, sizeof(buf), "%s I/O port window",
156 device_get_nameunit(dev));
157 sc->io_rman.rm_descr = strdup(buf, M_DEVBUF);
158
159 /* Initialize rman and allocate memory regions */
160 error = rman_init(&sc->pmem_rman);
161 if (error) {
162 device_printf(dev, "rman_init() failed. error = %d\n", error);
163 goto err_pmem_rman;
164 }
165
166 error = rman_init(&sc->mem_rman);
167 if (error) {
168 device_printf(dev, "rman_init() failed. error = %d\n", error);
169 goto err_mem_rman;
170 }
171
172 error = rman_init(&sc->io_rman);
173 if (error) {
174 device_printf(dev, "rman_init() failed. error = %d\n", error);
175 goto err_io_rman;
176 }
177
178 for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) {
179 phys_base = sc->ranges[tuple].phys_base;
180 pci_base = sc->ranges[tuple].pci_base;
181 size = sc->ranges[tuple].size;
182 rid = RANGE_RID(tuple);
183 if (size == 0)
184 continue; /* empty range element */
185 switch (FLAG_TYPE(sc->ranges[tuple].flags)) {
186 case FLAG_TYPE_PMEM:
187 sc->has_pmem = true;
188 range_descr = "prefetch";
189 flags = RF_PREFETCHABLE;
190 rm = &sc->pmem_rman;
191 break;
192 case FLAG_TYPE_MEM:
193 range_descr = "memory";
194 flags = 0;
195 rm = &sc->mem_rman;
196 break;
197 case FLAG_TYPE_IO:
198 range_descr = "I/O port";
199 flags = 0;
200 rm = &sc->io_rman;
201 break;
202 default:
203 continue;
204 }
205 if (bootverbose)
206 device_printf(dev,
207 "PCI addr: 0x%jx, CPU addr: 0x%jx, Size: 0x%jx, Type: %s\n",
208 pci_base, phys_base, size, range_descr);
209 error = bus_set_resource(dev, SYS_RES_MEMORY, rid, phys_base,
210 size);
211 if (error != 0) {
212 device_printf(dev,
213 "failed to set resource for range %d: %d\n", tuple,
214 error);
215 continue;
216 }
217 sc->ranges[tuple].rid = rid;
218 sc->ranges[tuple].res = bus_alloc_resource_any(dev,
219 SYS_RES_MEMORY, &rid, RF_ACTIVE | RF_UNMAPPED | flags);
220 if (sc->ranges[tuple].res == NULL) {
221 device_printf(dev,
222 "failed to allocate resource for range %d\n", tuple);
223 continue;
224 }
225 error = rman_manage_region(rm, pci_base, pci_base + size - 1);
226 if (error) {
227 device_printf(dev, "rman_manage_region() failed."
228 "error = %d\n", error);
229 continue;
230 }
231 }
232
233 return (0);
234
235 err_io_rman:
236 rman_fini(&sc->mem_rman);
237 err_mem_rman:
238 rman_fini(&sc->pmem_rman);
239 err_pmem_rman:
240 free(__DECONST(char *, sc->io_rman.rm_descr), M_DEVBUF);
241 free(__DECONST(char *, sc->mem_rman.rm_descr), M_DEVBUF);
242 free(__DECONST(char *, sc->pmem_rman.rm_descr), M_DEVBUF);
243 if (sc->res != NULL)
244 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->res);
245 err_resource:
246 bus_dma_tag_destroy(sc->dmat);
247 return (error);
248 }
249
250 int
pci_host_generic_core_detach(device_t dev)251 pci_host_generic_core_detach(device_t dev)
252 {
253 int error;
254
255 error = bus_generic_detach(dev);
256 if (error != 0)
257 return (error);
258
259 return (pci_host_generic_core_free(dev));
260 }
261
262 int
pci_host_generic_core_free(device_t dev)263 pci_host_generic_core_free(device_t dev)
264 {
265 struct generic_pcie_core_softc *sc;
266 int rid, tuple;
267
268 sc = device_get_softc(dev);
269 for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) {
270 rid = sc->ranges[tuple].rid;
271 if (sc->ranges[tuple].size == 0) {
272 MPASS(sc->ranges[tuple].res == NULL);
273 continue; /* empty range element */
274 }
275
276 MPASS(rid != -1);
277 switch (FLAG_TYPE(sc->ranges[tuple].flags)) {
278 case FLAG_TYPE_PMEM:
279 case FLAG_TYPE_MEM:
280 case FLAG_TYPE_IO:
281 break;
282 default:
283 continue;
284 }
285 if (sc->ranges[tuple].res != NULL)
286 bus_release_resource(dev, SYS_RES_MEMORY, rid,
287 sc->ranges[tuple].res);
288 bus_delete_resource(dev, SYS_RES_MEMORY, rid);
289 }
290 rman_fini(&sc->io_rman);
291 rman_fini(&sc->mem_rman);
292 rman_fini(&sc->pmem_rman);
293 free(__DECONST(char *, sc->io_rman.rm_descr), M_DEVBUF);
294 free(__DECONST(char *, sc->mem_rman.rm_descr), M_DEVBUF);
295 free(__DECONST(char *, sc->pmem_rman.rm_descr), M_DEVBUF);
296 if (sc->res != NULL)
297 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->res);
298 bus_dma_tag_destroy(sc->dmat);
299
300 return (0);
301 }
302
303 static uint32_t
generic_pcie_read_config(device_t dev,u_int bus,u_int slot,u_int func,u_int reg,int bytes)304 generic_pcie_read_config(device_t dev, u_int bus, u_int slot,
305 u_int func, u_int reg, int bytes)
306 {
307 struct generic_pcie_core_softc *sc;
308 uint64_t offset;
309 uint32_t data;
310
311 sc = device_get_softc(dev);
312 if ((bus < sc->bus_start) || (bus > sc->bus_end))
313 return (~0U);
314 if ((slot > PCI_SLOTMAX) || (func > PCI_FUNCMAX) ||
315 (reg > PCIE_REGMAX))
316 return (~0U);
317 if ((sc->quirks & PCIE_ECAM_DESIGNWARE_QUIRK) && bus == 0 && slot > 0)
318 return (~0U);
319
320 offset = PCIE_ADDR_OFFSET(bus - sc->bus_start, slot, func, reg);
321
322 switch (bytes) {
323 case 1:
324 data = bus_read_1(sc->res, offset);
325 break;
326 case 2:
327 data = le16toh(bus_read_2(sc->res, offset));
328 break;
329 case 4:
330 data = le32toh(bus_read_4(sc->res, offset));
331 break;
332 default:
333 return (~0U);
334 }
335
336 return (data);
337 }
338
339 static void
generic_pcie_write_config(device_t dev,u_int bus,u_int slot,u_int func,u_int reg,uint32_t val,int bytes)340 generic_pcie_write_config(device_t dev, u_int bus, u_int slot,
341 u_int func, u_int reg, uint32_t val, int bytes)
342 {
343 struct generic_pcie_core_softc *sc;
344 uint64_t offset;
345
346 sc = device_get_softc(dev);
347 if ((bus < sc->bus_start) || (bus > sc->bus_end))
348 return;
349 if ((slot > PCI_SLOTMAX) || (func > PCI_FUNCMAX) ||
350 (reg > PCIE_REGMAX))
351 return;
352
353 offset = PCIE_ADDR_OFFSET(bus - sc->bus_start, slot, func, reg);
354
355 switch (bytes) {
356 case 1:
357 bus_write_1(sc->res, offset, val);
358 break;
359 case 2:
360 bus_write_2(sc->res, offset, htole16(val));
361 break;
362 case 4:
363 bus_write_4(sc->res, offset, htole32(val));
364 break;
365 default:
366 return;
367 }
368 }
369
370 static int
generic_pcie_maxslots(device_t dev)371 generic_pcie_maxslots(device_t dev)
372 {
373
374 return (31); /* max slots per bus acc. to standard */
375 }
376
377 int
generic_pcie_read_ivar(device_t dev,device_t child,int index,uintptr_t * result)378 generic_pcie_read_ivar(device_t dev, device_t child, int index,
379 uintptr_t *result)
380 {
381 struct generic_pcie_core_softc *sc;
382
383 sc = device_get_softc(dev);
384 switch (index) {
385 case PCIB_IVAR_BUS:
386 *result = sc->bus_start;
387 return (0);
388 case PCIB_IVAR_DOMAIN:
389 *result = sc->ecam;
390 return (0);
391 }
392
393 if (bootverbose)
394 device_printf(dev, "ERROR: Unknown index %d.\n", index);
395 return (ENOENT);
396 }
397
398 static int
generic_pcie_write_ivar(device_t dev,device_t child,int index,uintptr_t value)399 generic_pcie_write_ivar(device_t dev, device_t child, int index,
400 uintptr_t value)
401 {
402
403 return (ENOENT);
404 }
405
406 static struct rman *
generic_pcie_get_rman(device_t dev,int type,u_int flags)407 generic_pcie_get_rman(device_t dev, int type, u_int flags)
408 {
409 struct generic_pcie_core_softc *sc = device_get_softc(dev);
410
411 switch (type) {
412 case SYS_RES_IOPORT:
413 return (&sc->io_rman);
414 case SYS_RES_MEMORY:
415 if (sc->has_pmem && (flags & RF_PREFETCHABLE) != 0)
416 return (&sc->pmem_rman);
417 return (&sc->mem_rman);
418 default:
419 break;
420 }
421
422 return (NULL);
423 }
424
425 int
pci_host_generic_core_release_resource(device_t dev,device_t child,struct resource * res)426 pci_host_generic_core_release_resource(device_t dev, device_t child,
427 struct resource *res)
428 {
429 struct generic_pcie_core_softc *sc;
430
431 sc = device_get_softc(dev);
432 switch (rman_get_type(res)) {
433 case PCI_RES_BUS:
434 return (pci_domain_release_bus(sc->ecam, child, res));
435 case SYS_RES_IOPORT:
436 case SYS_RES_MEMORY:
437 return (bus_generic_rman_release_resource(dev, child, res));
438 default:
439 return (bus_generic_release_resource(dev, child, res));
440 }
441 }
442
443 static struct pcie_range *
generic_pcie_containing_range(device_t dev,int type,rman_res_t start,rman_res_t end)444 generic_pcie_containing_range(device_t dev, int type, rman_res_t start,
445 rman_res_t end)
446 {
447 struct generic_pcie_core_softc *sc = device_get_softc(dev);
448 uint64_t pci_base;
449 uint64_t size;
450 int i, space;
451
452 switch (type) {
453 case SYS_RES_IOPORT:
454 case SYS_RES_MEMORY:
455 break;
456 default:
457 return (NULL);
458 }
459
460 for (i = 0; i < MAX_RANGES_TUPLES; i++) {
461 pci_base = sc->ranges[i].pci_base;
462 size = sc->ranges[i].size;
463 if (size == 0)
464 continue; /* empty range element */
465
466 if (start < pci_base || end >= pci_base + size)
467 continue;
468
469 switch (FLAG_TYPE(sc->ranges[i].flags)) {
470 case FLAG_TYPE_MEM:
471 case FLAG_TYPE_PMEM:
472 space = SYS_RES_MEMORY;
473 break;
474 case FLAG_TYPE_IO:
475 space = SYS_RES_IOPORT;
476 break;
477 default:
478 continue;
479 }
480
481 if (type == space)
482 return (&sc->ranges[i]);
483 }
484 return (NULL);
485 }
486
487 static int
generic_pcie_translate_resource(device_t dev,int type,rman_res_t start,rman_res_t * new_start)488 generic_pcie_translate_resource(device_t dev, int type, rman_res_t start,
489 rman_res_t *new_start)
490 {
491 struct pcie_range *range;
492
493 /* Translate the address from a PCI address to a physical address */
494 switch (type) {
495 case SYS_RES_IOPORT:
496 case SYS_RES_MEMORY:
497 range = generic_pcie_containing_range(dev, type, start, start);
498 if (range == NULL)
499 return (ENOENT);
500 *new_start = start - range->pci_base + range->phys_base;
501 break;
502 default:
503 /* No translation for non-memory types */
504 *new_start = start;
505 break;
506 }
507
508 return (0);
509 }
510
511 struct resource *
pci_host_generic_core_alloc_resource(device_t dev,device_t child,int type,int rid,rman_res_t start,rman_res_t end,rman_res_t count,u_int flags)512 pci_host_generic_core_alloc_resource(device_t dev, device_t child, int type,
513 int rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
514 {
515 struct generic_pcie_core_softc *sc;
516 struct resource *res;
517
518 sc = device_get_softc(dev);
519
520 switch (type) {
521 case PCI_RES_BUS:
522 res = pci_domain_alloc_bus(sc->ecam, child, rid, start, end,
523 count, flags);
524 break;
525 case SYS_RES_IOPORT:
526 case SYS_RES_MEMORY:
527 res = bus_generic_rman_alloc_resource(dev, child, type, rid,
528 start, end, count, flags);
529 break;
530 default:
531 res = bus_generic_alloc_resource(dev, child, type, rid, start,
532 end, count, flags);
533 break;
534 }
535 if (res == NULL) {
536 device_printf(dev, "%s FAIL: type=%d, rid=%d, "
537 "start=%016jx, end=%016jx, count=%016jx, flags=%x\n",
538 __func__, type, rid, start, end, count, flags);
539 }
540 return (res);
541 }
542
543 static int
generic_pcie_activate_resource(device_t dev,device_t child,struct resource * r)544 generic_pcie_activate_resource(device_t dev, device_t child, struct resource *r)
545 {
546 struct generic_pcie_core_softc *sc;
547
548 sc = device_get_softc(dev);
549 switch (rman_get_type(r)) {
550 case PCI_RES_BUS:
551 return (pci_domain_activate_bus(sc->ecam, child, r));
552 case SYS_RES_IOPORT:
553 case SYS_RES_MEMORY:
554 return (bus_generic_rman_activate_resource(dev, child, r));
555 default:
556 return (bus_generic_activate_resource(dev, child, r));
557 }
558 }
559
560 static int
generic_pcie_deactivate_resource(device_t dev,device_t child,struct resource * r)561 generic_pcie_deactivate_resource(device_t dev, device_t child,
562 struct resource *r)
563 {
564 struct generic_pcie_core_softc *sc;
565
566 sc = device_get_softc(dev);
567 switch (rman_get_type(r)) {
568 case PCI_RES_BUS:
569 return (pci_domain_deactivate_bus(sc->ecam, child, r));
570 case SYS_RES_IOPORT:
571 case SYS_RES_MEMORY:
572 return (bus_generic_rman_deactivate_resource(dev, child, r));
573 default:
574 return (bus_generic_deactivate_resource(dev, child, r));
575 }
576 }
577
578 static int
generic_pcie_adjust_resource(device_t dev,device_t child,struct resource * res,rman_res_t start,rman_res_t end)579 generic_pcie_adjust_resource(device_t dev, device_t child,
580 struct resource *res, rman_res_t start, rman_res_t end)
581 {
582 struct generic_pcie_core_softc *sc;
583
584 sc = device_get_softc(dev);
585 switch (rman_get_type(res)) {
586 case PCI_RES_BUS:
587 return (pci_domain_adjust_bus(sc->ecam, child, res, start,
588 end));
589 case SYS_RES_IOPORT:
590 case SYS_RES_MEMORY:
591 return (bus_generic_rman_adjust_resource(dev, child, res,
592 start, end));
593 default:
594 return (bus_generic_adjust_resource(dev, child, res, start,
595 end));
596 }
597 }
598
599 static int
generic_pcie_map_resource(device_t dev,device_t child,struct resource * r,struct resource_map_request * argsp,struct resource_map * map)600 generic_pcie_map_resource(device_t dev, device_t child, struct resource *r,
601 struct resource_map_request *argsp, struct resource_map *map)
602 {
603 struct resource_map_request args;
604 struct pcie_range *range;
605 rman_res_t length, start;
606 int error, type;
607
608 type = rman_get_type(r);
609 switch (type) {
610 case PCI_RES_BUS:
611 return (EINVAL);
612 case SYS_RES_IOPORT:
613 case SYS_RES_MEMORY:
614 break;
615 default:
616 return (bus_generic_map_resource(dev, child, r, argsp, map));
617 }
618
619 /* Resources must be active to be mapped. */
620 if (!(rman_get_flags(r) & RF_ACTIVE))
621 return (ENXIO);
622
623 resource_init_map_request(&args);
624 error = resource_validate_map_request(r, argsp, &args, &start, &length);
625 if (error)
626 return (error);
627
628 range = generic_pcie_containing_range(dev, type, rman_get_start(r),
629 rman_get_end(r));
630 if (range == NULL || range->res == NULL)
631 return (ENOENT);
632
633 args.offset = start - range->pci_base;
634 args.length = length;
635 return (bus_map_resource(dev, range->res, &args, map));
636 }
637
638 static int
generic_pcie_unmap_resource(device_t dev,device_t child,struct resource * r,struct resource_map * map)639 generic_pcie_unmap_resource(device_t dev, device_t child, struct resource *r,
640 struct resource_map *map)
641 {
642 struct pcie_range *range;
643 int type;
644
645 type = rman_get_type(r);
646 switch (type) {
647 case PCI_RES_BUS:
648 return (EINVAL);
649 case SYS_RES_IOPORT:
650 case SYS_RES_MEMORY:
651 break;
652 default:
653 return (bus_generic_unmap_resource(dev, child, r, map));
654 }
655
656 range = generic_pcie_containing_range(dev, type, rman_get_start(r),
657 rman_get_end(r));
658 if (range == NULL || range->res == NULL)
659 return (ENOENT);
660 return (bus_unmap_resource(dev, range->res, map));
661 }
662
663 static bus_dma_tag_t
generic_pcie_get_dma_tag(device_t dev,device_t child)664 generic_pcie_get_dma_tag(device_t dev, device_t child)
665 {
666 struct generic_pcie_core_softc *sc;
667
668 sc = device_get_softc(dev);
669 return (sc->dmat);
670 }
671
672 static device_method_t generic_pcie_methods[] = {
673 DEVMETHOD(device_attach, pci_host_generic_core_attach),
674 DEVMETHOD(device_detach, pci_host_generic_core_detach),
675
676 DEVMETHOD(bus_get_rman, generic_pcie_get_rman),
677 DEVMETHOD(bus_read_ivar, generic_pcie_read_ivar),
678 DEVMETHOD(bus_write_ivar, generic_pcie_write_ivar),
679 DEVMETHOD(bus_alloc_resource, pci_host_generic_core_alloc_resource),
680 DEVMETHOD(bus_adjust_resource, generic_pcie_adjust_resource),
681 DEVMETHOD(bus_activate_resource, generic_pcie_activate_resource),
682 DEVMETHOD(bus_deactivate_resource, generic_pcie_deactivate_resource),
683 DEVMETHOD(bus_release_resource, pci_host_generic_core_release_resource),
684 DEVMETHOD(bus_translate_resource, generic_pcie_translate_resource),
685 DEVMETHOD(bus_map_resource, generic_pcie_map_resource),
686 DEVMETHOD(bus_unmap_resource, generic_pcie_unmap_resource),
687 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
688 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
689
690 DEVMETHOD(bus_get_dma_tag, generic_pcie_get_dma_tag),
691
692 /* pcib interface */
693 DEVMETHOD(pcib_maxslots, generic_pcie_maxslots),
694 DEVMETHOD(pcib_read_config, generic_pcie_read_config),
695 DEVMETHOD(pcib_write_config, generic_pcie_write_config),
696
697 DEVMETHOD_END
698 };
699
700 DEFINE_CLASS_0(pcib, generic_pcie_core_driver,
701 generic_pcie_methods, sizeof(struct generic_pcie_core_softc));
702