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