2 * Copyright (c) 2015 Ruslan Bukin <br@bsdpad.com>
3 * Copyright (c) 2014 The FreeBSD Foundation
6 * This software was developed by Semihalf under
7 * the sponsorship of the FreeBSD Foundation.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
31 /* Generic ECAM PCIe driver */
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
36 #include "opt_platform.h"
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/malloc.h>
41 #include <sys/kernel.h>
43 #include <sys/module.h>
45 #include <sys/endian.h>
46 #include <sys/cpuset.h>
47 #include <sys/rwlock.h>
50 #include <machine/intr.h>
53 #include <dev/ofw/openfirm.h>
54 #include <dev/ofw/ofw_bus.h>
55 #include <dev/ofw/ofw_bus_subr.h>
56 #include <dev/ofw/ofw_pci.h>
57 #include <dev/pci/pcivar.h>
58 #include <dev/pci/pcireg.h>
59 #include <dev/pci/pcib_private.h>
60 #include <dev/pci/pci_host_generic.h>
62 #include <machine/cpu.h>
63 #include <machine/bus.h>
64 #include <machine/intr.h>
65 #include <vm/vm_page.h>
69 /* Assembling ECAM Configuration Address */
70 #define PCIE_BUS_SHIFT 20
71 #define PCIE_SLOT_SHIFT 15
72 #define PCIE_FUNC_SHIFT 12
73 #define PCIE_BUS_MASK 0xFF
74 #define PCIE_SLOT_MASK 0x1F
75 #define PCIE_FUNC_MASK 0x07
76 #define PCIE_REG_MASK 0xFFF
78 #define PCIE_ADDR_OFFSET(bus, slot, func, reg) \
79 ((((bus) & PCIE_BUS_MASK) << PCIE_BUS_SHIFT) | \
80 (((slot) & PCIE_SLOT_MASK) << PCIE_SLOT_SHIFT) | \
81 (((func) & PCIE_FUNC_MASK) << PCIE_FUNC_SHIFT) | \
82 ((reg) & PCIE_REG_MASK))
84 #define PCI_IO_WINDOW_OFFSET 0x1000
86 #define SPACE_CODE_SHIFT 24
87 #define SPACE_CODE_MASK 0x3
88 #define SPACE_CODE_IO_SPACE 0x1
89 #define PROPS_CELL_SIZE 1
90 #define PCI_ADDR_CELL_SIZE 2
92 /* OFW bus interface */
93 struct generic_pcie_ofw_devinfo {
94 struct ofw_bus_devinfo di_dinfo;
95 struct resource_list di_rl;
98 /* Forward prototypes */
100 static int generic_pcie_probe(device_t dev);
101 static int parse_pci_mem_ranges(struct generic_pcie_softc *sc);
102 static uint32_t generic_pcie_read_config(device_t dev, u_int bus, u_int slot,
103 u_int func, u_int reg, int bytes);
104 static void generic_pcie_write_config(device_t dev, u_int bus, u_int slot,
105 u_int func, u_int reg, uint32_t val, int bytes);
106 static int generic_pcie_maxslots(device_t dev);
107 static int generic_pcie_read_ivar(device_t dev, device_t child, int index,
109 static int generic_pcie_write_ivar(device_t dev, device_t child, int index,
111 static struct resource *generic_pcie_alloc_resource_ofw(device_t, device_t,
112 int, int *, rman_res_t, rman_res_t, rman_res_t, u_int);
113 static struct resource *generic_pcie_alloc_resource_pcie(device_t dev,
114 device_t child, int type, int *rid, rman_res_t start, rman_res_t end,
115 rman_res_t count, u_int flags);
116 static int generic_pcie_release_resource(device_t dev, device_t child,
117 int type, int rid, struct resource *res);
118 static int generic_pcie_release_resource_ofw(device_t, device_t, int, int,
120 static int generic_pcie_release_resource_pcie(device_t, device_t, int, int,
122 static int generic_pcie_ofw_bus_attach(device_t);
123 static const struct ofw_bus_devinfo *generic_pcie_ofw_get_devinfo(device_t,
127 get_addr_size_cells(phandle_t node, pcell_t *addr_cells, pcell_t *size_cells)
131 /* Find address cells if present */
132 OF_getencprop(node, "#address-cells", addr_cells, sizeof(*addr_cells));
135 /* Find size cells if present */
136 OF_getencprop(node, "#size-cells", size_cells, sizeof(*size_cells));
140 generic_pcie_probe(device_t dev)
143 if (!ofw_bus_status_okay(dev))
146 if (ofw_bus_is_compatible(dev, "pci-host-ecam-generic")) {
147 device_set_desc(dev, "Generic PCI host controller");
148 return (BUS_PROBE_GENERIC);
150 if (ofw_bus_is_compatible(dev, "arm,gem5_pcie")) {
151 device_set_desc(dev, "GEM5 PCIe host controller");
152 return (BUS_PROBE_DEFAULT);
159 pci_host_generic_attach(device_t dev)
161 struct generic_pcie_softc *sc;
170 sc = device_get_softc(dev);
173 /* Retrieve 'ranges' property from FDT */
175 device_printf(dev, "parsing FDT for ECAM%d:\n",
177 if (parse_pci_mem_ranges(sc))
181 if (generic_pcie_ofw_bus_attach(dev) != 0)
185 sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
186 if (sc->res == NULL) {
187 device_printf(dev, "could not map memory.\n");
191 sc->bst = rman_get_bustag(sc->res);
192 sc->bsh = rman_get_bushandle(sc->res);
194 sc->mem_rman.rm_type = RMAN_ARRAY;
195 sc->mem_rman.rm_descr = "PCIe Memory";
196 sc->io_rman.rm_type = RMAN_ARRAY;
197 sc->io_rman.rm_descr = "PCIe IO window";
199 /* Initialize rman and allocate memory regions */
200 error = rman_init(&sc->mem_rman);
202 device_printf(dev, "rman_init() failed. error = %d\n", error);
206 error = rman_init(&sc->io_rman);
208 device_printf(dev, "rman_init() failed. error = %d\n", error);
212 for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) {
213 phys_base = sc->ranges[tuple].phys_base;
214 pci_base = sc->ranges[tuple].pci_base;
215 size = sc->ranges[tuple].size;
216 if (phys_base == 0 || size == 0)
217 continue; /* empty range element */
218 if (sc->ranges[tuple].flags & FLAG_MEM) {
219 error = rman_manage_region(&sc->mem_rman,
220 phys_base, phys_base + size - 1);
221 } else if (sc->ranges[tuple].flags & FLAG_IO) {
222 error = rman_manage_region(&sc->io_rman,
223 pci_base + PCI_IO_WINDOW_OFFSET,
224 pci_base + PCI_IO_WINDOW_OFFSET + size - 1);
228 device_printf(dev, "rman_manage_region() failed."
229 "error = %d\n", error);
230 rman_fini(&sc->mem_rman);
235 node = ofw_bus_get_node(dev);
236 ofw_bus_setup_iinfo(node, &sc->pci_iinfo, sizeof(cell_t));
238 /* Find the MSI interrupt handler */
239 OF_searchencprop(node, "msi-parent", &sc->msi_parent,
240 sizeof(sc->msi_parent));
242 device_add_child(dev, "pci", -1);
243 return (bus_generic_attach(dev));
247 parse_pci_mem_ranges(struct generic_pcie_softc *sc)
249 pcell_t pci_addr_cells, parent_addr_cells;
250 pcell_t attributes, size_cells;
257 node = ofw_bus_get_node(sc->dev);
259 OF_getencprop(node, "#address-cells", &pci_addr_cells,
260 sizeof(pci_addr_cells));
261 OF_getencprop(node, "#size-cells", &size_cells,
263 OF_getencprop(OF_parent(node), "#address-cells", &parent_addr_cells,
264 sizeof(parent_addr_cells));
266 if (parent_addr_cells != 2 || pci_addr_cells != 3 || size_cells != 2) {
267 device_printf(sc->dev,
268 "Unexpected number of address or size cells in FDT\n");
272 nbase_ranges = OF_getproplen(node, "ranges");
273 sc->nranges = nbase_ranges / sizeof(cell_t) /
274 (parent_addr_cells + pci_addr_cells + size_cells);
275 base_ranges = malloc(nbase_ranges, M_DEVBUF, M_WAITOK);
276 OF_getencprop(node, "ranges", base_ranges, nbase_ranges);
278 for (i = 0, j = 0; i < sc->nranges; i++) {
279 attributes = (base_ranges[j++] >> SPACE_CODE_SHIFT) & \
281 if (attributes == SPACE_CODE_IO_SPACE) {
282 sc->ranges[i].flags |= FLAG_IO;
284 sc->ranges[i].flags |= FLAG_MEM;
287 sc->ranges[i].pci_base = 0;
288 for (k = 0; k < (pci_addr_cells - 1); k++) {
289 sc->ranges[i].pci_base <<= 32;
290 sc->ranges[i].pci_base |= base_ranges[j++];
292 sc->ranges[i].phys_base = 0;
293 for (k = 0; k < parent_addr_cells; k++) {
294 sc->ranges[i].phys_base <<= 32;
295 sc->ranges[i].phys_base |= base_ranges[j++];
297 sc->ranges[i].size = 0;
298 for (k = 0; k < size_cells; k++) {
299 sc->ranges[i].size <<= 32;
300 sc->ranges[i].size |= base_ranges[j++];
304 for (; i < MAX_RANGES_TUPLES; i++) {
305 /* zero-fill remaining tuples to mark empty elements in array */
306 sc->ranges[i].pci_base = 0;
307 sc->ranges[i].phys_base = 0;
308 sc->ranges[i].size = 0;
312 for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) {
313 device_printf(sc->dev,
314 "\tPCI addr: 0x%jx, CPU addr: 0x%jx, Size: 0x%jx\n",
315 sc->ranges[tuple].pci_base,
316 sc->ranges[tuple].phys_base,
317 sc->ranges[tuple].size);
321 free(base_ranges, M_DEVBUF);
326 generic_pcie_read_config(device_t dev, u_int bus, u_int slot,
327 u_int func, u_int reg, int bytes)
329 struct generic_pcie_softc *sc;
330 bus_space_handle_t h;
335 if ((bus > PCI_BUSMAX) || (slot > PCI_SLOTMAX) ||
336 (func > PCI_FUNCMAX) || (reg > PCIE_REGMAX))
339 sc = device_get_softc(dev);
341 offset = PCIE_ADDR_OFFSET(bus, slot, func, reg);
347 data = bus_space_read_1(t, h, offset);
350 data = le16toh(bus_space_read_2(t, h, offset));
353 data = le32toh(bus_space_read_4(t, h, offset));
363 generic_pcie_write_config(device_t dev, u_int bus, u_int slot,
364 u_int func, u_int reg, uint32_t val, int bytes)
366 struct generic_pcie_softc *sc;
367 bus_space_handle_t h;
371 if ((bus > PCI_BUSMAX) || (slot > PCI_SLOTMAX) ||
372 (func > PCI_FUNCMAX) || (reg > PCIE_REGMAX))
375 sc = device_get_softc(dev);
377 offset = PCIE_ADDR_OFFSET(bus, slot, func, reg);
384 bus_space_write_1(t, h, offset, val);
387 bus_space_write_2(t, h, offset, htole16(val));
390 bus_space_write_4(t, h, offset, htole32(val));
398 generic_pcie_maxslots(device_t dev)
401 return (31); /* max slots per bus acc. to standard */
405 generic_pcie_route_interrupt(device_t bus, device_t dev, int pin)
407 struct generic_pcie_softc *sc;
408 struct ofw_pci_register reg;
409 uint32_t pintr, mintr[2];
413 sc = device_get_softc(bus);
416 bzero(®, sizeof(reg));
417 reg.phys_hi = (pci_get_bus(dev) << OFW_PCI_PHYS_HI_BUSSHIFT) |
418 (pci_get_slot(dev) << OFW_PCI_PHYS_HI_DEVICESHIFT) |
419 (pci_get_function(dev) << OFW_PCI_PHYS_HI_FUNCTIONSHIFT);
421 intrcells = ofw_bus_lookup_imap(ofw_bus_get_node(dev),
422 &sc->pci_iinfo, ®, sizeof(reg), &pintr, sizeof(pintr),
423 mintr, sizeof(mintr), &iparent);
425 pintr = ofw_bus_map_intr(dev, iparent, intrcells, mintr);
429 device_printf(bus, "could not route pin %d for device %d.%d\n",
430 pin, pci_get_slot(dev), pci_get_function(dev));
431 return (PCI_INVALID_IRQ);
436 generic_pcie_read_ivar(device_t dev, device_t child, int index,
439 struct generic_pcie_softc *sc;
442 sc = device_get_softc(dev);
444 if (index == PCIB_IVAR_BUS) {
445 /* this pcib adds only pci bus 0 as child */
447 *result = secondary_bus;
452 if (index == PCIB_IVAR_DOMAIN) {
458 device_printf(dev, "ERROR: Unknown index %d.\n", index);
463 generic_pcie_write_ivar(device_t dev, device_t child, int index,
471 generic_pcie_rman(struct generic_pcie_softc *sc, int type)
476 return (&sc->io_rman);
478 return (&sc->mem_rman);
487 generic_pcie_release_resource_pcie(device_t dev, device_t child, int type,
488 int rid, struct resource *res)
490 struct generic_pcie_softc *sc;
493 sc = device_get_softc(dev);
495 rm = generic_pcie_rman(sc, type);
497 KASSERT(rman_is_region_manager(res, rm), ("rman mismatch"));
498 rman_release_resource(res);
501 return (bus_generic_release_resource(dev, child, type, rid, res));
505 generic_pcie_release_resource(device_t dev, device_t child, int type,
506 int rid, struct resource *res)
509 /* For PCIe devices that do not have FDT nodes, use PCIB method */
510 if ((int)ofw_bus_get_node(child) <= 0) {
511 return (generic_pcie_release_resource_pcie(dev,
512 child, type, rid, res));
515 /* For other devices use OFW method */
516 return (generic_pcie_release_resource_ofw(dev,
517 child, type, rid, res));
521 pci_host_generic_alloc_resource(device_t dev, device_t child, int type, int *rid,
522 rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
525 /* For PCIe devices that do not have FDT nodes, use PCIB method */
526 if ((int)ofw_bus_get_node(child) <= 0)
527 return (generic_pcie_alloc_resource_pcie(dev, child, type, rid,
528 start, end, count, flags));
530 /* For other devices use OFW method */
531 return (generic_pcie_alloc_resource_ofw(dev, child, type, rid,
532 start, end, count, flags));
535 static struct resource *
536 generic_pcie_alloc_resource_pcie(device_t dev, device_t child, int type, int *rid,
537 rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
539 struct generic_pcie_softc *sc;
540 struct resource *res;
543 sc = device_get_softc(dev);
545 rm = generic_pcie_rman(sc, type);
547 return (BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
548 type, rid, start, end, count, flags));
552 "rman_reserve_resource: start=%#jx, end=%#jx, count=%#jx\n",
556 res = rman_reserve_resource(rm, start, end, count, flags, child);
560 rman_set_rid(res, *rid);
562 if (flags & RF_ACTIVE)
563 if (bus_activate_resource(child, type, *rid, res)) {
564 rman_release_resource(res);
571 device_printf(dev, "%s FAIL: type=%d, rid=%d, "
572 "start=%016jx, end=%016jx, count=%016jx, flags=%x\n",
573 __func__, type, *rid, start, end, count, flags);
579 generic_pcie_adjust_resource(device_t dev, device_t child, int type,
580 struct resource *res, rman_res_t start, rman_res_t end)
582 struct generic_pcie_softc *sc;
585 sc = device_get_softc(dev);
587 rm = generic_pcie_rman(sc, type);
589 return (rman_adjust_resource(res, start, end));
590 return (bus_generic_adjust_resource(dev, child, type, res, start, end));
594 generic_pcie_activate_resource(device_t dev, device_t child, int type, int rid,
597 struct generic_pcie_softc *sc;
605 sc = device_get_softc(dev);
607 if ((res = rman_activate_resource(r)) != 0)
613 for (i = 0; i < MAX_RANGES_TUPLES; i++) {
614 pci_base = sc->ranges[i].pci_base;
615 phys_base = sc->ranges[i].phys_base;
616 size = sc->ranges[i].size;
618 if ((rid > pci_base) && (rid < (pci_base + size))) {
624 rman_set_start(r, rman_get_start(r) + phys_base);
625 rman_set_end(r, rman_get_end(r) + phys_base);
626 BUS_ACTIVATE_RESOURCE(device_get_parent(dev), child,
629 device_printf(dev, "Failed to activate IOPORT resource\n");
634 BUS_ACTIVATE_RESOURCE(device_get_parent(dev), child, type, rid, r);
644 generic_pcie_deactivate_resource(device_t dev, device_t child, int type, int rid,
647 struct generic_pcie_softc *sc;
651 sc = device_get_softc(dev);
653 if ((res = rman_deactivate_resource(r)) != 0)
659 vaddr = (vm_offset_t)rman_get_virtual(r);
660 pmap_unmapdev(vaddr, rman_get_size(r));
670 generic_pcie_alloc_msi(device_t pci, device_t child, int count, int maxcount,
674 struct generic_pcie_softc *sc;
676 sc = device_get_softc(pci);
677 return (intr_alloc_msi(pci, child, sc->msi_parent, count, maxcount,
679 #elif defined(__aarch64__)
680 return (arm_alloc_msi(pci, child, count, maxcount, irqs));
687 generic_pcie_release_msi(device_t pci, device_t child, int count, int *irqs)
690 struct generic_pcie_softc *sc;
692 sc = device_get_softc(pci);
693 return (intr_release_msi(pci, child, sc->msi_parent, count, irqs));
694 #elif defined(__aarch64__)
695 return (arm_release_msi(pci, child, count, irqs));
702 generic_pcie_map_msi(device_t pci, device_t child, int irq, uint64_t *addr,
706 struct generic_pcie_softc *sc;
708 sc = device_get_softc(pci);
709 return (intr_map_msi(pci, child, sc->msi_parent, irq, addr, data));
710 #elif defined(__aarch64__)
711 return (arm_map_msi(pci, child, irq, addr, data));
718 generic_pcie_alloc_msix(device_t pci, device_t child, int *irq)
721 struct generic_pcie_softc *sc;
723 sc = device_get_softc(pci);
724 return (intr_alloc_msix(pci, child, sc->msi_parent, irq));
725 #elif defined(__aarch64__)
726 return (arm_alloc_msix(pci, child, irq));
733 generic_pcie_release_msix(device_t pci, device_t child, int irq)
736 struct generic_pcie_softc *sc;
738 sc = device_get_softc(pci);
739 return (intr_release_msix(pci, child, sc->msi_parent, irq));
740 #elif defined(__aarch64__)
741 return (arm_release_msix(pci, child, irq));
747 static device_method_t generic_pcie_methods[] = {
748 DEVMETHOD(device_probe, generic_pcie_probe),
749 DEVMETHOD(device_attach, pci_host_generic_attach),
750 DEVMETHOD(bus_read_ivar, generic_pcie_read_ivar),
751 DEVMETHOD(bus_write_ivar, generic_pcie_write_ivar),
752 DEVMETHOD(bus_alloc_resource, pci_host_generic_alloc_resource),
753 DEVMETHOD(bus_adjust_resource, generic_pcie_adjust_resource),
754 DEVMETHOD(bus_release_resource, generic_pcie_release_resource),
755 DEVMETHOD(bus_activate_resource, generic_pcie_activate_resource),
756 DEVMETHOD(bus_deactivate_resource, generic_pcie_deactivate_resource),
757 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
758 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
761 DEVMETHOD(pcib_maxslots, generic_pcie_maxslots),
762 DEVMETHOD(pcib_route_interrupt, generic_pcie_route_interrupt),
763 DEVMETHOD(pcib_read_config, generic_pcie_read_config),
764 DEVMETHOD(pcib_write_config, generic_pcie_write_config),
765 DEVMETHOD(pcib_alloc_msi, generic_pcie_alloc_msi),
766 DEVMETHOD(pcib_release_msi, generic_pcie_release_msi),
767 DEVMETHOD(pcib_alloc_msix, generic_pcie_alloc_msix),
768 DEVMETHOD(pcib_release_msix, generic_pcie_release_msix),
769 DEVMETHOD(pcib_map_msi, generic_pcie_map_msi),
771 /* ofw_bus interface */
772 DEVMETHOD(ofw_bus_get_devinfo, generic_pcie_ofw_get_devinfo),
773 DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat),
774 DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model),
775 DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name),
776 DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node),
777 DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type),
782 static const struct ofw_bus_devinfo *
783 generic_pcie_ofw_get_devinfo(device_t bus __unused, device_t child)
785 struct generic_pcie_ofw_devinfo *di;
787 di = device_get_ivars(child);
788 return (&di->di_dinfo);
791 static struct resource *
792 generic_pcie_alloc_resource_ofw(device_t bus, device_t child, int type, int *rid,
793 rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
795 struct generic_pcie_softc *sc;
796 struct generic_pcie_ofw_devinfo *di;
797 struct resource_list_entry *rle;
800 sc = device_get_softc(bus);
802 if (RMAN_IS_DEFAULT_RANGE(start, end)) {
803 if ((di = device_get_ivars(child)) == NULL)
805 if (type == SYS_RES_IOPORT)
806 type = SYS_RES_MEMORY;
808 /* Find defaults for this rid */
809 rle = resource_list_find(&di->di_rl, type, *rid);
818 if (type == SYS_RES_MEMORY) {
819 /* Remap through ranges property */
820 for (i = 0; i < MAX_RANGES_TUPLES; i++) {
821 if (start >= sc->ranges[i].phys_base && end <
822 sc->ranges[i].pci_base + sc->ranges[i].size) {
823 start -= sc->ranges[i].phys_base;
824 start += sc->ranges[i].pci_base;
825 end -= sc->ranges[i].phys_base;
826 end += sc->ranges[i].pci_base;
831 if (i == MAX_RANGES_TUPLES) {
832 device_printf(bus, "Could not map resource "
833 "%#jx-%#jx\n", start, end);
838 return (bus_generic_alloc_resource(bus, child, type, rid, start, end,
843 generic_pcie_release_resource_ofw(device_t bus, device_t child, int type, int rid,
844 struct resource *res)
847 return (bus_generic_release_resource(bus, child, type, rid, res));
850 /* Helper functions */
853 generic_pcie_ofw_bus_attach(device_t dev)
855 struct generic_pcie_ofw_devinfo *di;
857 phandle_t parent, node;
858 pcell_t addr_cells, size_cells;
860 parent = ofw_bus_get_node(dev);
862 get_addr_size_cells(parent, &addr_cells, &size_cells);
863 /* Iterate through all bus subordinates */
864 for (node = OF_child(parent); node > 0; node = OF_peer(node)) {
866 /* Allocate and populate devinfo. */
867 di = malloc(sizeof(*di), M_DEVBUF, M_WAITOK | M_ZERO);
868 if (ofw_bus_gen_setup_devinfo(&di->di_dinfo, node) != 0) {
873 /* Initialize and populate resource list. */
874 resource_list_init(&di->di_rl);
875 ofw_bus_reg_to_rl(dev, node, addr_cells, size_cells,
877 ofw_bus_intr_to_rl(dev, node, &di->di_rl, NULL);
879 /* Add newbus device for this FDT node */
880 child = device_add_child(dev, NULL, -1);
882 resource_list_free(&di->di_rl);
883 ofw_bus_gen_destroy_devinfo(&di->di_dinfo);
888 device_set_ivars(child, di);
895 DEFINE_CLASS_0(pcib, generic_pcie_driver,
896 generic_pcie_methods, sizeof(struct generic_pcie_softc));
898 devclass_t generic_pcie_devclass;
900 DRIVER_MODULE(pcib, simplebus, generic_pcie_driver,
901 generic_pcie_devclass, 0, 0);
902 DRIVER_MODULE(pcib, ofwbus, generic_pcie_driver,
903 generic_pcie_devclass, 0, 0);