xref: /freebsd/sys/dev/pci/pci_host_generic.c (revision 276da39af92f48350aa01091a2b8b3e735217eea)
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 <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 #include <sys/cpuset.h>
45 #include <sys/rwlock.h>
46 #include <dev/ofw/openfirm.h>
47 #include <dev/ofw/ofw_bus.h>
48 #include <dev/ofw/ofw_bus_subr.h>
49 #include <dev/pci/pcivar.h>
50 #include <dev/pci/pcireg.h>
51 #include <dev/pci/pcib_private.h>
52 #include <machine/cpu.h>
53 #include <machine/bus.h>
54 #include <machine/intr.h>
55 #include <vm/vm_page.h>
56 
57 #include "pcib_if.h"
58 
59 /* Assembling ECAM Configuration Address */
60 #define	PCIE_BUS_SHIFT		20
61 #define	PCIE_SLOT_SHIFT		15
62 #define	PCIE_FUNC_SHIFT		12
63 #define	PCIE_BUS_MASK		0xFF
64 #define	PCIE_SLOT_MASK		0x1F
65 #define	PCIE_FUNC_MASK		0x07
66 #define	PCIE_REG_MASK		0xFFF
67 
68 #define	PCIE_ADDR_OFFSET(bus, slot, func, reg)			\
69 	((((bus) & PCIE_BUS_MASK) << PCIE_BUS_SHIFT)	|	\
70 	(((slot) & PCIE_SLOT_MASK) << PCIE_SLOT_SHIFT)	|	\
71 	(((func) & PCIE_FUNC_MASK) << PCIE_FUNC_SHIFT)	|	\
72 	((reg) & PCIE_REG_MASK))
73 
74 #define	MAX_RANGES_TUPLES	5
75 #define	MIN_RANGES_TUPLES	2
76 
77 #define	PCI_IO_WINDOW_OFFSET	0x1000
78 #define	PCI_IRQ_START		32
79 #define	PCI_IRQ_END		(PCI_IRQ_START + 4)
80 
81 #define	SPACE_CODE_SHIFT	24
82 #define	SPACE_CODE_MASK		0x3
83 #define	SPACE_CODE_IO_SPACE	0x1
84 #define	PROPS_CELL_SIZE		1
85 #define	PCI_ADDR_CELL_SIZE	2
86 
87 struct pcie_range {
88 	uint64_t	pci_base;
89 	uint64_t	phys_base;
90 	uint64_t	size;
91 	uint64_t	flags;
92 #define	FLAG_IO		(1 << 0)
93 #define	FLAG_MEM	(1 << 1)
94 };
95 
96 struct generic_pcie_softc {
97 	struct pcie_range	ranges[MAX_RANGES_TUPLES];
98 	int			nranges;
99 	struct rman		mem_rman;
100 	struct rman		io_rman;
101 	struct rman		irq_rman;
102 	struct resource		*res;
103 	struct resource		*res1;
104 	int			ecam;
105 	bus_space_tag_t		bst;
106 	bus_space_handle_t	bsh;
107 	device_t		dev;
108 	bus_space_handle_t	ioh;
109 };
110 
111 /* Forward prototypes */
112 
113 static int generic_pcie_probe(device_t dev);
114 static int generic_pcie_attach(device_t dev);
115 static int parse_pci_mem_ranges(struct generic_pcie_softc *sc);
116 static uint32_t generic_pcie_read_config(device_t dev, u_int bus, u_int slot,
117     u_int func, u_int reg, int bytes);
118 static void generic_pcie_write_config(device_t dev, u_int bus, u_int slot,
119     u_int func, u_int reg, uint32_t val, int bytes);
120 static int generic_pcie_maxslots(device_t dev);
121 static int generic_pcie_read_ivar(device_t dev, device_t child, int index,
122     uintptr_t *result);
123 static int generic_pcie_write_ivar(device_t dev, device_t child, int index,
124     uintptr_t value);
125 static struct resource *generic_pcie_alloc_resource(device_t dev,
126     device_t child, int type, int *rid, u_long start, u_long end,
127     u_long count, u_int flags);
128 static int generic_pcie_release_resource(device_t dev, device_t child,
129     int type, int rid, struct resource *res);
130 
131 static int
132 generic_pcie_probe(device_t dev)
133 {
134 
135 	if (!ofw_bus_status_okay(dev))
136 		return (ENXIO);
137 
138 	if (ofw_bus_is_compatible(dev, "pci-host-ecam-generic")) {
139 		device_set_desc(dev, "Generic PCI host controller");
140 		return (BUS_PROBE_DEFAULT);
141 	}
142 
143 	return (ENXIO);
144 }
145 
146 static int
147 generic_pcie_attach(device_t dev)
148 {
149 	struct generic_pcie_softc *sc;
150 	uint64_t phys_base;
151 	uint64_t pci_base;
152 	uint64_t size;
153 	int error;
154 	int tuple;
155 	int rid;
156 
157 	sc = device_get_softc(dev);
158 	sc->dev = dev;
159 
160 	rid = 0;
161 	sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
162 	if (sc->res == NULL) {
163 		device_printf(dev, "could not map memory.\n");
164 		return (ENXIO);
165 	}
166 
167 	sc->bst = rman_get_bustag(sc->res);
168 	sc->bsh = rman_get_bushandle(sc->res);
169 
170 	sc->mem_rman.rm_type = RMAN_ARRAY;
171 	sc->mem_rman.rm_descr = "PCIe Memory";
172 	sc->io_rman.rm_type = RMAN_ARRAY;
173 	sc->io_rman.rm_descr = "PCIe IO window";
174 
175 	/* Retrieve 'ranges' property from FDT */
176 	if (bootverbose)
177 		device_printf(dev, "parsing FDT for ECAM%d:\n",
178 		    sc->ecam);
179 	if (parse_pci_mem_ranges(sc))
180 		return (ENXIO);
181 
182 	/* Initialize rman and allocate memory regions */
183 	error = rman_init(&sc->mem_rman);
184 	if (error) {
185 		device_printf(dev, "rman_init() failed. error = %d\n", error);
186 		return (error);
187 	}
188 
189 	error = rman_init(&sc->io_rman);
190 	if (error) {
191 		device_printf(dev, "rman_init() failed. error = %d\n", error);
192 		return (error);
193 	}
194 
195 	for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) {
196 		phys_base = sc->ranges[tuple].phys_base;
197 		pci_base = sc->ranges[tuple].pci_base;
198 		size = sc->ranges[tuple].size;
199 		if (phys_base == 0 || size == 0)
200 			continue; /* empty range element */
201 		if (sc->ranges[tuple].flags & FLAG_MEM) {
202 			error = rman_manage_region(&sc->mem_rman,
203 						phys_base,
204 						phys_base + size);
205 		} else if (sc->ranges[tuple].flags & FLAG_IO) {
206 			error = rman_manage_region(&sc->io_rman,
207 					pci_base + PCI_IO_WINDOW_OFFSET,
208 					pci_base + PCI_IO_WINDOW_OFFSET + size);
209 		} else
210 			continue;
211 		if (error) {
212 			device_printf(dev, "rman_manage_region() failed."
213 						"error = %d\n", error);
214 			rman_fini(&sc->mem_rman);
215 			return (error);
216 		}
217 	}
218 
219 	/* TODO: get IRQ numbers from FDT */
220 	sc->irq_rman.rm_type = RMAN_ARRAY;
221 	sc->irq_rman.rm_descr = "Generic PCIe IRQs";
222 	if (rman_init(&sc->irq_rman) != 0 ||
223 	    rman_manage_region(&sc->irq_rman, PCI_IRQ_START,
224 		PCI_IRQ_END) != 0) {
225 		panic("Generic PCI: failed to set up IRQ rman");
226 	}
227 
228 	device_add_child(dev, "pci", -1);
229 	return (bus_generic_attach(dev));
230 }
231 
232 static int
233 parse_pci_mem_ranges(struct generic_pcie_softc *sc)
234 {
235 	pcell_t pci_addr_cells, parent_addr_cells;
236 	pcell_t attributes, size_cells;
237 	cell_t *base_ranges;
238 	int nbase_ranges;
239 	phandle_t node;
240 	int i, j, k;
241 	int tuple;
242 
243 	node = ofw_bus_get_node(sc->dev);
244 
245 	OF_getencprop(node, "#address-cells", &pci_addr_cells,
246 					sizeof(pci_addr_cells));
247 	OF_getencprop(node, "#size-cells", &size_cells,
248 					sizeof(size_cells));
249 	OF_getencprop(OF_parent(node), "#address-cells", &parent_addr_cells,
250 					sizeof(parent_addr_cells));
251 
252 	if (parent_addr_cells != 2 || pci_addr_cells != 3 || size_cells != 2) {
253 		device_printf(sc->dev,
254 		    "Unexpected number of address or size cells in FDT\n");
255 		return (ENXIO);
256 	}
257 
258 	nbase_ranges = OF_getproplen(node, "ranges");
259 	sc->nranges = nbase_ranges / sizeof(cell_t) /
260 	    (parent_addr_cells + pci_addr_cells + size_cells);
261 	base_ranges = malloc(nbase_ranges, M_DEVBUF, M_WAITOK);
262 	OF_getencprop(node, "ranges", base_ranges, nbase_ranges);
263 
264 	for (i = 0, j = 0; i < sc->nranges; i++) {
265 		attributes = (base_ranges[j++] >> SPACE_CODE_SHIFT) & \
266 							SPACE_CODE_MASK;
267 		if (attributes == SPACE_CODE_IO_SPACE) {
268 			sc->ranges[i].flags |= FLAG_IO;
269 		} else {
270 			sc->ranges[i].flags |= FLAG_MEM;
271 		}
272 
273 		sc->ranges[i].pci_base = 0;
274 		for (k = 0; k < (pci_addr_cells - 1); k++) {
275 			sc->ranges[i].pci_base <<= 32;
276 			sc->ranges[i].pci_base |= base_ranges[j++];
277 		}
278 		sc->ranges[i].phys_base = 0;
279 		for (k = 0; k < parent_addr_cells; k++) {
280 			sc->ranges[i].phys_base <<= 32;
281 			sc->ranges[i].phys_base |= base_ranges[j++];
282 		}
283 		sc->ranges[i].size = 0;
284 		for (k = 0; k < size_cells; k++) {
285 			sc->ranges[i].size <<= 32;
286 			sc->ranges[i].size |= base_ranges[j++];
287 		}
288 	}
289 
290 	for (; i < MAX_RANGES_TUPLES; i++) {
291 		/* zero-fill remaining tuples to mark empty elements in array */
292 		sc->ranges[i].pci_base = 0;
293 		sc->ranges[i].phys_base = 0;
294 		sc->ranges[i].size = 0;
295 	}
296 
297 	if (bootverbose) {
298 		for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) {
299 			device_printf(sc->dev,
300 			    "\tPCI addr: 0x%jx, CPU addr: 0x%jx, Size: 0x%jx\n",
301 			    sc->ranges[tuple].pci_base,
302 			    sc->ranges[tuple].phys_base,
303 			    sc->ranges[tuple].size);
304 		}
305 	}
306 
307 	free(base_ranges, M_DEVBUF);
308 	return (0);
309 }
310 
311 static uint32_t
312 generic_pcie_read_config(device_t dev, u_int bus, u_int slot,
313     u_int func, u_int reg, int bytes)
314 {
315 	struct generic_pcie_softc *sc;
316 	bus_space_handle_t h;
317 	bus_space_tag_t	t;
318 	uint64_t offset;
319 	uint32_t data;
320 
321 	if (bus > 255 || slot > 31 || func > 7 || reg > 4095)
322 		return (~0U);
323 
324 	sc = device_get_softc(dev);
325 
326 	offset = PCIE_ADDR_OFFSET(bus, slot, func, reg);
327 	t = sc->bst;
328 	h = sc->bsh;
329 
330 	switch (bytes) {
331 	case 1:
332 		data = bus_space_read_1(t, h, offset);
333 		break;
334 	case 2:
335 		data = le16toh(bus_space_read_2(t, h, offset));
336 		break;
337 	case 4:
338 		data = le32toh(bus_space_read_4(t, h, offset));
339 		break;
340 	default:
341 		return (~0U);
342 	}
343 
344 	if (reg == PCIR_INTLINE) {
345 		data += PCI_IRQ_START;
346 	}
347 
348 	return (data);
349 }
350 
351 static void
352 generic_pcie_write_config(device_t dev, u_int bus, u_int slot,
353     u_int func, u_int reg, uint32_t val, int bytes)
354 {
355 	struct generic_pcie_softc *sc;
356 	bus_space_handle_t h;
357 	bus_space_tag_t t;
358 	uint64_t offset;
359 
360 	if (bus > 255 || slot > 31 || func > 7 || reg > 4095)
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_read_ivar(device_t dev, device_t child, int index,
394     uintptr_t *result)
395 {
396 	struct generic_pcie_softc *sc;
397 	int secondary_bus;
398 
399 	sc = device_get_softc(dev);
400 
401 	if (index == PCIB_IVAR_BUS) {
402 		/* this pcib adds only pci bus 0 as child */
403 		secondary_bus = 0;
404 		*result = secondary_bus;
405 		return (0);
406 
407 	}
408 
409 	if (index == PCIB_IVAR_DOMAIN) {
410 		*result = sc->ecam;
411 		return (0);
412 	}
413 
414 	device_printf(dev, "ERROR: Unknown index.\n");
415 	return (ENOENT);
416 }
417 
418 static int
419 generic_pcie_write_ivar(device_t dev, device_t child, int index,
420     uintptr_t value)
421 {
422 
423 	return (ENOENT);
424 }
425 
426 static struct rman *
427 generic_pcie_rman(struct generic_pcie_softc *sc, int type)
428 {
429 
430 	switch (type) {
431 	case SYS_RES_IOPORT:
432 		return (&sc->io_rman);
433 	case SYS_RES_MEMORY:
434 		return (&sc->mem_rman);
435 	case SYS_RES_IRQ:
436 		return (&sc->irq_rman);
437 	default:
438 		break;
439 	}
440 
441 	return (NULL);
442 }
443 
444 static int
445 generic_pcie_release_resource(device_t dev, device_t child, int type,
446     int rid, struct resource *res)
447 {
448 	struct generic_pcie_softc *sc;
449 	struct rman *rm;
450 
451 	sc = device_get_softc(dev);
452 
453 	rm = generic_pcie_rman(sc, type);
454 	if (rm != NULL) {
455 		KASSERT(rman_is_region_manager(res, rm), ("rman mismatch"));
456 		rman_release_resource(res);
457 	}
458 
459 	return (bus_generic_release_resource(dev, child, type, rid, res));
460 }
461 
462 static struct resource *
463 generic_pcie_alloc_resource(device_t dev, device_t child, int type, int *rid,
464     u_long start, u_long end, u_long count, u_int flags)
465 {
466 	struct generic_pcie_softc *sc;
467 	struct resource *res;
468 	struct rman *rm;
469 
470 	sc = device_get_softc(dev);
471 
472 	rm = generic_pcie_rman(sc, type);
473 	if (rm == NULL)
474 		return (BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
475 		    type, rid, start, end, count, flags));
476 
477 	if (bootverbose) {
478 		device_printf(dev,
479 		    "rman_reserve_resource: start=%#lx, end=%#lx, count=%#lx\n",
480 		    start, end, count);
481 	}
482 
483 	res = rman_reserve_resource(rm, start, end, count, flags, child);
484 	if (res == NULL)
485 		goto fail;
486 
487 	rman_set_rid(res, *rid);
488 
489 	if (flags & RF_ACTIVE)
490 		if (bus_activate_resource(child, type, *rid, res)) {
491 			rman_release_resource(res);
492 			goto fail;
493 		}
494 
495 	return (res);
496 
497 fail:
498 	if (bootverbose) {
499 		device_printf(dev, "%s FAIL: type=%d, rid=%d, "
500 		    "start=%016lx, end=%016lx, count=%016lx, flags=%x\n",
501 		    __func__, type, *rid, start, end, count, flags);
502 	}
503 
504 	return (NULL);
505 }
506 
507 static int
508 generic_pcie_adjust_resource(device_t dev, device_t child, int type,
509     struct resource *res, u_long start, u_long end)
510 {
511 	struct generic_pcie_softc *sc;
512 	struct rman *rm;
513 
514 	sc = device_get_softc(dev);
515 
516 	rm = generic_pcie_rman(sc, type);
517 	if (rm != NULL)
518 		return (rman_adjust_resource(res, start, end));
519 	return (bus_generic_adjust_resource(dev, child, type, res, start, end));
520 }
521 
522 static int
523 generic_pcie_activate_resource(device_t dev, device_t child, int type, int rid,
524     struct resource *r)
525 {
526 	struct generic_pcie_softc *sc;
527 	uint64_t phys_base;
528 	uint64_t pci_base;
529 	uint64_t size;
530 	int found;
531 	int res;
532 	int i;
533 
534 	sc = device_get_softc(dev);
535 
536 	if ((res = rman_activate_resource(r)) != 0)
537 		return (res);
538 
539 	switch(type) {
540 	case SYS_RES_IOPORT:
541 		found = 0;
542 		for (i = 0; i < MAX_RANGES_TUPLES; i++) {
543 			pci_base = sc->ranges[i].pci_base;
544 			phys_base = sc->ranges[i].phys_base;
545 			size = sc->ranges[i].size;
546 
547 			if ((rid > pci_base) && (rid < (pci_base + size))) {
548 				found = 1;
549 				break;
550 			}
551 		}
552 		if (found) {
553 			rman_set_start(r, rman_get_start(r) + phys_base);
554 			BUS_ACTIVATE_RESOURCE(device_get_parent(dev), child,
555 						type, rid, r);
556 		} else {
557 			device_printf(dev, "Failed to activate IOPORT resource\n");
558 			res = 0;
559 		}
560 		break;
561 	case SYS_RES_MEMORY:
562 		BUS_ACTIVATE_RESOURCE(device_get_parent(dev), child, type, rid, r);
563 		break;
564 	default:
565 		break;
566 	}
567 
568 	return (res);
569 }
570 
571 static int
572 generic_pcie_deactivate_resource(device_t dev, device_t child, int type, int rid,
573     struct resource *r)
574 {
575 	struct generic_pcie_softc *sc;
576 	vm_offset_t vaddr;
577 	int res;
578 
579 	sc = device_get_softc(dev);
580 
581 	if ((res = rman_deactivate_resource(r)) != 0)
582 		return (res);
583 
584 	switch(type) {
585 	case SYS_RES_IOPORT:
586 	case SYS_RES_MEMORY:
587 		vaddr = (vm_offset_t)rman_get_virtual(r);
588 		pmap_unmapdev(vaddr, rman_get_size(r));
589 		break;
590 	default:
591 		break;
592 	}
593 
594 	return (res);
595 }
596 
597 static device_method_t generic_pcie_methods[] = {
598 	DEVMETHOD(device_probe,			generic_pcie_probe),
599 	DEVMETHOD(device_attach,		generic_pcie_attach),
600 	DEVMETHOD(bus_read_ivar,		generic_pcie_read_ivar),
601 	DEVMETHOD(bus_write_ivar,		generic_pcie_write_ivar),
602 	DEVMETHOD(bus_alloc_resource,		generic_pcie_alloc_resource),
603 	DEVMETHOD(bus_adjust_resource,		generic_pcie_adjust_resource),
604 	DEVMETHOD(bus_release_resource,		generic_pcie_release_resource),
605 	DEVMETHOD(bus_activate_resource,	generic_pcie_activate_resource),
606 	DEVMETHOD(bus_deactivate_resource,	generic_pcie_deactivate_resource),
607 	DEVMETHOD(bus_setup_intr,		bus_generic_setup_intr),
608 	DEVMETHOD(bus_teardown_intr,		bus_generic_teardown_intr),
609 	DEVMETHOD(pcib_maxslots,		generic_pcie_maxslots),
610 	DEVMETHOD(pcib_read_config,		generic_pcie_read_config),
611 	DEVMETHOD(pcib_write_config,		generic_pcie_write_config),
612 	DEVMETHOD_END
613 };
614 
615 static driver_t generic_pcie_driver = {
616 	"pcib",
617 	generic_pcie_methods,
618 	sizeof(struct generic_pcie_softc),
619 };
620 
621 static devclass_t generic_pcie_devclass;
622 
623 DRIVER_MODULE(pcib, simplebus, generic_pcie_driver,
624 generic_pcie_devclass, 0, 0);
625 DRIVER_MODULE(pcib, ofwbus, generic_pcie_driver,
626 generic_pcie_devclass, 0, 0);
627