5 * This file walks through the PCI bus, enumarates each device and gathers
6 * informatiom about each device.
10 * Copyright (c) 2007, 2008, 2009, 2010, 2011, ETH Zurich.
11 * All rights reserved.
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.
21 #include <barrelfish/barrelfish.h>
22 #include <barrelfish/deferred.h>
24 #include <pci/devids.h>
27 #include <octopus/getset.h>
28 #include <acpi_client/acpi_client.h>
29 #include <dev/pci_sr_iov_cap_dev.h>
32 #include "ht_config.h"
33 #include <dev/ht_config_dev.h>
34 #include "pci_debug.h"
36 #define MIN(a,b) ((a) < (b) ? (a) : (b))
38 #define BAR_PROBE 0xffffffff
40 #define PAGE_BITS BASE_PAGE_BITS
44 struct capref *phys_cap;
45 struct capref *frame_cap;
49 bool assigned; //false => this entry is not in use
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;
58 query_bars(pci_hdr0_t devhdr,
59 struct pci_address addr,
63 setup_interrupt(uint32_t bus,
67 enable_busmaster(uint8_t bus,
72 static uint32_t bar_mapping_size(pci_hdr0_bar32_t bar)
78 for (uint32_t mask = 1;; mask <<= 1) {
80 if (bar.base & mask) {
86 static pciaddr_t bar_mapping_size64(uint64_t base)
92 for (pciaddr_t mask = 1;; mask <<= 1) {
96 * Note: we get the actual raw register content here and not
97 * the bar.base value so no shift.
105 void pci_init_datastructures(void)
107 memset(dev_caps, 0, sizeof(dev_caps));
110 int pci_bar_to_caps_index(uint8_t bus,
116 for (i = 0; i < PCI_NBARS && dev_caps[bus][dev][fun][i].assigned; i++) {
117 if (dev_caps[bus][dev][fun][i].bar_nr == BAR) {
124 int pci_get_bar_nr_for_index(uint8_t bus,
129 return (dev_caps[bus][dev][fun][idx].bar_nr);
132 int pci_get_nr_caps_for_bar(uint8_t bus,
137 return (dev_caps[bus][dev][fun][idx].nr_caps);
140 struct capref pci_get_bar_cap_for_device(uint8_t bus,
146 return (dev_caps[bus][dev][fun][idx].frame_cap[cap_nr]);
148 uint8_t pci_get_bar_cap_type_for_device(uint8_t bus,
153 return (dev_caps[bus][dev][fun][idx].type);
156 static errval_t alloc_device_bar(uint8_t idx,
165 struct acpi_rpc_client* acl = get_acpi_rpc_client();
167 struct device_caps *c = &dev_caps[bus][dev][fun][idx];
170 // first try with maximally-sized caps (we'll reduce this if it doesn't work)
171 uint8_t bits = log2ceil(size);
174 pcisize_t framesize = 1UL << bits;
175 c->nr_caps = size / framesize;
176 PCI_DEBUG("nr caps for one BAR of size %"PRIuPCISIZE": %lu\n", size,
179 c->phys_cap = malloc(c->nr_caps * sizeof(struct capref));
180 if (c->phys_cap == NULL) {
181 return PCI_ERR_MEM_ALLOC;
184 for (int i = 0; i < c->nr_caps; i++) {
185 /*err = mm_alloc_range(&pci_mm_physaddr, bits, base + i * framesize,
186 base + (i + 1) * framesize, &c->phys_cap[i], NULL);*/
188 err = acl->vtbl.mm_alloc_range_proxy(acl, bits, base + i * framesize,
189 base + (i + 1) * framesize,
190 &c->phys_cap[i], &error_code);
191 assert(err_is_ok(err));
193 if (err_is_fail(err)) {
194 PCI_DEBUG("mm_alloc_range() failed: bits = %hhu, base = %"PRIxPCIADDR","
195 " end = %"PRIxPCIADDR"\n", bits, base + i * framesize,
196 base + (i + 1) * framesize);
197 if (err_no(err) == MM_ERR_MISSING_CAPS && bits > PAGE_BITS) {
198 /* try again with smaller page-sized caps */
199 for (int j = 0; j < i; j++) {
200 err = acl->vtbl.mm_free_proxy(acl, c->phys_cap[i],
201 base + j * framesize, bits,
203 assert(err_is_ok(err) && err_is_ok(error_code));
215 c->frame_cap = malloc(c->nr_caps * sizeof(struct capref));
216 if (c->frame_cap == NULL) {
217 /* TODO: mm_free() */
219 return PCI_ERR_MEM_ALLOC;
222 for (int i = 0; i < c->nr_caps; i++) {
223 err = devframe_type(&c->frame_cap[i], c->phys_cap[i], bits);
224 if (err_is_fail(err)) {
225 PCI_DEBUG("devframe_type() failed: bits = %hhu, base = %"PRIxPCIADDR
226 ", doba = %"PRIxPCIADDR"\n", bits, base, base + (1UL << bits));
239 //XXX: FIXME: HACK: BAD!!! Only needed to allocate a full I/O range cap to
240 // the VESA graphics driver
241 static errval_t assign_complete_io_range(uint8_t idx,
247 dev_caps[bus][dev][fun][idx].frame_cap = (struct capref*) malloc(
248 sizeof(struct capref));
249 errval_t err = slot_alloc(&(dev_caps[bus][dev][fun][idx].frame_cap[0]));
250 assert(err_is_ok(err));
251 err = cap_copy(dev_caps[bus][dev][fun][idx].frame_cap[0], cap_io);
252 assert(err_is_ok(err));
254 dev_caps[bus][dev][fun][idx].bits = 16;
255 dev_caps[bus][dev][fun][idx].bar_nr = BAR;
256 dev_caps[bus][dev][fun][idx].assigned = true;
257 dev_caps[bus][dev][fun][idx].type = 1;
258 dev_caps[bus][dev][fun][idx].nr_caps = 1;
262 errval_t device_init(uint32_t class_code,
271 int *nr_allocated_bars)
273 *nr_allocated_bars = 0;
276 char s_bus[10], s_dev[10], s_fun[10], s_vendor_id[10], s_device_id[10];
277 char s_class_code[10], s_sub_class[10], s_prog_if[10];
281 pciaddr_t bar_base, bar_high;
284 if (*bus != PCI_DONT_CARE) {
285 snprintf(s_bus, sizeof(s_bus), "%"PRIu32"", *bus);
287 strncpy(s_bus, "Bus", sizeof(s_bus));
289 if (*dev != PCI_DONT_CARE) {
290 snprintf(s_dev, sizeof(s_dev), "%"PRIu32, *dev);
292 strncpy(s_dev, "Dev", sizeof(s_dev));
294 if (*fun != PCI_DONT_CARE) {
295 snprintf(s_fun, sizeof(s_fun), "%"PRIu32, *fun);
297 strncpy(s_fun, "Fun", sizeof(s_fun));
299 if (vendor_id != PCI_DONT_CARE) {
300 snprintf(s_vendor_id, sizeof(s_vendor_id), "%"PRIu32, vendor_id);
302 strncpy(s_vendor_id, "Ven", sizeof(s_vendor_id));
304 if (device_id != PCI_DONT_CARE) {
305 snprintf(s_device_id, sizeof(s_device_id), "%"PRIu32, device_id);
307 strncpy(s_device_id, "DevID", sizeof(s_device_id));
309 if (class_code != PCI_DONT_CARE) {
310 snprintf(s_class_code, sizeof(s_class_code), "%"PRIu32, class_code);
312 strncpy(s_class_code, "Cl", sizeof(s_class_code));
314 if (sub_class != PCI_DONT_CARE) {
315 snprintf(s_sub_class, sizeof(s_sub_class), "%"PRIu32, sub_class);
317 strncpy(s_sub_class, "Sub", sizeof(s_sub_class));
319 if (prog_if != PCI_DONT_CARE) {
320 snprintf(s_prog_if, sizeof(s_prog_if), "%"PRIu32, prog_if);
322 strncpy(s_prog_if, "ProgIf", sizeof(s_prog_if));
325 PCI_DEBUG("device_init(): Searching device %s, %s, %s, %s, %s, %s, %s, %s\n",
326 s_bus, s_dev, s_fun, s_vendor_id, s_device_id, s_class_code,
327 s_sub_class, s_prog_if);
329 //find the device: Unify all values
330 error_code = skb_execute_query(
331 "device(PCIE,addr(%s, %s, %s), %s, %s, %s, %s, %s, _),"
332 "writeln(d(PCIE,%s,%s,%s,%s,%s,%s,%s,%s)).",
333 s_bus, s_dev, s_fun, s_vendor_id, s_device_id, s_class_code,
334 s_sub_class, s_prog_if, s_bus, s_dev, s_fun, s_vendor_id,
335 s_device_id, s_class_code, s_sub_class, s_prog_if);
336 if (error_code != 0) {
338 PCI_DEBUG("pci.c: device_init(): SKB returnd error code %s\n",
339 err_getcode(error_code));
341 PCI_DEBUG("SKB returned: %s\n", skb_get_output());
342 PCI_DEBUG("SKB error returned: %s\n", skb_get_error_output());
344 return PCI_ERR_DEVICE_INIT;
347 err = skb_read_output("d(%[a-z], %"PRIu32", %"PRIu32", %"PRIu32", %"PRIu32
348 ",%"PRIu32", %"PRIu32", %"PRIu32", %"PRIu32").",
349 s_pcie, bus, dev, fun, &vendor_id, &device_id,
350 &class_code, &sub_class, &prog_if);
352 if (err_is_fail(err)) {
353 DEBUG_ERR(err, "skb read output\n");
355 PCI_DEBUG("device_init(): Could not read the SKB's output for the device\n");
356 PCI_DEBUG("device_init(): SKB returned: %s\n", skb_get_output());
357 PCI_DEBUG("device_init(): SKB error returned: %s\n",
358 skb_get_error_output());
359 return err_push(err, PCI_ERR_DEVICE_INIT);
361 if (strncmp(s_pcie, "pcie", strlen("pcie")) == 0) {
367 PCI_DEBUG("device_init(): Found device at %u:%u:%u\n", *bus, *dev, *fun);
368 //get the implemented BARs for the found device
369 error_code = skb_execute_query("pci_get_implemented_BAR_addresses(%"PRIu32
370 ",%"PRIu32",%"PRIu32",%"PRIu32",%"PRIu32",%"
371 PRIu32",%"PRIu32",%"PRIu32",L),length(L,Len)"
372 ",writeln(L)", *bus, *dev, *fun, vendor_id,
373 device_id, class_code, sub_class, prog_if);
375 if (error_code != 0) {
376 PCI_DEBUG("pci.c: device_init(): SKB returnd error code %d\n",
379 PCI_DEBUG("SKB returned: %s\n", skb_get_output());
380 PCI_DEBUG("SKB error returned: %s\n", skb_get_error_output());
382 return PCI_ERR_DEVICE_INIT;
385 struct list_parser_status status;
386 skb_read_list_init(&status);
388 //iterate over all buselements
389 while (skb_read_list(&status, "baraddr(%d, %"PRIuPCIADDR", %"PRIuPCIADDR", "
390 "%"PRIuPCISIZE")", &bar_nr, &bar_base, &bar_high, &bar_size)) {
391 err = alloc_device_bar(*nr_allocated_bars, *bus, *dev, *fun, bar_nr,
392 bar_base, bar_high, bar_size);
394 PCI_DEBUG("device_init(): BAR %d: base = %"PRIxPCIADDR ", size = %"
395 PRIxPCISIZE"\n", bar_nr, bar_base, bar_size);
397 if (err_is_fail(err)) {
398 PCI_DEBUG("device_init(): Could not allocate cap for BAR %d\n", bar_nr);
399 return err_push(err, PCI_ERR_DEVICE_INIT);
401 (*nr_allocated_bars)++;
404 //XXX: FIXME: HACK: BAD!!! Only needed to allocate a full I/O range cap to
405 // the VESA graphics driver
406 if (class_code == PCI_CLASS_DISPLAY) {
407 assert(*nr_allocated_bars < PCI_NBARS);
408 err = assign_complete_io_range(*nr_allocated_bars, *bus, *dev, *fun,
410 (*nr_allocated_bars)++;
414 PCI_DEBUG("device_init(): Allocated caps for %d BARs\n", *nr_allocated_bars);
416 PCI_DEBUG("enable busmaster for device (%u, %u, %u)...\n", *bus, *dev, *fun);
417 enable_busmaster(*bus, *dev, *fun, *pcie);
422 errval_t device_reregister_interrupt(uint8_t coreid, int vector,
423 uint32_t class_code, uint32_t sub_class, uint32_t prog_if,
424 uint32_t vendor_id, uint32_t device_id, uint32_t *bus,
425 uint32_t *dev,uint32_t *fun)
428 char s_bus[10], s_dev[10], s_fun[10], s_vendor_id[10], s_device_id[10];
429 char s_class_code[10], s_sub_class[10], s_prog_if[10];
434 if (*bus != PCI_DONT_CARE) {
435 snprintf(s_bus, sizeof(s_bus), "%"PRIu32"", *bus);
437 strncpy(s_bus, "Bus", sizeof(s_bus));
439 if (*dev != PCI_DONT_CARE) {
440 snprintf(s_dev, sizeof(s_dev), "%"PRIu32, *dev);
442 strncpy(s_dev, "Dev", sizeof(s_dev));
444 if (*fun != PCI_DONT_CARE) {
445 snprintf(s_fun, sizeof(s_fun), "%"PRIu32, *fun);
447 strncpy(s_fun, "Fun", sizeof(s_fun));
449 if (vendor_id != PCI_DONT_CARE) {
450 snprintf(s_vendor_id, sizeof(s_vendor_id), "%"PRIu32, vendor_id);
452 strncpy(s_vendor_id, "Ven", sizeof(s_vendor_id));
454 if (device_id != PCI_DONT_CARE) {
455 snprintf(s_device_id, sizeof(s_device_id), "%"PRIu32, device_id);
457 strncpy(s_device_id, "DevID", sizeof(s_device_id));
459 if (class_code != PCI_DONT_CARE) {
460 snprintf(s_class_code, sizeof(s_class_code), "%"PRIu32, class_code);
462 strncpy(s_class_code, "Cl", sizeof(s_class_code));
464 if (sub_class != PCI_DONT_CARE) {
465 snprintf(s_sub_class, sizeof(s_sub_class), "%"PRIu32, sub_class);
467 strncpy(s_sub_class, "Sub", sizeof(s_sub_class));
469 if (prog_if != PCI_DONT_CARE) {
470 snprintf(s_prog_if, sizeof(s_prog_if), "%"PRIu32, prog_if);
472 strncpy(s_prog_if, "ProgIf", sizeof(s_prog_if));
475 PCI_DEBUG("device_init(): Searching device %s, %s, %s, %s, %s, %s, %s, %s\n",
476 s_bus, s_dev, s_fun, s_vendor_id, s_device_id, s_class_code,
477 s_sub_class, s_prog_if);
479 //find the device: Unify all values
480 error_code = skb_execute_query(
481 "device(PCIE,addr(%s, %s, %s), %s, %s, %s, %s, %s, _),"
482 "writeln(d(PCIE,%s,%s,%s,%s,%s,%s,%s,%s)).",
483 s_bus, s_dev, s_fun, s_vendor_id, s_device_id, s_class_code,
484 s_sub_class, s_prog_if,
485 s_bus, s_dev, s_fun, s_vendor_id, s_device_id, s_class_code,
486 s_sub_class, s_prog_if
488 if (error_code != 0) {
490 PCI_DEBUG("pci.c: device_init(): SKB returnd error code %s\n",
491 err_getcode(error_code));
493 PCI_DEBUG("SKB returned: %s\n", skb_get_output());
494 PCI_DEBUG("SKB error returned: %s\n", skb_get_error_output());
496 return PCI_ERR_DEVICE_INIT;
499 err = skb_read_output("d(%[a-z], %"PRIu32", %"PRIu32", %"PRIu32", %"PRIu32
500 ",%"PRIu32", %"PRIu32", %"PRIu32", %"PRIu32").",
501 s_pcie, bus, dev, fun, &vendor_id,
502 &device_id, &class_code, &sub_class, &prog_if);
504 if (err_is_fail(err)) {
505 DEBUG_ERR(err, "skb read output\n");
507 PCI_DEBUG("device_init(): Could not read the SKB's output for the device\n");
508 PCI_DEBUG("device_init(): SKB returned: %s\n", skb_get_output());
509 PCI_DEBUG("device_init(): SKB error returned: %s\n", skb_get_error_output());
510 return err_push(err,PCI_ERR_DEVICE_INIT);
512 if(strncmp(s_pcie, "pcie", strlen("pcie")) == 0) {
519 PCI_DEBUG("device_init(): Found device at %u:%u:%u\n",
521 //get the implemented BARs for the found device
523 int irq = setup_interrupt(*bus, *dev, *fun);
524 PCI_DEBUG("pci: init_device_handler_irq: init interrupt.\n");
525 PCI_DEBUG("pci: irq = %u, core = %hhu, vector = %u\n",
526 irq, coreid, vector);
527 struct acpi_rpc_client* cl = get_acpi_rpc_client();
529 err = cl->vtbl.enable_and_route_interrupt(cl, irq, coreid, vector, &ret_error);
530 assert(err_is_ok(err));
531 assert(err_is_ok(ret_error)); // FIXME
532 // printf("IRQ for this device is %d\n", irq);
533 //DEBUG_ERR(err, "enable_and_route_interrupt");
534 pci_enable_interrupt_for_device(*bus, *dev, *fun, pcie);
539 void pci_enable_interrupt_for_device(uint32_t bus, uint32_t dev, uint32_t fun,
542 struct pci_address addr = { .bus = (uint8_t)(bus & 0xff),
543 .device = (uint8_t)(dev & 0xff),
544 .function = (uint8_t)(fun % 0xff) };
547 pci_hdr0_initialize(&hdr, addr);
555 pci_hdr0_command_t cmd = pci_hdr0_command_rd(&hdr);
557 pci_hdr0_command_wr(&hdr, cmd);
561 * This function performs a recursive, depth-first search through the
562 * PCI hierarchy starting at parentaddr (this should initially be a
563 * PCI root complex), with bus number A. It enters whatever it
564 * discovers (bridges and devices) into the SKB.
566 * Refer to http://www.tldp.org/LDP/tlk/dd/pci.html for an overview of
567 * a similar discovery algorithm.
569 * Upon discovery of a bridge, it sets the bridge's primary bus number
570 * to A and assigns a secondary bus number of A + 2. The subordinate
571 * bus number is set to A + 3. This way, buses are spaced 2 apart,
572 * which is sometimes required for SR-IOV hot-plugged buses.
574 static void assign_bus_numbers(struct pci_address parentaddr,
579 struct pci_address addr = {
580 .bus = parentaddr.bus
585 // First go through all bridges on this bus and disable them
586 for (addr.device = 0; addr.device < PCI_NDEVICES; addr.device++) {
587 for (addr.function = 0; addr.function < PCI_NFUNCTIONS; addr.function++) {
589 pci_hdr1_initialize(&bhdr, addr);
591 uint16_t vendor = pci_hdr1_vendor_id_rd(&bhdr);
593 if (vendor == 0xffff) {
594 if (addr.function == 0) {
595 // this device doesn't exist at all
598 // this function doesn't exist, but there may be others
603 pci_hdr1_hdr_type_t hdr_type = pci_hdr1_hdr_type_rd(&bhdr);
604 if (hdr_type.fmt == pci_hdr1_pci2pci) {
605 PCI_DEBUG("Disabling bridge (%u,%u,%u)\n", addr.bus, addr.device,
608 pci_hdr1_bcfg_t bcfg = pci_hdr1_bcfg_rd(&bhdr);
612 pci_hdr1_bcfg_wr(&bhdr, bcfg);
617 for (addr.device = 0; addr.device < PCI_NDEVICES; addr.device++) {
618 for (addr.function = 0; addr.function < PCI_NFUNCTIONS; addr.function++) {
620 pci_hdr0_initialize(&hdr, addr);
623 uint16_t pcie_vendor = pci_hdr0_vendor_id_rd(&hdr);
624 uint16_t vendor = pcie_vendor;
626 bool extended_caps = false; // Whether to scan for PCI Express extended caps
628 // Disable PCIe if device exists only in PCI
629 if (pcie_vendor != 0xffff) {
630 vendor = pcie_vendor;
634 vendor = pci_hdr0_vendor_id_rd(&hdr);
638 if (vendor == 0xffff) {
639 if (addr.function == 0) {
640 // this device doesn't exist at all
643 // this function doesn't exist, but there may be others
647 pci_hdr0_class_code_t classcode = pci_hdr0_class_code_rd(&hdr);
648 uint16_t device_id = pci_hdr0_device_id_rd(&hdr);
650 /* Disable all decoders for this device,
651 * they will be re-enabled as devices are setup.
652 * NB: we are using "pci_hdr1" here, but the command field is
653 * common to all configuration header types.
655 /* PCI_DEBUG("disabling decoders for (%hhu,%hhu,%hhu)\n", */
656 /* addr.bus, addr.device, addr.function); */
657 pci_hdr0_command_t cmd = pci_hdr0_command_rd(&hdr);
660 cmd.io_space = 0; // XXX: not handled in setup yet
663 //XXX: This should be set to 0 and only enabled if needed
664 // (whenever a driver attaches to a device).
665 // For bridges the pci driver enables the bit later when
666 // programming the bridge window
670 //pci_hdr0_command_wr(&hdr, cmd);
672 // do we have a bridge?
673 pci_hdr0_hdr_type_t hdr_type = pci_hdr0_hdr_type_rd(&hdr);
674 if (hdr_type.fmt == pci_hdr0_pci2pci) {
676 pci_hdr1_initialize(&bhdr, addr);
681 PCI_DEBUG("get irq table for (%hhu,%hhu,%hhu)\n", (*busnum) + 1,
682 addr.device, addr.function);
683 struct acpi_rpc_client* cl = get_acpi_rpc_client();
684 // XXX: why do we have two different types for the same thing?
685 acpi_pci_address_t xaddr = {
687 .device = addr.device,
688 .function = addr.function,
690 cl->vtbl.read_irq_table(cl, handle, xaddr, (*busnum) + 1,
691 &error_code, &child);
692 if (err_is_fail(error_code)) {
693 DEBUG_ERR(error_code, "Reading IRQs failed");
694 assert(!"Check ACPI code");
697 // Increase by 2 to leave room for SR-IOV
699 //assert(*busnum <= maxchild);
701 PCI_DEBUG("program busses for bridge (%hhu,%hhu,%hhu)\n"
702 "primary: %hhu, secondary: %hhu, subordinate: %hhu\n",
703 addr.bus, addr.device, addr.function, addr.bus, *busnum,
706 // Disable master abort mode on the bridge
707 pci_hdr1_brdg_ctrl_mabort_wrf(&bhdr, 0);
710 pci_hdr1_status_wr_raw(&bhdr, 0);
712 // program bus numbers for this bridge
713 pci_hdr1_bcfg_t bcfg = pci_hdr1_bcfg_rd(&bhdr);
714 bcfg.pri_bus = addr.bus;
715 bcfg.sec_bus = *busnum;
717 pci_hdr1_bcfg_wr(&bhdr, bcfg);
719 skb_add_fact("bridge(%s,addr(%u,%u,%u),%u,%u,%u,%u,%u, secondary(%hhu)).",
720 (pcie ? "pcie" : "pci"), addr.bus, addr.device,
721 addr.function, vendor, device_id, classcode.clss,
722 classcode.subclss, classcode.prog_if, *busnum);
724 //use the original hdr (pci_hdr0_t) here
725 query_bars(hdr, addr, true);
727 // assign bus numbers to secondary bus
728 struct pci_address bridge_addr = {
730 .device = addr.device,
731 .function = addr.function
733 assign_bus_numbers(bridge_addr, busnum, maxchild, child);
734 // Restore the old state of pcie. The above call changes this
735 // state according to the devices under this bridge
742 // Set this bridge's subordinate to the maximum of the underlying hierarchy
743 pci_hdr1_bcfg_sub_bus_wrf(&bhdr, (*busnum) + 1);
746 //is this a normal PCI device?
747 if (hdr_type.fmt == pci_hdr0_nonbridge) {
748 PCI_DEBUG("Found device (%u, %u, %u), vendor = %x, device = %x\n",
749 addr.bus, addr.device, addr.function, vendor,
753 pci_hdr0_initialize(&devhdr, addr);
754 skb_add_fact("device(%s,addr(%u,%u,%u),%u,%u,%u, %u, %u, %d).",
755 (pcie ? "pcie" : "pci"), addr.bus, addr.device,
756 addr.function, vendor, device_id, classcode.clss,
757 classcode.subclss, classcode.prog_if,
758 pci_hdr0_int_pin_rd(&devhdr) - 1);
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 }";
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);
772 assert(err_is_ok(err));
776 query_bars(devhdr, addr, false);
778 // Process device capabilities if existing
779 if (pci_hdr0_status_rd(&devhdr).caplist) {
780 uint8_t cap_ptr = pci_hdr0_cap_ptr_rd(&devhdr);
782 // Walk capabilities list
783 while (cap_ptr != 0) {
784 assert(cap_ptr % 4 == 0 && cap_ptr >= 0x40);
785 uint32_t capword = pci_read_conf_header(&addr,
788 switch (capword & 0xff) {
789 case 0x10: // PCI Express
790 PCI_DEBUG("PCI Express device\n");
791 extended_caps = true;
795 PCI_DEBUG("Unknown PCI device capability 0x%x at 0x%x\n",
796 capword & 0xff, cap_ptr);
800 cap_ptr = (capword >> 8) & 0xff;
804 // Process extended device capabilities if existing
805 if (pcie && extended_caps && addr.bus < pcie_get_endbus()) {
806 uint32_t *ad = (uint32_t *) pcie_confspace_access(addr);
808 uint16_t cap_ptr = 0x100;
810 while (cap_ptr != 0) {
811 uint32_t capword = *(ad + (cap_ptr / 4));
812 assert(cap_ptr % 4 == 0 && cap_ptr >= 0x100
813 && cap_ptr < 0x1000);
815 switch (capword & 0xffff) { // Switch on capability ID
824 * XXX: When using our e1000 driver with the
825 * I350 network card (device id 0x152x),
826 * the configuration fails when VF are
827 * enabled: Legacy descriptors are ignored
828 * when VF are enabled.
830 if (vendor == 0x8086 && (device_id & 0xFFF0) == 0x1520) {
831 debug_printf("skipping SR IOV initialization"
832 "for e1000 card.\n");
835 pci_sr_iov_cap_t sr_iov_cap;
836 pci_sr_iov_cap_initialize(&sr_iov_cap,
837 (mackerel_addr_t) (ad + (cap_ptr / 4)));
839 PCI_DEBUG("Found SR-IOV capability\n");
841 // Support version 1 for the moment
842 assert(pci_sr_iov_cap_hdr_ver_rdf(&sr_iov_cap) == 1);
844 // Support system page size of 4K at the moment
845 assert(pci_sr_iov_cap_sys_psize_rd(&sr_iov_cap)
848 #if 0 // Dump cap contents
849 pci_sr_iov_cap_caps_pr(str, 256, &sr_iov_cap);
850 PCI_DEBUG("%s\n", str);
851 pci_sr_iov_cap_ctrl_pr(str, 256, &sr_iov_cap);
852 PCI_DEBUG("%s\n", str);
853 pci_sr_iov_cap_status_pr(str, 256, &sr_iov_cap);
854 PCI_DEBUG("%s\n", str);
855 pci_sr_iov_cap_initialvfs_pr(str, 256, &sr_iov_cap);
856 PCI_DEBUG("%s\n", str);
857 pci_sr_iov_cap_totalvfs_pr(str, 256, &sr_iov_cap);
858 PCI_DEBUG("%s\n", str);
859 pci_sr_iov_cap_numvfs_pr(str, 256, &sr_iov_cap);
860 PCI_DEBUG("%s\n", str);
861 pci_sr_iov_cap_fdl_pr(str, 256, &sr_iov_cap);
862 PCI_DEBUG("%s\n", str);
863 pci_sr_iov_cap_offset_pr(str, 256, &sr_iov_cap);
864 PCI_DEBUG("%s\n", str);
865 pci_sr_iov_cap_stride_pr(str, 256, &sr_iov_cap);
866 PCI_DEBUG("%s\n", str);
867 pci_sr_iov_cap_devid_pr(str, 256, &sr_iov_cap);
868 PCI_DEBUG("%s\n", str);
869 pci_sr_iov_cap_sup_psize_pr(str, 256, &sr_iov_cap);
870 PCI_DEBUG("%s\n", str);
871 pci_sr_iov_cap_sys_psize_pr(str, 256, &sr_iov_cap);
872 PCI_DEBUG("%s\n", str);
875 if (max_numvfs > 0) {
876 // Set maximum number of VFs
877 uint16_t totalvfs = pci_sr_iov_cap_totalvfs_rd( &sr_iov_cap);
878 uint16_t numvfs = MIN(totalvfs, max_numvfs);
879 // uint16_t numvfs = 8;
880 PCI_DEBUG("Maximum supported VFs: %u. Enabling: %u\n",
882 pci_sr_iov_cap_numvfs_wr(&sr_iov_cap, numvfs);
884 uint16_t offset = pci_sr_iov_cap_offset_rd(&sr_iov_cap);
885 uint16_t stride = pci_sr_iov_cap_stride_rd(&sr_iov_cap);
886 uint16_t vf_devid = pci_sr_iov_cap_devid_rd(&sr_iov_cap);
888 PCI_DEBUG("VF offset is 0x%x, stride is 0x%x, "
889 "device ID is 0x%x\n",
890 offset, stride, vf_devid);
893 // Make sure we enable the PF
894 cmd = pci_hdr0_command_rd(&hdr);
897 /* cmd.master = 1; */
898 pci_hdr0_command_wr(&hdr, cmd);
901 // Start VFs (including memory spaces)
902 pci_sr_iov_cap_ctrl_vf_mse_wrf(&sr_iov_cap, 1);
903 pci_sr_iov_cap_ctrl_vf_enable_wrf(&sr_iov_cap, 1);
905 // Spec says to wait here for at least 100ms
906 err = barrelfish_usleep(100000);
907 assert(err_is_ok(err));
910 for (int vfn = 0; vfn < numvfs; vfn++) {
911 uint8_t busnr = addr.bus + ((((addr.device << 3)
916 uint8_t devfn = (((addr.device << 3)
921 struct pci_address vf_addr = {
923 .device = devfn >> 3,
924 .function = devfn & 7,
927 PCI_DEBUG("Adding VF (%u, %u, %u)\n",
928 vf_addr.bus, vf_addr.device,
931 skb_add_fact("device(%s,addr(%u,%u,%u),%u,%u,%u, %u, %u, %d).",
932 (pcie ? "pcie" : "pci"),
935 vf_addr.function, vendor,
936 vf_devid, classcode.clss,
938 classcode.prog_if, 0);
941 device_fmt ="hw.pci.device. { "
942 "bus: %u, device: %u, function: %u, "
943 "vendor: %u, device_id: %u, class: %u, "
944 "subclass: %u, prog_if: %u }";
945 err = oct_mset(SET_SEQUENTIAL,
955 assert(err_is_ok(err));
958 // We probe the BARs several times. Strictly
959 // speaking, this is not necessary, as we
960 // can calculate all offsets, but we're
962 pci_hdr0_bar32_t bar, barorigaddr;
963 for (int i = 0; i < pci_sr_iov_cap_vf_bar_length; i++) {
964 union pci_hdr0_bar32_un orig_value;
965 orig_value.raw = pci_sr_iov_cap_vf_bar_rd(&sr_iov_cap, i);
966 barorigaddr = orig_value.val;
968 // probe BAR to see if it is implemented
969 pci_sr_iov_cap_vf_bar_wr(&sr_iov_cap, i, BAR_PROBE);
971 union pci_hdr0_bar32_un bar_value;
972 bar_value.raw = pci_sr_iov_cap_vf_bar_rd(&sr_iov_cap, i);
973 bar = (union pci_hdr0_bar32_un ) {
977 //write original value back to the BAR
978 pci_sr_iov_cap_vf_bar_wr(&sr_iov_cap,
982 * We need to check the entire register
983 * here to make sure the bar is not
984 * implemented as it could lie in the
985 * high 64 bit range...
987 if (bar_value.raw == 0) {
988 // BAR not implemented
992 // SR-IOV doesn't support IO space BARs
993 assert(bar.space == 0);
995 if (bar.tpe == pci_hdr0_bar_32bit) {
998 if (bar.tpe == pci_hdr0_bar_64bit) {
1002 if (bar.tpe == pci_hdr0_bar_64bit) {
1003 //read the upper 32bits of the address
1004 pci_hdr0_bar32_t bar_high, barorigaddr_high;
1005 union pci_hdr0_bar32_un orig_value_high;
1006 orig_value_high.raw = pci_sr_iov_cap_vf_bar_rd(&sr_iov_cap, i + 1);
1007 barorigaddr_high = orig_value_high.val;
1009 // probe BAR to determine the mapping size
1010 pci_sr_iov_cap_vf_bar_wr(&sr_iov_cap, i + 1, BAR_PROBE);
1012 bar_high = (union pci_hdr0_bar32_un ) {
1013 .raw =pci_sr_iov_cap_vf_bar_rd(&sr_iov_cap,i + 1)
1016 //write original value back to the BAR
1017 pci_sr_iov_cap_vf_bar_wr(&sr_iov_cap,
1018 i + 1, orig_value_high.raw);
1020 pciaddr_t base64 = bar_high.base;
1022 base64 |= bar.base << 7;
1024 pciaddr_t origbase64 = barorigaddr_high.base;
1026 origbase64 |= barorigaddr.base << 7;
1028 PCI_DEBUG("(%u,%u,%u): 64bit BAR %d at 0x%"
1029 PRIxPCIADDR ", size %" PRIx64 ", %s\n",
1030 vf_addr.bus, vf_addr.device,
1031 vf_addr.function, i,
1032 (origbase64 << 7) + bar_mapping_size64(base64) * vfn,
1033 bar_mapping_size64(base64),
1034 (bar.prefetch == 1 ? "prefetchable" : "nonprefetchable"));
1036 skb_add_fact("bar(addr(%u, %u, %u), %d, 16'%"
1037 PRIxPCIADDR", ""16'%" PRIx64 ", vf, %s, %d).",
1038 vf_addr.bus, vf_addr.device, vf_addr.function, i,
1039 (origbase64 << 7) + bar_mapping_size64(base64) * vfn,
1040 bar_mapping_size64(base64),
1041 (bar.prefetch == 1 ? "prefetchable" : "nonprefetchable"),
1044 i++; //step one forward, because it is a 64bit BAR
1046 PCI_DEBUG("(%u,%u,%u): 32bit BAR %d at 0x%" PRIx32 ", size %x, %s\n",
1047 vf_addr.bus, vf_addr.device, vf_addr.function, i,
1048 (barorigaddr.base << 7) + bar_mapping_size(bar) * vfn,
1049 bar_mapping_size(bar),
1050 (bar.prefetch == 1 ? "prefetchable" : "nonprefetchable"));
1053 skb_add_fact("bar(addr(%u, %u, %u), %d, 16'%"PRIx32", 16'%"
1054 PRIx32 ", vf, %s, %d).", vf_addr.bus,
1055 vf_addr.device, vf_addr.function, i,
1056 (uint32_t) ((barorigaddr.base << 7)
1057 + bar_mapping_size( bar) * vfn),
1058 (uint32_t) bar_mapping_size(bar),
1059 (bar.prefetch == 1 ? "prefetchable" : "nonprefetchable"),
1069 PCI_DEBUG("Unknown extended PCI device capability 0x%x at 0x%x\n",
1070 capword & 0xffff, cap_ptr);
1074 cap_ptr = capword >> 20;
1079 // is this a multi-function device?
1080 if (addr.function == 0 && !hdr_type.multi) {
1090 static void get_bridges(struct pci_address myad)
1092 struct pci_address addr = {.bus = myad.bus};
1096 // First go through all bridges on this bus and disable them
1097 for (addr.device = 0; addr.device < PCI_NDEVICES; addr.device++) {
1098 for (addr.function = 0; addr.function < PCI_NFUNCTIONS; addr.function++) {
1100 pci_hdr1_initialize(&bhdr, addr);
1102 uint16_t vendor = pci_hdr1_vendor_id_rd(&bhdr);
1104 if (vendor == 0xffff) {
1105 if (addr.function == 0) {
1106 // this device doesn't exist at all
1109 // this function doesn't exist, but there may be others
1114 pci_hdr1_hdr_type_t hdr_type = pci_hdr1_hdr_type_rd(&bhdr);
1115 if (hdr_type.fmt == pci_hdr1_pci2pci) {
1116 pci_hdr1_bcfg_t bcfg = pci_hdr1_bcfg_rd(&bhdr);
1118 PCI_DEBUG("Found bridge (%u,%u,%u), primary %u, secondary %u, subordinate %u\n",
1119 addr.bus, addr.device, addr.function,
1120 bcfg.pri_bus, bcfg.sec_bus, bcfg.sub_bus);
1122 struct pci_address bridge_addr= {
1123 .bus = bcfg.sec_bus, .device = addr.device,
1124 .function = addr.function
1127 get_bridges(bridge_addr);
1134 void pci_add_root(struct pci_address addr,
1138 uint8_t busnum = addr.bus;
1139 /* get_bridges(addr); */
1140 assign_bus_numbers(addr, &busnum, maxchild, handle);
1141 /* get_bridges(addr); */
1144 errval_t pci_setup_root_complex(void)
1147 char* record = NULL;
1148 char** names = NULL;
1151 // TODO: react to new rootbridges
1152 err = oct_get_names(&names, &len, "r'hw.pci.rootbridge.[0-9]+' "
1153 "{ acpi_node: _, bus: _, device: _, function: _, maxbus: _ }");
1154 if (err_is_fail(err)) {
1155 DEBUG_ERR(err, "get names");
1159 for (size_t i = 0; i < len; i++) {
1160 err = oct_get(&record, names[i]);
1161 if (err_is_fail(err)) {
1165 PCI_DEBUG("found new root complex: %s\n", record);
1167 char* acpi_node = NULL; // freed in pci_add_root
1168 int64_t bus, device, function, maxbus;
1169 static char* format =
1170 "_ { acpi_node: %s, bus: %d, device: %d, function: %d, maxbus: %d }";
1171 err = oct_read(record, format, &acpi_node, &bus, &device, &function,
1173 if (err_is_fail(err)) {
1179 struct pci_address addr;
1180 addr.bus = (uint8_t) bus;
1181 addr.device = (uint8_t) device;
1182 addr.function = (uint8_t) function;
1185 pci_add_root(addr, maxbus, acpi_node);
1191 out: oct_free_names(names, len);
1195 //query all BARs. That means, get the original address, the mapping size
1196 //and all attributes.
1198 // XXX: asq: We are using this function to program also the _two_ BARs
1199 // of a PCI-to-PCI bridge. They are at the same offset within the
1200 // PCI header like for any PCI device. PCI HDR0 is misused
1201 // here for the bridges.
1203 static void query_bars(pci_hdr0_t devhdr,
1204 struct pci_address addr,
1205 bool pci2pci_bridge)
1207 pci_hdr0_bar32_t bar, barorigaddr;
1209 int maxbars = pci2pci_bridge ? 1 : pci_hdr0_bars_length;
1210 for (int i = 0; i <= maxbars; i++) {
1211 union pci_hdr0_bar32_un orig_value;
1212 orig_value.raw = pci_hdr0_bars_rd(&devhdr, i);
1213 barorigaddr = orig_value.val;
1215 // probe BAR to determine the mapping size
1216 pci_hdr0_bars_wr(&devhdr, i, BAR_PROBE);
1218 uint32_t bar_value = pci_hdr0_bars_rd(&devhdr, i);
1220 bar = (union pci_hdr0_bar32_un ) { .raw = bar_value }.val;
1222 //write original value back to the BAR
1223 pci_hdr0_bars_wr(&devhdr, i, orig_value.raw);
1226 * Cannot just compare the base value, with addresses over 4G there
1227 * will be a problem. Thus we need to check if the entire register is
1228 * zero. If it is a 32bit register, then the address part will be filled.
1229 * If it is a 64bit register, the type will contain a nonzero value.
1232 if (bar_value == 0) {
1233 // BAR not implemented
1237 if (bar.space == 0) { // memory mapped
1238 //bar(addr(bus, device, function), barnr, orig address, size, space,
1239 // prefetchable?, 64bit?).
1240 //where space = mem | io, prefetchable= prefetchable | nonprefetchable,
1241 //64bit = 64bit | 32bit.
1244 if (bar.tpe == pci_hdr0_bar_32bit) {
1247 if (bar.tpe == pci_hdr0_bar_64bit) {
1251 if (bar.tpe == pci_hdr0_bar_64bit) {
1252 //we must take the next BAR into account and do the same
1253 //tests like in the 32bit case, but this time with the combined
1254 //value from the current and the next BAR, since a 64bit BAR
1255 //is constructed out of two consequtive 32bit BARs
1257 //read the upper 32bits of the address
1258 uint32_t orig_value_high = pci_hdr0_bars_rd(&devhdr, i + 1);
1260 // probe BAR to determine the mapping size
1261 pci_hdr0_bars_wr(&devhdr, i + 1, BAR_PROBE);
1263 // read the size information of the bar
1264 uint32_t bar_value_high = pci_hdr0_bars_rd(&devhdr, i + 1);
1266 //write original value back to the BAR
1267 pci_hdr0_bars_wr(&devhdr, i + 1, orig_value_high);
1269 pciaddr_t base64 = 0, origbase64 = 0;
1270 base64 = bar_value_high;
1272 base64 |= (uint32_t) (bar.base << 7);
1274 origbase64 = orig_value_high;
1276 origbase64 |= (uint32_t) (barorigaddr.base << 7);
1278 PCI_DEBUG("(%u,%u,%u): 64bit BAR %d at 0x%" PRIxPCIADDR ", size %"
1279 PRIx64 ", %s\n", addr.bus, addr.device, addr.function,
1280 i, origbase64, bar_mapping_size64(base64),
1281 (bar.prefetch == 1 ? "prefetchable" : "nonprefetchable"));
1283 PCI_DEBUG("(%u,%u,%u): 64bit BAR %d at 0x%" PRIxPCIADDR ", size %" PRIx64 ", %s\n",
1284 addr.bus, addr.device, addr.function,
1285 i, origbase64 << 7, bar_mapping_size64(base64),
1286 (bar.prefetch == 1 ? "prefetchable" : "nonprefetchable"));
1288 skb_add_fact("bar(addr(%u, %u, %u), %d, 16'%"PRIxPCIADDR", "
1289 "16'%" PRIx64 ", mem, %s, %d).", addr.bus,
1290 addr.device, addr.function, i, origbase64,
1291 bar_mapping_size64(base64),
1292 (bar.prefetch == 1 ? "prefetchable" : "nonprefetchable"),
1295 i++; //step one forward, because it is a 64bit BAR
1297 PCI_DEBUG("(%u,%u,%u): 32bit BAR %d at 0x%" PRIx32 ", size %x, %s\n",
1298 addr.bus, addr.device, addr.function,
1299 i, barorigaddr.base << 7, bar_mapping_size(bar),
1300 (bar.prefetch == 1 ? "prefetchable" : "nonprefetchable"));
1303 skb_add_fact("bar(addr(%u, %u, %u), %d, 16'%"PRIx32", 16'%" PRIx32
1304 ", mem, %s, %d).", addr.bus, addr.device, addr.function,
1305 i, (uint32_t) (barorigaddr.base << 7),
1306 (uint32_t) bar_mapping_size(bar),
1307 (bar.prefetch == 1 ? "prefetchable" : "nonprefetchable"),
1311 PCI_DEBUG("(%u,%u,%u): IO BAR %d at 0x%x, size %x\n",
1312 addr.bus, addr.device, addr.function,
1313 i, barorigaddr.base << 7, bar_mapping_size(bar));
1314 //bar(addr(bus, device, function), barnr, orig address, size, space).
1315 //where space = mem | io
1316 skb_add_fact("bar(addr(%u, %u, %u), %d, 16'%"PRIx32", 16'%" PRIx32 ", io, "
1317 "nonprefetchable, 32).", addr.bus, addr.device, addr.function, i,
1318 (uint32_t) (barorigaddr.base << 7), (uint32_t) bar_mapping_size(bar));
1323 static void program_bridge_window(uint8_t bus,
1332 struct pci_address addr;
1333 pci_hdr1_prefbl_t pref_reg;
1334 pci_hdr1_command_t cmd;
1342 assert((base & 0x000fffff) == 0);
1343 assert((high & 0x000fffff) == 0x000fffff);
1347 addr.function = fun;
1349 pci_hdr1_t bridgehdr;
1350 pci_hdr1_initialize(&bridgehdr, addr);
1352 cmd = pci_hdr1_command_rd(&bridgehdr);
1356 pci_hdr1_pref_base_upper_wr(&bridgehdr, base >> 32);
1357 pci_hdr1_pref_limit_upper_wr(&bridgehdr, high >> 32);
1359 * The least significant nibble of this register value (1h)
1360 * indicates that a 64 bit address decoder is supported and
1361 * that the Upper Base/Limit Registers are also used.
1364 pref_reg.tpe = pci_hdr1_mem_64bit;
1366 pref_reg.tpe = pci_hdr1_mem_32bit;
1368 pref_reg.val = base >> 20;
1369 pci_hdr1_pref_base_wr(&bridgehdr, pref_reg);
1371 pref_reg.tpe = pci_hdr1_mem_64bit;
1373 pref_reg.tpe = pci_hdr1_mem_32bit;
1375 pref_reg.val = high >> 20;
1376 pci_hdr1_pref_limit_wr(&bridgehdr, pref_reg);
1378 assert((base & 0xffffffff00000000) == 0);
1379 assert((high & 0xffffffff00000000) == 0);
1380 pci_hdr1_membl_t membl = {
1382 .limit = high >> 16,
1384 pci_hdr1_membl_wr(&bridgehdr, membl);
1385 /* pci_hdr1_mem_base_wr(&bridgehdr, base >> 16); */
1386 /* pci_hdr1_mem_limit_wr(&bridgehdr, high >> 16); */
1388 // enable the memory decoder
1396 pci_hdr1_command_wr(&bridgehdr, cmd);
1399 static void program_device_bar(uint8_t bus,
1409 struct pci_address addr;
1412 addr.function = fun;
1421 pci_hdr0_initialize(&devhdr, addr);
1423 //disable the address decoder for programming the BARs
1424 pci_hdr0_command_t cmd = pci_hdr0_command_rd(&devhdr);
1430 //disbale interrupts here. enable them as soon as a driver requests
1433 pci_hdr0_command_wr(&devhdr, cmd);
1436 pci_hdr0_bars_wr(&devhdr, bar, base & 0xffffffff);
1437 pci_hdr0_bars_wr(&devhdr, bar + 1, base >> 32);
1439 assert(base + size <= 0xffffffff); // 32-bit BAR
1440 pci_hdr0_bars_wr(&devhdr, bar, base);
1443 //re-enable the decoder for the BARs
1449 pci_hdr0_command_wr(&devhdr, cmd);
1452 static void enable_busmaster(uint8_t bus,
1457 struct pci_address addr;
1460 addr.function = fun;
1469 pci_hdr0_initialize(&devhdr, addr);
1472 pci_hdr0_command_t cmd = pci_hdr0_command_rd(&devhdr);
1474 pci_hdr0_command_wr(&devhdr, cmd);
1477 void pci_program_bridges(void)
1479 char element_type[7]; // "device" | "bridge"
1480 char bar_secondary[16]; //[0-6] | secondary(<0-255>)
1481 char space[4]; // "mem" | "io"
1482 char prefetch[16]; // "prefetchable" | "nonprefetchable"
1483 char pcie_pci[5]; // "pcie" | "pci"
1484 int bar; // the value of bar_secondary after parsing secondary(<nr>) to <nr>
1485 uint8_t bus, dev, fun;
1486 pciaddr_t base, high;
1489 bool mem, pcie, pref;
1490 char *output = NULL;
1491 int output_length = 0;
1497 skb_execute("listing.");
1498 output = skb_get_output();
1499 assert(output != NULL);
1500 output_length = strlen(output);
1501 PCI_DEBUG("pci_program_bridges: output = %s\n", output);
1502 PCI_DEBUG("pci_program_bridges: output length = %d\n", output_length);
1504 error_code = skb_read_error_code();
1505 if (error_code != 0) {
1506 printf("pci.c: pci_program_bridges(): SKB returnd error code %d\n",
1509 const char *errout = skb_get_error_output();
1510 printf("\nSKB error returned: %s\n", errout);
1511 printf("\nSKB output: %s\n", output);
1512 // XXX: no device can be used...
1519 char bridge_program[512];
1520 snprintf(bridge_program, 512, "[%s], bridge_programming(P, Nr),"
1521 "flatten(P, F),replace_current_BAR_values(F),"
1522 "write(nrelements(Nr)),writeln(P).",
1523 skb_bridge_program);
1524 skb_execute(bridge_program);
1525 output = skb_get_output();
1526 assert(output != NULL);
1527 output_length = strlen(output);
1528 PCI_DEBUG("pci_program_bridges: output = %s\n", output);
1529 PCI_DEBUG("pci_program_bridges: output length = %d\n", output_length);
1531 error_code = skb_read_error_code();
1532 if (error_code != 0) {
1533 printf("pci.c: pci_program_bridges(): SKB returned error code %d\n",
1536 const char *errout = skb_get_error_output();
1537 printf("SKB error returned: %s\n", errout);
1538 printf("SKB output: %s\n", output);
1539 // XXX: no device can be used...
1540 printf("WARNING: CONTINUING, HOWEVER PCI DEVICES WILL BE UNUSABLE\n");
1541 // except IO-space devices which aren't yet affected by bridge programming
1546 ********************************************************************************
1547 //for the ASPLOS11 paper:
1548 skb_execute("[bridge_page].");
1549 while (skb_read_error_code() == SKB_PROCESSING) messages_wait_and_handle_next();
1550 char *output = skb_get_output();
1551 assert(output != NULL);
1552 int output_length = strlen(output);
1553 PCI_DEBUG("pci_program_bridges: output = %s\n", output);
1554 PCI_DEBUG("pci_program_bridges: output length = %d\n", output_length);
1556 int error_code = skb_read_error_code();
1557 if (error_code != 0) {
1558 printf("pci.c: pci_program_bridges() <2>: SKB returnd error code %d\n",
1561 const char *errout = skb_get_error_output();
1562 printf("\nSKB error returned <2>: %s\n", errout);
1563 printf("\nSKB output <2>: %s\n", output);
1564 // XXX: no device can be used...
1567 uint64_t start =rdtsc();
1568 // uint64_t start =rdtscp();
1569 skb_execute("bridge_programming(P, Nr),write(nrelements(Nr)),writeln(P).");
1570 uint64_t end =rdtsc();
1571 // uint64_t end =rdtscp();
1572 assert(end >= start);
1574 printf("\n\nTicks: %lu\n\n", end - start);
1575 while (skb_read_error_code() == SKB_PROCESSING) messages_wait_and_handle_next();
1576 output = skb_get_output();
1577 assert(output != NULL);
1578 output_length = strlen(output);
1579 printf("pci_program_bridges: output = %s\n", output);
1580 PCI_DEBUG("pci_program_bridges: output length = %d\n", output_length);
1582 error_code = skb_read_error_code();
1583 if (error_code != 0) {
1584 printf("pci.c: pci_program_bridges() <3>: SKB returnd error code %d\n",
1587 const char *errout = skb_get_error_output();
1588 printf("\nSKB error returned <3>: %s\n", errout);
1589 printf("\nSKB output <3>: %s\n", output);
1590 // XXX: no device can be used...
1593 ********************************************************************************
1596 //get the number of buselements from the output
1599 nr_conversions = sscanf(output, "nrelements(%d)", &nr_elements);
1600 if (nr_conversions != 1) {
1601 printf("pci.c: No valid pci plan returned by the SKB\n.");
1602 //XXX: no device can be used
1606 //keep a pointer to the current location within the output
1607 char *conv_ptr = output;
1609 //iterate over all buselements
1610 for (int i = 0; i < nr_elements; i++) {
1611 // search the beginning of the next buselement
1612 while ((conv_ptr < output + output_length) && (strncmp(
1613 conv_ptr, "buselement", strlen("buselement"))
1617 //convert the string to single elements and numbers
1618 nr_conversions = sscanf(conv_ptr, "buselement(%[a-z], addr(%hhu, %hhu, %hhu), "
1619 "%[a-z0-9()], %"PRIuPCIADDR", %"PRIuPCIADDR", "
1620 "%"PRIuPCISIZE", %[a-z], %[a-z], %[a-z], %d",
1621 element_type, &bus, &dev, &fun, bar_secondary,
1622 &base, &high, &size, space, prefetch, pcie_pci,
1625 if (nr_conversions != 12) {
1626 printf("Could not parse output for device or bridge number %d\n"
1627 "nr conversions: %d\n",
1631 if (strncmp(space, "mem", strlen("mem")) == 0) {
1636 if (strncmp(pcie_pci, "pcie", strlen("pcie")) == 0) {
1641 if (strncmp(prefetch, "prefetchable", strlen("prefetchable")) == 0) {
1647 // Skip virtual functions
1648 if (strncmp(space, "vf", strlen("vf")) == 0) {
1649 /* PCI_DEBUG("Skipping VF addr(%hhu, %hhu, %hhu)\n", */
1650 /* bus, dev, fun); */
1654 if (strncmp(element_type, "device", strlen("device")) == 0) {
1655 nr_conversions = sscanf(bar_secondary, "%d", &bar);
1656 if (nr_conversions != 1) {
1657 printf("Could not determine BAR number while programming BAR\n");
1660 PCI_DEBUG("programming %s addr(%hhu, %hhu, %hhu), BAR %d, with base = "
1661 "%"PRIxPCIADDR", high = %"PRIxPCIADDR", size = %"PRIxPCISIZE
1662 " in" "space = %s, prefetch = %s, %s...\n",
1663 element_type, bus, dev, fun, bar, base, high, size, space,
1664 prefetch, pcie ? "PCIe" : "PCI");
1665 program_device_bar(bus, dev, fun, bar, base, size, bits, mem, pcie);
1668 PCI_DEBUG("programming %s addr(%hhu, %hhu, %hhu), with base = "
1669 "%"PRIxPCIADDR", high = %"PRIxPCIADDR", size = %"PRIxPCISIZE
1670 " in space = %s, prefetch = %s...\n",
1671 element_type, bus, dev, fun, base, high, size, space,
1673 //a bridge expects the high address excluding the last byte which
1674 //is the base for the next bridge => decrement by one
1676 program_bridge_window(bus, dev, fun, base, high, pcie, mem, pref);
1681 static uint32_t setup_interrupt(uint32_t bus,
1685 char str[256], ldev[128];
1687 snprintf(str, 256, "[\"irq_routing.pl\"], assigndeviceirq(addr(%"PRIu32
1688 ", %"PRIu32", %"PRIu32")).",
1690 char *output, *error_out;
1692 errval_t err = skb_evaluate(str, &output, &error_out, &int_err);
1693 assert(output != NULL);
1694 assert(err_is_ok(err));
1697 sscanf(output, "%s %hhu", ldev, &irq);
1700 if (strcmp(ldev, "fixedGsi") == 0) {
1701 printf("Got GSI %u\n", irq);
1705 struct acpi_rpc_client* cl = get_acpi_rpc_client();
1706 errval_t error_code;
1707 err = cl->vtbl.set_device_irq(cl, ldev, irq, &error_code);
1708 assert(err_is_ok(err));
1709 if (err_is_fail(error_code)) {
1710 //DEBUG_ERR(error_code, "set device irq failed.");