#include <palacios/vmm_dev_mgr.h>
#include <palacios/vmm_sprintf.h>
#include <palacios/vmm_lowlevel.h>
-
+#include <palacios/vm_guest.h> // must include this to avoid dependency issue
+#include <palacios/vmm_sym_iface.h>
#include <devices/pci.h>
#include <devices/pci_types.h>
-#include <devices/pci_passthrough.h>
// Hardcoded... Are these standard??
#define PCI_CFG_ADDR 0xcf8
#define PCI_CFG_DATA 0xcfc
-#define PCI_BUS_MAX 4
+#define PCI_BUS_MAX 7
#define PCI_DEV_MAX 32
#define PCI_FN_MAX 7
//v3_irq_restore(irq_state);
- pbar->size = ~PCI_IO_BASE(max_val) + 1;
+ V3_Print("max_val = %x\n", max_val);
+
+ pbar->size = (uint16_t)~PCI_IO_BASE(max_val) + 1;
+ V3_Print("IO Bar with %d (%x) ports %x->%x\n", pbar->size, pbar->size, pbar->addr, pbar->addr + pbar->size);
// setup a set of null io hooks
// This allows the guest to do passthrough IO to these ports
// While still reserving them in the IO map
}
}
-
-
// Initially the virtual bars match the physical ones
state->virt_bars[bar_num].type, state->virt_bars[bar_num].addr,
state->virt_bars[bar_num].size);
-
-
// Update the pci subsystem versions
*dst = bar_val;
struct pt_bar * pbar = &(state->phys_bars[bar_num]);
struct pt_bar * vbar = &(state->virt_bars[bar_num]);
- PrintDebug("Bar update src=0x%x\n", *src);
+ PrintDebug("Bar update: bar_num=%d, src=0x%x\n", bar_num,*src);
+ PrintDebug("vbar is size=%u, type=%d, addr=0x%x, val=0x%x\n",vbar->size, vbar->type, vbar->addr, vbar->val);
+ PrintDebug("pbar is size=%u, type=%d, addr=0x%x, val=0x%x\n",pbar->size, pbar->type, pbar->addr, pbar->val);
+
+
if (vbar->type == PT_BAR_NONE) {
return 0;
} __attribute__((packed)) pci_hdr = {0};
-
+ //PrintDebug("Scanning PCI busses for vendor=%x, device=%x\n", vendor_id, device_id);
for (i = 0, pci_addr.bus = 0; i < PCI_BUS_MAX; i++, pci_addr.bus++) {
for (j = 0, pci_addr.dev = 0; j < PCI_DEV_MAX; j++, pci_addr.dev++) {
for (k = 0, pci_addr.func = 0; k < PCI_FN_MAX; k++, pci_addr.func++) {
v3_outdw(PCI_CFG_ADDR, pci_addr.value);
pci_hdr.value = v3_indw(PCI_CFG_DATA);
+ //PrintDebug("\bus=%d, tvendor=%x, device=%x\n", pci_addr.bus, pci_hdr.vendor, pci_hdr.device);
+
if ((pci_hdr.vendor == vendor_id) && (pci_hdr.device == device_id)) {
uint32_t * cfg_space = (uint32_t *)&state->real_hdr;
bus_num, -1, 0,
state->name, bars,
pt_config_update, NULL, NULL,
- dev, dev);
+ dev);
// This will overwrite the bar registers.. but that should be ok.
memcpy(pci_dev->config_space, (uint8_t *)&(state->real_hdr), sizeof(struct pci_config_header));
+ state->pci_dev = pci_dev;
+
+ v3_sym_map_pci_passthrough(info, pci_dev->bus_num, pci_dev->dev_num, pci_dev->fn_num);
+
+
return 0;
}
-static int passthrough_init(struct guest_info * info, void * cfg_data) {
- struct pci_passthrough_cfg * cfg = (struct pci_passthrough_cfg *)cfg_data;
+static int irq_handler(struct guest_info * info, struct v3_interrupt * intr, void * private_data) {
+ struct vm_device * dev = (struct vm_device *)private_data;
+ struct pt_dev_state * state = (struct pt_dev_state *)dev->private_data;
+
+// PrintDebug("Handling E1000 IRQ %d\n", intr->irq);
+
+ v3_pci_raise_irq(state->pci_bus, 0, state->pci_dev);
+
+ V3_ACK_IRQ(intr->irq);
+
+ return 0;
+}
+
+
+
+
+static int passthrough_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
struct pt_dev_state * state = V3_Malloc(sizeof(struct pt_dev_state));
struct vm_device * dev = NULL;
- struct vm_device * pci = v3_find_dev(info, cfg->pci_bus_name);
-
+ struct vm_device * pci = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
+ char * name = v3_cfg_val(cfg, "name");
memset(state, 0, sizeof(struct pt_dev_state));
}
state->pci_bus = pci;
- strncpy(state->name, cfg->name, 32);
-
+ strncpy(state->name, name, 32);
- dev = v3_allocate_device("PCI_PASSTHROUGH", &dev_ops, state);
+ dev = v3_allocate_device(name, &dev_ops, state);
- if (v3_attach_device(info, dev) == -1) {
- PrintError("Could not attach device %s\n", "PCI_PASSTHROUGH");
+ if (v3_attach_device(vm, dev) == -1) {
+ PrintError("Could not attach device %s\n", name);
return -1;
}
- if (find_real_pci_dev(cfg->vendor_id, cfg->device_id, state) == -1) {
- PrintError("Could not find PCI Device %x:%x\n", cfg->vendor_id, cfg->device_id);
+ if (find_real_pci_dev(atox(v3_cfg_val(cfg, "vendor_id")),
+ atox(v3_cfg_val(cfg, "device_id")),
+ state) == -1) {
+ PrintError("Could not find PCI Device %s:%s\n",
+ v3_cfg_val(cfg, "vendor_id"),
+ v3_cfg_val(cfg, "device_id"));
return 0;
}
- setup_virt_pci_dev(info, dev);
+ setup_virt_pci_dev(vm, dev);
+
+ v3_hook_irq(vm, atoi(v3_cfg_val(cfg, "irq")), irq_handler, dev);
+ // v3_hook_irq(info, 64, irq_handler, dev);
return 0;
}