1 /*
2  * Copyright (c) 2019 Intel Corporation
3  * Copyright (c) 2020 acontis technologies GmbH
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #define DT_DRV_COMPAT pcie_controller
9 
10 #include <zephyr/logging/log.h>
11 LOG_MODULE_REGISTER(pcie, LOG_LEVEL_ERR);
12 
13 #include <zephyr/init.h>
14 #include <zephyr/kernel.h>
15 #include <zephyr/device.h>
16 #include <zephyr/sys/check.h>
17 #include <stdbool.h>
18 #include <zephyr/drivers/pcie/pcie.h>
19 #include <zephyr/sys/iterable_sections.h>
20 
21 #ifdef CONFIG_ACPI
22 #include <zephyr/acpi/acpi.h>
23 #endif
24 
25 #if CONFIG_PCIE_MSI
26 #include <zephyr/drivers/pcie/msi.h>
27 #endif
28 
29 #ifdef CONFIG_PCIE_CONTROLLER
30 #include <zephyr/drivers/pcie/controller.h>
31 #endif
32 
33 #ifdef CONFIG_PCIE_PRT
34 /* platform interrupt are hardwired or can be dynamically allocated. */
35 static bool prt_en;
36 #endif
37 
38 /* functions documented in drivers/pcie/pcie.h */
39 
pcie_probe(pcie_bdf_t bdf,pcie_id_t id)40 bool pcie_probe(pcie_bdf_t bdf, pcie_id_t id)
41 {
42 	uint32_t data;
43 
44 	data = pcie_conf_read(bdf, PCIE_CONF_ID);
45 
46 	if (!PCIE_ID_IS_VALID(data)) {
47 		return false;
48 	}
49 
50 	if (id == PCIE_ID_NONE) {
51 		return true;
52 	}
53 
54 	return (id == data);
55 }
56 
pcie_set_cmd(pcie_bdf_t bdf,uint32_t bits,bool on)57 void pcie_set_cmd(pcie_bdf_t bdf, uint32_t bits, bool on)
58 {
59 	uint32_t cmdstat;
60 
61 	cmdstat = pcie_conf_read(bdf, PCIE_CONF_CMDSTAT);
62 
63 	if (on) {
64 		cmdstat |= bits;
65 	} else {
66 		cmdstat &= ~bits;
67 	}
68 
69 	pcie_conf_write(bdf, PCIE_CONF_CMDSTAT, cmdstat);
70 }
71 
pcie_get_cap(pcie_bdf_t bdf,uint32_t cap_id)72 uint32_t pcie_get_cap(pcie_bdf_t bdf, uint32_t cap_id)
73 {
74 	uint32_t reg = 0U;
75 	uint32_t data;
76 
77 	data = pcie_conf_read(bdf, PCIE_CONF_CMDSTAT);
78 	if ((data & PCIE_CONF_CMDSTAT_CAPS) != 0U) {
79 		data = pcie_conf_read(bdf, PCIE_CONF_CAPPTR);
80 		reg = PCIE_CONF_CAPPTR_FIRST(data);
81 	}
82 
83 	while (reg != 0U) {
84 		data = pcie_conf_read(bdf, reg);
85 
86 		if (PCIE_CONF_CAP_ID(data) == cap_id) {
87 			break;
88 		}
89 
90 		reg = PCIE_CONF_CAP_NEXT(data);
91 	}
92 
93 	return reg;
94 }
95 
pcie_get_ext_cap(pcie_bdf_t bdf,uint32_t cap_id)96 uint32_t pcie_get_ext_cap(pcie_bdf_t bdf, uint32_t cap_id)
97 {
98 	unsigned int reg = PCIE_CONF_EXT_CAPPTR; /* Start at end of the PCI configuration space */
99 	uint32_t data;
100 
101 	while (reg != 0U) {
102 		data = pcie_conf_read(bdf, reg);
103 		if (!data || data == 0xffffffffU) {
104 			return 0;
105 		}
106 
107 		if (PCIE_CONF_EXT_CAP_ID(data) == cap_id) {
108 			break;
109 		}
110 
111 		reg = PCIE_CONF_EXT_CAP_NEXT(data) >> 2;
112 
113 		if (reg < PCIE_CONF_EXT_CAPPTR) {
114 			return 0;
115 		}
116 	}
117 
118 	return reg;
119 }
120 
121 /**
122  * @brief Get the BAR at a specific BAR index
123  *
124  * @param bdf the PCI(e) endpoint
125  * @param bar_index 0-based BAR index
126  * @param bar Pointer to struct pcie_bar
127  * @param io true for I/O BARs, false otherwise
128  * @return true if the BAR was found and is valid, false otherwise
129  */
pcie_get_bar(pcie_bdf_t bdf,unsigned int bar_index,struct pcie_bar * bar,bool io)130 static bool pcie_get_bar(pcie_bdf_t bdf,
131 			 unsigned int bar_index,
132 			 struct pcie_bar *bar,
133 			 bool io)
134 {
135 	uint32_t reg = bar_index + PCIE_CONF_BAR0;
136 	uint32_t cmd_reg;
137 	bool ret = false;
138 #ifdef CONFIG_PCIE_CONTROLLER
139 	const struct device *dev;
140 #endif
141 	uintptr_t phys_addr;
142 	size_t size;
143 
144 #ifdef CONFIG_PCIE_CONTROLLER
145 	dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_pcie_controller));
146 	if (!dev) {
147 		LOG_ERR("Failed to get PCIe root complex");
148 		return false;
149 	}
150 #endif
151 
152 	if (reg > PCIE_CONF_BAR5) {
153 		return false;
154 	}
155 
156 	phys_addr = pcie_conf_read(bdf, reg);
157 #ifndef CONFIG_PCIE_CONTROLLER
158 	if ((PCIE_CONF_BAR_MEM(phys_addr) && io) || (PCIE_CONF_BAR_IO(phys_addr) && !io)) {
159 		return false;
160 	}
161 #endif
162 
163 	if (PCIE_CONF_BAR_INVAL_FLAGS(phys_addr)) {
164 		/* Discard on invalid flags */
165 		return false;
166 	}
167 
168 	cmd_reg = pcie_conf_read(bdf, PCIE_CONF_CMDSTAT);
169 
170 	/* IO/memory decode should be disabled before sizing/update BAR. */
171 	pcie_conf_write(bdf, PCIE_CONF_CMDSTAT,
172 			cmd_reg & (~(PCIE_CONF_CMDSTAT_IO | PCIE_CONF_CMDSTAT_MEM)));
173 
174 	pcie_conf_write(bdf, reg, 0xFFFFFFFFU);
175 	size = pcie_conf_read(bdf, reg);
176 	pcie_conf_write(bdf, reg, (uint32_t)phys_addr);
177 
178 	if (IS_ENABLED(CONFIG_64BIT) && PCIE_CONF_BAR_64(phys_addr)) {
179 		reg++;
180 		phys_addr |= ((uint64_t)pcie_conf_read(bdf, reg)) << 32;
181 
182 		if (PCIE_CONF_BAR_ADDR(phys_addr) == PCIE_CONF_BAR_INVAL64 ||
183 		    PCIE_CONF_BAR_ADDR(phys_addr) == PCIE_CONF_BAR_NONE) {
184 			/* Discard on invalid address */
185 			goto err_exit;
186 		}
187 
188 		pcie_conf_write(bdf, reg, 0xFFFFFFFFU);
189 		size |= ((uint64_t)pcie_conf_read(bdf, reg)) << 32;
190 		pcie_conf_write(bdf, reg, (uint32_t)((uint64_t)phys_addr >> 32));
191 	} else if (PCIE_CONF_BAR_ADDR(phys_addr) == PCIE_CONF_BAR_INVAL ||
192 		   PCIE_CONF_BAR_ADDR(phys_addr) == PCIE_CONF_BAR_NONE) {
193 		/* Discard on invalid address */
194 		goto err_exit;
195 	}
196 
197 	if (PCIE_CONF_BAR_IO(phys_addr)) {
198 		size = PCIE_CONF_BAR_IO_ADDR(size);
199 		if (size == 0) {
200 			/* Discard on invalid size */
201 			goto err_exit;
202 		}
203 	} else {
204 		size = PCIE_CONF_BAR_ADDR(size);
205 		if (size == 0) {
206 			/* Discard on invalid size */
207 			goto err_exit;
208 		}
209 	}
210 
211 #ifdef CONFIG_PCIE_CONTROLLER
212 	/* Translate to physical memory address from bus address */
213 	if (!pcie_ctrl_region_translate(dev, bdf, PCIE_CONF_BAR_MEM(phys_addr),
214 					PCIE_CONF_BAR_64(phys_addr),
215 					PCIE_CONF_BAR_MEM(phys_addr) ?
216 						PCIE_CONF_BAR_ADDR(phys_addr)
217 						: PCIE_CONF_BAR_IO_ADDR(phys_addr),
218 					&bar->phys_addr)) {
219 		goto err_exit;
220 	}
221 #else
222 	bar->phys_addr = PCIE_CONF_BAR_ADDR(phys_addr);
223 #endif /* CONFIG_PCIE_CONTROLLER */
224 	bar->size = size & ~(size-1);
225 
226 	ret = true;
227 err_exit:
228 	pcie_conf_write(bdf, PCIE_CONF_CMDSTAT, cmd_reg);
229 
230 	return ret;
231 }
232 
233 /**
234  * @brief Probe the nth BAR assigned to an endpoint.
235  *
236  * A PCI(e) endpoint has 0 or more BARs. This function
237  * allows the caller to enumerate them by calling with index=0..n.
238  * Value of n has to be below 6, as there is a maximum of 6 BARs. The indices
239  * are order-preserving with respect to the endpoint BARs: e.g., index 0
240  * will return the lowest-numbered BAR on the endpoint.
241  *
242  * @param bdf the PCI(e) endpoint
243  * @param index (0-based) index
244  * @param bar Pointer to struct pcie_bar
245  * @param io true for I/O BARs, false otherwise
246  * @return true if the BAR was found and is valid, false otherwise
247  */
pcie_probe_bar(pcie_bdf_t bdf,unsigned int index,struct pcie_bar * bar,bool io)248 static bool pcie_probe_bar(pcie_bdf_t bdf,
249 			   unsigned int index,
250 			   struct pcie_bar *bar,
251 			   bool io)
252 {
253 	uint32_t reg;
254 
255 	for (reg = PCIE_CONF_BAR0;
256 	     index > 0 && reg <= PCIE_CONF_BAR5; reg++, index--) {
257 		uintptr_t addr = pcie_conf_read(bdf, reg);
258 
259 		if (PCIE_CONF_BAR_MEM(addr) && PCIE_CONF_BAR_64(addr)) {
260 			reg++;
261 		}
262 	}
263 
264 	if (index != 0) {
265 		return false;
266 	}
267 
268 	return pcie_get_bar(bdf, reg - PCIE_CONF_BAR0, bar, io);
269 }
270 
pcie_get_mbar(pcie_bdf_t bdf,unsigned int bar_index,struct pcie_bar * mbar)271 bool pcie_get_mbar(pcie_bdf_t bdf,
272 		   unsigned int bar_index,
273 		   struct pcie_bar *mbar)
274 {
275 	return pcie_get_bar(bdf, bar_index, mbar, false);
276 }
277 
pcie_probe_mbar(pcie_bdf_t bdf,unsigned int index,struct pcie_bar * mbar)278 bool pcie_probe_mbar(pcie_bdf_t bdf,
279 		     unsigned int index,
280 		     struct pcie_bar *mbar)
281 {
282 	return pcie_probe_bar(bdf, index, mbar, false);
283 }
284 
pcie_get_iobar(pcie_bdf_t bdf,unsigned int bar_index,struct pcie_bar * iobar)285 bool pcie_get_iobar(pcie_bdf_t bdf,
286 		    unsigned int bar_index,
287 		    struct pcie_bar *iobar)
288 {
289 	return pcie_get_bar(bdf, bar_index, iobar, true);
290 }
291 
pcie_probe_iobar(pcie_bdf_t bdf,unsigned int index,struct pcie_bar * iobar)292 bool pcie_probe_iobar(pcie_bdf_t bdf,
293 		      unsigned int index,
294 		      struct pcie_bar *iobar)
295 {
296 	return pcie_probe_bar(bdf, index, iobar, true);
297 }
298 
299 #ifndef CONFIG_PCIE_CONTROLLER
300 
pcie_alloc_irq(pcie_bdf_t bdf)301 unsigned int pcie_alloc_irq(pcie_bdf_t bdf)
302 {
303 	unsigned int irq;
304 	uint32_t data;
305 
306 	data = pcie_conf_read(bdf, PCIE_CONF_INTR);
307 	irq = PCIE_CONF_INTR_IRQ(data);
308 
309 	if (irq == PCIE_CONF_INTR_IRQ_NONE ||
310 	    irq >= CONFIG_MAX_IRQ_LINES ||
311 	    arch_irq_is_used(irq)) {
312 
313 		/* In some platforms, PCI interrupts are hardwired to specific interrupt inputs
314 		 * on the interrupt controller and are not configurable. Hence we need to retrieve
315 		 * IRQ from acpi. But if it is configurable then we allocate irq dynamically.
316 		 */
317 #ifdef CONFIG_PCIE_PRT
318 		if (prt_en) {
319 			irq = acpi_legacy_irq_get(bdf);
320 		} else {
321 			irq = arch_irq_allocate();
322 		}
323 #else
324 		irq = arch_irq_allocate();
325 #endif
326 
327 		if (irq == UINT_MAX) {
328 			return PCIE_CONF_INTR_IRQ_NONE;
329 		}
330 
331 		data &= ~0xffU;
332 		data |= irq;
333 		pcie_conf_write(bdf, PCIE_CONF_INTR, data);
334 	} else {
335 		arch_irq_set_used(irq);
336 	}
337 
338 	return irq;
339 }
340 #endif /* CONFIG_PCIE_CONTROLLER */
341 
pcie_get_irq(pcie_bdf_t bdf)342 unsigned int pcie_get_irq(pcie_bdf_t bdf)
343 {
344 	uint32_t data = pcie_conf_read(bdf, PCIE_CONF_INTR);
345 
346 	return PCIE_CONF_INTR_IRQ(data);
347 }
348 
pcie_connect_dynamic_irq(pcie_bdf_t bdf,unsigned int irq,unsigned int priority,void (* routine)(const void * parameter),const void * parameter,uint32_t flags)349 bool pcie_connect_dynamic_irq(pcie_bdf_t bdf,
350 			      unsigned int irq,
351 			      unsigned int priority,
352 			      void (*routine)(const void *parameter),
353 			      const void *parameter,
354 			      uint32_t flags)
355 {
356 #if defined(CONFIG_PCIE_MSI) && defined(CONFIG_PCIE_MSI_MULTI_VECTOR)
357 	if (pcie_is_msi(bdf)) {
358 		msi_vector_t vector;
359 
360 		if ((pcie_msi_vectors_allocate(bdf, priority,
361 					       &vector, 1) == 0) ||
362 		    !pcie_msi_vector_connect(bdf, &vector,
363 					     routine, parameter, flags)) {
364 			return false;
365 		}
366 	} else
367 #endif /* CONFIG_PCIE_MSI && CONFIG_PCIE_MSI_MULTI_VECTOR */
368 	{
369 		if (irq_connect_dynamic(irq, priority, routine,
370 					parameter, flags) < 0) {
371 			return false;
372 		}
373 	}
374 
375 	return true;
376 }
377 
pcie_irq_enable(pcie_bdf_t bdf,unsigned int irq)378 void pcie_irq_enable(pcie_bdf_t bdf, unsigned int irq)
379 {
380 #if CONFIG_PCIE_MSI
381 	if (pcie_msi_enable(bdf, NULL, 1, irq)) {
382 		return;
383 	}
384 #endif
385 	irq_enable(irq);
386 }
387 
388 struct lookup_data {
389 	pcie_bdf_t bdf;
390 	pcie_id_t id;
391 };
392 
lookup_cb(pcie_bdf_t bdf,pcie_id_t id,void * cb_data)393 static bool lookup_cb(pcie_bdf_t bdf, pcie_id_t id, void *cb_data)
394 {
395 	struct lookup_data *data = cb_data;
396 
397 	if (id == data->id) {
398 		data->bdf = bdf;
399 		return false;
400 	}
401 
402 	return true;
403 }
404 
pcie_bdf_lookup(pcie_id_t id)405 pcie_bdf_t pcie_bdf_lookup(pcie_id_t id)
406 {
407 	struct lookup_data data = {
408 		.bdf = PCIE_BDF_NONE,
409 		.id = id,
410 	};
411 	struct pcie_scan_opt opt = {
412 		.cb = lookup_cb,
413 		.cb_data = &data,
414 		.flags = (PCIE_SCAN_RECURSIVE | PCIE_SCAN_CB_ALL),
415 	};
416 
417 	pcie_scan(&opt);
418 
419 	return data.bdf;
420 }
421 
scan_flag(const struct pcie_scan_opt * opt,uint32_t flag)422 static bool scan_flag(const struct pcie_scan_opt *opt, uint32_t flag)
423 {
424 	return ((opt->flags & flag) != 0U);
425 }
426 
427 /* Forward declaration needed since scanning a device may reveal a bridge */
428 static bool scan_bus(uint8_t bus, const struct pcie_scan_opt *opt);
429 
scan_dev(uint8_t bus,uint8_t dev,const struct pcie_scan_opt * opt)430 static bool scan_dev(uint8_t bus, uint8_t dev, const struct pcie_scan_opt *opt)
431 {
432 	for (uint8_t func = 0; func <= PCIE_MAX_FUNC; func++) {
433 		pcie_bdf_t bdf = PCIE_BDF(bus, dev, func);
434 		uint32_t secondary = 0;
435 		uint32_t id, type;
436 		bool do_cb;
437 
438 		id = pcie_conf_read(bdf, PCIE_CONF_ID);
439 		if (!PCIE_ID_IS_VALID(id)) {
440 			continue;
441 		}
442 
443 		type = pcie_conf_read(bdf, PCIE_CONF_TYPE);
444 		switch (PCIE_CONF_TYPE_GET(type)) {
445 		case PCIE_CONF_TYPE_STANDARD:
446 			do_cb = true;
447 			break;
448 		case PCIE_CONF_TYPE_PCI_BRIDGE:
449 			if (scan_flag(opt, PCIE_SCAN_RECURSIVE)) {
450 				uint32_t num = pcie_conf_read(bdf,
451 							      PCIE_BUS_NUMBER);
452 				secondary = PCIE_BUS_SECONDARY_NUMBER(num);
453 			}
454 			__fallthrough;
455 		default:
456 			do_cb = scan_flag(opt, PCIE_SCAN_CB_ALL);
457 			break;
458 		}
459 
460 		if (do_cb && !opt->cb(bdf, id, opt->cb_data)) {
461 			return false;
462 		}
463 
464 		if (scan_flag(opt, PCIE_SCAN_RECURSIVE) && secondary != 0) {
465 			if (!scan_bus(secondary, opt)) {
466 				return false;
467 			}
468 		}
469 
470 		/* Only function 0 is valid for non-multifunction devices */
471 		if (func == 0 && !PCIE_CONF_MULTIFUNCTION(type)) {
472 			break;
473 		}
474 	}
475 
476 	return true;
477 }
478 
scan_bus(uint8_t bus,const struct pcie_scan_opt * opt)479 static bool scan_bus(uint8_t bus, const struct pcie_scan_opt *opt)
480 {
481 	for (uint8_t dev = 0; dev <= PCIE_MAX_DEV; dev++) {
482 		if (!scan_dev(bus, dev, opt)) {
483 			return false;
484 		}
485 	}
486 
487 	return true;
488 }
489 
pcie_scan(const struct pcie_scan_opt * opt)490 int pcie_scan(const struct pcie_scan_opt *opt)
491 {
492 	uint32_t type;
493 	bool multi;
494 
495 	CHECKIF(opt->cb == NULL) {
496 		return -EINVAL;
497 	}
498 
499 	type = pcie_conf_read(PCIE_HOST_CONTROLLER(0), PCIE_CONF_TYPE);
500 	multi = PCIE_CONF_MULTIFUNCTION(type);
501 	if (opt->bus == 0 && scan_flag(opt, PCIE_SCAN_RECURSIVE) && multi) {
502 		/* Each function on the host controller represents a portential bus */
503 		for (uint8_t bus = 0; bus <= PCIE_MAX_FUNC; bus++) {
504 			pcie_bdf_t bdf = PCIE_HOST_CONTROLLER(bus);
505 
506 			if (pcie_conf_read(bdf, PCIE_CONF_ID) == PCIE_ID_NONE) {
507 				continue;
508 			}
509 
510 			if (!scan_bus(bus, opt)) {
511 				break;
512 			}
513 		}
514 	} else {
515 		/* Single PCI host controller */
516 		scan_bus(opt->bus, opt);
517 	}
518 
519 	return 0;
520 }
521 
522 struct scan_data {
523 	size_t found;
524 	size_t max_dev;
525 };
526 
pcie_dev_cb(pcie_bdf_t bdf,pcie_id_t id,void * cb_data)527 static bool pcie_dev_cb(pcie_bdf_t bdf, pcie_id_t id, void *cb_data)
528 {
529 	struct scan_data *data = cb_data;
530 
531 	STRUCT_SECTION_FOREACH(pcie_dev, dev) {
532 		if (dev->bdf != PCIE_BDF_NONE) {
533 			continue;
534 		}
535 
536 		if (dev->id != id) {
537 			continue;
538 		}
539 
540 		uint32_t class_rev = pcie_conf_read(bdf, PCIE_CONF_CLASSREV);
541 
542 		if (dev->class_rev == (class_rev & dev->class_rev_mask)) {
543 			dev->bdf = bdf;
544 			dev->class_rev = class_rev;
545 			data->found++;
546 			break;
547 		}
548 	}
549 
550 	/* Continue if we've not yet found all devices */
551 	return (data->found != data->max_dev);
552 }
553 
pcie_init(void)554 static int pcie_init(void)
555 {
556 	struct scan_data data;
557 	struct pcie_scan_opt opt = {
558 		.cb = pcie_dev_cb,
559 		.cb_data = &data,
560 		.flags = PCIE_SCAN_RECURSIVE,
561 	};
562 
563 #ifdef CONFIG_PCIE_PRT
564 	const char *hid, *uid = ACPI_DT_UID(DT_DRV_INST(0));
565 	int ret;
566 
567 	BUILD_ASSERT(ACPI_DT_HAS_HID(DT_DRV_INST(0)),
568 		 "No HID property for PCIe devicetree node");
569 	hid = ACPI_DT_HID(DT_DRV_INST(0));
570 
571 	ret = acpi_legacy_irq_init(hid, uid);
572 	if (!ret) {
573 		prt_en = true;
574 	} else {
575 		__ASSERT(ret == -ENOENT, "Error retrieve interrupt routing table!");
576 	}
577 #endif
578 
579 	STRUCT_SECTION_COUNT(pcie_dev, &data.max_dev);
580 	/* Don't bother calling pcie_scan() if there are no devices to look for */
581 	if (data.max_dev == 0) {
582 		return 0;
583 	}
584 
585 	data.found = 0;
586 
587 	pcie_scan(&opt);
588 
589 	return 0;
590 }
591 
592 
593 /*
594  * If a pcie controller is employed, pcie_scan() depends on it for working.
595  * Thus, pcie must be bumped to the next level
596  */
597 #ifdef CONFIG_PCIE_CONTROLLER
598 #define PCIE_SYS_INIT_LEVEL	PRE_KERNEL_2
599 #else
600 #define PCIE_SYS_INIT_LEVEL	PRE_KERNEL_1
601 #endif
602 
603 SYS_INIT(pcie_init, PCIE_SYS_INIT_LEVEL, CONFIG_PCIE_INIT_PRIORITY);
604