xref: /freebsd/sys/dev/pci/pci_host_generic.c (revision 80a87461087caa71c74d891c5b7cddf0156ad58a)
1 /*-
2  * Copyright (c) 2015 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 __FBSDID("$FreeBSD$");
35 
36 #include "opt_platform.h"
37 
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/malloc.h>
41 #include <sys/kernel.h>
42 #include <sys/rman.h>
43 #include <sys/module.h>
44 #include <sys/bus.h>
45 #include <sys/endian.h>
46 #include <sys/cpuset.h>
47 #include <sys/rwlock.h>
48 
49 #include <dev/ofw/openfirm.h>
50 #include <dev/ofw/ofw_bus.h>
51 #include <dev/ofw/ofw_bus_subr.h>
52 #include <dev/ofw/ofw_pci.h>
53 #include <dev/pci/pcivar.h>
54 #include <dev/pci/pcireg.h>
55 #include <dev/pci/pcib_private.h>
56 #include <dev/pci/pci_host_generic.h>
57 
58 #include <machine/cpu.h>
59 #include <machine/bus.h>
60 #include <machine/intr.h>
61 #include <vm/vm_page.h>
62 
63 #include "pcib_if.h"
64 
65 /* Assembling ECAM Configuration Address */
66 #define	PCIE_BUS_SHIFT		20
67 #define	PCIE_SLOT_SHIFT		15
68 #define	PCIE_FUNC_SHIFT		12
69 #define	PCIE_BUS_MASK		0xFF
70 #define	PCIE_SLOT_MASK		0x1F
71 #define	PCIE_FUNC_MASK		0x07
72 #define	PCIE_REG_MASK		0xFFF
73 
74 #define	PCIE_ADDR_OFFSET(bus, slot, func, reg)			\
75 	((((bus) & PCIE_BUS_MASK) << PCIE_BUS_SHIFT)	|	\
76 	(((slot) & PCIE_SLOT_MASK) << PCIE_SLOT_SHIFT)	|	\
77 	(((func) & PCIE_FUNC_MASK) << PCIE_FUNC_SHIFT)	|	\
78 	((reg) & PCIE_REG_MASK))
79 
80 #define	PCI_IO_WINDOW_OFFSET	0x1000
81 
82 #define	SPACE_CODE_SHIFT	24
83 #define	SPACE_CODE_MASK		0x3
84 #define	SPACE_CODE_IO_SPACE	0x1
85 #define	PROPS_CELL_SIZE		1
86 #define	PCI_ADDR_CELL_SIZE	2
87 
88 /* OFW bus interface */
89 struct generic_pcie_ofw_devinfo {
90 	struct ofw_bus_devinfo	di_dinfo;
91 	struct resource_list	di_rl;
92 };
93 
94 /* Forward prototypes */
95 
96 static int generic_pcie_probe(device_t dev);
97 static int parse_pci_mem_ranges(struct generic_pcie_softc *sc);
98 static uint32_t generic_pcie_read_config(device_t dev, u_int bus, u_int slot,
99     u_int func, u_int reg, int bytes);
100 static void generic_pcie_write_config(device_t dev, u_int bus, u_int slot,
101     u_int func, u_int reg, uint32_t val, int bytes);
102 static int generic_pcie_maxslots(device_t dev);
103 static int generic_pcie_read_ivar(device_t dev, device_t child, int index,
104     uintptr_t *result);
105 static int generic_pcie_write_ivar(device_t dev, device_t child, int index,
106     uintptr_t value);
107 static struct resource *generic_pcie_alloc_resource_ofw(device_t, device_t,
108     int, int *, rman_res_t, rman_res_t, rman_res_t, u_int);
109 static struct resource *generic_pcie_alloc_resource_pcie(device_t dev,
110     device_t child, int type, int *rid, rman_res_t start, rman_res_t end,
111     rman_res_t count, u_int flags);
112 static int generic_pcie_release_resource(device_t dev, device_t child,
113     int type, int rid, struct resource *res);
114 static int generic_pcie_release_resource_ofw(device_t, device_t, int, int,
115     struct resource *);
116 static int generic_pcie_release_resource_pcie(device_t, device_t, int, int,
117     struct resource *);
118 static int generic_pcie_ofw_bus_attach(device_t);
119 static const struct ofw_bus_devinfo *generic_pcie_ofw_get_devinfo(device_t,
120     device_t);
121 
122 static __inline void
123 get_addr_size_cells(phandle_t node, pcell_t *addr_cells, pcell_t *size_cells)
124 {
125 
126 	*addr_cells = 2;
127 	/* Find address cells if present */
128 	OF_getencprop(node, "#address-cells", addr_cells, sizeof(*addr_cells));
129 
130 	*size_cells = 2;
131 	/* Find size cells if present */
132 	OF_getencprop(node, "#size-cells", size_cells, sizeof(*size_cells));
133 }
134 
135 static int
136 generic_pcie_probe(device_t dev)
137 {
138 
139 	if (!ofw_bus_status_okay(dev))
140 		return (ENXIO);
141 
142 	if (ofw_bus_is_compatible(dev, "pci-host-ecam-generic")) {
143 		device_set_desc(dev, "Generic PCI host controller");
144 		return (BUS_PROBE_GENERIC);
145 	}
146 
147 	return (ENXIO);
148 }
149 
150 int
151 pci_host_generic_attach(device_t dev)
152 {
153 	struct generic_pcie_softc *sc;
154 	uint64_t phys_base;
155 	uint64_t pci_base;
156 	uint64_t size;
157 	int error;
158 	int tuple;
159 	int rid;
160 
161 	sc = device_get_softc(dev);
162 	sc->dev = dev;
163 
164 	/* Retrieve 'ranges' property from FDT */
165 	if (bootverbose)
166 		device_printf(dev, "parsing FDT for ECAM%d:\n",
167 		    sc->ecam);
168 	if (parse_pci_mem_ranges(sc))
169 		return (ENXIO);
170 
171 	/* Attach OFW bus */
172 	if (generic_pcie_ofw_bus_attach(dev) != 0)
173 		return (ENXIO);
174 
175 	rid = 0;
176 	sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
177 	if (sc->res == NULL) {
178 		device_printf(dev, "could not map memory.\n");
179 		return (ENXIO);
180 	}
181 
182 	sc->bst = rman_get_bustag(sc->res);
183 	sc->bsh = rman_get_bushandle(sc->res);
184 
185 	sc->mem_rman.rm_type = RMAN_ARRAY;
186 	sc->mem_rman.rm_descr = "PCIe Memory";
187 	sc->io_rman.rm_type = RMAN_ARRAY;
188 	sc->io_rman.rm_descr = "PCIe IO window";
189 
190 	/* Initialize rman and allocate memory regions */
191 	error = rman_init(&sc->mem_rman);
192 	if (error) {
193 		device_printf(dev, "rman_init() failed. error = %d\n", error);
194 		return (error);
195 	}
196 
197 	error = rman_init(&sc->io_rman);
198 	if (error) {
199 		device_printf(dev, "rman_init() failed. error = %d\n", error);
200 		return (error);
201 	}
202 
203 	for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) {
204 		phys_base = sc->ranges[tuple].phys_base;
205 		pci_base = sc->ranges[tuple].pci_base;
206 		size = sc->ranges[tuple].size;
207 		if (phys_base == 0 || size == 0)
208 			continue; /* empty range element */
209 		if (sc->ranges[tuple].flags & FLAG_MEM) {
210 			error = rman_manage_region(&sc->mem_rman,
211 						phys_base,
212 						phys_base + size);
213 		} else if (sc->ranges[tuple].flags & FLAG_IO) {
214 			error = rman_manage_region(&sc->io_rman,
215 					pci_base + PCI_IO_WINDOW_OFFSET,
216 					pci_base + PCI_IO_WINDOW_OFFSET + size);
217 		} else
218 			continue;
219 		if (error) {
220 			device_printf(dev, "rman_manage_region() failed."
221 						"error = %d\n", error);
222 			rman_fini(&sc->mem_rman);
223 			return (error);
224 		}
225 	}
226 
227 	ofw_bus_setup_iinfo(ofw_bus_get_node(dev), &sc->pci_iinfo,
228 	    sizeof(cell_t));
229 
230 	device_add_child(dev, "pci", -1);
231 	return (bus_generic_attach(dev));
232 }
233 
234 static int
235 parse_pci_mem_ranges(struct generic_pcie_softc *sc)
236 {
237 	pcell_t pci_addr_cells, parent_addr_cells;
238 	pcell_t attributes, size_cells;
239 	cell_t *base_ranges;
240 	int nbase_ranges;
241 	phandle_t node;
242 	int i, j, k;
243 	int tuple;
244 
245 	node = ofw_bus_get_node(sc->dev);
246 
247 	OF_getencprop(node, "#address-cells", &pci_addr_cells,
248 					sizeof(pci_addr_cells));
249 	OF_getencprop(node, "#size-cells", &size_cells,
250 					sizeof(size_cells));
251 	OF_getencprop(OF_parent(node), "#address-cells", &parent_addr_cells,
252 					sizeof(parent_addr_cells));
253 
254 	if (parent_addr_cells != 2 || pci_addr_cells != 3 || size_cells != 2) {
255 		device_printf(sc->dev,
256 		    "Unexpected number of address or size cells in FDT\n");
257 		return (ENXIO);
258 	}
259 
260 	nbase_ranges = OF_getproplen(node, "ranges");
261 	sc->nranges = nbase_ranges / sizeof(cell_t) /
262 	    (parent_addr_cells + pci_addr_cells + size_cells);
263 	base_ranges = malloc(nbase_ranges, M_DEVBUF, M_WAITOK);
264 	OF_getencprop(node, "ranges", base_ranges, nbase_ranges);
265 
266 	for (i = 0, j = 0; i < sc->nranges; i++) {
267 		attributes = (base_ranges[j++] >> SPACE_CODE_SHIFT) & \
268 							SPACE_CODE_MASK;
269 		if (attributes == SPACE_CODE_IO_SPACE) {
270 			sc->ranges[i].flags |= FLAG_IO;
271 		} else {
272 			sc->ranges[i].flags |= FLAG_MEM;
273 		}
274 
275 		sc->ranges[i].pci_base = 0;
276 		for (k = 0; k < (pci_addr_cells - 1); k++) {
277 			sc->ranges[i].pci_base <<= 32;
278 			sc->ranges[i].pci_base |= base_ranges[j++];
279 		}
280 		sc->ranges[i].phys_base = 0;
281 		for (k = 0; k < parent_addr_cells; k++) {
282 			sc->ranges[i].phys_base <<= 32;
283 			sc->ranges[i].phys_base |= base_ranges[j++];
284 		}
285 		sc->ranges[i].size = 0;
286 		for (k = 0; k < size_cells; k++) {
287 			sc->ranges[i].size <<= 32;
288 			sc->ranges[i].size |= base_ranges[j++];
289 		}
290 	}
291 
292 	for (; i < MAX_RANGES_TUPLES; i++) {
293 		/* zero-fill remaining tuples to mark empty elements in array */
294 		sc->ranges[i].pci_base = 0;
295 		sc->ranges[i].phys_base = 0;
296 		sc->ranges[i].size = 0;
297 	}
298 
299 	if (bootverbose) {
300 		for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) {
301 			device_printf(sc->dev,
302 			    "\tPCI addr: 0x%jx, CPU addr: 0x%jx, Size: 0x%jx\n",
303 			    sc->ranges[tuple].pci_base,
304 			    sc->ranges[tuple].phys_base,
305 			    sc->ranges[tuple].size);
306 		}
307 	}
308 
309 	free(base_ranges, M_DEVBUF);
310 	return (0);
311 }
312 
313 static uint32_t
314 generic_pcie_read_config(device_t dev, u_int bus, u_int slot,
315     u_int func, u_int reg, int bytes)
316 {
317 	struct generic_pcie_softc *sc;
318 	bus_space_handle_t h;
319 	bus_space_tag_t	t;
320 	uint64_t offset;
321 	uint32_t data;
322 
323 	if ((bus > PCI_BUSMAX) || (slot > PCI_SLOTMAX) ||
324 	    (func > PCI_FUNCMAX) || (reg > PCIE_REGMAX))
325 		return (~0U);
326 
327 	sc = device_get_softc(dev);
328 
329 	offset = PCIE_ADDR_OFFSET(bus, slot, func, reg);
330 	t = sc->bst;
331 	h = sc->bsh;
332 
333 	switch (bytes) {
334 	case 1:
335 		data = bus_space_read_1(t, h, offset);
336 		break;
337 	case 2:
338 		data = le16toh(bus_space_read_2(t, h, offset));
339 		break;
340 	case 4:
341 		data = le32toh(bus_space_read_4(t, h, offset));
342 		break;
343 	default:
344 		return (~0U);
345 	}
346 
347 	return (data);
348 }
349 
350 static void
351 generic_pcie_write_config(device_t dev, u_int bus, u_int slot,
352     u_int func, u_int reg, uint32_t val, int bytes)
353 {
354 	struct generic_pcie_softc *sc;
355 	bus_space_handle_t h;
356 	bus_space_tag_t t;
357 	uint64_t offset;
358 
359 	if ((bus > PCI_BUSMAX) || (slot > PCI_SLOTMAX) ||
360 	    (func > PCI_FUNCMAX) || (reg > PCIE_REGMAX))
361 		return;
362 
363 	sc = device_get_softc(dev);
364 
365 	offset = PCIE_ADDR_OFFSET(bus, slot, func, reg);
366 
367 	t = sc->bst;
368 	h = sc->bsh;
369 
370 	switch (bytes) {
371 	case 1:
372 		bus_space_write_1(t, h, offset, val);
373 		break;
374 	case 2:
375 		bus_space_write_2(t, h, offset, htole16(val));
376 		break;
377 	case 4:
378 		bus_space_write_4(t, h, offset, htole32(val));
379 		break;
380 	default:
381 		return;
382 	}
383 }
384 
385 static int
386 generic_pcie_maxslots(device_t dev)
387 {
388 
389 	return (31); /* max slots per bus acc. to standard */
390 }
391 
392 static int
393 generic_pcie_route_interrupt(device_t bus, device_t dev, int pin)
394 {
395 	struct generic_pcie_softc *sc;
396 	struct ofw_pci_register reg;
397 	uint32_t pintr, mintr[2];
398 	phandle_t iparent;
399 	int intrcells;
400 
401 	sc = device_get_softc(bus);
402 	pintr = pin;
403 
404 	bzero(&reg, sizeof(reg));
405 	reg.phys_hi = (pci_get_bus(dev) << OFW_PCI_PHYS_HI_BUSSHIFT) |
406 	    (pci_get_slot(dev) << OFW_PCI_PHYS_HI_DEVICESHIFT) |
407 	    (pci_get_function(dev) << OFW_PCI_PHYS_HI_FUNCTIONSHIFT);
408 
409 	intrcells = ofw_bus_lookup_imap(ofw_bus_get_node(dev),
410 	    &sc->pci_iinfo, &reg, sizeof(reg), &pintr, sizeof(pintr),
411 	    mintr, sizeof(mintr), &iparent);
412 	if (intrcells) {
413 		pintr = ofw_bus_map_intr(dev, iparent, intrcells, mintr);
414 		return (pintr);
415 	}
416 
417 	device_printf(bus, "could not route pin %d for device %d.%d\n",
418 	    pin, pci_get_slot(dev), pci_get_function(dev));
419 	return (PCI_INVALID_IRQ);
420 }
421 
422 
423 static int
424 generic_pcie_read_ivar(device_t dev, device_t child, int index,
425     uintptr_t *result)
426 {
427 	struct generic_pcie_softc *sc;
428 	int secondary_bus;
429 
430 	sc = device_get_softc(dev);
431 
432 	if (index == PCIB_IVAR_BUS) {
433 		/* this pcib adds only pci bus 0 as child */
434 		secondary_bus = 0;
435 		*result = secondary_bus;
436 		return (0);
437 
438 	}
439 
440 	if (index == PCIB_IVAR_DOMAIN) {
441 		*result = sc->ecam;
442 		return (0);
443 	}
444 
445 	if (bootverbose)
446 		device_printf(dev, "ERROR: Unknown index %d.\n", index);
447 	return (ENOENT);
448 }
449 
450 static int
451 generic_pcie_write_ivar(device_t dev, device_t child, int index,
452     uintptr_t value)
453 {
454 
455 	return (ENOENT);
456 }
457 
458 static struct rman *
459 generic_pcie_rman(struct generic_pcie_softc *sc, int type)
460 {
461 
462 	switch (type) {
463 	case SYS_RES_IOPORT:
464 		return (&sc->io_rman);
465 	case SYS_RES_MEMORY:
466 		return (&sc->mem_rman);
467 	default:
468 		break;
469 	}
470 
471 	return (NULL);
472 }
473 
474 static int
475 generic_pcie_release_resource_pcie(device_t dev, device_t child, int type,
476     int rid, struct resource *res)
477 {
478 	struct generic_pcie_softc *sc;
479 	struct rman *rm;
480 
481 	sc = device_get_softc(dev);
482 
483 	rm = generic_pcie_rman(sc, type);
484 	if (rm != NULL) {
485 		KASSERT(rman_is_region_manager(res, rm), ("rman mismatch"));
486 		rman_release_resource(res);
487 	}
488 
489 	return (bus_generic_release_resource(dev, child, type, rid, res));
490 }
491 
492 static int
493 generic_pcie_release_resource(device_t dev, device_t child, int type,
494     int rid, struct resource *res)
495 {
496 
497 	/* For PCIe devices that do not have FDT nodes, use PCIB method */
498 	if ((int)ofw_bus_get_node(child) <= 0) {
499 		return (generic_pcie_release_resource_pcie(dev,
500 		    child, type, rid, res));
501 	}
502 
503 	/* For other devices use OFW method */
504 	return (generic_pcie_release_resource_ofw(dev,
505 	    child, type, rid, res));
506 }
507 
508 struct resource *
509 pci_host_generic_alloc_resource(device_t dev, device_t child, int type, int *rid,
510     rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
511 {
512 
513 	/* For PCIe devices that do not have FDT nodes, use PCIB method */
514 	if ((int)ofw_bus_get_node(child) <= 0)
515 		return (generic_pcie_alloc_resource_pcie(dev, child, type, rid,
516 		    start, end, count, flags));
517 
518 	/* For other devices use OFW method */
519 	return (generic_pcie_alloc_resource_ofw(dev, child, type, rid,
520 	    start, end, count, flags));
521 }
522 
523 static struct resource *
524 generic_pcie_alloc_resource_pcie(device_t dev, device_t child, int type, int *rid,
525     rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
526 {
527 	struct generic_pcie_softc *sc;
528 	struct resource *res;
529 	struct rman *rm;
530 
531 	sc = device_get_softc(dev);
532 
533 	rm = generic_pcie_rman(sc, type);
534 	if (rm == NULL)
535 		return (BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
536 		    type, rid, start, end, count, flags));
537 
538 	if (bootverbose) {
539 		device_printf(dev,
540 		    "rman_reserve_resource: start=%#lx, end=%#lx, count=%#lx\n",
541 		    start, end, count);
542 	}
543 
544 	res = rman_reserve_resource(rm, start, end, count, flags, child);
545 	if (res == NULL)
546 		goto fail;
547 
548 	rman_set_rid(res, *rid);
549 
550 	if (flags & RF_ACTIVE)
551 		if (bus_activate_resource(child, type, *rid, res)) {
552 			rman_release_resource(res);
553 			goto fail;
554 		}
555 
556 	return (res);
557 
558 fail:
559 	device_printf(dev, "%s FAIL: type=%d, rid=%d, "
560 	    "start=%016lx, end=%016lx, count=%016lx, flags=%x\n",
561 	    __func__, type, *rid, start, end, count, flags);
562 
563 	return (NULL);
564 }
565 
566 static int
567 generic_pcie_adjust_resource(device_t dev, device_t child, int type,
568     struct resource *res, rman_res_t start, rman_res_t end)
569 {
570 	struct generic_pcie_softc *sc;
571 	struct rman *rm;
572 
573 	sc = device_get_softc(dev);
574 
575 	rm = generic_pcie_rman(sc, type);
576 	if (rm != NULL)
577 		return (rman_adjust_resource(res, start, end));
578 	return (bus_generic_adjust_resource(dev, child, type, res, start, end));
579 }
580 
581 static int
582 generic_pcie_activate_resource(device_t dev, device_t child, int type, int rid,
583     struct resource *r)
584 {
585 	struct generic_pcie_softc *sc;
586 	uint64_t phys_base;
587 	uint64_t pci_base;
588 	uint64_t size;
589 	int found;
590 	int res;
591 	int i;
592 
593 	sc = device_get_softc(dev);
594 
595 	if ((res = rman_activate_resource(r)) != 0)
596 		return (res);
597 
598 	switch(type) {
599 	case SYS_RES_IOPORT:
600 		found = 0;
601 		for (i = 0; i < MAX_RANGES_TUPLES; i++) {
602 			pci_base = sc->ranges[i].pci_base;
603 			phys_base = sc->ranges[i].phys_base;
604 			size = sc->ranges[i].size;
605 
606 			if ((rid > pci_base) && (rid < (pci_base + size))) {
607 				found = 1;
608 				break;
609 			}
610 		}
611 		if (found) {
612 			rman_set_start(r, rman_get_start(r) + phys_base);
613 			BUS_ACTIVATE_RESOURCE(device_get_parent(dev), child,
614 						type, rid, r);
615 		} else {
616 			device_printf(dev, "Failed to activate IOPORT resource\n");
617 			res = 0;
618 		}
619 		break;
620 	case SYS_RES_MEMORY:
621 		BUS_ACTIVATE_RESOURCE(device_get_parent(dev), child, type, rid, r);
622 		break;
623 	default:
624 		break;
625 	}
626 
627 	return (res);
628 }
629 
630 static int
631 generic_pcie_deactivate_resource(device_t dev, device_t child, int type, int rid,
632     struct resource *r)
633 {
634 	struct generic_pcie_softc *sc;
635 	vm_offset_t vaddr;
636 	int res;
637 
638 	sc = device_get_softc(dev);
639 
640 	if ((res = rman_deactivate_resource(r)) != 0)
641 		return (res);
642 
643 	switch(type) {
644 	case SYS_RES_IOPORT:
645 	case SYS_RES_MEMORY:
646 		vaddr = (vm_offset_t)rman_get_virtual(r);
647 		pmap_unmapdev(vaddr, rman_get_size(r));
648 		break;
649 	default:
650 		break;
651 	}
652 
653 	return (res);
654 }
655 
656 static device_method_t generic_pcie_methods[] = {
657 	DEVMETHOD(device_probe,			generic_pcie_probe),
658 	DEVMETHOD(device_attach,		pci_host_generic_attach),
659 	DEVMETHOD(bus_read_ivar,		generic_pcie_read_ivar),
660 	DEVMETHOD(bus_write_ivar,		generic_pcie_write_ivar),
661 	DEVMETHOD(bus_alloc_resource,		pci_host_generic_alloc_resource),
662 	DEVMETHOD(bus_adjust_resource,		generic_pcie_adjust_resource),
663 	DEVMETHOD(bus_release_resource,		generic_pcie_release_resource),
664 	DEVMETHOD(bus_activate_resource,	generic_pcie_activate_resource),
665 	DEVMETHOD(bus_deactivate_resource,	generic_pcie_deactivate_resource),
666 	DEVMETHOD(bus_setup_intr,		bus_generic_setup_intr),
667 	DEVMETHOD(bus_teardown_intr,		bus_generic_teardown_intr),
668 
669 	/* pcib interface */
670 	DEVMETHOD(pcib_maxslots,		generic_pcie_maxslots),
671 	DEVMETHOD(pcib_route_interrupt,		generic_pcie_route_interrupt),
672 	DEVMETHOD(pcib_read_config,		generic_pcie_read_config),
673 	DEVMETHOD(pcib_write_config,		generic_pcie_write_config),
674 #if defined(__aarch64__)
675 	DEVMETHOD(pcib_alloc_msi,		arm_alloc_msi),
676 	DEVMETHOD(pcib_release_msi,		arm_release_msi),
677 	DEVMETHOD(pcib_alloc_msix,		arm_alloc_msix),
678 	DEVMETHOD(pcib_release_msix,		arm_release_msix),
679 	DEVMETHOD(pcib_map_msi,			arm_map_msi),
680 #endif
681 
682 	/* ofw_bus interface */
683 	DEVMETHOD(ofw_bus_get_devinfo,		generic_pcie_ofw_get_devinfo),
684 	DEVMETHOD(ofw_bus_get_compat,		ofw_bus_gen_get_compat),
685 	DEVMETHOD(ofw_bus_get_model,		ofw_bus_gen_get_model),
686 	DEVMETHOD(ofw_bus_get_name,		ofw_bus_gen_get_name),
687 	DEVMETHOD(ofw_bus_get_node,		ofw_bus_gen_get_node),
688 	DEVMETHOD(ofw_bus_get_type,		ofw_bus_gen_get_type),
689 
690 	DEVMETHOD_END
691 };
692 
693 static const struct ofw_bus_devinfo *
694 generic_pcie_ofw_get_devinfo(device_t bus __unused, device_t child)
695 {
696 	struct generic_pcie_ofw_devinfo *di;
697 
698 	di = device_get_ivars(child);
699 	return (&di->di_dinfo);
700 }
701 
702 static struct resource *
703 generic_pcie_alloc_resource_ofw(device_t bus, device_t child, int type, int *rid,
704     rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
705 {
706 	struct generic_pcie_softc *sc;
707 	struct generic_pcie_ofw_devinfo *di;
708 	struct resource_list_entry *rle;
709 	int i;
710 
711 	sc = device_get_softc(bus);
712 
713 	if ((start == 0UL) && (end == ~0UL)) {
714 		if ((di = device_get_ivars(child)) == NULL)
715 			return (NULL);
716 		if (type == SYS_RES_IOPORT)
717 		    type = SYS_RES_MEMORY;
718 
719 		/* Find defaults for this rid */
720 		rle = resource_list_find(&di->di_rl, type, *rid);
721 		if (rle == NULL)
722 			return (NULL);
723 
724 		start = rle->start;
725 		end = rle->end;
726 		count = rle->count;
727 	}
728 
729 	if (type == SYS_RES_MEMORY) {
730 		/* Remap through ranges property */
731 		for (i = 0; i < MAX_RANGES_TUPLES; i++) {
732 			if (start >= sc->ranges[i].phys_base && end <
733 			    sc->ranges[i].pci_base + sc->ranges[i].size) {
734 				start -= sc->ranges[i].phys_base;
735 				start += sc->ranges[i].pci_base;
736 				end -= sc->ranges[i].phys_base;
737 				end += sc->ranges[i].pci_base;
738 				break;
739 			}
740 		}
741 
742 		if (i == MAX_RANGES_TUPLES) {
743 			device_printf(bus, "Could not map resource "
744 			    "%#lx-%#lx\n", start, end);
745 			return (NULL);
746 		}
747 	}
748 
749 	return (bus_generic_alloc_resource(bus, child, type, rid, start, end,
750 	    count, flags));
751 }
752 
753 static int
754 generic_pcie_release_resource_ofw(device_t bus, device_t child, int type, int rid,
755     struct resource *res)
756 {
757 
758 	return (bus_generic_release_resource(bus, child, type, rid, res));
759 }
760 
761 /* Helper functions */
762 
763 static int
764 generic_pcie_ofw_bus_attach(device_t dev)
765 {
766 	struct generic_pcie_ofw_devinfo *di;
767 	device_t child;
768 	phandle_t parent, node;
769 	pcell_t addr_cells, size_cells;
770 
771 	parent = ofw_bus_get_node(dev);
772 	if (parent > 0) {
773 		get_addr_size_cells(parent, &addr_cells, &size_cells);
774 		/* Iterate through all bus subordinates */
775 		for (node = OF_child(parent); node > 0; node = OF_peer(node)) {
776 
777 			/* Allocate and populate devinfo. */
778 			di = malloc(sizeof(*di), M_DEVBUF, M_WAITOK | M_ZERO);
779 			if (ofw_bus_gen_setup_devinfo(&di->di_dinfo, node) != 0) {
780 				free(di, M_DEVBUF);
781 				continue;
782 			}
783 
784 			/* Initialize and populate resource list. */
785 			resource_list_init(&di->di_rl);
786 			ofw_bus_reg_to_rl(dev, node, addr_cells, size_cells,
787 			    &di->di_rl);
788 			ofw_bus_intr_to_rl(dev, node, &di->di_rl, NULL);
789 
790 			/* Add newbus device for this FDT node */
791 			child = device_add_child(dev, NULL, -1);
792 			if (child == NULL) {
793 				resource_list_free(&di->di_rl);
794 				ofw_bus_gen_destroy_devinfo(&di->di_dinfo);
795 				free(di, M_DEVBUF);
796 				continue;
797 			}
798 
799 			device_set_ivars(child, di);
800 		}
801 	}
802 
803 	return (0);
804 }
805 
806 DEFINE_CLASS_0(pcib, generic_pcie_driver,
807     generic_pcie_methods, sizeof(struct generic_pcie_softc));
808 
809 devclass_t generic_pcie_devclass;
810 
811 DRIVER_MODULE(pcib, simplebus, generic_pcie_driver,
812     generic_pcie_devclass, 0, 0);
813 DRIVER_MODULE(pcib, ofwbus, generic_pcie_driver,
814     generic_pcie_devclass, 0, 0);
815 
816