2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2009, Jack Lange <jarusl@cs.northwestern.edu>
11 * Copyright (c) 2009, Lei Xia <lxia@northwestern.edu>
12 * Copyright (c) 2009, Chang Seok Bae <jhuell@gmail.com>
13 * Copyright (c) 2009, The V3VEE Project <http://www.v3vee.org>
14 * All rights reserved.
16 * Author: Jack Lange <jarusl@cs.northwestern.edu>
17 * Lei Xia <lxia@northwestern.edu>
18 * Chang Seok Bae <jhuell@gmail.com>
20 * This is free software. You are permitted to use,
21 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
26 #include <palacios/vmm.h>
27 #include <palacios/vmm_types.h>
28 #include <palacios/vmm_io.h>
29 #include <palacios/vmm_intr.h>
30 #include <palacios/vmm_rbtree.h>
31 #include <palacios/vmm_dev_mgr.h>
33 #include <devices/pci.h>
34 #include <devices/pci_types.h>
36 #include <palacios/vm_guest.h>
37 #include <palacios/vm_guest_mem.h>
40 #include <devices/apic.h>
43 #ifndef V3_CONFIG_DEBUG_PCI
45 #define PrintDebug(fmt, args...)
49 #define CONFIG_ADDR_PORT 0x0cf8
50 #define CONFIG_DATA_PORT 0x0cfc
52 #define PCI_DEV_IO_PORT_BASE 0xc000
54 #define PCI_BUS_COUNT 1
56 // This must always be a multiple of 8
57 #define MAX_BUS_DEVICES 32
59 #define PCI_CAP_ID_MSI 0x05
60 #define PCI_CAP_ID_MSIX 0x11
72 uint_t hi_reg_num : 4;
75 } __attribute__((packed));
76 } __attribute__((packed));
77 } __attribute__((packed));
86 // Red Black tree containing all attached devices
87 struct rb_root devices;
89 // Bitmap of the allocated device numbers
90 uint8_t dev_map[MAX_BUS_DEVICES / 8];
93 int (*raise_pci_irq)(struct pci_device * pci_dev, void * dev_data, struct v3_irq * vec);
94 int (*lower_pci_irq)(struct pci_device * pci_dev, void * dev_data, struct v3_irq * vec);
100 struct pci_internal {
101 // Configuration address register
102 struct pci_addr_reg addr_reg;
104 // Base IO Port which PCI devices will register with...
105 uint16_t dev_io_base;
108 struct pci_bus bus_list[PCI_BUS_COUNT];
113 struct cfg_range_hook {
117 int (*write)(struct pci_device * pci_dev, uint32_t offset,
118 void * src, uint_t length, void * private_data);
120 int (*read)(struct pci_device * pci_dev, uint32_t offset,
121 void * dst, uint_t length, void * private_data);
125 struct list_head list_node;
135 struct list_head cap_node;
139 // These mark read only fields in the pci config header.
140 // If a bit is 1, then the field is writable in the header
142 * BIST is disabled by default (All writes to it will be dropped
143 * Cardbus CIS is disabled (All writes are dropped)
144 * Writes to capability pointer are disabled
146 static uint8_t pci_hdr_write_mask_00[64] = { 0x00, 0x00, 0x00, 0x00, /* Device ID, Vendor ID */
147 0xbf, 0xff, 0x00, 0xf9, /* Command, status */
148 0x00, 0x00, 0x00, 0x00, /* Revision ID, Class code */
149 0x00, 0xff, 0x00, 0x00, /* CacheLine Size, Latency Timer, Header Type, BIST */
150 0xff, 0xff, 0xff, 0xff, /* BAR 0 */
151 0xff, 0xff, 0xff, 0xff, /* BAR 1 */
152 0xff, 0xff, 0xff, 0xff, /* BAR 2 */
153 0xff, 0xff, 0xff, 0xff, /* BAR 3 */
154 0xff, 0xff, 0xff, 0xff, /* BAR 4 */
155 0xff, 0xff, 0xff, 0xff, /* BAR 5 */
156 0x00, 0x00, 0x00, 0x00, /* CardBus CIS Ptr */
157 0xff, 0xff, 0xff, 0xff, /* SubSystem Vendor ID, SubSystem ID */
158 0xff, 0xff, 0xff, 0xff, /* ExpRom BAR */
159 0x00, 0x00, 0x00, 0x00, /* CAP ptr (0xfc to enable), RSVD */
160 0x00, 0x00, 0x00, 0x00, /* Reserved */
161 0xff, 0x00, 0x00, 0x00 /* INTR Line, INTR Pin, MIN_GNT, MAX_LAT */
167 #ifdef V3_CONFIG_DEBUG_PCI
169 static void pci_dump_state(struct pci_internal * pci_state) {
170 struct rb_node * node = v3_rb_first(&(pci_state->bus_list[0].devices));
171 struct pci_device * tmp_dev = NULL;
173 PrintDebug(VM_NONE, VCORE_NONE, "===PCI: Dumping state Begin ==========\n");
176 tmp_dev = rb_entry(node, struct pci_device, dev_tree_node);
178 PrintDebug(VM_NONE, VCORE_NONE, "PCI Device Number: %d (%s):\n", tmp_dev->dev_num, tmp_dev->name);
179 PrintDebug(VM_NONE, VCORE_NONE, "irq = %d\n", tmp_dev->config_header.intr_line);
180 PrintDebug(VM_NONE, VCORE_NONE, "Vend ID: 0x%x\n", tmp_dev->config_header.vendor_id);
181 PrintDebug(VM_NONE, VCORE_NONE, "Device ID: 0x%x\n", tmp_dev->config_header.device_id);
183 } while ((node = v3_rb_next(node)));
185 PrintDebug(VM_NONE, VCORE_NONE, "====PCI: Dumping state End==========\n");
193 // Scan the dev_map bitmap for the first '0' bit
194 static int get_free_dev_num(struct pci_bus * bus) {
197 for (i = 0; i < sizeof(bus->dev_map); i++) {
198 PrintDebug(VM_NONE, VCORE_NONE, "i=%d\n", i);
199 if (bus->dev_map[i] != 0xff) {
201 for (j = 0; j < 8; j++) {
202 PrintDebug(VM_NONE, VCORE_NONE, "\tj=%d\n", j);
203 if (!(bus->dev_map[i] & (0x1 << j))) {
204 return ((i * 8) + j);
213 static void allocate_dev_num(struct pci_bus * bus, int dev_num) {
214 int major = (dev_num / 8);
215 int minor = dev_num % 8;
217 bus->dev_map[major] |= (0x1 << minor);
223 struct pci_device * __add_device_to_bus(struct pci_bus * bus, struct pci_device * dev) {
225 struct rb_node ** p = &(bus->devices.rb_node);
226 struct rb_node * parent = NULL;
227 struct pci_device * tmp_dev = NULL;
231 tmp_dev = rb_entry(parent, struct pci_device, dev_tree_node);
233 if (dev->devfn < tmp_dev->devfn) {
235 } else if (dev->devfn > tmp_dev->devfn) {
242 rb_link_node(&(dev->dev_tree_node), parent, p);
249 struct pci_device * add_device_to_bus(struct pci_bus * bus, struct pci_device * dev) {
251 struct pci_device * ret = NULL;
253 if ((ret = __add_device_to_bus(bus, dev))) {
257 v3_rb_insert_color(&(dev->dev_tree_node), &(bus->devices));
259 allocate_dev_num(bus, dev->dev_num);
265 static struct pci_device * get_device(struct pci_bus * bus, uint8_t dev_num, uint8_t fn_num) {
266 struct rb_node * n = bus->devices.rb_node;
267 struct pci_device * dev = NULL;
268 uint8_t devfn = ((dev_num & 0x1f) << 3) | (fn_num & 0x7);
271 dev = rb_entry(n, struct pci_device, dev_tree_node);
273 if (devfn < dev->devfn) {
275 } else if (devfn > dev->devfn) {
288 // There won't be many hooks at all, so unordered lists are acceptible for now
289 static struct cfg_range_hook * find_cfg_range_hook(struct pci_device * pci, uint32_t start, uint32_t length) {
290 uint32_t end = start + length - 1; // end is inclusive
291 struct cfg_range_hook * hook = NULL;
293 list_for_each_entry(hook, &(pci->cfg_hooks), list_node) {
294 uint32_t hook_end = hook->start + hook->length - 1;
295 if (!((hook->start > end) || (hook_end < start))) {
304 int v3_pci_hook_config_range(struct pci_device * pci,
305 uint32_t start, uint32_t length,
306 int (*write)(struct pci_device * pci_dev, uint32_t offset,
307 void * src, uint_t length, void * private_data),
308 int (*read)(struct pci_device * pci_dev, uint32_t offset,
309 void * dst, uint_t length, void * private_data),
310 void * private_data) {
311 struct cfg_range_hook * hook = NULL;
314 if (find_cfg_range_hook(pci, start, length)) {
315 PrintError(VM_NONE, VCORE_NONE, "Tried to hook an already hooked config region\n");
319 hook = V3_Malloc(sizeof(struct cfg_range_hook));
322 PrintError(VM_NONE, VCORE_NONE, "Could not allocate range hook\n");
326 memset(hook, 0, sizeof(struct cfg_range_hook));
329 hook->length = length;
330 hook->private_data = private_data;
334 list_add(&(hook->list_node), &(pci->cfg_hooks));
343 // Note byte ordering: LSB -> MSB
344 static uint8_t msi_32_rw_bitmask[10] = { 0x00, 0x00, /* ID, next ptr */
345 0x71, 0x00, /* MSG CTRL */
346 0xfc, 0xff, 0xff, 0xff, /* MSG ADDR */
347 0xff, 0xff}; /* MSG DATA */
349 static uint8_t msi_64_rw_bitmask[14] = { 0x00, 0x00, /* ID, next ptr */
350 0x71, 0x00, /* MSG CTRL */
351 0xfc, 0xff, 0xff, 0xff, /* MSG LO ADDR */
352 0xff, 0xff, 0xff, 0xff, /* MSG HI ADDR */
353 0xff, 0xff}; /* MSG DATA */
355 static uint8_t msi_64pervect_rw_bitmask[24] = { 0x00, 0x00, /* ID, next ptr */
356 0x71, 0x00, /* MSG CTRL */
357 0xfc, 0xff, 0xff, 0xff, /* MSG LO CTRL */
358 0xff, 0xff, 0xff, 0xff, /* MSG HI ADDR */
359 0xff, 0xff, /* MSG DATA */
360 0x00, 0x00, /* RSVD */
361 0xff, 0xff, 0xff, 0xff,
362 0x00, 0x00, 0x00, 0x00};
364 static uint8_t msix_rw_bitmask[12] = { 0x00, 0x00, /* ID, next ptr */
366 0xff, 0xff, 0xff, 0xff,
367 0x08, 0xff, 0xff, 0xff};
370 /* I am completely guessing what the format is here.
371 I only have version 1 of the PCIe spec and cannot download version 2 or 3
372 without paying the PCI-SIG $3000 a year for membership.
373 So this is just cobbled together from the version 1 spec and KVM.
377 static uint8_t pciev1_rw_bitmask[20] = { 0x00, 0x00, /* ID, next ptr */
378 0x00, 0x00, /* PCIE CAP register */
379 0x00, 0x00, 0x00, 0x00, /* DEV CAP */
380 0xff, 0xff, /* DEV CTRL */
381 0x0f, 0x00, /* DEV STATUS */
382 0x00, 0x00, 0x00, 0x00, /* LINK CAP */
383 0xfb, 0x01, /* LINK CTRL */
384 0x00, 0x00 /* LINK STATUS */
388 static uint8_t pciev2_rw_bitmask[60] = { 0x00, 0x00, /* ID, next ptr */
389 0x00, 0x00, /* PCIE CAP register */
390 0x00, 0x00, 0x00, 0x00, /* DEV CAP */
391 0xff, 0xff, /* DEV CTRL */
392 0x0f, 0x00, /* DEV STATUS */
393 0x00, 0x00, 0x00, 0x00, /* LINK CAP */
394 0xfb, 0x01, /* LINK CTRL */
395 0x00, 0x00, /* LINK STATUS */
396 0x00, 0x00, 0x00, 0x00, /* SLOT CAP ?? */
397 0x00, 0x00, /* SLOT CTRL ?? */
398 0x00, 0x00, /* SLOT STATUS */
399 0x00, 0x00, /* ROOT CTRL */
400 0x00, 0x00, /* ROOT CAP */
401 0x00, 0x00, 0x00, 0x00, /* ROOT STATUS */
402 0x00, 0x00, 0x00, 0x00, /* WHO THE FUCK KNOWS */
403 0x00, 0x00, 0x00, 0x00,
404 0x00, 0x00, 0x00, 0x00,
405 0x00, 0x00, 0x00, 0x00,
406 0x00, 0x00, 0x00, 0x00
409 static uint8_t pm_rw_bitmask[] = { 0x00, 0x00, /* ID, next ptr */
410 0x00, 0x00, /* PWR MGMT CAPS */
411 0x03, 0x9f, /* PWR MGMT CTRL */
412 0x00, 0x00 /* PMCSR_BSE, Data */
417 int cap_write(struct pci_device * pci, uint32_t offset, void * src, uint_t length, void * private_data) {
418 struct pci_cap * cap = private_data;
419 uint32_t cap_offset = cap->offset;
420 pci_cap_type_t cap_type = cap->id;
422 uint32_t write_offset = offset - cap_offset;
423 void * cap_ptr = &(pci->config_space[cap_offset + 2]);
426 int msi_was_enabled = 0;
427 int msix_was_enabled = 0;
430 V3_Print(VM_NONE, VCORE_NONE, "CAP write trapped (val=%x, cfg_offset=%d, write_offset=%d)\n", *(uint32_t *)src, offset, write_offset);
432 if (cap_type == PCI_CAP_MSI) {
433 struct msi_msg_ctrl * msg_ctrl = cap_ptr;
435 if (msg_ctrl->msi_enable == 1) {
438 } else if (cap_type == PCI_CAP_MSIX) {
439 struct msix_cap * msix_cap = cap_ptr;
441 if (msix_cap->msg_ctrl.msix_enable == 1) {
442 msix_was_enabled = 1;
446 for (i = 0; i < length; i++) {
449 if (cap_type == PCI_CAP_MSI) {
450 struct msi_msg_ctrl * msg_ctrl = cap_ptr;
452 V3_Print(VM_NONE, VCORE_NONE, "MSI Cap Ctrl=%x\n", *(uint16_t *)pci->msi_cap);
453 V3_Print(VM_NONE, VCORE_NONE, "MSI ADDR=%x\n", *(uint32_t *)(cap_ptr + 2));
454 V3_Print(VM_NONE, VCORE_NONE, "MSI HI ADDR=%x\n", *(uint32_t *)(cap_ptr + 6));
455 V3_Print(VM_NONE, VCORE_NONE, "MSI Data=%x\n", *(uint16_t *)(cap_ptr + 10));
457 if (msg_ctrl->cap_64bit) {
458 if (msg_ctrl->per_vect_mask) {
459 mask = msi_64pervect_rw_bitmask[write_offset];
461 mask = msi_64_rw_bitmask[write_offset];
464 mask = msi_32_rw_bitmask[write_offset];
466 } else if (cap_type == PCI_CAP_MSIX) {
467 mask = msix_rw_bitmask[write_offset];
468 } else if (cap_type == PCI_CAP_PCIE) {
469 struct pcie_cap_reg * pcie_cap = cap_ptr;
471 if (pcie_cap->version == 1) {
472 mask = pciev1_rw_bitmask[write_offset];
473 } else if (pcie_cap->version == 2) {
474 mask = pciev2_rw_bitmask[write_offset];
478 } else if (cap_type == PCI_CAP_PM) {
479 mask = pm_rw_bitmask[write_offset];
482 pci->config_space[offset + i] &= ~mask;
483 pci->config_space[offset + i] |= ((*(uint8_t *)(src + i)) & mask);
489 if (pci->cmd_update) {
491 /* Detect changes to interrupt types for cmd updates */
492 if (cap_type == PCI_CAP_MSI) {
493 struct msi_msg_ctrl * msg_ctrl = cap_ptr;
495 V3_Print(VM_NONE, VCORE_NONE, "msi_was_enabled=%d, msi_is_enabled=%d\n", msi_was_enabled, msg_ctrl->msi_enable);
497 if ((msg_ctrl->msi_enable == 1) && (msi_was_enabled == 0)) {
498 pci->irq_type = IRQ_MSI;
499 pci->cmd_update(pci, PCI_CMD_MSI_ENABLE, msg_ctrl->mult_msg_enable, pci->priv_data);
500 } else if ((msg_ctrl->msi_enable == 0) && (msi_was_enabled == 1)) {
501 pci->irq_type = IRQ_NONE;
502 pci->cmd_update(pci, PCI_CMD_MSI_DISABLE, 0, pci->priv_data);
504 } else if (cap_type == PCI_CAP_MSIX) {
505 struct msix_cap * msix_cap = cap_ptr;
507 if ((msix_cap->msg_ctrl.msix_enable == 1) && (msix_was_enabled == 0)) {
508 pci->irq_type = IRQ_MSIX;
509 pci->cmd_update(pci, PCI_CMD_MSIX_ENABLE, msix_cap->msg_ctrl.table_size, pci->priv_data);
510 } else if ((msix_cap->msg_ctrl.msix_enable == 0) && (msix_was_enabled == 1)) {
511 pci->irq_type = IRQ_NONE;
512 pci->cmd_update(pci, PCI_CMD_MSIX_DISABLE, msix_cap->msg_ctrl.table_size, pci->priv_data);
521 static int init_pci_cap(struct pci_device * pci, pci_cap_type_t cap_type, uint_t cap_offset) {
522 void * cap_ptr = &(pci->config_space[cap_offset + 2]);
524 if (cap_type == PCI_CAP_MSI) {
525 struct msi32_msg_addr * msi = cap_ptr;
527 // We only expose a basic 32 bit MSI interface
528 msi->msg_ctrl.msi_enable = 0;
529 msi->msg_ctrl.mult_msg_enable = 0;
530 msi->msg_ctrl.cap_64bit = 0;
531 msi->msg_ctrl.per_vect_mask = 0;
536 } else if (cap_type == PCI_CAP_MSIX) {
540 } else if (cap_type == PCI_CAP_PCIE) {
541 struct pcie_cap_v2 * pcie = cap_ptr;
543 // The v1 and v2 formats are identical for the first X bytes
544 // So we use the v2 struct, and only modify extended fields if v2 is detected
546 pcie->dev_cap.fn_level_reset = 0;
548 pcie->dev_ctrl.val &= 0x70e0; // only preserve max_payload_size and max_read_req_size untouched
549 pcie->dev_ctrl.relaxed_order_enable = 1;
550 pcie->dev_ctrl.no_snoop_enable = 1;
552 pcie->dev_status.val = 0;
554 pcie->link_cap.val &= 0x0003ffff;
556 pcie->link_status.val &= 0x03ff;
558 if (pcie->pcie_cap.version >= 2) {
561 pcie->slot_status = 0;
565 pcie->root_status = 0;
567 } else if (cap_type == PCI_CAP_PM) {
576 // enumerate all capabilities and disable them.
577 static int scan_pci_caps(struct pci_device * pci) {
578 uint_t cap_offset = pci->config_header.cap_ptr;
580 V3_Print(VM_NONE, VCORE_NONE, "Scanning for Capabilities (cap_offset=%d)\n", cap_offset);
582 while (cap_offset != 0) {
583 uint8_t id = pci->config_space[cap_offset];
584 uint8_t next = pci->config_space[cap_offset + 1];
586 V3_Print(VM_NONE, VCORE_NONE, "Found Capability 0x%x at offset %d (0x%x)\n",
587 id, cap_offset, cap_offset);
589 struct pci_cap * cap = V3_Malloc(sizeof(struct pci_cap));
592 PrintError(VM_NONE, VCORE_NONE, "Error allocating PCI CAP info\n");
595 memset(cap, 0, sizeof(struct pci_cap));
598 cap->offset = cap_offset;
600 list_add(&(cap->cap_node), &(pci->capabilities));
602 // set correct init values
603 init_pci_cap(pci, id, cap_offset);
606 // set to the next pointer
610 // Disable Capabilities
611 pci->config_header.cap_ptr = 0;
613 // Hook Cap pointer to return cached config space value
614 if (v3_pci_hook_config_range(pci, 0x34, 1,
615 NULL, NULL, NULL) == -1) {
616 PrintError(VM_NONE, VCORE_NONE, "Could not hook cap pointer\n");
623 // Disable all PCIE extended capabilities for now
624 pci->config_space[0x100] = 0;
625 pci->config_space[0x101] = 0;
626 pci->config_space[0x102] = 0;
627 pci->config_space[0x103] = 0;
635 int v3_pci_enable_capability(struct pci_device * pci, pci_cap_type_t cap_type) {
637 struct pci_cap * tmp_cap = NULL;
638 struct pci_cap * cap = NULL;
639 void * cap_ptr = NULL;
642 list_for_each_entry(tmp_cap, &(pci->capabilities), cap_node) {
643 if (tmp_cap->id == cap_type) {
649 if ((cap == NULL) || (cap->enabled)) {
654 V3_Print(VM_NONE, VCORE_NONE, "Found Capability %x at %x (%d)\n", cap_type, cap->offset, cap->offset);
656 // found the capability
658 // mark it as enabled
661 cap_ptr = &(pci->config_space[cap->offset + 2]);
663 if (cap_type == PCI_CAP_MSI) {
664 pci->msi_cap = cap_ptr;
666 if (pci->msi_cap->cap_64bit) {
667 if (pci->msi_cap->per_vect_mask) {
668 // 64 bit MSI w/ per vector masking
678 } else if (cap_type == PCI_CAP_MSIX) {
679 pci->msix_cap = cap_ptr;
681 // disable passthrough for MSIX BAR
683 pci->bar[pci->msix_cap->bir].type = PCI_BAR_MEM32;
686 } else if (cap_type == PCI_CAP_PCIE) {
687 struct pcie_cap_reg * pcie_cap = (struct pcie_cap_reg *)&(pci->config_space[cap->offset + 2]);
689 if (pcie_cap->version == 1) {
691 } else if (pcie_cap->version == 2) {
696 } else if (cap_type == PCI_CAP_PM) {
701 V3_Print(VM_NONE, VCORE_NONE, "Hooking capability range (offset=%d, size=%d)\n", cap->offset, size);
703 if (v3_pci_hook_config_range(pci, cap->offset, size + 2,
704 cap_write, NULL, cap) == -1) {
705 PrintError(VM_NONE, VCORE_NONE, "Could not hook config range (start=%d, size=%d)\n",
706 cap->offset + 2, size);
712 // link it to the active capabilities list
713 pci->config_space[cap->offset + 1] = pci->config_header.cap_ptr;
714 pci->config_header.cap_ptr = cap->offset; // add to the head of the list
722 static int addr_port_read(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * priv_data) {
723 struct pci_internal * pci_state = priv_data;
724 int reg_offset = port & 0x3;
725 uint8_t * reg_addr = ((uint8_t *)&(pci_state->addr_reg.val)) + reg_offset;
727 PrintDebug(core->vm_info, core, "Reading PCI Address Port (%x): %x len=%d\n", port, pci_state->addr_reg.val, length);
729 if (reg_offset + length > 4) {
730 PrintError(core->vm_info, core, "Invalid Address port write\n");
734 memcpy(dst, reg_addr, length);
740 static int addr_port_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
741 struct pci_internal * pci_state = priv_data;
742 int reg_offset = port & 0x3;
743 uint8_t * reg_addr = ((uint8_t *)&(pci_state->addr_reg.val)) + reg_offset;
745 if (reg_offset + length > 4) {
746 PrintError(core->vm_info, core, "Invalid Address port write\n");
750 // Set address register
751 memcpy(reg_addr, src, length);
753 PrintDebug(core->vm_info, core, "Writing PCI Address Port(%x): AddrReg=%x (op_val = %x, len=%d) \n", port, pci_state->addr_reg.val, *(uint32_t *)src, length);
759 static int data_port_read(struct guest_info * core, uint16_t port, void * dst, uint_t length, void * priv_data) {
760 struct pci_internal * pci_state = priv_data;
761 struct pci_device * pci_dev = NULL;
762 uint_t reg_num = (pci_state->addr_reg.hi_reg_num << 16) +(pci_state->addr_reg.reg_num << 2) + (port & 0x3);
764 int bytes_left = length;
766 if (pci_state->addr_reg.bus_num != 0) {
767 memset(dst, 0xff, length);
772 pci_dev = get_device(&(pci_state->bus_list[0]), pci_state->addr_reg.dev_num, pci_state->addr_reg.fn_num);
775 if (pci_dev == NULL) {
776 memset(dst, 0xff, length);
780 PrintDebug(core->vm_info, core, "Reading PCI Data register. bus = %d, dev = %d, fn = %d, reg = %d (%x), cfg_reg = %x\n",
781 pci_state->addr_reg.bus_num,
782 pci_state->addr_reg.dev_num,
783 pci_state->addr_reg.fn_num,
785 pci_state->addr_reg.val);
788 while (bytes_left > 0) {
789 struct cfg_range_hook * cfg_hook = find_cfg_range_hook(pci_dev, reg_num + i, 1);
790 void * cfg_dst = &(pci_dev->config_space[reg_num + i]);
793 uint_t range_len = cfg_hook->length - ((reg_num + i) - cfg_hook->start);
794 range_len = (range_len > bytes_left) ? bytes_left : range_len;
796 if (cfg_hook->read) {
797 cfg_hook->read(pci_dev, reg_num + i, cfg_dst, range_len, cfg_hook->private_data);
799 if (pci_dev->config_read) {
800 if (pci_dev->config_read(pci_dev, reg_num + i, cfg_dst, range_len, pci_dev->priv_data) != 0) {
801 PrintError(core->vm_info, core, "Error in config_read from PCI device (%s)\n", pci_dev->name);
806 bytes_left -= range_len;
809 if (pci_dev->config_read) {
810 if (pci_dev->config_read(pci_dev, reg_num + i, cfg_dst, 1, pci_dev->priv_data) != 0) {
811 PrintError(core->vm_info, core, "Error in config_read from PCI device (%s)\n", pci_dev->name);
820 memcpy(dst, &(pci_dev->config_space[reg_num]), length);
822 PrintDebug(core->vm_info, core, "\tVal=%x, len=%d\n", *(uint32_t *)dst, length);
829 static int bar_update(struct pci_device * pci_dev, uint32_t offset,
830 void * src, uint_t length, void * private_data) {
831 struct v3_pci_bar * bar = (struct v3_pci_bar *)private_data;
832 int bar_offset = offset & ~0x03;
833 int bar_num = (bar_offset - 0x10) / 4;
834 uint32_t new_val = *(uint32_t *)src;
836 PrintDebug(VM_NONE, VCORE_NONE, "Updating BAR Register (Dev=%s) (bar=%d) (old_val=0x%x) (new_val=0x%x) (length=%d)\n",
837 pci_dev->name, bar_num, bar->val, new_val, length);
839 // Cache the changes locally
840 memcpy(&(pci_dev->config_space[offset]), src, length);
842 if (bar->type == PCI_BAR_PASSTHROUGH) {
843 if (bar->bar_write(bar_num, (void *)(pci_dev->config_space + bar_offset), bar->private_data) == -1) {
844 PrintError(VM_NONE, VCORE_NONE, "Error in Passthrough bar write operation\n");
851 // Else we are a virtualized BAR
853 *(uint32_t *)(pci_dev->config_space + offset) &= bar->mask;
855 // Handle buggy code that discards the freaking I/O bit...
856 if (bar->type == PCI_BAR_IO && !(new_val & 0x1) ) {
857 PrintError(VM_NONE,VCORE_NONE,"Buggy guest: Updating BAR %d of device %s discards the I/O bit...\n", bar_num, pci_dev->name);
858 *(uint32_t *)(pci_dev->config_space + offset) |= 0x1;
863 // V3_Print(VM_NONE, VCORE_NONE,"mask=%x written val=%x\n", bar->mask, *(uint32_t *)(pci_dev->config_space + offset));
869 PrintDebug(VM_NONE, VCORE_NONE, "\tRehooking %d IO ports from base 0x%x to 0x%x for %d ports\n",
870 bar->num_ports, PCI_IO_BASE(bar->val), PCI_IO_BASE(new_val),
873 for (i = 0; i < bar->num_ports; i++) {
875 PrintDebug(VM_NONE, VCORE_NONE, "Rehooking PCI IO port (old port=%u) (new port=%u)\n",
876 PCI_IO_BASE(bar->val) + i, PCI_IO_BASE(new_val) + i);
878 v3_unhook_io_port(pci_dev->vm, PCI_IO_BASE(bar->val) + i);
880 if (v3_hook_io_port(pci_dev->vm, PCI_IO_BASE(new_val) + i,
881 bar->io_read, bar->io_write,
882 bar->private_data) == -1) {
884 PrintError(VM_NONE, VCORE_NONE, "Could not hook PCI IO port (old port=%u) (new port=%u)\n",
885 PCI_IO_BASE(bar->val) + i, PCI_IO_BASE(new_val) + i);
886 //v3_print_io_map(pci_dev->vm);
895 case PCI_BAR_MEM32: {
896 v3_unhook_mem(pci_dev->vm, V3_MEM_CORE_ANY, (addr_t)(bar->val));
899 v3_hook_full_mem(pci_dev->vm, V3_MEM_CORE_ANY, PCI_MEM32_BASE(new_val),
900 PCI_MEM32_BASE(new_val) + (bar->num_pages * PAGE_SIZE_4KB),
901 bar->mem_read, bar->mem_write, pci_dev->priv_data);
903 PrintError(VM_NONE, VCORE_NONE, "Write hooks not supported for PCI\n");
912 PrintDebug(VM_NONE, VCORE_NONE, "Reprogramming an unsupported BAR register (Dev=%s) (bar=%d) (val=%x)\n",
913 pci_dev->name, bar_num, new_val);
917 PrintError(VM_NONE, VCORE_NONE, "Invalid Bar Reg updated (bar=%d)\n", bar_num);
925 static int data_port_write(struct guest_info * core, uint16_t port, void * src, uint_t length, void * priv_data) {
926 struct pci_internal * pci_state = priv_data;
927 struct pci_device * pci_dev = NULL;
928 uint_t reg_num = (pci_state->addr_reg.hi_reg_num << 16) +(pci_state->addr_reg.reg_num << 2) + (port & 0x3);
932 if (pci_state->addr_reg.bus_num != 0) {
936 PrintDebug(VM_NONE, VCORE_NONE, "Writing PCI Data register. bus = %d, dev = %d, fn = %d, reg = %d (0x%x) addr_reg = 0x%x (val=0x%x, len=%d)\n",
937 pci_state->addr_reg.bus_num,
938 pci_state->addr_reg.dev_num,
939 pci_state->addr_reg.fn_num,
941 pci_state->addr_reg.val,
942 *(uint32_t *)src, length);
945 pci_dev = get_device(&(pci_state->bus_list[0]), pci_state->addr_reg.dev_num, pci_state->addr_reg.fn_num);
947 if (pci_dev == NULL) {
948 PrintError(VM_NONE, VCORE_NONE, "Writing configuration space for non-present device (dev_num=%d)\n",
949 pci_state->addr_reg.dev_num);
953 /* update the config space
954 If a hook has been registered for a given region, call the hook with the max write length
957 struct cfg_range_hook * cfg_hook = find_cfg_range_hook(pci_dev, reg_num + i, 1);
960 uint_t range_len = cfg_hook->length - ((reg_num + i) - cfg_hook->start);
961 range_len = (range_len > length) ? length : range_len;
963 if (cfg_hook->write) {
964 cfg_hook->write(pci_dev, reg_num + i, (void *)(src + i), range_len, cfg_hook->private_data);
970 // send the writes to the cached config space, and to the generic callback if present
974 mask = pci_hdr_write_mask_00[reg_num + i];
978 uint8_t new_val = *(uint8_t *)(src + i);
979 uint8_t old_val = pci_dev->config_space[reg_num + i];
981 pci_dev->config_space[reg_num + i] = ((new_val & mask) | (old_val & ~mask));
983 if (pci_dev->config_write) {
984 pci_dev->config_write(pci_dev, reg_num + i, &(pci_dev->config_space[reg_num + i]), 1, pci_dev->priv_data);
998 static int exp_rom_write(struct pci_device * pci_dev, uint32_t offset,
999 void * src, uint_t length, void * private_data) {
1000 int bar_offset = offset & ~0x03;
1002 if (pci_dev->config_write) {
1003 pci_dev->config_write(pci_dev, offset, src, length, pci_dev->priv_data);
1006 if (pci_dev->exp_rom_update) {
1007 pci_dev->exp_rom_update(pci_dev, (void *)(pci_dev->config_space + bar_offset), pci_dev->priv_data);
1012 PrintError(VM_NONE, VCORE_NONE, "Expansion ROM update not handled. Will appear to not Exist\n");
1018 static int cmd_write(struct pci_device * pci_dev, uint32_t offset,
1019 void * src, uint_t length, void * private_data) {
1021 PrintDebug(VM_NONE, VCORE_NONE, "PCI command update!\n");
1025 struct pci_cmd_reg old_cmd;
1026 struct pci_cmd_reg new_cmd;
1027 if (pci_dev->config_write) {
1028 pci_dev->config_write(pci_dev, offset, src, length, pci_dev->priv_data);
1030 old_cmd.val = pci_dev->config_header.command;
1032 for (i = 0; i < length; i++) {
1033 uint8_t mask = pci_hdr_write_mask_00[offset + i];
1034 uint8_t new_val = *(uint8_t *)(src + i);
1035 uint8_t old_val = pci_dev->config_space[offset + i];
1037 pci_dev->config_space[offset + i] = ((new_val & mask) | (old_val & ~mask));
1040 new_cmd.val = pci_dev->config_header.command;
1042 if (pci_dev->cmd_update) {
1043 if ((new_cmd.intx_disable == 1) && (old_cmd.intx_disable == 0)) {
1044 pci_dev->irq_type = IRQ_NONE;
1045 pci_dev->cmd_update(pci_dev, PCI_CMD_INTX_DISABLE, 0, pci_dev->priv_data);
1046 } else if ((new_cmd.intx_disable == 0) && (old_cmd.intx_disable == 1)) {
1047 pci_dev->irq_type = IRQ_INTX;
1048 pci_dev->cmd_update(pci_dev, PCI_CMD_INTX_ENABLE, 0, pci_dev->priv_data);
1052 if ((new_cmd.dma_enable == 1) && (old_cmd.dma_enable == 0)) {
1053 pci_dev->cmd_update(pci_dev, PCI_CMD_DMA_ENABLE, 0, pci_dev->priv_data);
1054 } else if ((new_cmd.dma_enable == 0) && (old_cmd.dma_enable == 1)) {
1055 pci_dev->cmd_update(pci_dev, PCI_CMD_DMA_DISABLE, 0, pci_dev->priv_data);
1063 static void init_pci_busses(struct pci_internal * pci_state) {
1066 for (i = 0; i < PCI_BUS_COUNT; i++) {
1067 pci_state->bus_list[i].bus_num = i;
1068 pci_state->bus_list[i].devices.rb_node = NULL;
1069 memset(pci_state->bus_list[i].dev_map, 0, sizeof(pci_state->bus_list[i].dev_map));
1074 static int pci_free(struct pci_internal * pci_state) {
1079 for (i = 0; i < PCI_BUS_COUNT; i++) {
1080 struct pci_bus * bus = &(pci_state->bus_list[i]);
1081 struct rb_node * node = v3_rb_first(&(bus->devices));
1082 struct pci_device * dev = NULL;
1085 dev = rb_entry(node, struct pci_device, dev_tree_node);
1086 node = v3_rb_next(node);
1088 v3_rb_erase(&(dev->dev_tree_node), &(bus->devices));
1090 // Free config range hooks
1092 struct cfg_range_hook * hook = NULL;
1093 struct cfg_range_hook * tmp = NULL;
1094 list_for_each_entry_safe(hook, tmp, &(dev->cfg_hooks), list_node) {
1095 list_del(&(hook->list_node));
1102 struct pci_cap * cap = NULL;
1103 struct pci_cap * tmp = NULL;
1104 list_for_each_entry_safe(cap, tmp, &(dev->cfg_hooks), cap_node) {
1105 list_del(&(cap->cap_node));
1119 #ifdef V3_CONFIG_CHECKPOINT
1121 #include <palacios/vmm_sprintf.h>
1123 static int pci_save_extended(struct v3_chkpt *chkpt, char *id, void * private_data) {
1124 struct pci_internal * pci = (struct pci_internal *)private_data;
1125 struct v3_chkpt_ctx *ctx=0;
1129 ctx = v3_chkpt_open_ctx(chkpt,id);
1132 PrintError(VM_NONE, VCORE_NONE, "Unable to open base context on save\n");
1136 V3_CHKPT_SAVE(ctx, "ADDR_REG", pci->addr_reg.val, savefailout);
1137 V3_CHKPT_SAVE(ctx, "IO_BASE", pci->dev_io_base, savefailout);
1139 v3_chkpt_close_ctx(ctx); ctx=0;
1141 for (i = 0; i < PCI_BUS_COUNT; i++) {
1142 struct pci_bus * bus = &(pci->bus_list[i]);
1143 struct rb_node * node = v3_rb_first(&(bus->devices));
1144 struct pci_device * dev = NULL;
1146 snprintf(buf, 128, "%s-%d", id, i);
1148 ctx = v3_chkpt_open_ctx(chkpt, buf);
1151 PrintError(VM_NONE, VCORE_NONE, "Failed to open context for %s\n", buf);
1155 // nothing actually saved on the bus context... (later expansion)
1157 v3_chkpt_close_ctx(ctx); ctx=0;
1161 dev = rb_entry(node, struct pci_device, dev_tree_node);
1163 snprintf(buf, 128, "%s-%d.%d-%d", id, i, dev->dev_num, dev->fn_num);
1165 ctx = v3_chkpt_open_ctx(chkpt, buf);
1168 PrintError(VM_NONE, VCORE_NONE, "Failed to open context for device\n");
1172 V3_CHKPT_SAVE(ctx, "CONFIG_SPACE", dev->config_space, savefailout);
1174 for (bar_idx = 0; bar_idx < 6; bar_idx++) {
1175 snprintf(buf, 128, "BAR-%d", bar_idx);
1176 V3_CHKPT_SAVE(ctx, buf, dev->bar[bar_idx].val, savefailout);
1179 v3_chkpt_close_ctx(ctx); ctx=0;
1181 node = v3_rb_next(node);
1190 PrintError(VM_NONE, VCORE_NONE, "Failed to save PCI\n");
1191 if (ctx) { v3_chkpt_close_ctx(ctx); }
1197 static int pci_load_extended(struct v3_chkpt *chkpt, char *id, void * private_data) {
1198 struct pci_internal * pci = (struct pci_internal *)private_data;
1199 struct v3_chkpt_ctx *ctx=0;
1203 ctx = v3_chkpt_open_ctx(chkpt,id);
1206 PrintError(VM_NONE, VCORE_NONE, "Unable to open base context on load\n");
1210 V3_CHKPT_LOAD(ctx, "ADDR_REG", pci->addr_reg.val, loadfailout);
1211 V3_CHKPT_LOAD(ctx, "IO_BASE", pci->dev_io_base, loadfailout);
1213 v3_chkpt_close_ctx(ctx); ctx=0;
1215 for (i = 0; i < PCI_BUS_COUNT; i++) {
1216 struct pci_bus * bus = &(pci->bus_list[i]);
1217 struct rb_node * node = v3_rb_first(&(bus->devices));
1218 struct pci_device * dev = NULL;
1220 snprintf(buf, 128, "pci-%d", i);
1222 ctx = v3_chkpt_open_ctx(chkpt, buf);
1225 PrintError(VM_NONE, VCORE_NONE, "Failed to open context for %s\n", buf);
1229 // nothing actually saved on the bus context... (later expansion)
1231 v3_chkpt_close_ctx(ctx); ctx=0;
1235 dev = rb_entry(node, struct pci_device, dev_tree_node);
1237 snprintf(buf, 128, "pci-%d.%d-%d", i, dev->dev_num, dev->fn_num);
1239 ctx = v3_chkpt_open_ctx(chkpt, buf);
1242 PrintError(VM_NONE, VCORE_NONE, "Failed to open context for device\n");
1246 V3_CHKPT_LOAD(ctx, "CONFIG_SPACE", dev->config_space, loadfailout);
1248 for (bar_idx = 0; bar_idx < 6; bar_idx++) {
1249 snprintf(buf, 128, "BAR-%d", bar_idx);
1250 V3_CHKPT_LOAD(ctx, buf, dev->bar[bar_idx].val, loadfailout);
1253 v3_chkpt_close_ctx(ctx); ctx=0;
1255 node = v3_rb_next(node);
1263 PrintError(VM_NONE, VCORE_NONE, "Failed to load PCI\n");
1264 if (ctx) { v3_chkpt_close_ctx(ctx); }
1275 static struct v3_device_ops dev_ops = {
1276 .free = (int (*)(void *))pci_free,
1277 #ifdef V3_CONFIG_CHECKPOINT
1278 .save_extended = pci_save_extended,
1279 .load_extended = pci_load_extended
1286 static int pci_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
1287 struct pci_internal * pci_state = V3_Malloc(sizeof(struct pci_internal));
1290 PrintError(vm, VCORE_NONE, "Cannot allocate in init\n");
1295 char * dev_id = v3_cfg_val(cfg, "ID");
1298 PrintDebug(vm, VCORE_NONE, "PCI internal at %p\n",(void *)pci_state);
1300 struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, pci_state);
1303 PrintError(vm, VCORE_NONE, "Could not attach device %s\n", dev_id);
1309 pci_state->addr_reg.val = 0;
1310 pci_state->dev_io_base = PCI_DEV_IO_PORT_BASE;
1312 init_pci_busses(pci_state);
1314 PrintDebug(vm, VCORE_NONE, "Sizeof config header=%d\n", (int)sizeof(struct pci_config_header));
1316 for (i = 0; i < 4; i++) {
1317 ret |= v3_dev_hook_io(dev, CONFIG_ADDR_PORT + i, &addr_port_read, &addr_port_write);
1318 ret |= v3_dev_hook_io(dev, CONFIG_DATA_PORT + i, &data_port_read, &data_port_write);
1322 PrintError(vm, VCORE_NONE, "Error hooking PCI IO ports\n");
1323 v3_remove_device(dev);
1331 device_register("PCI", pci_init)
1334 static inline int init_bars(struct v3_vm_info * vm, struct pci_device * pci_dev) {
1337 for (i = 0; i < 6; i++) {
1338 int bar_offset = 0x10 + (4 * i);
1339 struct v3_pci_bar * bar = &(pci_dev->bar[i]);
1341 if (bar->type == PCI_BAR_IO) {
1343 bar->mask = (~((bar->num_ports) - 1)) | 0x01;
1345 if (bar->default_base_port != 0xffff) {
1346 bar->val = bar->default_base_port & bar->mask;
1351 bar->val |= 0x00000001;
1353 for (j = 0; j < bar->num_ports; j++) {
1355 if (bar->default_base_port != 0xffff) {
1356 if (v3_hook_io_port(vm, bar->default_base_port + j,
1357 bar->io_read, bar->io_write,
1358 bar->private_data) == -1) {
1359 PrintError(vm, VCORE_NONE, "Could not hook default io port %x\n", bar->default_base_port + j);
1365 *(uint32_t *)(pci_dev->config_space + bar_offset) = bar->val;
1367 } else if (bar->type == PCI_BAR_MEM32) {
1368 bar->mask = ~((bar->num_pages << 12) - 1);
1369 bar->mask |= 0xf; // preserve the configuration flags
1372 if (bar->default_base_addr != 0xffffffff) {
1373 bar->val = bar->default_base_addr & bar->mask;
1379 if (bar->mem_read) {
1381 v3_hook_full_mem(vm, V3_MEM_CORE_ANY, bar->default_base_addr,
1382 bar->default_base_addr + (bar->num_pages * PAGE_SIZE_4KB),
1383 bar->mem_read, bar->mem_write, pci_dev->priv_data);
1384 } else if (bar->mem_write) {
1386 PrintError(vm, VCORE_NONE, "Write hooks not supported for PCI devices\n");
1389 v3_hook_write_mem(pci_dev->vm_dev->vm, bar->default_base_addr,
1390 bar->default_base_addr + (bar->num_pages * PAGE_SIZE_4KB),
1391 bar->mem_write, pci_dev->vm_dev);
1394 // set the prefetchable flag...
1395 bar->val |= 0x00000008;
1399 *(uint32_t *)(pci_dev->config_space + bar_offset) = bar->val;
1401 } else if (bar->type == PCI_BAR_MEM24) {
1402 PrintError(vm, VCORE_NONE, "16 Bit memory ranges not supported (reg: %d)\n", i);
1404 } else if (bar->type == PCI_BAR_NONE) {
1405 bar->val = 0x00000000;
1406 bar->mask = 0x00000000; // This ensures that all updates will be dropped
1407 *(uint32_t *)(pci_dev->config_space + bar_offset) = bar->val;
1408 } else if (bar->type == PCI_BAR_PASSTHROUGH) {
1410 // Call the bar init function to get the local cached value
1411 bar->bar_init(i, &(bar->val), bar->private_data);
1413 // Copy back changes it made
1414 *(uint32_t *)(pci_dev->config_space + bar_offset) = bar->val;
1417 PrintError(vm, VCORE_NONE, "Invalid BAR type for bar #%d\n", i);
1421 v3_pci_hook_config_range(pci_dev, bar_offset, 4, bar_update, NULL, bar);
1428 int v3_pci_set_irq_bridge(struct vm_device * pci_bus, int bus_num,
1429 int (*raise_pci_irq)(struct pci_device * pci_dev, void * dev_data, struct v3_irq * vec),
1430 int (*lower_pci_irq)(struct pci_device * pci_dev, void * dev_data, struct v3_irq * vec),
1432 struct pci_internal * pci_state = (struct pci_internal *)pci_bus->private_data;
1435 pci_state->bus_list[bus_num].raise_pci_irq = raise_pci_irq;
1436 pci_state->bus_list[bus_num].lower_pci_irq = lower_pci_irq;
1437 pci_state->bus_list[bus_num].irq_dev_data = priv_data;
1442 int v3_pci_raise_irq(struct vm_device * pci_bus, struct pci_device * dev, uint32_t vec_index) {
1446 vec.private_data = NULL;
1447 vec.irq = vec_index;
1449 return v3_pci_raise_acked_irq(pci_bus, dev, vec);
1452 int v3_pci_lower_irq(struct vm_device * pci_bus, struct pci_device * dev, uint32_t vec_index) {
1455 vec.irq = vec_index;
1457 vec.private_data = NULL;
1459 return v3_pci_lower_acked_irq(pci_bus, dev, vec);
1462 int v3_pci_raise_acked_irq(struct vm_device * pci_bus, struct pci_device * dev, struct v3_irq vec) {
1463 struct pci_internal * pci_state = (struct pci_internal *)pci_bus->private_data;
1464 struct pci_bus * bus = &(pci_state->bus_list[dev->bus_num]);
1467 if (dev->irq_type == IRQ_INTX) {
1468 return bus->raise_pci_irq(dev, bus->irq_dev_data, &vec);
1469 } else if (dev->irq_type == IRQ_MSI) {
1470 struct v3_gen_ipi ipi;
1471 struct msi_addr * addr = NULL;
1472 struct msi_data * data = NULL;
1474 if (dev->msi_cap->cap_64bit) {
1475 if (dev->msi_cap->per_vect_mask) {
1476 struct msi64_pervec_msg_addr * msi = (void *)dev->msi_cap;
1477 addr = &(msi->addr);
1478 data = &(msi->data);
1480 struct msi64_msg_addr * msi = (void *)dev->msi_cap;
1481 addr = &(msi->addr);
1482 data = &(msi->data);
1485 struct msi32_msg_addr * msi = (void *)dev->msi_cap;
1486 addr = &(msi->addr);
1487 data = &(msi->data);
1490 memset(&ipi, 0, sizeof(struct v3_gen_ipi));
1492 // decode MSI fields into IPI
1494 ipi.vector = data->vector + vec.irq;
1495 ipi.mode = data->del_mode;
1496 ipi.logical = addr->dst_mode;
1497 ipi.trigger_mode = data->trig_mode;
1498 ipi.dst_shorthand = 0;
1499 ipi.dst = addr->dst_id;
1502 v3_apic_send_ipi(dev->vm, &ipi, dev->apic_dev);
1505 } else if (dev->irq_type == IRQ_MSIX) {
1506 addr_t msix_table_gpa = 0;
1507 struct msix_table * msix_table = NULL;
1508 uint_t bar_idx = dev->msix_cap->bir;
1509 struct v3_gen_ipi ipi;
1510 struct msi_addr * addr = NULL;
1511 struct msi_data * data = NULL;
1513 if (dev->bar[bar_idx].type != PCI_BAR_MEM32) {
1514 PrintError(VM_NONE, VCORE_NONE, "Non 32bit MSIX BAR registers are not supported\n");
1518 msix_table_gpa = dev->bar[bar_idx].val;
1519 msix_table_gpa += dev->msix_cap->table_offset;
1521 if (v3_gpa_to_hva(&(dev->vm->cores[0]), msix_table_gpa, (void *)&(msix_table)) != 0) {
1522 PrintError(VM_NONE, VCORE_NONE, "Could not translate MSIX Table GPA (%p)\n", (void *)msix_table_gpa);
1526 memset(&ipi, 0, sizeof(struct v3_gen_ipi));
1528 data = &(msix_table->entries[vec.irq].data);
1529 addr = &(msix_table->entries[vec.irq].addr);;
1531 // decode MSIX fields into IPI
1532 ipi.vector = data->vector + vec.irq;
1533 ipi.mode = data->del_mode;
1534 ipi.logical = addr->dst_mode;
1535 ipi.trigger_mode = data->trig_mode;
1536 ipi.dst_shorthand = 0;
1537 ipi.dst = addr->dst_id;
1541 V3_Print(VM_NONE, VCORE_NONE, "Decode MSIX\n");
1543 v3_apic_send_ipi(dev->vm, &ipi, dev->apic_dev);
1548 // Should never get here
1553 int v3_pci_lower_acked_irq(struct vm_device * pci_bus, struct pci_device * dev, struct v3_irq vec) {
1554 if (dev->irq_type == IRQ_INTX) {
1555 struct pci_internal * pci_state = (struct pci_internal *)pci_bus->private_data;
1556 struct pci_bus * bus = &(pci_state->bus_list[dev->bus_num]);
1558 return bus->lower_pci_irq(dev, bus->irq_dev_data, &vec);
1565 // if dev_num == -1, auto assign
1566 struct pci_device * v3_pci_register_device(struct vm_device * pci,
1567 pci_device_type_t dev_type,
1572 struct v3_pci_bar * bars,
1573 int (*config_write)(struct pci_device * pci_dev, uint32_t reg_num, void * src,
1574 uint_t length, void * priv_data),
1575 int (*config_read)(struct pci_device * pci_dev, uint32_t reg_num, void * dst,
1576 uint_t length, void * priv_data),
1577 int (*cmd_update)(struct pci_device * pci_dev, pci_cmd_t cmd, uint64_t arg, void * priv_data),
1578 int (*exp_rom_update)(struct pci_device * pci_dev, uint32_t * src, void * priv_data),
1581 struct pci_internal * pci_state = (struct pci_internal *)pci->private_data;
1582 struct pci_bus * bus = &(pci_state->bus_list[bus_num]);
1583 struct pci_device * pci_dev = NULL;
1586 if (dev_num > MAX_BUS_DEVICES) {
1587 PrintError(VM_NONE, VCORE_NONE, "Requested Invalid device number (%d)\n", dev_num);
1591 if (dev_num == PCI_AUTO_DEV_NUM) {
1592 PrintDebug(VM_NONE, VCORE_NONE, "Searching for free device number\n");
1593 if ((dev_num = get_free_dev_num(bus)) == -1) {
1594 PrintError(VM_NONE, VCORE_NONE, "No more available PCI slots on bus %d\n", bus->bus_num);
1597 V3_Print(VM_NONE, VCORE_NONE,"assigning dev num %d to device (%s, busnum=%d,fnnum=%d)\n", dev_num, name, bus->bus_num, fn_num);
1600 PrintDebug(VM_NONE, VCORE_NONE, "Checking for PCI Device\n");
1602 if (get_device(bus, dev_num, fn_num) != NULL) {
1603 PrintError(VM_NONE, VCORE_NONE, "PCI Device already registered at slot %d on bus %d\n",
1604 dev_num, bus->bus_num);
1609 pci_dev = (struct pci_device *)V3_Malloc(sizeof(struct pci_device));
1611 if (pci_dev == NULL) {
1612 PrintError(VM_NONE, VCORE_NONE, "Could not allocate pci device\n");
1616 memset(pci_dev, 0, sizeof(struct pci_device));
1619 pci_dev->type = dev_type;
1621 switch (pci_dev->type) {
1622 case PCI_STD_DEVICE:
1623 pci_dev->config_header.header_type = 0x00;
1625 case PCI_MULTIFUNCTION:
1626 pci_dev->config_header.header_type = 0x80;
1629 PrintError(VM_NONE, VCORE_NONE, "Unhandled PCI Device Type: %d\n", dev_type);
1635 pci_dev->bus_num = bus_num;
1636 pci_dev->dev_num = dev_num;
1637 pci_dev->fn_num = fn_num;
1639 strncpy(pci_dev->name, name, sizeof(pci_dev->name));
1640 pci_dev->vm = pci->vm;
1641 pci_dev->priv_data = priv_data;
1643 INIT_LIST_HEAD(&(pci_dev->cfg_hooks));
1644 INIT_LIST_HEAD(&(pci_dev->capabilities));
1648 // locate APIC for MSI/MSI-X
1649 pci_dev->apic_dev = v3_find_dev(pci->vm, "apic");
1652 // register update callbacks
1653 pci_dev->config_write = config_write;
1654 pci_dev->config_read = config_read;
1655 pci_dev->cmd_update = cmd_update;
1656 pci_dev->exp_rom_update = exp_rom_update;
1663 // Only 256 bytes for now, should expand it in the future
1664 for (i = 0; i < 256; i++) {
1665 config_read(pci_dev, i, &(pci_dev->config_space[i]), 1, pci_dev->priv_data);
1669 V3_Print(VM_NONE, VCORE_NONE, "Scanning for Capabilities\n");
1672 scan_pci_caps(pci_dev);
1674 pci_dev->irq_type = IRQ_INTX;
1676 V3_Print(VM_NONE, VCORE_NONE, "Caps scanned\n");
1678 // hook important regions
1679 v3_pci_hook_config_range(pci_dev, 0x30, 4, exp_rom_write, NULL, NULL); // ExpRom
1680 v3_pci_hook_config_range(pci_dev, 0x04, 2, cmd_write, NULL, NULL); // CMD Reg
1688 for (i = 0; i < 6; i ++) {
1689 pci_dev->bar[i].type = bars[i].type;
1690 pci_dev->bar[i].private_data = bars[i].private_data;
1692 if (pci_dev->bar[i].type == PCI_BAR_IO) {
1693 pci_dev->bar[i].num_ports = bars[i].num_ports;
1695 // This is a horrible HACK becaues the BIOS is supposed to set the PCI base ports
1696 // And if the BIOS doesn't, Linux just happily overlaps device port assignments
1697 if (bars[i].default_base_port != (uint16_t)-1) {
1698 pci_dev->bar[i].default_base_port = bars[i].default_base_port;
1700 pci_dev->bar[i].default_base_port = pci_state->dev_io_base;
1701 pci_state->dev_io_base += ( 0x100 * ((bars[i].num_ports / 0x100) + 1) );
1704 pci_dev->bar[i].io_read = bars[i].io_read;
1705 pci_dev->bar[i].io_write = bars[i].io_write;
1706 } else if (pci_dev->bar[i].type == PCI_BAR_MEM32) {
1707 pci_dev->bar[i].num_pages = bars[i].num_pages;
1708 pci_dev->bar[i].default_base_addr = bars[i].default_base_addr;
1709 pci_dev->bar[i].mem_read = bars[i].mem_read;
1710 pci_dev->bar[i].mem_write = bars[i].mem_write;
1711 } else if (pci_dev->bar[i].type == PCI_BAR_PASSTHROUGH) {
1712 pci_dev->bar[i].bar_init = bars[i].bar_init;
1713 pci_dev->bar[i].bar_write = bars[i].bar_write;
1715 pci_dev->bar[i].num_pages = 0;
1716 pci_dev->bar[i].default_base_addr = 0;
1717 pci_dev->bar[i].mem_read = NULL;
1718 pci_dev->bar[i].mem_write = NULL;
1722 if (init_bars(pci->vm, pci_dev) == -1) {
1723 PrintError(VM_NONE, VCORE_NONE, "could not initialize bar registers\n");
1728 add_device_to_bus(bus, pci_dev);
1730 #ifdef V3_CONFIG_DEBUG_PCI
1731 pci_dump_state(pci_state);