e10k: driver working using legacy descriptors
[barrelfish] / usr / pci / pci.c
1 /**
2  * \file
3  * \brief PCI driver
4  *
5  *  This file walks through the PCI bus, enumarates each device and gathers
6  *  informatiom about each device.
7  */
8
9 /*
10  * Copyright (c) 2007, 2008, 2009, 2010, 2011, ETH Zurich.
11  * All rights reserved.
12  *
13  * This file is distributed under the terms in the attached LICENSE file.
14  * If you do not find this file, copies can be found by writing to:
15  * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
16  */
17
18 #include <stdio.h>
19 #include <stdlib.h>
20
21 #include <barrelfish/barrelfish.h>
22 #include <barrelfish/deferred.h>
23
24 #include <pci/devids.h>
25 #include <mm/mm.h>
26 #include <skb/skb.h>
27 #include <octopus/getset.h>
28 #include <acpi_client/acpi_client.h>
29 #include <dev/pci_sr_iov_cap_dev.h>
30
31 #include "pci.h"
32 #include "ht_config.h"
33 #include <dev/ht_config_dev.h>
34 #include "pci_debug.h"
35
36 #include <if/acpi_defs.h>
37
38 #define BAR_PROBE       0xffffffff
39
40 #define PAGE_BITS BASE_PAGE_BITS
41
42 struct device_caps
43 {
44     struct capref *phys_cap;
45     struct capref *frame_cap;
46     size_t nr_caps;
47     uint8_t bar_nr;
48     uint8_t bits;
49     bool assigned;  //false => this entry is not in use
50     uint8_t type;
51 };
52
53 struct device_caps dev_caps[PCI_NBUSES][PCI_NDEVICES][PCI_NFUNCTIONS][PCI_NBARS];
54 const char *skb_bridge_program = "bridge_page";
55 uint16_t max_numvfs = 256;
56
57 static void
58 query_bars(pci_hdr0_t devhdr,
59            struct pci_address addr,
60            bool pci2pci_bridge);
61
62 static void
63 enable_busmaster(uint8_t bus,
64                  uint8_t dev,
65                  uint8_t fun,
66                  bool pcie);
67
68 static uint32_t bar_mapping_size(pci_hdr0_bar32_t bar)
69 {
70     if (bar.base == 0) {
71         return 0;
72     }
73
74     for (uint32_t mask = 1;; mask <<= 1) {
75         assert(mask != 0);
76         if (bar.base & mask) {
77             return mask << 7;
78         }
79     }
80 }
81
82 static pciaddr_t bar_mapping_size64(uint64_t base)
83 {
84     if (base == 0) {
85         return 0;
86     }
87
88     for (pciaddr_t mask = 1;; mask <<= 1) {
89         assert(mask != 0);
90         if (base & mask) {
91             /*
92              * Note: we get the actual raw register content here and not
93              *       the bar.base value so no shift.
94              *       - 2014-05-03, RA
95              */
96             return mask;
97         }
98     }
99 }
100
101 void pci_init_datastructures(void)
102 {
103     memset(dev_caps, 0, sizeof(dev_caps));
104 }
105
106 int pci_bar_to_caps_index(uint8_t bus,
107                           uint8_t dev,
108                           uint8_t fun,
109                           uint8_t BAR)
110 {
111     uint8_t i;
112     for (i = 0; i < PCI_NBARS && dev_caps[bus][dev][fun][i].assigned; i++) {
113         if (dev_caps[bus][dev][fun][i].bar_nr == BAR) {
114             return i;
115         }
116     }
117     return -1;
118 }
119
120 int pci_get_bar_nr_for_index(uint8_t bus,
121                             uint8_t dev,
122                             uint8_t fun,
123                             uint8_t idx)
124 {
125     return (dev_caps[bus][dev][fun][idx].bar_nr);
126 }
127
128 int pci_get_nr_caps_for_bar(uint8_t bus,
129                             uint8_t dev,
130                             uint8_t fun,
131                             uint8_t idx)
132 {
133     return (dev_caps[bus][dev][fun][idx].nr_caps);
134 }
135
136 struct capref pci_get_bar_cap_for_device(uint8_t bus,
137                                      uint8_t dev,
138                                      uint8_t fun,
139                                      uint8_t idx,
140                                      int cap_nr)
141 {
142     return (dev_caps[bus][dev][fun][idx].frame_cap[cap_nr]);
143 }
144 uint8_t pci_get_bar_cap_type_for_device(uint8_t bus,
145                                     uint8_t dev,
146                                     uint8_t fun,
147                                     uint8_t idx)
148 {
149     return (dev_caps[bus][dev][fun][idx].type);
150 }
151
152 static errval_t alloc_device_bar(uint8_t idx,
153                                  uint8_t bus,
154                                  uint8_t dev,
155                                  uint8_t fun,
156                                  uint8_t BAR,
157                                  pciaddr_t base,
158                                  pciaddr_t high,
159                                  pcisize_t size)
160 {
161     struct acpi_binding* acl = get_acpi_binding();
162
163     struct device_caps *c = &dev_caps[bus][dev][fun][idx];
164     errval_t err;
165     size = ROUND_UP(size, BASE_PAGE_SIZE); // Some BARs are less than 4 KiB
166
167     // first try with maximally-sized caps (we'll reduce this if it doesn't work)
168     uint8_t bits = log2ceil(size);
169
170     restart: ;
171     pcisize_t framesize = 1UL << bits;
172     c->nr_caps = size / framesize;
173     PCI_DEBUG("nr caps for one BAR of size %"PRIuPCISIZE": %lu\n", size,
174               c->nr_caps);
175
176     c->phys_cap = malloc(c->nr_caps * sizeof(struct capref));
177     if (c->phys_cap == NULL) {
178         return PCI_ERR_MEM_ALLOC;
179     }
180
181     for (int i = 0; i < c->nr_caps; i++) {
182         /*err = mm_alloc_range(&pci_mm_physaddr, bits, base + i * framesize,
183          base + (i + 1) * framesize, &c->phys_cap[i], NULL);*/
184         errval_t error_code;
185         err = slot_alloc(&c->phys_cap[i]);
186         assert(err_is_ok(err));
187         err = acl->rpc_tx_vtbl.mm_alloc_range_proxy(acl, bits, base + i * framesize,
188                                              base + (i + 1) * framesize,
189                                              &c->phys_cap[i], &error_code);
190         assert(err_is_ok(err));
191         err = error_code;
192         if (err_is_fail(err)) {
193             PCI_DEBUG("mm_alloc_range() failed: bits = %hhu, base = %"PRIxPCIADDR","
194                       " end = %"PRIxPCIADDR"\n", bits, base + i * framesize,
195                       base + (i + 1) * framesize);
196             if (err_no(err) == MM_ERR_MISSING_CAPS && bits > PAGE_BITS) {
197                 /* try again with smaller page-sized caps */
198                 for (int j = 0; j < i; j++) {
199                     err = acl->rpc_tx_vtbl.mm_free_proxy(acl, c->phys_cap[i],
200                                                   base + j * framesize, bits,
201                                                   &error_code);
202                     assert(err_is_ok(err) && err_is_ok(error_code));
203                 }
204
205                 free(c->phys_cap);
206                 bits = PAGE_BITS;
207                 goto restart;
208             } else {
209                 return err;
210             }
211         }
212     }
213
214     c->frame_cap = malloc(c->nr_caps * sizeof(struct capref));
215     if (c->frame_cap == NULL) {
216         /* TODO: mm_free() */
217         free(c->phys_cap);
218         return PCI_ERR_MEM_ALLOC;
219     }
220
221     for (int i = 0; i < c->nr_caps; i++) {
222         err = devframe_type(&c->frame_cap[i], c->phys_cap[i], bits);
223         if (err_is_fail(err)) {
224             PCI_DEBUG("devframe_type() failed: bits = %hhu, base = %"PRIxPCIADDR
225                       ", doba = %"PRIxPCIADDR"\n", bits, base, base + (1UL << bits));
226             return err;
227         }
228     }
229
230     c->bits = bits;
231     c->bar_nr = BAR;
232     c->assigned = true;
233     c->type = 0;
234
235     return SYS_ERR_OK;
236 }
237
238 //XXX: FIXME: HACK: BAD!!! Only needed to allocate a full I/O range cap to
239 //                         the VESA graphics driver
240 static errval_t assign_complete_io_range(uint8_t idx,
241                                          uint8_t bus,
242                                          uint8_t dev,
243                                          uint8_t fun,
244                                          uint8_t BAR)
245 {
246     dev_caps[bus][dev][fun][idx].frame_cap = (struct capref*) malloc(
247                     sizeof(struct capref));
248     errval_t err = slot_alloc(&(dev_caps[bus][dev][fun][idx].frame_cap[0]));
249     assert(err_is_ok(err));
250     err = cap_copy(dev_caps[bus][dev][fun][idx].frame_cap[0], cap_io);
251     assert(err_is_ok(err));
252
253     dev_caps[bus][dev][fun][idx].bits = 16;
254     dev_caps[bus][dev][fun][idx].bar_nr = BAR;
255     dev_caps[bus][dev][fun][idx].assigned = true;
256     dev_caps[bus][dev][fun][idx].type = 1;
257     dev_caps[bus][dev][fun][idx].nr_caps = 1;
258     return SYS_ERR_OK;
259 }
260
261 errval_t device_init(uint32_t class_code,
262                      uint32_t sub_class,
263                      uint32_t prog_if,
264                      uint32_t vendor_id,
265                      uint32_t device_id,
266                      uint32_t *bus,
267                      uint32_t *dev,
268                      uint32_t *fun,
269                      bool *pcie,
270                      int *nr_allocated_bars)
271 {
272     *nr_allocated_bars = 0;
273
274     errval_t err;
275     char s_bus[10], s_dev[10], s_fun[10], s_vendor_id[10], s_device_id[10];
276     char s_class_code[10], s_sub_class[10], s_prog_if[10];
277     char s_pcie[5];
278     int error_code;
279     int bar_nr;
280     pciaddr_t bar_base, bar_high;
281     pcisize_t bar_size;
282
283     if (*bus != PCI_DONT_CARE) {
284         snprintf(s_bus, sizeof(s_bus), "%"PRIu32"", *bus);
285     } else {
286         strncpy(s_bus, "Bus", sizeof(s_bus));
287     }
288     if (*dev != PCI_DONT_CARE) {
289         snprintf(s_dev, sizeof(s_dev), "%"PRIu32, *dev);
290     } else {
291         strncpy(s_dev, "Dev", sizeof(s_dev));
292     }
293     if (*fun != PCI_DONT_CARE) {
294         snprintf(s_fun, sizeof(s_fun), "%"PRIu32, *fun);
295     } else {
296         strncpy(s_fun, "Fun", sizeof(s_fun));
297     }
298     if (vendor_id != PCI_DONT_CARE) {
299         snprintf(s_vendor_id, sizeof(s_vendor_id), "%"PRIu32, vendor_id);
300     } else {
301         strncpy(s_vendor_id, "Ven", sizeof(s_vendor_id));
302     }
303     if (device_id != PCI_DONT_CARE) {
304         snprintf(s_device_id, sizeof(s_device_id), "%"PRIu32, device_id);
305     } else {
306         strncpy(s_device_id, "DevID", sizeof(s_device_id));
307     }
308     if (class_code != PCI_DONT_CARE) {
309         snprintf(s_class_code, sizeof(s_class_code), "%"PRIu32, class_code);
310     } else {
311         strncpy(s_class_code, "Cl", sizeof(s_class_code));
312     }
313     if (sub_class != PCI_DONT_CARE) {
314         snprintf(s_sub_class, sizeof(s_sub_class), "%"PRIu32, sub_class);
315     } else {
316         strncpy(s_sub_class, "Sub", sizeof(s_sub_class));
317     }
318     if (prog_if != PCI_DONT_CARE) {
319         snprintf(s_prog_if, sizeof(s_prog_if), "%"PRIu32, prog_if);
320     } else {
321         strncpy(s_prog_if, "ProgIf", sizeof(s_prog_if));
322     }
323
324     PCI_DEBUG("device_init(): Searching device %s, %s, %s, %s, %s, %s, %s, %s\n",
325               s_bus, s_dev, s_fun, s_vendor_id, s_device_id, s_class_code,
326               s_sub_class, s_prog_if);
327
328 //find the device: Unify all values
329     error_code = skb_execute_query(
330                     "device(PCIE,addr(%s, %s, %s), %s, %s, %s, %s, %s, _),"
331                     "writeln(d(PCIE,%s,%s,%s,%s,%s,%s,%s,%s)).",
332                     s_bus, s_dev, s_fun, s_vendor_id, s_device_id, s_class_code,
333                     s_sub_class, s_prog_if, s_bus, s_dev, s_fun, s_vendor_id,
334                     s_device_id, s_class_code, s_sub_class, s_prog_if);
335     if (error_code != 0) {
336
337         PCI_DEBUG("pci.c: device_init(): SKB returnd error code %s\n",
338                   err_getcode(error_code));
339
340         PCI_DEBUG("SKB returned: %s\n", skb_get_output());
341         PCI_DEBUG("SKB error returned: %s\n", skb_get_error_output());
342
343         return PCI_ERR_DEVICE_INIT;
344     }
345
346     err = skb_read_output("d(%[a-z], %"PRIu32", %"PRIu32", %"PRIu32", %"PRIu32
347                           ",%"PRIu32", %"PRIu32", %"PRIu32", %"PRIu32").",
348                           s_pcie, bus, dev, fun, &vendor_id, &device_id,
349                           &class_code, &sub_class, &prog_if);
350
351     if (err_is_fail(err)) {
352         DEBUG_ERR(err, "skb read output\n");
353
354         PCI_DEBUG("device_init(): Could not read the SKB's output for the device\n");
355         PCI_DEBUG("device_init(): SKB returned: %s\n", skb_get_output());
356         PCI_DEBUG("device_init(): SKB error returned: %s\n",
357                   skb_get_error_output());
358         return err_push(err, PCI_ERR_DEVICE_INIT);
359     }
360     if (strncmp(s_pcie, "pcie", strlen("pcie")) == 0) {
361         *pcie = true;
362     } else {
363         *pcie = false;
364     }
365
366     PCI_DEBUG("device_init(): Found device at %u:%u:%u\n", *bus, *dev, *fun);
367     //get the implemented BARs for the found device
368     error_code = skb_execute_query("pci_get_implemented_BAR_addresses(%"PRIu32
369                                    ",%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32",%"
370                                    PRIu32",%"PRIu32",%"PRIu32",L),length(L,Len)"
371                                    ",writeln(L)", *bus, *dev, *fun, vendor_id,
372                                    device_id, class_code, sub_class, prog_if);
373
374     if (error_code != 0) {
375         PCI_DEBUG("pci.c: device_init(): SKB returnd error code %d\n",
376                   error_code);
377
378         PCI_DEBUG("SKB returned: %s\n", skb_get_output());
379         PCI_DEBUG("SKB error returned: %s\n", skb_get_error_output());
380
381         return PCI_ERR_DEVICE_INIT;
382     }
383
384     struct list_parser_status status;
385     skb_read_list_init(&status);
386
387     //iterate over all buselements
388     while (skb_read_list(&status, "baraddr(%d, %"PRIuPCIADDR", %"PRIuPCIADDR", "
389                          "%"PRIuPCISIZE")", &bar_nr, &bar_base, &bar_high, &bar_size)) {
390         err = alloc_device_bar(*nr_allocated_bars, *bus, *dev, *fun, bar_nr,
391                                bar_base, bar_high, bar_size);
392
393         PCI_DEBUG("device_init(): BAR %d: base = %"PRIxPCIADDR ", size = %"
394                   PRIxPCISIZE"\n", bar_nr, bar_base, bar_size);
395
396         if (err_is_fail(err)) {
397             PCI_DEBUG("device_init(): Could not allocate cap for BAR %d\n", bar_nr);
398             return err_push(err, PCI_ERR_DEVICE_INIT);
399         }
400         (*nr_allocated_bars)++;
401     }
402
403 //XXX: FIXME: HACK: BAD!!! Only needed to allocate a full I/O range cap to
404 //                         the VESA graphics driver
405     if (class_code == PCI_CLASS_DISPLAY) {
406         assert(*nr_allocated_bars < PCI_NBARS);
407         err = assign_complete_io_range(*nr_allocated_bars, *bus, *dev, *fun,
408                                        5 /*very BAAAD */);
409         (*nr_allocated_bars)++;
410     }
411 //end of badness
412
413     PCI_DEBUG("device_init(): Allocated caps for %d BARs\n", *nr_allocated_bars);
414
415     PCI_DEBUG("enable busmaster for device (%u, %u, %u)...\n", *bus, *dev, *fun);
416     enable_busmaster(*bus, *dev, *fun, *pcie);
417
418     return SYS_ERR_OK;
419 }
420
421 errval_t device_reregister_interrupt(uint8_t coreid, int vector,
422                  uint32_t class_code, uint32_t sub_class, uint32_t prog_if,
423                  uint32_t vendor_id, uint32_t device_id, uint32_t *bus,
424                  uint32_t *dev,uint32_t *fun)
425 {
426     errval_t err;
427     char s_bus[10], s_dev[10], s_fun[10], s_vendor_id[10], s_device_id[10];
428     char s_class_code[10], s_sub_class[10], s_prog_if[10];
429     char s_pcie[5];
430     bool pcie;
431     int error_code;
432
433     if (*bus != PCI_DONT_CARE) {
434         snprintf(s_bus, sizeof(s_bus), "%"PRIu32"", *bus);
435     } else {
436         strncpy(s_bus, "Bus", sizeof(s_bus));
437     }
438     if (*dev != PCI_DONT_CARE) {
439         snprintf(s_dev, sizeof(s_dev), "%"PRIu32, *dev);
440     } else {
441         strncpy(s_dev, "Dev", sizeof(s_dev));
442     }
443     if (*fun != PCI_DONT_CARE) {
444         snprintf(s_fun, sizeof(s_fun), "%"PRIu32, *fun);
445     } else {
446         strncpy(s_fun, "Fun", sizeof(s_fun));
447     }
448     if (vendor_id != PCI_DONT_CARE) {
449         snprintf(s_vendor_id, sizeof(s_vendor_id), "%"PRIu32, vendor_id);
450     } else {
451         strncpy(s_vendor_id, "Ven", sizeof(s_vendor_id));
452     }
453     if (device_id != PCI_DONT_CARE) {
454         snprintf(s_device_id, sizeof(s_device_id), "%"PRIu32, device_id);
455     } else {
456         strncpy(s_device_id, "DevID", sizeof(s_device_id));
457     }
458     if (class_code != PCI_DONT_CARE) {
459         snprintf(s_class_code, sizeof(s_class_code), "%"PRIu32, class_code);
460     } else {
461         strncpy(s_class_code, "Cl", sizeof(s_class_code));
462     }
463     if (sub_class != PCI_DONT_CARE) {
464         snprintf(s_sub_class, sizeof(s_sub_class), "%"PRIu32, sub_class);
465     } else {
466         strncpy(s_sub_class, "Sub", sizeof(s_sub_class));
467     }
468     if (prog_if != PCI_DONT_CARE) {
469         snprintf(s_prog_if, sizeof(s_prog_if), "%"PRIu32, prog_if);
470     } else {
471         strncpy(s_prog_if, "ProgIf", sizeof(s_prog_if));
472     }
473
474     PCI_DEBUG("device_init(): Searching device %s, %s, %s, %s, %s, %s, %s, %s\n",
475         s_bus, s_dev, s_fun, s_vendor_id, s_device_id, s_class_code,
476         s_sub_class, s_prog_if);
477
478 //find the device: Unify all values
479     error_code = skb_execute_query(
480         "device(PCIE,addr(%s, %s, %s), %s, %s, %s, %s, %s, _),"
481         "writeln(d(PCIE,%s,%s,%s,%s,%s,%s,%s,%s)).",
482         s_bus, s_dev, s_fun, s_vendor_id, s_device_id, s_class_code,
483         s_sub_class, s_prog_if,
484         s_bus, s_dev, s_fun, s_vendor_id, s_device_id, s_class_code,
485         s_sub_class, s_prog_if
486     );
487     if (error_code != 0) {
488
489         PCI_DEBUG("pci.c: device_init(): SKB returnd error code %s\n",
490             err_getcode(error_code));
491
492         PCI_DEBUG("SKB returned: %s\n", skb_get_output());
493         PCI_DEBUG("SKB error returned: %s\n", skb_get_error_output());
494
495         return PCI_ERR_DEVICE_INIT;
496     }
497
498     err = skb_read_output("d(%[a-z], %"PRIu32", %"PRIu32", %"PRIu32", %"PRIu32
499                           ",%"PRIu32", %"PRIu32", %"PRIu32", %"PRIu32").",
500                     s_pcie, bus, dev, fun, &vendor_id,
501                     &device_id, &class_code, &sub_class, &prog_if);
502
503     if (err_is_fail(err)) {
504         DEBUG_ERR(err, "skb read output\n");
505
506         PCI_DEBUG("device_init(): Could not read the SKB's output for the device\n");
507         PCI_DEBUG("device_init(): SKB returned: %s\n", skb_get_output());
508         PCI_DEBUG("device_init(): SKB error returned: %s\n", skb_get_error_output());
509         return err_push(err,PCI_ERR_DEVICE_INIT);
510     }
511     if(strncmp(s_pcie, "pcie", strlen("pcie")) == 0) {
512         pcie = true;
513     } else {
514         pcie = false;
515     }
516
517
518     PCI_DEBUG("device_init(): Found device at %u:%u:%u\n",
519                 *bus, *dev, *fun);
520 //get the implemented BARs for the found device
521
522     int irq = pci_setup_interrupt(*bus, *dev, *fun);
523     PCI_DEBUG("pci: init_device_handler_irq: init interrupt.\n");
524     PCI_DEBUG("pci: irq = %u, core = %hhu, vector = %u\n",
525             irq, coreid, vector);
526     struct acpi_binding* cl = get_acpi_binding();
527     errval_t ret_error;
528     err = cl->rpc_tx_vtbl.enable_and_route_interrupt(cl, irq, coreid, vector, &ret_error);
529     assert(err_is_ok(err));
530     assert(err_is_ok(ret_error)); // FIXME
531     //        printf("IRQ for this device is %d\n", irq);
532     //DEBUG_ERR(err, "enable_and_route_interrupt");
533     pci_enable_interrupt_for_device(*bus, *dev, *fun, pcie);
534
535     return SYS_ERR_OK;
536 }
537
538 void pci_enable_interrupt_for_device(uint32_t bus, uint32_t dev, uint32_t fun,
539                                     bool pcie)
540 {
541     struct pci_address addr = { .bus = (uint8_t)(bus & 0xff),
542                                 .device = (uint8_t)(dev & 0xff),
543                                 .function = (uint8_t)(fun % 0xff) };
544
545     pci_hdr0_t hdr;
546     pci_hdr0_initialize(&hdr, addr);
547
548     if (pcie) {
549         pcie_enable();
550     } else {
551         pcie_disable();
552     }
553
554     pci_hdr0_command_t cmd = pci_hdr0_command_rd(&hdr);
555     cmd.int_dis = 0;
556     pci_hdr0_command_wr(&hdr, cmd);
557 }
558
559 /**
560  * This function performs a recursive, depth-first search through the
561  * PCI hierarchy starting at parentaddr (this should initially be a
562  * PCI root complex), with bus number A. It enters whatever it
563  * discovers (bridges and devices) into the SKB.
564  *
565  * Refer to http://www.tldp.org/LDP/tlk/dd/pci.html for an overview of
566  * a similar discovery algorithm.
567  *
568  * Upon discovery of a bridge, it sets the bridge's primary bus number
569  * to A and assigns a secondary bus number of A + 2. The subordinate
570  * bus number is set to A + 3. This way, buses are spaced 2 apart,
571  * which is sometimes required for SR-IOV hot-plugged buses.
572  */
573 static void assign_bus_numbers(struct pci_address parentaddr,
574                                uint8_t *busnum,
575                                uint8_t maxchild,
576                                char* handle)
577 {
578     struct pci_address addr = {
579         .bus = parentaddr.bus
580     };
581
582     pcie_enable();
583
584     // First go through all bridges on this bus and disable them
585     for (addr.device = 0; addr.device < PCI_NDEVICES; addr.device++) {
586         for (addr.function = 0; addr.function < PCI_NFUNCTIONS; addr.function++) {
587             pci_hdr1_t bhdr;
588             pci_hdr1_initialize(&bhdr, addr);
589
590             uint16_t vendor = pci_hdr1_vendor_id_rd(&bhdr);
591
592             if (vendor == 0xffff) {
593                 if (addr.function == 0) {
594                     // this device doesn't exist at all
595                     break;
596                 } else {
597                     // this function doesn't exist, but there may be others
598                     continue;
599                 }
600             }
601
602             pci_hdr1_hdr_type_t hdr_type = pci_hdr1_hdr_type_rd(&bhdr);
603             if (hdr_type.fmt == pci_hdr1_pci2pci) {
604                 PCI_DEBUG("Disabling bridge (%u,%u,%u)\n", addr.bus, addr.device,
605                           addr.function);
606
607                 pci_hdr1_bcfg_t bcfg = pci_hdr1_bcfg_rd(&bhdr);
608                 bcfg.pri_bus = 0;
609                 bcfg.sec_bus = 0;
610                 bcfg.sub_bus = 0;
611                 pci_hdr1_bcfg_wr(&bhdr, bcfg);
612             }
613         }
614     }
615
616     for (addr.device = 0; addr.device < PCI_NDEVICES; addr.device++) {
617         for (addr.function = 0; addr.function < PCI_NFUNCTIONS; addr.function++) {
618             pci_hdr0_t hdr;
619             pci_hdr0_initialize(&hdr, addr);
620
621             pcie_enable();
622             uint16_t pcie_vendor = pci_hdr0_vendor_id_rd(&hdr);
623             uint16_t vendor = pcie_vendor;
624             bool pcie = true;
625             bool extended_caps = false;  // Whether to scan for PCI Express extended caps
626
627             // Disable PCIe if device exists only in PCI
628             if (pcie_vendor != 0xffff) {
629                 vendor = pcie_vendor;
630                 pcie = true;
631             } else {
632                 pcie_disable();
633                 vendor = pci_hdr0_vendor_id_rd(&hdr);
634                 pcie = false;
635             }
636
637             if (vendor == 0xffff) {
638                 if (addr.function == 0) {
639                     // this device doesn't exist at all
640                     break;
641                 } else {
642                     // this function doesn't exist, but there may be others
643                     continue;
644                 }
645             }
646             pci_hdr0_class_code_t classcode = pci_hdr0_class_code_rd(&hdr);
647             uint16_t device_id = pci_hdr0_device_id_rd(&hdr);
648
649             /* Disable all decoders for this device,
650              * they will be re-enabled as devices are setup.
651              * NB: we are using "pci_hdr1" here, but the command field is
652              * common to all configuration header types.
653              */
654             /* PCI_DEBUG("disabling decoders for (%hhu,%hhu,%hhu)\n", */
655             /*     addr.bus, addr.device, addr.function); */
656             pci_hdr0_command_t cmd = pci_hdr0_command_rd(&hdr);
657
658             cmd.mem_space = 0;
659             cmd.io_space = 0;  // XXX: not handled in setup yet
660
661             // Ticket #210
662             //XXX: This should be set to 0 and only enabled if needed
663             //     (whenever a driver attaches to a device).
664             //     For bridges the pci driver enables the bit later when
665             //     programming the bridge window
666 //            cmd.master = 0;
667
668             // Ticket 229
669             //pci_hdr0_command_wr(&hdr, cmd);
670
671             // do we have a bridge?
672             pci_hdr0_hdr_type_t hdr_type = pci_hdr0_hdr_type_rd(&hdr);
673             if (hdr_type.fmt == pci_hdr0_pci2pci) {
674                 pci_hdr1_t bhdr;
675                 pci_hdr1_initialize(&bhdr, addr);
676
677                 //ACPI_HANDLE child;
678                 char* child = malloc(acpi__read_irq_table_response_child_MAX_ARGUMENT_SIZE);
679                 assert(child);
680                 errval_t error_code;
681                 PCI_DEBUG("get irq table for (%hhu,%hhu,%hhu)\n", (*busnum) + 2,
682                           addr.device, addr.function);
683                 struct acpi_binding* cl = get_acpi_binding();
684                 // XXX: why do we have two different types for the same thing?
685                 acpi_pci_address_t xaddr = {
686                     .bus = addr.bus,
687                     .device = addr.device,
688                     .function = addr.function,
689                 };
690                 errval_t err = cl->rpc_tx_vtbl.read_irq_table(cl, handle, xaddr, (*busnum) + 2,
691                                         &error_code, child);
692                 if (err_is_ok(err) && error_code == ACPI_ERR_NO_CHILD_BRIDGE){
693                     PCI_DEBUG("No corresponding ACPI entry for bridge found\n");
694                 } else if (err_is_fail(err) || err_is_fail(error_code)) {
695                     DEBUG_ERR(error_code, "Reading IRQs failed");
696                 }
697
698                 // Increase by 2 to leave room for SR-IOV
699                 (*busnum) += 2;
700                 //assert(*busnum <= maxchild);
701
702                 PCI_DEBUG("program busses for bridge (%hhu,%hhu,%hhu)\n"
703                           "primary: %hhu, secondary: %hhu, subordinate: %hhu\n",
704                           addr.bus, addr.device, addr.function, addr.bus, *busnum,
705                           (*busnum) + 1);
706
707                 // Disable master abort mode on the bridge
708                 pci_hdr1_brdg_ctrl_mabort_wrf(&bhdr, 0);
709
710                 // Clear all errors
711                 pci_hdr1_status_wr_raw(&bhdr, 0);
712
713                 // program bus numbers for this bridge
714                 pci_hdr1_bcfg_t bcfg = pci_hdr1_bcfg_rd(&bhdr);
715                 bcfg.pri_bus = addr.bus;
716                 bcfg.sec_bus = *busnum;
717                 bcfg.sub_bus = 0xff;
718                 pci_hdr1_bcfg_wr(&bhdr, bcfg);
719
720                 skb_add_fact("bridge(%s,addr(%u,%u,%u),%u,%u,%u,%u,%u, secondary(%hhu)).",
721                              (pcie ? "pcie" : "pci"), addr.bus, addr.device,
722                              addr.function, vendor, device_id, classcode.clss,
723                              classcode.subclss, classcode.prog_if, *busnum);
724
725                 //use the original hdr (pci_hdr0_t) here
726                 query_bars(hdr, addr, true);
727
728                 // assign bus numbers to secondary bus
729                 struct pci_address bridge_addr = {
730                     .bus = *busnum,
731                     .device = addr.device,
732                     .function = addr.function
733                 };
734                 assign_bus_numbers(bridge_addr, busnum, maxchild, child);
735                 // Restore the old state of pcie. The above call changes this
736                 // state according to the devices under this bridge
737                 if (pcie) {
738                     pcie_enable();
739                 } else {
740                     pcie_disable();
741                 }
742
743                 // Set this bridge's subordinate to the maximum of the underlying hierarchy
744                 pci_hdr1_bcfg_sub_bus_wrf(&bhdr, (*busnum) + 1);
745             }
746
747             //is this a normal PCI device?
748             if (hdr_type.fmt == pci_hdr0_nonbridge) {
749                 PCI_DEBUG("Found device (%u, %u, %u), vendor = %x, device = %x\n",
750                           addr.bus, addr.device, addr.function, vendor,
751                           device_id);
752
753                 pci_hdr0_t devhdr;
754                 pci_hdr0_initialize(&devhdr, addr);
755                 skb_add_fact("device(%s,addr(%u,%u,%u),%u,%u,%u, %u, %u, %d).",
756                              (pcie ? "pcie" : "pci"), addr.bus, addr.device,
757                              addr.function, vendor, device_id, classcode.clss,
758                              classcode.subclss, classcode.prog_if,
759                              pci_hdr0_int_pin_rd(&devhdr) - 1);
760
761                 // octopus start
762                 static char* device_fmt = "hw.pci.device. { "
763                                 "bus: %u, device: %u, function: %u, "
764                                 "vendor: %u, device_id: %u, class: %u, "
765                                 "subclass: %u, prog_if: %u }";
766
767                 errval_t err = oct_mset(SET_SEQUENTIAL, device_fmt, addr.bus,
768                                         addr.device, addr.function, vendor,
769                                         device_id, classcode.clss,
770                                         classcode.subclss, classcode.prog_if);
771
772                 assert(err_is_ok(err));
773                 // end octopus
774
775                 query_bars(devhdr, addr, false);
776
777                 // Process device capabilities if existing
778                 if (pci_hdr0_status_rd(&devhdr).caplist) {
779                     uint8_t cap_ptr = pci_hdr0_cap_ptr_rd(&devhdr);
780
781                     // Walk capabilities list
782                     while (cap_ptr != 0) {
783                         assert(cap_ptr % 4 == 0 && cap_ptr >= 0x40);
784                         uint32_t capword = pci_read_conf_header(&addr,
785                                                                 cap_ptr / 4);
786
787                         switch (capword & 0xff) {
788                             case 0x10:  // PCI Express
789                                 PCI_DEBUG("PCI Express device\n");
790                                 extended_caps = true;
791                                 break;
792
793                             default:
794                                 PCI_DEBUG("Unknown PCI device capability 0x%x at 0x%x\n",
795                                           capword & 0xff, cap_ptr);
796                                 break;
797                         }
798
799                         cap_ptr = (capword >> 8) & 0xff;
800                     }
801                 }
802
803                 // Process extended device capabilities if existing
804                 if (pcie && extended_caps && addr.bus < pcie_get_endbus()) {
805                     uint32_t *ad = (uint32_t *) pcie_confspace_access(addr);
806                     assert(ad != NULL);
807                     uint16_t cap_ptr = 0x100;
808
809                     while (cap_ptr != 0) {
810                         uint32_t capword = *(ad + (cap_ptr / 4));
811                         assert(cap_ptr % 4 == 0 && cap_ptr >= 0x100
812                                && cap_ptr < 0x1000);
813
814                         switch (capword & 0xffff) {  // Switch on capability ID
815                             case 0:
816                                 // No extended caps
817                                 break;
818
819                             case 16:
820                                 // SR-IOV capability
821                                 {
822                                 /*
823                                  * XXX: When using our e1000 driver with the
824                                  *      I350 network card (device id 0x152x),
825                                  *      the configuration fails when VF are
826                                  *      enabled: Legacy descriptors are ignored
827                                  *      when VF are enabled. Same goes for e10k
828                                  */
829                                 if (vendor == 0x8086 && (device_id & 0xFFF0) == 0x1520) {
830                                     debug_printf("skipping SR IOV initialization"
831                                                     "for e1000 card.\n");
832                                     break;
833                                 }
834                 
835                                 if (vendor == 0x8086 && (device_id  == 0x10FB)) {
836                                     debug_printf("skipping SR IOV initialization"
837                                                     "for e10k card.\n");
838                                     break;
839                                 }
840
841                                 pci_sr_iov_cap_t sr_iov_cap;
842                                 pci_sr_iov_cap_initialize(&sr_iov_cap,
843                                      (mackerel_addr_t) (ad + (cap_ptr / 4)));
844
845                                 PCI_DEBUG("Found SR-IOV capability\n");
846
847                                 // Support version 1 for the moment
848                                 assert(pci_sr_iov_cap_hdr_ver_rdf(&sr_iov_cap) == 1);
849
850                                 // Support system page size of 4K at the moment
851                                 assert(pci_sr_iov_cap_sys_psize_rd(&sr_iov_cap)
852                                        == 1);
853
854 #if 0   // Dump cap contents
855                                 pci_sr_iov_cap_caps_pr(str, 256, &sr_iov_cap);
856                                 PCI_DEBUG("%s\n", str);
857                                 pci_sr_iov_cap_ctrl_pr(str, 256, &sr_iov_cap);
858                                 PCI_DEBUG("%s\n", str);
859                                 pci_sr_iov_cap_status_pr(str, 256, &sr_iov_cap);
860                                 PCI_DEBUG("%s\n", str);
861                                 pci_sr_iov_cap_initialvfs_pr(str, 256, &sr_iov_cap);
862                                 PCI_DEBUG("%s\n", str);
863                                 pci_sr_iov_cap_totalvfs_pr(str, 256, &sr_iov_cap);
864                                 PCI_DEBUG("%s\n", str);
865                                 pci_sr_iov_cap_numvfs_pr(str, 256, &sr_iov_cap);
866                                 PCI_DEBUG("%s\n", str);
867                                 pci_sr_iov_cap_fdl_pr(str, 256, &sr_iov_cap);
868                                 PCI_DEBUG("%s\n", str);
869                                 pci_sr_iov_cap_offset_pr(str, 256, &sr_iov_cap);
870                                 PCI_DEBUG("%s\n", str);
871                                 pci_sr_iov_cap_stride_pr(str, 256, &sr_iov_cap);
872                                 PCI_DEBUG("%s\n", str);
873                                 pci_sr_iov_cap_devid_pr(str, 256, &sr_iov_cap);
874                                 PCI_DEBUG("%s\n", str);
875                                 pci_sr_iov_cap_sup_psize_pr(str, 256, &sr_iov_cap);
876                                 PCI_DEBUG("%s\n", str);
877                                 pci_sr_iov_cap_sys_psize_pr(str, 256, &sr_iov_cap);
878                                 PCI_DEBUG("%s\n", str);
879 #endif
880
881                                 if (max_numvfs > 0) {
882                                     // Set maximum number of VFs
883                                     uint16_t totalvfs = pci_sr_iov_cap_totalvfs_rd( &sr_iov_cap);
884                                     uint16_t numvfs = MIN(totalvfs, max_numvfs);
885                                     //                  uint16_t numvfs = 8;
886                                     PCI_DEBUG("Maximum supported VFs: %u. Enabling: %u\n",
887                                               totalvfs, numvfs);
888                                     pci_sr_iov_cap_numvfs_wr(&sr_iov_cap, numvfs);
889
890                                     uint16_t offset = pci_sr_iov_cap_offset_rd(&sr_iov_cap);
891                                     uint16_t stride = pci_sr_iov_cap_stride_rd(&sr_iov_cap);
892                                     uint16_t vf_devid = pci_sr_iov_cap_devid_rd(&sr_iov_cap);
893
894                                     PCI_DEBUG("VF offset is 0x%x, stride is 0x%x, "
895                                               "device ID is 0x%x\n",
896                                               offset, stride, vf_devid);
897
898 #if 0
899                                     // Make sure we enable the PF
900                                     cmd = pci_hdr0_command_rd(&hdr);
901                                     cmd.mem_space = 1;
902                                     cmd.io_space = 1;
903                                     /* cmd.master = 1; */
904                                     pci_hdr0_command_wr(&hdr, cmd);
905 #endif
906
907                                     // Start VFs (including memory spaces)
908                                     pci_sr_iov_cap_ctrl_vf_mse_wrf(&sr_iov_cap, 1);
909                                     pci_sr_iov_cap_ctrl_vf_enable_wrf(&sr_iov_cap, 1);
910
911                                     // Spec says to wait here for at least 100ms
912                                     err = barrelfish_usleep(100000);
913                                     assert(err_is_ok(err));
914
915                                     // Add all VFs
916                                     for (int vfn = 0; vfn < numvfs; vfn++) {
917                                         uint8_t busnr = addr.bus + ((((addr.device << 3)
918                                                                  + addr.function)
919                                                                  + offset
920                                                                  + stride * vfn)
921                                                                  >> 8);
922                                         uint8_t devfn = (((addr.device << 3)
923                                                         + addr.function)
924                                                         + offset
925                                                         + stride * vfn)
926                                                         & 0xff;
927                                         struct pci_address vf_addr = {
928                                             .bus = busnr,
929                                             .device = devfn >> 3,
930                                             .function = devfn & 7,
931                                         };
932
933                                         PCI_DEBUG("Adding VF (%u, %u, %u)\n",
934                                                   vf_addr.bus, vf_addr.device,
935                                                   vf_addr.function);
936
937                                         skb_add_fact("device(%s,addr(%u,%u,%u),%u,%u,%u, %u, %u, %d).",
938                                                      (pcie ? "pcie" : "pci"),
939                                                      vf_addr.bus,
940                                                      vf_addr.device,
941                                                      vf_addr.function, vendor,
942                                                      vf_devid, classcode.clss,
943                                                      classcode.subclss,
944                                                      classcode.prog_if, 0);
945
946                                         // octopus start
947                                         device_fmt ="hw.pci.device. { "
948                                                      "bus: %u, device: %u, function: %u, "
949                                                      "vendor: %u, device_id: %u, class: %u, "
950                                                      "subclass: %u, prog_if: %u }";
951                                         err = oct_mset(SET_SEQUENTIAL,
952                                                        device_fmt,
953                                                        vf_addr.bus,
954                                                        vf_addr.device,
955                                                        vf_addr.function,
956                                                        vendor, vf_devid,
957                                                        classcode.clss,
958                                                        classcode.subclss,
959                                                        classcode.prog_if);
960
961                                         assert(err_is_ok(err));
962                                         // end octopus
963
964                                         // We probe the BARs several times. Strictly
965                                         // speaking, this is not necessary, as we
966                                         // can calculate all offsets, but we're
967                                         // lazy...
968                                         pci_hdr0_bar32_t bar, barorigaddr;
969                                         for (int i = 0; i < pci_sr_iov_cap_vf_bar_length; i++) {
970                                             union pci_hdr0_bar32_un orig_value;
971                                             orig_value.raw = pci_sr_iov_cap_vf_bar_rd(&sr_iov_cap, i);
972                                             barorigaddr = orig_value.val;
973
974                                             // probe BAR to see if it is implemented
975                                             pci_sr_iov_cap_vf_bar_wr(&sr_iov_cap, i, BAR_PROBE);
976
977                                             union pci_hdr0_bar32_un bar_value;
978                                             bar_value.raw = pci_sr_iov_cap_vf_bar_rd(&sr_iov_cap, i);
979                                             bar = (union pci_hdr0_bar32_un ) {
980                                                         .raw =bar_value.raw
981                                                    }.val;
982
983                                             //write original value back to the BAR
984                                             pci_sr_iov_cap_vf_bar_wr(&sr_iov_cap,
985                                                                  i, orig_value.raw);
986
987                                             /*
988                                              * We need to check the entire register
989                                              * here to make sure the bar is not
990                                              * implemented as it could lie in the
991                                              * high 64 bit range...
992                                              */
993                                             if (bar_value.raw == 0) {
994                                                 // BAR not implemented
995                                                 continue;
996                                             }
997
998                                             // SR-IOV doesn't support IO space BARs
999                                             assert(bar.space == 0);
1000                                             int type = -1;
1001                                             if (bar.tpe == pci_hdr0_bar_32bit) {
1002                                                 type = 32;
1003                                             }
1004                                             if (bar.tpe == pci_hdr0_bar_64bit) {
1005                                                 type = 64;
1006                                             }
1007
1008                                             if (bar.tpe == pci_hdr0_bar_64bit) {
1009                                                 //read the upper 32bits of the address
1010                                                 pci_hdr0_bar32_t bar_high, barorigaddr_high;
1011                                                 union pci_hdr0_bar32_un orig_value_high;
1012                                                 orig_value_high.raw = pci_sr_iov_cap_vf_bar_rd(&sr_iov_cap, i + 1);
1013                                                 barorigaddr_high = orig_value_high.val;
1014
1015                                                 // probe BAR to determine the mapping size
1016                                                 pci_sr_iov_cap_vf_bar_wr(&sr_iov_cap, i + 1, BAR_PROBE);
1017
1018                                                 bar_high = (union pci_hdr0_bar32_un ) {
1019                                                               .raw =pci_sr_iov_cap_vf_bar_rd(&sr_iov_cap,i + 1)
1020                                                             }.val;
1021
1022                                                 //write original value back to the BAR
1023                                                 pci_sr_iov_cap_vf_bar_wr(&sr_iov_cap,
1024                                                           i + 1, orig_value_high.raw);
1025
1026                                                 pciaddr_t base64 = bar_high.base;
1027                                                 base64 <<= 32;
1028                                                 base64 |= bar.base << 7;
1029
1030                                                 pciaddr_t origbase64 = barorigaddr_high.base;
1031                                                 origbase64 <<= 32;
1032                                                 origbase64 |= barorigaddr.base << 7;
1033
1034                                                 PCI_DEBUG("(%u,%u,%u): 64bit BAR %d at 0x%"
1035                                                           PRIxPCIADDR ", size %" PRIx64 ", %s\n",
1036                                                           vf_addr.bus, vf_addr.device,
1037                                                           vf_addr.function, i,
1038                                                           (origbase64 << 7) + bar_mapping_size64(base64) * vfn,
1039                                                           bar_mapping_size64(base64),
1040                                                           (bar.prefetch == 1 ? "prefetchable" : "nonprefetchable"));
1041
1042                                                 skb_add_fact("bar(addr(%u, %u, %u), %d, 16'%"
1043                                                              PRIxPCIADDR", ""16'%" PRIx64 ", vf, %s, %d).",
1044                                                              vf_addr.bus, vf_addr.device, vf_addr.function, i,
1045                                                              (origbase64 << 7) + bar_mapping_size64(base64) * vfn,
1046                                                              bar_mapping_size64(base64),
1047                                                              (bar.prefetch == 1 ? "prefetchable" : "nonprefetchable"),
1048                                                              type);
1049
1050                                                 i++;  //step one forward, because it is a 64bit BAR
1051                                             } else {
1052                                                 PCI_DEBUG("(%u,%u,%u): 32bit BAR %d at 0x%" PRIx32 ", size %x, %s\n",
1053                                                           vf_addr.bus, vf_addr.device, vf_addr.function, i,
1054                                                           (barorigaddr.base << 7) + bar_mapping_size(bar) * vfn,
1055                                                           bar_mapping_size(bar),
1056                                                           (bar.prefetch == 1 ? "prefetchable" : "nonprefetchable"));
1057
1058                                                 //32bit BAR
1059                                                 skb_add_fact("bar(addr(%u, %u, %u), %d, 16'%"PRIx32", 16'%"
1060                                                              PRIx32 ", vf, %s, %d).", vf_addr.bus,
1061                                                              vf_addr.device, vf_addr.function, i,
1062                                                              (uint32_t) ((barorigaddr.base << 7)
1063                                                                          + bar_mapping_size( bar) * vfn),
1064                                                              (uint32_t) bar_mapping_size(bar),
1065                                                              (bar.prefetch == 1 ? "prefetchable" : "nonprefetchable"),
1066                                                              type);
1067                                             }
1068                                         }
1069                                     }
1070                                 }
1071                             }
1072                                 break;
1073
1074                             default:
1075                                 PCI_DEBUG("Unknown extended PCI device capability 0x%x at 0x%x\n",
1076                                           capword & 0xffff, cap_ptr);
1077                                 break;
1078                         }
1079
1080                         cap_ptr = capword >> 20;
1081                     }
1082                 }
1083             }
1084
1085             if(hdr_type.fmt == pci_hdr0_cardbus) {
1086                 printf("PCI: WARNING: Found cardbus bridge.\n");
1087             }
1088             // is this a multi-function device?
1089             if (addr.function == 0 && !hdr_type.multi) {
1090                 break;
1091             }
1092         }
1093     }
1094
1095     free(handle);
1096     
1097 }
1098
1099 #if 0
1100 static void get_bridges(struct pci_address myad)
1101 {
1102     struct pci_address addr = {.bus = myad.bus};
1103
1104     pcie_enable();
1105
1106     // First go through all bridges on this bus and disable them
1107     for (addr.device = 0; addr.device < PCI_NDEVICES; addr.device++) {
1108         for (addr.function = 0; addr.function < PCI_NFUNCTIONS; addr.function++) {
1109             pci_hdr1_t bhdr;
1110             pci_hdr1_initialize(&bhdr, addr);
1111
1112             uint16_t vendor = pci_hdr1_vendor_id_rd(&bhdr);
1113
1114             if (vendor == 0xffff) {
1115                 if (addr.function == 0) {
1116                     // this device doesn't exist at all
1117                     break;
1118                 } else {
1119                     // this function doesn't exist, but there may be others
1120                     continue;
1121                 }
1122             }
1123
1124             pci_hdr1_hdr_type_t hdr_type = pci_hdr1_hdr_type_rd(&bhdr);
1125             if (hdr_type.fmt == pci_hdr1_pci2pci) {
1126                 pci_hdr1_bcfg_t bcfg = pci_hdr1_bcfg_rd(&bhdr);
1127
1128                 PCI_DEBUG("Found bridge (%u,%u,%u), primary %u, secondary %u, subordinate %u\n",
1129                                 addr.bus, addr.device, addr.function,
1130                                 bcfg.pri_bus, bcfg.sec_bus, bcfg.sub_bus);
1131
1132                 struct pci_address bridge_addr= {
1133                     .bus = bcfg.sec_bus, .device = addr.device,
1134                     .function = addr.function
1135                 };
1136
1137                 get_bridges(bridge_addr);
1138             }
1139         }
1140     }
1141 }
1142 #endif
1143
1144 void pci_add_root(struct pci_address addr,
1145                   uint8_t maxchild,
1146                   char* handle)
1147 {
1148     uint8_t busnum = addr.bus;
1149     /* get_bridges(addr); */
1150     assign_bus_numbers(addr, &busnum, maxchild, handle);
1151     /* get_bridges(addr); */
1152 }
1153
1154 errval_t pci_setup_root_complex(void)
1155 {
1156     errval_t err;
1157     char* record = NULL;
1158     char** names = NULL;
1159     size_t len = 0;
1160
1161     // TODO: react to new rootbridges
1162     err = oct_get_names(&names, &len, "r'hw.pci.rootbridge.[0-9]+' "
1163                         "{ acpi_node: _, bus: _, device: _, function: _, maxbus: _ }");
1164     if (err_is_fail(err)) {
1165         DEBUG_ERR(err, "get names");
1166         goto out;
1167     }
1168
1169     for (size_t i = 0; i < len; i++) {
1170         err = oct_get(&record, names[i]);
1171         if (err_is_fail(err)) {
1172             goto out;
1173         }
1174
1175         PCI_DEBUG("found new root complex: %s\n", record);
1176
1177         char* acpi_node = NULL;  // freed in pci_add_root
1178         int64_t bus, device, function, maxbus;
1179         static char* format =
1180                         "_ { acpi_node: %s, bus: %d, device: %d, function: %d, maxbus: %d }";
1181         err = oct_read(record, format, &acpi_node, &bus, &device, &function,
1182                        &maxbus);
1183         if (err_is_fail(err)) {
1184             free(acpi_node);
1185             free(record);
1186             goto out;
1187         }
1188
1189         struct pci_address addr;
1190         addr.bus = (uint8_t) bus;
1191         addr.device = (uint8_t) device;
1192         addr.function = (uint8_t) function;
1193
1194         pcie_enable();
1195         pci_add_root(addr, maxbus, acpi_node);
1196         pcie_disable();
1197     }
1198
1199     out: oct_free_names(names, len);
1200     return err;
1201 }
1202
1203 //query all BARs. That means, get the original address, the mapping size
1204 //and all attributes.
1205
1206 // XXX: asq: We are using this function to program also the _two_ BARs
1207 //           of a PCI-to-PCI bridge. They are at the same offset within the
1208 //           PCI header like for any PCI device. PCI HDR0 is misused
1209 //           here for the bridges.
1210
1211 static void query_bars(pci_hdr0_t devhdr,
1212                        struct pci_address addr,
1213                        bool pci2pci_bridge)
1214 {
1215     pci_hdr0_bar32_t bar, barorigaddr;
1216
1217     int maxbars = pci2pci_bridge ? 1 : pci_hdr0_bars_length;
1218     for (int i = 0; i <= maxbars; i++) {
1219         union pci_hdr0_bar32_un orig_value;
1220         orig_value.raw = pci_hdr0_bars_rd(&devhdr, i);
1221         barorigaddr = orig_value.val;
1222
1223         // probe BAR to determine the mapping size
1224         pci_hdr0_bars_wr(&devhdr, i, BAR_PROBE);
1225
1226         uint32_t bar_value = pci_hdr0_bars_rd(&devhdr, i);
1227
1228         bar = (union pci_hdr0_bar32_un ) { .raw = bar_value }.val;
1229
1230         //write original value back to the BAR
1231         pci_hdr0_bars_wr(&devhdr, i, orig_value.raw);
1232
1233         /*
1234          * Cannot just compare the base value, with addresses over 4G there
1235          * will be a problem. Thus we need to check if the entire register is
1236          * zero. If it is a 32bit register, then the address part will be filled.
1237          * If it is a 64bit register, the type will contain a nonzero value.
1238          * - 2014-05-02, RA
1239          */
1240         if (bar_value == 0) {
1241             // BAR not implemented
1242             continue;
1243         }
1244
1245         if (bar.space == 0) {  // memory mapped
1246             //bar(addr(bus, device, function), barnr, orig address, size, space,
1247             //         prefetchable?, 64bit?).
1248             //where space = mem | io, prefetchable= prefetchable | nonprefetchable,
1249             //64bit = 64bit | 32bit.
1250
1251             int type = -1;
1252             if (bar.tpe == pci_hdr0_bar_32bit) {
1253                 type = 32;
1254             }
1255             if (bar.tpe == pci_hdr0_bar_64bit) {
1256                 type = 64;
1257             }
1258
1259             if (bar.tpe == pci_hdr0_bar_64bit) {
1260                 //we must take the next BAR into account and do the same
1261                 //tests like in the 32bit case, but this time with the combined
1262                 //value from the current and the next BAR, since a 64bit BAR
1263                 //is constructed out of two consequtive 32bit BARs
1264
1265                 //read the upper 32bits of the address
1266                 uint32_t orig_value_high = pci_hdr0_bars_rd(&devhdr, i + 1);
1267
1268                 // probe BAR to determine the mapping size
1269                 pci_hdr0_bars_wr(&devhdr, i + 1, BAR_PROBE);
1270
1271                 // read the size information of the bar
1272                 uint32_t bar_value_high = pci_hdr0_bars_rd(&devhdr, i + 1);
1273
1274                 //write original value back to the BAR
1275                 pci_hdr0_bars_wr(&devhdr, i + 1, orig_value_high);
1276
1277                 pciaddr_t base64 = 0, origbase64 = 0;
1278                 base64 = bar_value_high;
1279                 base64 <<= 32;
1280                 base64 |= (uint32_t) (bar.base << 7);
1281
1282                 origbase64 = orig_value_high;
1283                 origbase64 <<= 32;
1284                 origbase64 |= (uint32_t) (barorigaddr.base << 7);
1285
1286                 PCI_DEBUG("(%u,%u,%u): 64bit BAR %d at 0x%" PRIxPCIADDR ", size %"
1287                           PRIx64 ", %s\n", addr.bus, addr.device, addr.function,
1288                           i, origbase64, bar_mapping_size64(base64),
1289                           (bar.prefetch == 1 ? "prefetchable" : "nonprefetchable"));
1290
1291               PCI_DEBUG("(%u,%u,%u): 64bit BAR %d at 0x%" PRIxPCIADDR ", size %" PRIx64 ", %s\n",
1292                         addr.bus, addr.device, addr.function,
1293                         i, origbase64 << 7, bar_mapping_size64(base64),
1294                         (bar.prefetch == 1 ? "prefetchable" : "nonprefetchable"));
1295
1296                 skb_add_fact("bar(addr(%u, %u, %u), %d, 16'%"PRIxPCIADDR", "
1297                              "16'%" PRIx64 ", mem, %s, %d).", addr.bus,
1298                              addr.device, addr.function, i, origbase64,
1299                              bar_mapping_size64(base64),
1300                              (bar.prefetch == 1 ? "prefetchable" : "nonprefetchable"),
1301                              type);
1302
1303                 i++;  //step one forward, because it is a 64bit BAR
1304             } else {
1305               PCI_DEBUG("(%u,%u,%u): 32bit BAR %d at 0x%" PRIx32 ", size %x, %s\n",
1306                         addr.bus, addr.device, addr.function,
1307                         i, barorigaddr.base << 7, bar_mapping_size(bar),
1308                         (bar.prefetch == 1 ? "prefetchable" : "nonprefetchable"));
1309
1310                 //32bit BAR
1311                 skb_add_fact("bar(addr(%u, %u, %u), %d, 16'%"PRIx32", 16'%" PRIx32
1312                              ", mem, %s, %d).", addr.bus, addr.device, addr.function,
1313                              i, (uint32_t) (barorigaddr.base << 7),
1314                              (uint32_t) bar_mapping_size(bar),
1315                              (bar.prefetch == 1 ? "prefetchable" : "nonprefetchable"),
1316                              type);
1317             }
1318         } else {
1319           PCI_DEBUG("(%u,%u,%u): IO BAR %d at 0x%x, size %x\n",
1320                     addr.bus, addr.device, addr.function,
1321                     i, barorigaddr.base << 7, bar_mapping_size(bar));
1322             //bar(addr(bus, device, function), barnr, orig address, size, space).
1323             //where space = mem | io
1324             skb_add_fact("bar(addr(%u, %u, %u), %d, 16'%"PRIx32", 16'%" PRIx32 ", io, "
1325                          "nonprefetchable, 32).", addr.bus, addr.device, addr.function, i,
1326                          (uint32_t) (barorigaddr.base << 7), (uint32_t) bar_mapping_size(bar));
1327         }
1328     }
1329 }
1330
1331 static void program_bridge_window(uint8_t bus,
1332                                   uint8_t dev,
1333                                   uint8_t fun,
1334                                   pciaddr_t base,
1335                                   pciaddr_t high,
1336                                   bool pcie,
1337                                   bool mem,
1338                                   bool pref)
1339 {
1340     struct pci_address addr;
1341     pci_hdr1_prefbl_t pref_reg;
1342     pci_hdr1_command_t cmd;
1343
1344     if (pcie) {
1345         pcie_enable();
1346     } else {
1347         pcie_disable();
1348     }
1349
1350     assert((base & 0x000fffff) == 0);
1351     assert((high & 0x000fffff) == 0x000fffff);
1352
1353     addr.bus = bus;
1354     addr.device = dev;
1355     addr.function = fun;
1356
1357     pci_hdr1_t bridgehdr;
1358     pci_hdr1_initialize(&bridgehdr, addr);
1359
1360     cmd = pci_hdr1_command_rd(&bridgehdr);
1361
1362     if (mem) {
1363         if (pref) {
1364             pci_hdr1_pref_base_upper_wr(&bridgehdr, base >> 32);
1365             pci_hdr1_pref_limit_upper_wr(&bridgehdr, high >> 32);
1366             /*
1367              * The least significant nibble of this register value (1h)
1368              * indicates that a 64 bit address decoder is supported and
1369              * that the Upper Base/Limit Registers are also used.
1370              */
1371             if ((base >> 32)) {
1372                 pref_reg.tpe = pci_hdr1_mem_64bit;
1373             } else {
1374                 pref_reg.tpe = pci_hdr1_mem_32bit;
1375             }
1376             pref_reg.val = base >> 20;
1377             pci_hdr1_pref_base_wr(&bridgehdr, pref_reg);
1378             if ((high >> 32)) {
1379                 pref_reg.tpe = pci_hdr1_mem_64bit;
1380             } else {
1381                 pref_reg.tpe = pci_hdr1_mem_32bit;
1382             }
1383             pref_reg.val = high >> 20;
1384             pci_hdr1_pref_limit_wr(&bridgehdr, pref_reg);
1385         } else {
1386             assert((base & 0xffffffff00000000) == 0);
1387             assert((high & 0xffffffff00000000) == 0);
1388             pci_hdr1_membl_t membl = {
1389                 .base = base >> 16,
1390                 .limit = high >> 16,
1391             };
1392             pci_hdr1_membl_wr(&bridgehdr, membl);
1393             /* pci_hdr1_mem_base_wr(&bridgehdr, base >> 16); */
1394             /* pci_hdr1_mem_limit_wr(&bridgehdr, high >> 16); */
1395         }
1396         // enable the memory decoder
1397         cmd.mem_space = 1;
1398     } else {
1399         // I/O
1400     }
1401
1402     cmd.int_dis = 0;
1403     cmd.master = 1;
1404     pci_hdr1_command_wr(&bridgehdr, cmd);
1405 }
1406
1407 static void program_device_bar(uint8_t bus,
1408                                uint8_t dev,
1409                                uint8_t fun,
1410                                int bar,
1411                                pciaddr_t base,
1412                                pcisize_t size,
1413                                int bits,
1414                                bool memspace,
1415                                bool pcie)
1416 {
1417     struct pci_address addr;
1418     addr.bus = bus;
1419     addr.device = dev;
1420     addr.function = fun;
1421
1422     if (pcie) {
1423         pcie_enable();
1424     } else {
1425         pcie_disable();
1426     }
1427
1428     pci_hdr0_t devhdr;
1429     pci_hdr0_initialize(&devhdr, addr);
1430
1431     //disable the address decoder for programming the BARs
1432     pci_hdr0_command_t cmd = pci_hdr0_command_rd(&devhdr);
1433     if (memspace) {
1434         cmd.mem_space = 0;
1435     } else {
1436         cmd.io_space = 0;
1437     }
1438     //disbale interrupts here. enable them as soon as a driver requests
1439     //interrupts
1440     cmd.int_dis = 1;
1441     pci_hdr0_command_wr(&devhdr, cmd);
1442
1443     if (bits == 64) {
1444         pci_hdr0_bars_wr(&devhdr, bar, base & 0xffffffff);
1445         pci_hdr0_bars_wr(&devhdr, bar + 1, base >> 32);
1446     } else {  // 32-bit
1447         assert(base + size <= 0xffffffff);  // 32-bit BAR
1448         pci_hdr0_bars_wr(&devhdr, bar, base);
1449     }
1450
1451     //re-enable the decoder for the BARs
1452     if (memspace) {
1453         cmd.mem_space = 1;
1454     } else {
1455         cmd.io_space = 1;
1456     }
1457     pci_hdr0_command_wr(&devhdr, cmd);
1458 }
1459
1460 static void enable_busmaster(uint8_t bus,
1461                              uint8_t dev,
1462                              uint8_t fun,
1463                              bool pcie)
1464 {
1465     struct pci_address addr;
1466     addr.bus = bus;
1467     addr.device = dev;
1468     addr.function = fun;
1469
1470     if (pcie) {
1471         pcie_enable();
1472     } else {
1473         pcie_disable();
1474     }
1475
1476     pci_hdr0_t devhdr;
1477     pci_hdr0_initialize(&devhdr, addr);
1478
1479     //enable bus master
1480     pci_hdr0_command_t cmd = pci_hdr0_command_rd(&devhdr);
1481     cmd.master = 1;
1482     pci_hdr0_command_wr(&devhdr, cmd);
1483 }
1484
1485 void pci_program_bridges(void)
1486 {
1487     char element_type[7];  // "device" | "bridge"
1488     char bar_secondary[16];  //[0-6] | secondary(<0-255>)
1489     char space[4];  // "mem" | "io"
1490     char prefetch[16];  // "prefetchable" | "nonprefetchable"
1491     char pcie_pci[5];  // "pcie" | "pci"
1492     int bar;  // the value of bar_secondary after parsing secondary(<nr>) to <nr>
1493     uint8_t bus, dev, fun;
1494     pciaddr_t base, high;
1495     pcisize_t size;
1496     int bits;
1497     bool mem, pcie, pref;
1498     char *output = NULL;
1499     int output_length = 0;
1500     int error_code = 0;
1501
1502     /*
1503      output = NULL;
1504      output_length = 0;
1505      skb_execute("listing.");
1506      output = skb_get_output();
1507      assert(output != NULL);
1508      output_length = strlen(output);
1509      PCI_DEBUG("pci_program_bridges: output = %s\n", output);
1510      PCI_DEBUG("pci_program_bridges: output length = %d\n", output_length);
1511
1512      error_code = skb_read_error_code();
1513      if (error_code != 0) {
1514      printf("pci.c: pci_program_bridges(): SKB returnd error code %d\n",
1515      error_code);
1516
1517      const char *errout = skb_get_error_output();
1518      printf("\nSKB error returned: %s\n", errout);
1519      printf("\nSKB output: %s\n", output);
1520      // XXX: no device can be used...
1521      return;
1522      }
1523      */
1524
1525     output = NULL;
1526     output_length = 0;
1527     char bridge_program[512];
1528     snprintf(bridge_program, 512, "[%s], bridge_programming(P, Nr),"
1529              "flatten(P, F),replace_current_BAR_values(F),"
1530              "write(nrelements(Nr)),writeln(P).",
1531              skb_bridge_program);
1532     skb_execute(bridge_program);
1533     output = skb_get_output();
1534     assert(output != NULL);
1535     output_length = strlen(output);
1536     PCI_DEBUG("pci_program_bridges: output = %s\n", output);
1537     PCI_DEBUG("pci_program_bridges: output length = %d\n", output_length);
1538
1539     error_code = skb_read_error_code();
1540     if (error_code != 0) {
1541         printf("pci.c: pci_program_bridges(): SKB returned error code %d\n",
1542                error_code);
1543
1544         const char *errout = skb_get_error_output();
1545         printf("SKB error returned: %s\n", errout);
1546         printf("SKB output: %s\n", output);
1547         // XXX: no device can be used...
1548         printf("WARNING: CONTINUING, HOWEVER PCI DEVICES WILL BE UNUSABLE\n");
1549         // except IO-space devices which aren't yet affected by bridge programming
1550         return;
1551     }
1552
1553     /*
1554      ********************************************************************************
1555      //for the ASPLOS11 paper:
1556      skb_execute("[bridge_page].");
1557      while (skb_read_error_code() == SKB_PROCESSING) messages_wait_and_handle_next();
1558      char *output = skb_get_output();
1559      assert(output != NULL);
1560      int output_length = strlen(output);
1561      PCI_DEBUG("pci_program_bridges: output = %s\n", output);
1562      PCI_DEBUG("pci_program_bridges: output length = %d\n", output_length);
1563
1564      int error_code = skb_read_error_code();
1565      if (error_code != 0) {
1566      printf("pci.c: pci_program_bridges() <2>: SKB returnd error code %d\n",
1567      error_code);
1568
1569      const char *errout = skb_get_error_output();
1570      printf("\nSKB error returned <2>: %s\n", errout);
1571      printf("\nSKB output <2>: %s\n", output);
1572      // XXX: no device can be used...
1573      return;
1574      }
1575      uint64_t start =rdtsc();
1576      //    uint64_t start =rdtscp();
1577      skb_execute("bridge_programming(P, Nr),write(nrelements(Nr)),writeln(P).");
1578      uint64_t end =rdtsc();
1579      //    uint64_t end =rdtscp();
1580      assert(end >= start);
1581
1582      printf("\n\nTicks: %lu\n\n", end - start);
1583      while (skb_read_error_code() == SKB_PROCESSING) messages_wait_and_handle_next();
1584      output = skb_get_output();
1585      assert(output != NULL);
1586      output_length = strlen(output);
1587      printf("pci_program_bridges: output = %s\n", output);
1588      PCI_DEBUG("pci_program_bridges: output length = %d\n", output_length);
1589
1590      error_code = skb_read_error_code();
1591      if (error_code != 0) {
1592      printf("pci.c: pci_program_bridges() <3>: SKB returnd error code %d\n",
1593      error_code);
1594
1595      const char *errout = skb_get_error_output();
1596      printf("\nSKB error returned <3>: %s\n", errout);
1597      printf("\nSKB output <3>: %s\n", output);
1598      // XXX: no device can be used...
1599      return;
1600      }
1601      ********************************************************************************
1602      */
1603
1604     //get the number of buselements from the output
1605     int nr_elements;
1606     int nr_conversions;
1607     nr_conversions = sscanf(output, "nrelements(%d)", &nr_elements);
1608     if (nr_conversions != 1) {
1609         printf("pci.c: No valid pci plan returned by the SKB\n.");
1610         //XXX: no device can be used
1611         return;
1612     }
1613
1614     //keep a pointer to the current location within the output
1615     char *conv_ptr = output;
1616
1617     //iterate over all buselements
1618     for (int i = 0; i < nr_elements; i++) {
1619         // search the beginning of the next buselement
1620         while ((conv_ptr < output + output_length) && (strncmp(
1621                         conv_ptr, "buselement", strlen("buselement"))
1622                                                        != 0)) {
1623             conv_ptr++;
1624         }
1625         //convert the string to single elements and numbers
1626         nr_conversions = sscanf(conv_ptr, "buselement(%[a-z], addr(%hhu, %hhu, %hhu), "
1627                                 "%[a-z0-9()], %"PRIuPCIADDR", %"PRIuPCIADDR", "
1628                                 "%"PRIuPCISIZE", %[a-z], %[a-z], %[a-z], %d",
1629                                 element_type, &bus, &dev, &fun, bar_secondary,
1630                                 &base, &high, &size, space, prefetch, pcie_pci,
1631                                 &bits);
1632         conv_ptr++;
1633         if (nr_conversions != 12) {
1634             printf("Could not parse output for device or bridge number %d\n"
1635                    "nr conversions: %d\n",
1636                    i, nr_conversions);
1637             continue;
1638         }
1639         if (strncmp(space, "mem", strlen("mem")) == 0) {
1640             mem = true;
1641         } else {
1642             mem = false;
1643         }
1644         if (strncmp(pcie_pci, "pcie", strlen("pcie")) == 0) {
1645             pcie = true;
1646         } else {
1647             pcie = false;
1648         }
1649         if (strncmp(prefetch, "prefetchable", strlen("prefetchable")) == 0) {
1650             pref = true;
1651         } else {
1652             pref = false;
1653         }
1654
1655         // Skip virtual functions
1656         if (strncmp(space, "vf", strlen("vf")) == 0) {
1657             /* PCI_DEBUG("Skipping VF addr(%hhu, %hhu, %hhu)\n", */
1658             /*      bus, dev, fun); */
1659             continue;
1660         }
1661
1662         if (strncmp(element_type, "device", strlen("device")) == 0) {
1663             nr_conversions = sscanf(bar_secondary, "%d", &bar);
1664             if (nr_conversions != 1) {
1665                 printf("Could not determine BAR number while programming BAR\n");
1666                 continue;
1667             }
1668             PCI_DEBUG("programming %s addr(%hhu, %hhu, %hhu), BAR %d, with base = "
1669                       "%"PRIxPCIADDR", high = %"PRIxPCIADDR", size = %"PRIxPCISIZE
1670                       " in" "space = %s, prefetch = %s, %s...\n",
1671                       element_type, bus, dev, fun, bar, base, high, size, space,
1672                       prefetch, pcie ? "PCIe" : "PCI");
1673             program_device_bar(bus, dev, fun, bar, base, size, bits, mem, pcie);
1674
1675         } else {
1676             PCI_DEBUG("programming %s addr(%hhu, %hhu, %hhu), with base = "
1677                       "%"PRIxPCIADDR", high = %"PRIxPCIADDR", size = %"PRIxPCISIZE
1678                       " in space = %s, prefetch = %s...\n",
1679                       element_type, bus, dev, fun, base, high, size, space,
1680                       prefetch);
1681             //a bridge expects the high address excluding the last byte which
1682             //is the base for the next bridge => decrement by one
1683             high--;
1684             program_bridge_window(bus, dev, fun, base, high, pcie, mem, pref);
1685         }
1686     }
1687 }
1688
1689 uint32_t pci_setup_interrupt(uint32_t bus,
1690                          uint32_t dev,
1691                          uint32_t fun)
1692 {
1693     char str[256], ldev[128];
1694
1695     snprintf(str, 256, "[\"irq_routing.pl\"], assigndeviceirq(addr(%"PRIu32
1696                        ", %"PRIu32", %"PRIu32")).",
1697                        bus, dev, fun);
1698     char *output, *error_out;
1699     int32_t int_err;
1700     errval_t err = skb_evaluate(str, &output, &error_out, &int_err);
1701     assert(output != NULL);
1702     assert(err_is_ok(err));
1703
1704     uint8_t irq;
1705     sscanf(output, "%s %hhu", ldev, &irq);
1706
1707     // It's a GSI
1708     if (strcmp(ldev, "fixedGsi") == 0) {
1709         printf("Got GSI %u\n", irq);
1710         return irq;
1711     }
1712
1713     struct acpi_binding* cl = get_acpi_binding();
1714     errval_t error_code;
1715     err = cl->rpc_tx_vtbl.set_device_irq(cl, ldev, irq, &error_code);
1716     assert(err_is_ok(err));
1717     if (err_is_fail(error_code)) {
1718         //DEBUG_ERR(error_code, "set device irq failed.");
1719         return 0;
1720     }
1721
1722     return irq;
1723 }