struct rb_node * node = v3_rb_first(&(pci_state->bus_list[0].devices));
struct pci_device * tmp_dev = NULL;
- PrintDebug(core->vm_info, core, "===PCI: Dumping state Begin ==========\n");
+ PrintDebug(VM_NONE, VCORE_NONE, "===PCI: Dumping state Begin ==========\n");
do {
tmp_dev = rb_entry(node, struct pci_device, dev_tree_node);
- PrintDebug(core->vm_info, core, "PCI Device Number: %d (%s):\n", tmp_dev->dev_num, tmp_dev->name);
- PrintDebug(core->vm_info, core, "irq = %d\n", tmp_dev->config_header.intr_line);
- PrintDebug(core->vm_info, core, "Vend ID: 0x%x\n", tmp_dev->config_header.vendor_id);
- PrintDebug(core->vm_info, core, "Device ID: 0x%x\n", tmp_dev->config_header.device_id);
+ PrintDebug(VM_NONE, VCORE_NONE, "PCI Device Number: %d (%s):\n", tmp_dev->dev_num, tmp_dev->name);
+ PrintDebug(VM_NONE, VCORE_NONE, "irq = %d\n", tmp_dev->config_header.intr_line);
+ PrintDebug(VM_NONE, VCORE_NONE, "Vend ID: 0x%x\n", tmp_dev->config_header.vendor_id);
+ PrintDebug(VM_NONE, VCORE_NONE, "Device ID: 0x%x\n", tmp_dev->config_header.device_id);
} while ((node = v3_rb_next(node)));
- PrintDebug(core->vm_info, core, "====PCI: Dumping state End==========\n");
+ PrintDebug(VM_NONE, VCORE_NONE, "====PCI: Dumping state End==========\n");
}
#endif
int i, j;
for (i = 0; i < sizeof(bus->dev_map); i++) {
- PrintDebug(core->vm_info, core, "i=%d\n", i);
+ PrintDebug(VM_NONE, VCORE_NONE, "i=%d\n", i);
if (bus->dev_map[i] != 0xff) {
// availability
for (j = 0; j < 8; j++) {
- PrintDebug(core->vm_info, core, "\tj=%d\n", j);
+ PrintDebug(VM_NONE, VCORE_NONE, "\tj=%d\n", j);
if (!(bus->dev_map[i] & (0x1 << j))) {
return ((i * 8) + j);
}
pci_dev = get_device(&(pci_state->bus_list[0]), pci_state->addr_reg.dev_num, pci_state->addr_reg.fn_num);
+
if (pci_dev == NULL) {
memset(dst, 0xff, length);
if (cfg_hook->read) {
cfg_hook->read(pci_dev, reg_num + i, cfg_dst, range_len, cfg_hook->private_data);
- }
+ } else {
+ if (pci_dev->config_read) {
+ if (pci_dev->config_read(pci_dev, reg_num + i, cfg_dst, range_len, pci_dev->priv_data) != 0) {
+ PrintError(core->vm_info, core, "Error in config_read from PCI device (%s)\n", pci_dev->name);
+ }
+ }
+ }
bytes_left -= range_len;
i += range_len;
} else {
if (pci_dev->config_read) {
- if (pci_dev->config_read(pci_dev, reg_num + i, cfg_dst, 1, pci_dev->priv_data) != 0) {
- PrintError(core->vm_info, core, "Error in config_read from PCI device (%s)\n", pci_dev->name);
- }
+ if (pci_dev->config_read(pci_dev, reg_num + i, cfg_dst, 1, pci_dev->priv_data) != 0) {
+ PrintError(core->vm_info, core, "Error in config_read from PCI device (%s)\n", pci_dev->name);
+ }
}
bytes_left--;
int bar_num = (bar_offset - 0x10) / 4;
uint32_t new_val = *(uint32_t *)src;
- PrintDebug(VM_NONE, VCORE_NONE, "Updating BAR Register (Dev=%s) (bar=%d) (old_val=0x%x) (new_val=0x%x)\n",
- pci_dev->name, bar_num, bar->val, new_val);
+ PrintDebug(VM_NONE, VCORE_NONE, "Updating BAR Register (Dev=%s) (bar=%d) (old_val=0x%x) (new_val=0x%x) (length=%d)\n",
+ pci_dev->name, bar_num, bar->val, new_val, length);
// Cache the changes locally
memcpy(&(pci_dev->config_space[offset]), src, length);
*(uint32_t *)(pci_dev->config_space + offset) &= bar->mask;
+ // Handle buggy code that discards the freaking I/O bit...
+ if (bar->type == PCI_BAR_IO && !(new_val & 0x1) ) {
+ PrintError(VM_NONE,VCORE_NONE,"Buggy guest: Updating BAR %d of device %s discards the I/O bit...\n", bar_num, pci_dev->name);
+ *(uint32_t *)(pci_dev->config_space + offset) |= 0x1;
+ new_val |= 0x1;
+ }
+
+
+ // V3_Print(VM_NONE, VCORE_NONE,"mask=%x written val=%x\n", bar->mask, *(uint32_t *)(pci_dev->config_space + offset));
+
switch (bar->type) {
case PCI_BAR_IO: {
int i = 0;
PrintDebug(VM_NONE, VCORE_NONE, "\tRehooking %d IO ports from base 0x%x to 0x%x for %d ports\n",
bar->num_ports, PCI_IO_BASE(bar->val), PCI_IO_BASE(new_val),
bar->num_ports);
-
- // only do this if pci device is enabled....
- if (!(pci_dev->config_header.status & 0x1)) {
- PrintError(VM_NONE, VCORE_NONE, "PCI Device IO space not enabled\n");
- }
for (i = 0; i < bar->num_ports; i++) {
PrintError(VM_NONE, VCORE_NONE, "Could not hook PCI IO port (old port=%u) (new port=%u)\n",
PCI_IO_BASE(bar->val) + i, PCI_IO_BASE(new_val) + i);
- v3_print_io_map(pci_dev->vm);
+ //v3_print_io_map(pci_dev->vm);
return -1;
}
}
if (cfg_hook->write) {
cfg_hook->write(pci_dev, reg_num + i, (void *)(src + i), range_len, cfg_hook->private_data);
- }
+ }
length -= range_len;
i += range_len;
void * src, uint_t length, void * private_data) {
int bar_offset = offset & ~0x03;
+ if (pci_dev->config_write) {
+ pci_dev->config_write(pci_dev, offset, src, length, pci_dev->priv_data);
+ }
+
if (pci_dev->exp_rom_update) {
pci_dev->exp_rom_update(pci_dev, (void *)(pci_dev->config_space + bar_offset), pci_dev->priv_data);
static int cmd_write(struct pci_device * pci_dev, uint32_t offset,
void * src, uint_t length, void * private_data) {
+ PrintDebug(VM_NONE, VCORE_NONE, "PCI command update!\n");
+
int i = 0;
struct pci_cmd_reg old_cmd;
struct pci_cmd_reg new_cmd;
+ if (pci_dev->config_write) {
+ pci_dev->config_write(pci_dev, offset, src, length, pci_dev->priv_data);
+ }
old_cmd.val = pci_dev->config_header.command;
for (i = 0; i < length; i++) {
new_cmd.val = pci_dev->config_header.command;
-
if (pci_dev->cmd_update) {
- if ((new_cmd.intx_disable == 1) && (old_cmd.intx_disable == 0)) {
- pci_dev->irq_type = IRQ_NONE;
- pci_dev->cmd_update(pci_dev, PCI_CMD_INTX_DISABLE, 0, pci_dev->priv_data);
- } else if ((new_cmd.intx_disable == 0) && (old_cmd.intx_disable == 1)) {
- pci_dev->irq_type = IRQ_INTX;
- pci_dev->cmd_update(pci_dev, PCI_CMD_INTX_ENABLE, 0, pci_dev->priv_data);
- }
-
-
- if ((new_cmd.dma_enable == 1) && (old_cmd.dma_enable == 0)) {
- pci_dev->cmd_update(pci_dev, PCI_CMD_DMA_ENABLE, 0, pci_dev->priv_data);
- } else if ((new_cmd.dma_enable == 0) && (old_cmd.dma_enable == 1)) {
- pci_dev->cmd_update(pci_dev, PCI_CMD_DMA_DISABLE, 0, pci_dev->priv_data);
- }
+ if ((new_cmd.intx_disable == 1) && (old_cmd.intx_disable == 0)) {
+ pci_dev->irq_type = IRQ_NONE;
+ pci_dev->cmd_update(pci_dev, PCI_CMD_INTX_DISABLE, 0, pci_dev->priv_data);
+ } else if ((new_cmd.intx_disable == 0) && (old_cmd.intx_disable == 1)) {
+ pci_dev->irq_type = IRQ_INTX;
+ pci_dev->cmd_update(pci_dev, PCI_CMD_INTX_ENABLE, 0, pci_dev->priv_data);
+ }
+
+
+ if ((new_cmd.dma_enable == 1) && (old_cmd.dma_enable == 0)) {
+ pci_dev->cmd_update(pci_dev, PCI_CMD_DMA_ENABLE, 0, pci_dev->priv_data);
+ } else if ((new_cmd.dma_enable == 0) && (old_cmd.dma_enable == 1)) {
+ pci_dev->cmd_update(pci_dev, PCI_CMD_DMA_DISABLE, 0, pci_dev->priv_data);
+ }
}
return 0;
bar->mask = ~((bar->num_pages << 12) - 1);
bar->mask |= 0xf; // preserve the configuration flags
+
if (bar->default_base_addr != 0xffffffff) {
bar->val = bar->default_base_addr & bar->mask;
} else {
// Call the bar init function to get the local cached value
bar->bar_init(i, &(bar->val), bar->private_data);
+ // Copy back changes it made
+ *(uint32_t *)(pci_dev->config_space + bar_offset) = bar->val;
+
} else {
PrintError(vm, VCORE_NONE, "Invalid BAR type for bar #%d\n", i);
return -1;
PrintError(VM_NONE, VCORE_NONE, "No more available PCI slots on bus %d\n", bus->bus_num);
return NULL;
}
+ 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);
}
PrintDebug(VM_NONE, VCORE_NONE, "Checking for PCI Device\n");