PT_BAR_IO,
PT_BAR_MEM32,
PT_BAR_MEM24,
- PT_BAR_MEM64_LOW,
- PT_BAR_MEM64_HIGH } pt_bar_type_t;
+ PT_BAR_MEM64_LO,
+ PT_BAR_MEM64_HI,
+ PT_EXP_ROM } pt_bar_type_t;
struct pt_bar {
uint32_t size;
pt_bar_type_t type;
- uint32_t addr;
+
+ /* We store 64 bit memory bar addresses in the high BAR
+ * because they are the last to be updated
+ * This means that the addr field must be 64 bits
+ */
+ uint64_t addr;
uint32_t val;
};
-//Zheng 03/15/2010
-struct pt_exp_rom_base {
- uint32_t size;
- uint32_t addr;
- uint32_t val;
-};
+
struct pt_dev_state {
union {
struct pt_bar phys_bars[6];
struct pt_bar virt_bars[6];
- //Zheng 03/19/2010
- struct pt_exp_rom_base phys_exp_rom_base;
- struct pt_exp_rom_base virt_exp_rom_base;
+ struct pt_bar phys_exp_rom;
+ struct pt_bar virt_exp_rom;
struct vm_device * pci_bus;
struct pci_device * pci_dev;
}
-//Zheng: 03/15/2010
-static inline bool is_pci_mem64_high_bar(struct pt_bar *prev_pbar)
-{
- return ((prev_pbar) &&
- (prev_pbar->type == PT_BAR_MEM64_LOW));
-}
-
-
-//Zheng: 03/19/2010
-static int pci_exp_rom_base_init(struct pci_device *pci_dev) {
- struct vm_device *dev = (struct vm_device *)(pci_dev->priv_data);
- struct pt_dev_state * state = (struct pt_dev_state *)dev->private_data;
+static int pci_exp_rom_init(struct vm_device * dev, struct pt_dev_state * state) {
+ struct pci_device * pci_dev = state->pci_dev;
const uint32_t exp_rom_base_reg = 12;
union pci_addr_reg pci_addr = {state->phys_pci_addr.value};
- uint32_t exp_rom_base_val = 0;
uint32_t max_val = 0;
-
- uint32_t *dst = ((uint32_t *)(&(pci_dev->config_space[4 * exp_rom_base_reg])));
-
- struct pt_exp_rom_base *pexp_rom_base = &(state->phys_exp_rom_base);
- // struct pt_exp_rom_base *vexp_rom_base = &(state->virt_exp_rom_base);
+ uint32_t rom_val = 0;
+ struct pt_bar * prom = &(state->phys_exp_rom);
+ struct pt_bar * vrom = &(state->virt_exp_rom);
// should read from cached header
pci_addr.reg = exp_rom_base_reg;
- exp_rom_base_val = pci_cfg_read32(pci_addr.value);
- pexp_rom_base->val = exp_rom_base_val;
+ rom_val = pci_cfg_read32(pci_addr.value);
+
+ prom->val = rom_val;
+ prom->type = PT_EXP_ROM;
- max_val = exp_rom_base_val | PCI_EXP_ROM_BASE_MASK;
+ max_val = rom_val | PCI_EXP_ROM_MASK;
// Cycle the physical bar, to determine the actual size
// Disable irqs, to try to prevent accesses to the space via a interrupt handler
pci_cfg_write32(pci_addr.value, max_val);
max_val = pci_cfg_read32(pci_addr.value);
- pci_cfg_write32(pci_addr.value, exp_rom_base_val);
+ pci_cfg_write32(pci_addr.value, rom_val);
//v3_irq_restore(irq_state);
+ prom->type = PT_EXP_ROM;
+ prom->addr = PCI_EXP_ROM_BASE(rom_val);
+ prom->size = ~PCI_EXP_ROM_BASE(max_val) + 1;
- if (max_val == 0) {
- PrintDebug("The real device doesn't implement the Exp_Rom_Base\n");
- } else {
-
- // if its a memory region, setup passthrough mem mapping
- pexp_rom_base->addr = PCI_EXP_ROM_BASE(exp_rom_base_val);
- pexp_rom_base->size = ~PCI_EXP_ROM_BASE(max_val) + 1;
-
- PrintDebug("Adding 32 bit PCI mem region: start=0x%x, end=0x%x\n",
- pexp_rom_base->addr, pexp_rom_base->addr + pexp_rom_base->size);
+ PrintDebug(VM_NONE, VCORE_NONE, "Adding 32 bit PCI mem region: start=%p, end=%p\n",
+ (void *)(addr_t)prom->addr,
+ (void *)(addr_t)(prom->addr + prom->size));
+
+ if ((prom->val & 0x1) == 0x1) {
+ // only map shadow memory if the ROM is enabled
v3_add_shadow_mem(dev->vm, V3_MEM_CORE_ANY,
- pexp_rom_base->addr,
- pexp_rom_base->addr + pexp_rom_base->size - 1,
- pexp_rom_base->addr);
+ prom->addr,
+ prom->addr + prom->size - 1,
+ prom->addr);
}
-
-
- // Initially the virtual bars match the physical ones
- memcpy(&(state->virt_exp_rom_base), &(state->phys_exp_rom_base), sizeof(struct pt_exp_rom_base));
- PrintDebug("exp_rom_base_val=0x%x\n", exp_rom_base_val);
+ // Initially the virtual location matches the physical ones
+ memcpy(&(state->virt_exp_rom), &(state->phys_exp_rom), sizeof(struct pt_bar));
- PrintDebug("phys exp_rom_base: addr=0x%x, size=%u\n",
- pexp_rom_base->addr,
- pexp_rom_base->size);
+ PrintDebug(VM_NONE, VCORE_NONE, "exp_rom_val=0x%x\n", rom_val);
- PrintDebug("virt exp_rom_base: addr=0x%x, size=%u\n",
- state->virt_exp_rom_base.addr,
- state->virt_exp_rom_base.size);
+ PrintDebug(VM_NONE, VCORE_NONE, "phys exp_rom: addr=%p, size=%u\n",
+ (void *)(addr_t)prom->addr,
+ prom->size);
+ PrintDebug(VM_NONE, VCORE_NONE, "virt exp_rom: addr=%p, size=%u\n",
+ (void *)(addr_t)vrom->addr,
+ vrom->size);
// Update the pci subsystem versions
- *dst = exp_rom_base_val;
+ pci_dev->config_header.expansion_rom_address = rom_val;
return 0;
}
uint32_t max_val = 0;
//addr_t irq_state = 0;
struct pt_bar * pbar = &(state->phys_bars[bar_num]);
- // struct pt_bar * vbar = &(state->virt_bars[bar_num]);
-
- struct pt_bar *prev_pbar = bar_num > 0 ?
- (&(state->phys_bars[bar_num - 1])) :
- NULL;
-
- struct pt_bar *prev_vbar = bar_num > 0 ?
- (&(state->virt_bars[bar_num - 1])) :
- NULL;
// should read from cached header
pci_addr.reg = bar_base_reg + bar_num;
- PrintDebug("PCI Address = 0x%x\n", pci_addr.value);
+ PrintDebug(VM_NONE, VCORE_NONE, "PCI Address = 0x%x\n", pci_addr.value);
bar_val = pci_cfg_read32(pci_addr.value);
pbar->val = bar_val;
+
+ // We preset this type when we encounter a MEM64 Low BAR
+ if (pbar->type == PT_BAR_MEM64_HI) {
+ struct pt_bar * lo_pbar = &(state->phys_bars[bar_num - 1]);
- if (is_pci_mem64_high_bar(prev_pbar)) {
-
- max_val = PCI_MEM64_HIGH_MASK32;
+ max_val = PCI_MEM64_MASK_HI;
pci_cfg_write32(pci_addr.value, max_val);
max_val = pci_cfg_read32(pci_addr.value);
pci_cfg_write32(pci_addr.value, bar_val);
- pbar->type = PT_BAR_MEM64_HIGH;
- pbar->addr = PCI_MEM64_BASE_HIGH(bar_val);
-
- uint64_t mem64_bar_size =
- (~(PCI_MEM64_BASE((((uint64_t)max_val) << PCI_MEM64_BASE_HIGH_SHIFT) | (prev_pbar->size)))) + 1;
-
-
- pbar->size =
- (mem64_bar_size >> PCI_MEM64_BASE_HIGH_SHIFT) &
- PCI_MEM64_HIGH_MASK32;
- prev_pbar->size = (uint32_t)mem64_bar_size;
- prev_vbar->size = (uint32_t)mem64_bar_size;
+ pbar->addr = PCI_MEM64_BASE_HI(bar_val);
+ pbar->addr <<= 32;
+ pbar->addr |= lo_pbar->addr;
- uint64_t mem64_addr =
- (((uint64_t)(pbar->addr)) << PCI_MEM64_BASE_HIGH_SHIFT) |
- (prev_pbar->addr);
+ // Executive Decision: We will not support devices with memory mapped regions over 4GB
+ // The right way to do this would be to change 'size' to the order (power of 2) of the region
+ pbar->size += lo_pbar->size;
- PrintDebug("Adding 64 bit PCI mem region: start=0x%llx, end=0x%llx\n",
- mem64_addr, mem64_addr + mem64_bar_size);
+ PrintDebug(VM_NONE, VCORE_NONE, "Adding 64 bit PCI mem region: start=0x%p, end=0x%p\n",
+ (void *)(addr_t)pbar->addr,
+ (void *)(addr_t)(pbar->addr + pbar->size));
- int ret = -1;
- if ((ret = (v3_add_shadow_mem(dev->vm, V3_MEM_CORE_ANY,
- mem64_addr,
- mem64_addr + mem64_bar_size - 1,
- mem64_addr)))) {
- PrintDebug("Fail to insert shadow region (0x%llx, 0x%llx) -> 0x%llx\n",
- mem64_addr,
- mem64_addr + mem64_bar_size - 1,
- mem64_addr);
+ if (v3_add_shadow_mem(dev->vm, V3_MEM_CORE_ANY, pbar->addr,
+ pbar->addr + pbar->size - 1, pbar->addr) == -1) {
+ PrintError(VM_NONE, VCORE_NONE, "Fail to insert shadow region (0x%p, 0x%p) -> 0x%p\n",
+ (void *)(addr_t)pbar->addr,
+ (void *)(addr_t)(pbar->addr + pbar->size - 1),
+ (void *)(addr_t)pbar->addr);
return -1;
-
}
- goto done;
-
- } //MEM64_HIGH
-
-
- if ((bar_val & 0x3) == 0x1) {
+ } else if ((bar_val & 0x3) == 0x1) {
int i = 0;
// IO bar
//v3_irq_restore(irq_state);
- V3_Print("max_val = %x\n", max_val);
+ V3_Print(VM_NONE, VCORE_NONE, "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);
+ V3_Print(VM_NONE, VCORE_NONE, "IO Bar with %d (%x) ports %x->%x\n", pbar->size, pbar->size,
+ (uint32_t)pbar->addr, (uint32_t)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
pbar->addr = PCI_MEM32_BASE(bar_val);
pbar->size = ~PCI_MEM32_BASE(max_val) + 1;
- PrintDebug("Adding 32 bit PCI mem region: start=0x%x, end=0x%x\n",
- pbar->addr, pbar->addr + pbar->size);
+ PrintDebug(VM_NONE, VCORE_NONE, "Adding 32 bit PCI mem region: start=%p, end=%p\n",
+ (void *)(addr_t)pbar->addr,
+ (void *)(addr_t)(pbar->addr + pbar->size));
v3_add_shadow_mem(dev->vm, V3_MEM_CORE_ANY,
pbar->addr,
pbar->addr);
} else if ((bar_val & 0x6) == 0x4) {
- // Mem 64
- /*
- PrintError("64 Bit PCI bars not supported\n");
- return -1;
- */
+ struct pt_bar * hi_pbar = &(state->phys_bars[bar_num + 1]);
- //Zheng 03/15/2010
- pbar->type = PT_BAR_MEM64_LOW;
- pbar->addr = PCI_MEM32_BASE(bar_val);
- /*temperary size, which will be corrected
- in the MEM_HIGH bar initialization*/
- pbar->size = PCI_MEM32_BASE(max_val);
+ pbar->type = PT_BAR_MEM64_LO;
+ hi_pbar->type = PT_BAR_MEM64_HI;
+
+ // Set the low bits, only for temporary storage until we calculate the high BAR
+ pbar->addr = PCI_MEM64_BASE_LO(bar_val);
+ pbar->size = ~PCI_MEM64_BASE_LO(max_val) + 1;
} else {
- PrintError("Invalid Memory bar type\n");
+ PrintError(VM_NONE, VCORE_NONE, "Invalid Memory bar type\n");
return -1;
}
}
}
- done:
// Initially the virtual bars match the physical ones
memcpy(&(state->virt_bars[bar_num]), &(state->phys_bars[bar_num]), sizeof(struct pt_bar));
- PrintDebug("bar_num=%d, bar_val=0x%x\n", bar_num, bar_val);
+ PrintDebug(VM_NONE, VCORE_NONE, "bar_num=%d, bar_val=0x%x\n", bar_num, bar_val);
- PrintDebug("phys bar type=%d, addr=0x%x, size=%d\n",
- pbar->type, pbar->addr,
+ PrintDebug(VM_NONE, VCORE_NONE, "phys bar type=%d, addr=%p, size=%d\n",
+ pbar->type, (void *)(addr_t)pbar->addr,
pbar->size);
- PrintDebug("virt bar type=%d, addr=0x%x, size=%d\n",
- state->virt_bars[bar_num].type, state->virt_bars[bar_num].addr,
+ PrintDebug(VM_NONE, VCORE_NONE, "virt bar type=%d, addr=%p, size=%d\n",
+ state->virt_bars[bar_num].type, (void *)(addr_t)state->virt_bars[bar_num].addr,
state->virt_bars[bar_num].size);
// Update the pci subsystem versions
} else if (length == 4) {
*(uint32_t *)dst = v3_indw(pbar->addr + port_offset);
} else {
- PrintError("Invalid PCI passthrough IO Redirection size read\n");
+ PrintError(core->vm_info, core, "Invalid PCI passthrough IO Redirection size read\n");
return -1;
}
} else if (length == 4) {
v3_outdw(pbar->addr + port_offset, *(uint32_t *)src);
} else {
- PrintError("Invalid PCI passthrough IO Redirection size write\n");
+ PrintError(core->vm_info, core, "Invalid PCI passthrough IO Redirection size write\n");
return -1;
}
struct pt_bar * pbar = &(state->phys_bars[bar_num]);
struct pt_bar * vbar = &(state->virt_bars[bar_num]);
- 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);
+ PrintDebug(VM_NONE, VCORE_NONE, "Bar update: bar_num=%d, src=0x%x\n", bar_num, *src);
+ PrintDebug(VM_NONE, VCORE_NONE, "vbar is size=%u, type=%d, addr=%p, val=0x%x\n",
+ vbar->size, vbar->type, (void *)(addr_t)vbar->addr, vbar->val);
+ PrintDebug(VM_NONE, VCORE_NONE, "pbar is size=%u, type=%d, addr=%p, val=0x%x\n",
+ pbar->size, pbar->type, (void *)(addr_t)pbar->addr, pbar->val);
// unhook old ports
for (i = 0; i < vbar->size; i++) {
if (v3_unhook_io_port(dev->vm, vbar->addr + i) == -1) {
- PrintError("Could not unhook previously hooked port.... %d (0x%x)\n",
- vbar->addr + i, vbar->addr + i);
+ PrintError(VM_NONE, VCORE_NONE, "Could not unhook previously hooked port.... %d (0x%x)\n",
+ (uint32_t)vbar->addr + i, (uint32_t)vbar->addr + i);
return -1;
}
}
- PrintDebug("Setting IO Port range size=%d\n", pbar->size);
+ PrintDebug(VM_NONE, VCORE_NONE, "Setting IO Port range size=%d\n", pbar->size);
// clear the low bits to match the size
*src &= ~(pbar->size - 1);
vbar->addr = PCI_IO_BASE(*src);
- PrintDebug("Cooked src=0x%x\n", *src);
+ PrintDebug(VM_NONE, VCORE_NONE, "Cooked src=0x%x\n", *src);
- PrintDebug("Rehooking passthrough IO ports starting at %d (0x%x)\n",
- vbar->addr, vbar->addr);
+ PrintDebug(VM_NONE, VCORE_NONE, "Rehooking passthrough IO ports starting at %d (0x%x)\n",
+ (uint32_t)vbar->addr, (uint32_t)vbar->addr);
if (vbar->addr == pbar->addr) {
// Map the io ports as passthrough
}
} else if (vbar->type == PT_BAR_MEM32) {
// remove old mapping
- struct v3_shadow_region * old_reg = v3_get_shadow_region(dev->vm, V3_MEM_CORE_ANY, vbar->addr);
+ struct v3_mem_region * old_reg = v3_get_mem_region(dev->vm, V3_MEM_CORE_ANY, vbar->addr);
if (old_reg == NULL) {
// uh oh...
- PrintError("Could not find PCI Passthrough memory redirection region (addr=0x%x)\n", vbar->addr);
+ PrintError(VM_NONE, VCORE_NONE, "Could not find PCI Passthrough memory redirection region (addr=0x%x)\n", (uint32_t)vbar->addr);
return -1;
}
- v3_delete_shadow_region(dev->vm, old_reg);
+ v3_delete_mem_region(dev->vm, old_reg);
// clear the low bits to match the size
*src &= ~(pbar->size - 1);
// Set reserved bits
*src |= (pbar->val & ~PCI_MEM_MASK);
- PrintDebug("Cooked src=0x%x\n", *src);
+ PrintDebug(VM_NONE, VCORE_NONE, "Cooked src=0x%x\n", *src);
vbar->addr = PCI_MEM32_BASE(*src);
- PrintDebug("Adding pci Passthrough remapping: start=0x%x, size=%d, end=0x%x\n",
- vbar->addr, vbar->size, vbar->addr + vbar->size);
+ PrintDebug(VM_NONE, VCORE_NONE, "Adding pci Passthrough remapping: start=0x%x, size=%d, end=0x%x\n",
+ (uint32_t)vbar->addr, vbar->size, (uint32_t)vbar->addr + vbar->size);
v3_add_shadow_mem(dev->vm, V3_MEM_CORE_ANY,
vbar->addr,
vbar->addr + vbar->size - 1,
pbar->addr);
- } else if (vbar->type == PT_BAR_MEM64_LOW) {
- //Zheng: 03/15/2010
-
- PrintDebug("Uncooked MEM64_LOW src=0x%x\n", *src);
+ } else if (vbar->type == PT_BAR_MEM64_LO) {
+ // We only store the written values here, the actual reconfig comes when the high BAR is updated
// clear the low bits to match the size
*src &= ~(pbar->size - 1);
// Set reserved bits
*src |= (pbar->val & ~PCI_MEM_MASK);
- PrintDebug("Cooked MEM64_LOW src=0x%x\n", *src);
-
- vbar->addr = PCI_MEM32_BASE(*src);
-
- } else if (vbar->type == PT_BAR_MEM64_HIGH) {
-
- //Zheng: 03/15/2010
- // remove old mapping
-
- if (bar_num == 0) {
- PrintError("The first bar register could not be of type PT_BAR_MEM64_HIGH\n");
- return -1;
- }
-
- struct pt_bar * prev_pbar = &(state->phys_bars[bar_num - 1]);
- struct pt_bar * prev_vbar = &(state->virt_bars[bar_num - 1]);
-
-
- addr_t valid_vbar_mem64_addr =
- (addr_t)(((((uint64_t)vbar->addr) << PCI_MEM64_BASE_HIGH_SHIFT) &
- (PCI_MEM64_HIGH_MASK64)) |
- (prev_vbar->addr));
+ // Temp storage, used when hi bar is written
+ vbar->addr = PCI_MEM64_BASE_LO(*src);
- struct v3_shadow_region * old_reg =
- v3_get_shadow_region(dev->vm, V3_MEM_CORE_ANY, valid_vbar_mem64_addr);
+ } else if (vbar->type == PT_BAR_MEM64_HI) {
+ struct pt_bar * lo_vbar = &(state->virt_bars[bar_num - 1]);
+ struct v3_mem_region * old_reg = v3_get_mem_region(dev->vm, V3_MEM_CORE_ANY, vbar->addr);
if (old_reg == NULL) {
-
- PrintError("Could not find PCI Passthrough memory redirection region (addr=0x%lx)\n", valid_vbar_mem64_addr);
-
+ // uh oh...
+ PrintError(VM_NONE, VCORE_NONE, "Could not find PCI Passthrough memory redirection region (addr=%p)\n",
+ (void *)(addr_t)vbar->addr);
return -1;
}
- v3_delete_shadow_region(dev->vm, old_reg);
-
- uint64_t mem64_src =
- ((((uint64_t)(*src)) << PCI_MEM64_BASE_HIGH_SHIFT) &
- (PCI_MEM64_HIGH_MASK64)) |
- (prev_vbar->val);
+ // remove old mapping
+ v3_delete_mem_region(dev->vm, old_reg);
- uint64_t mem64_bar_size =
- ((((uint64_t)(pbar->size)) << PCI_MEM64_BASE_HIGH_SHIFT) &
- (PCI_MEM64_HIGH_MASK64)) |
- (prev_pbar->size);
-
- // clear the low bits to match the size
- mem64_src &= ~(mem64_bar_size - 1);
+ // We don't set size, because we assume region is less than 4GB
- uint64_t mem64_pbar_val =
- ((((uint64_t)(pbar->val)) << PCI_MEM64_BASE_HIGH_SHIFT) &
- (PCI_MEM64_HIGH_MASK64)) |
- (prev_pbar->val);
-
// Set reserved bits
- mem64_src |= (mem64_pbar_val & ~PCI_MEM64_MASK);
-
- PrintDebug("Cooked mem64_src=0x%llx\n", mem64_src);
-
- prev_vbar->val = (uint32_t)mem64_src;
-
- *src = (uint32_t)((mem64_src & PCI_MEM64_HIGH_MASK64) >>
- PCI_MEM64_BASE_HIGH_SHIFT);
+ *src |= (pbar->val & ~PCI_MEM64_MASK_HI);
- uint64_t mem64_vbar_addr = PCI_MEM64_BASE(mem64_src);
- prev_vbar->addr = (uint32_t)(mem64_vbar_addr);
- vbar->addr =
- (uint32_t)(((uint64_t)(mem64_vbar_addr)) >> PCI_MEM64_BASE_HIGH_SHIFT);
+ vbar->addr = PCI_MEM64_BASE_HI(*src);
+ vbar->addr <<= 32;
+ vbar->addr += lo_vbar->addr;
- PrintDebug("Adding pci Passthrough remapping: start=0x%llx, size=0x%llu, end=0x%llx\n",
- mem64_vbar_addr, mem64_bar_size, mem64_vbar_addr + mem64_bar_size);
+ PrintDebug(VM_NONE, VCORE_NONE, "Adding pci Passthrough remapping: start=%p, size=%p, end=%p\n",
+ (void *)(addr_t)vbar->addr, (void *)(addr_t)vbar->size,
+ (void *)(addr_t)(vbar->addr + vbar->size));
- uint64_t mem64_pbar_addr =
- (((uint64_t)(pbar->addr)) << PCI_MEM64_BASE_HIGH_SHIFT) |
- (prev_pbar->addr);
-
- int ret = -1;
- if ((ret = (v3_add_shadow_mem(dev->vm, V3_MEM_CORE_ANY,
- mem64_vbar_addr,
- mem64_vbar_addr + mem64_bar_size - 1,
- mem64_pbar_addr)))) {
- PrintDebug("Fail to insert shadow region (0x%llx, 0x%llx) -> 0x%llx\n",
- mem64_vbar_addr,
- mem64_vbar_addr + mem64_bar_size - 1,
- mem64_pbar_addr);
+ if (v3_add_shadow_mem(dev->vm, V3_MEM_CORE_ANY, vbar->addr,
+ vbar->addr + vbar->size - 1, pbar->addr) == -1) {
+ PrintDebug(VM_NONE, VCORE_NONE, "Fail to insert shadow region (%p, %p) -> %p\n",
+ (void *)(addr_t)vbar->addr,
+ (void *)(addr_t)(vbar->addr + vbar->size - 1),
+ (void *)(addr_t)pbar->addr);
return -1;
}
} else {
- PrintError("Unhandled Pasthrough PCI Bar type %d\n", vbar->type);
+ PrintError(VM_NONE, VCORE_NONE, "Unhandled Pasthrough PCI Bar type %d\n", vbar->type);
return -1;
}
}
-#if 0 //Zheng: 03/19/2010
-static int pt_config_update(uint_t reg_num, void * src, uint_t length, void * private_data) {
+static int pt_config_update(struct pci_device * pci_dev, uint_t reg_num, void * src, uint_t length, void * private_data) {
struct vm_device * dev = (struct vm_device *)private_data;
struct pt_dev_state * state = (struct pt_dev_state *)dev->private_data;
union pci_addr_reg pci_addr = {state->phys_pci_addr.value};
- pci_addr.reg = reg_num;
+ pci_addr.reg = reg_num >> 2;
if (length == 1) {
pci_cfg_write8(pci_addr.value, *(uint8_t *)src);
pci_cfg_write32(pci_addr.value, *(uint32_t *)src);
}
-
- return 0;
-}
-
-#endif //old pt_config_update
-
-
-//Zheng: 03/19/2010
-static int pt_config_update(uint_t reg_num, void * src, uint_t length, void * private_data) {
- struct vm_device * dev = (struct vm_device *)private_data;
- struct pt_dev_state * state = (struct pt_dev_state *)dev->private_data;
- union pci_addr_reg pci_addr = {state->phys_pci_addr.value};
-
- pci_addr.reg = reg_num >> 2;
- uint32_t org_val = pci_cfg_read32(pci_addr.value);
- uint_t offset = reg_num & 0x3;
-
- uint32_t cooked_val = org_val;
- if (length == 1) {
- *(((uint8_t *)(&cooked_val)) + offset) = *((uint8_t *)src);
- } else if (length == 2) {
- *((uint16_t *)(((uint8_t *)(&cooked_val)) + offset)) = *((uint16_t *)src);
- } else if (length == 4) {
- *((uint32_t *)(((uint8_t *)(&cooked_val)) + offset)) = *((uint32_t *)src);
- }
-
- pci_cfg_write32(pci_addr.value, cooked_val);
-
- *(((uint32_t *)(state->pci_dev->config_space)) + pci_addr.reg) = pci_cfg_read32(pci_addr.value);
-
return 0;
}
-//Zheng 03/19/2010
-
-static int pci_exp_rom_base_write(struct pci_device *pci_dev) {
- struct vm_device * dev = (struct vm_device *)(pci_dev->priv_data);
+/* This is really iffy....
+ * It was totally broken before, but it's _not_ totally fixed now
+ * The Expansion rom can be enabled/disabled via software using the low order bit
+ * We should probably handle that somehow here...
+ */
+static int pt_exp_rom_write(struct pci_device * pci_dev, uint32_t * src, void * priv_data) {
+ struct vm_device * dev = (struct vm_device *)(priv_data);
struct pt_dev_state * state = (struct pt_dev_state *)dev->private_data;
- struct pt_exp_rom_base * pexp_rom_base = &(state->phys_exp_rom_base);
- struct pt_exp_rom_base * vexp_rom_base = &(state->virt_exp_rom_base);
-
- const uint32_t exp_rom_base_reg = 12;
- uint32_t *src = ((uint32_t *)(&(pci_dev->config_space[4 * exp_rom_base_reg])));
+ struct pt_bar * prom = &(state->phys_exp_rom);
+ struct pt_bar * vrom = &(state->virt_exp_rom);
- PrintDebug("exp_rom_base update: src=0x%x\n", *src);
- PrintDebug("vexp_rom_base is size=%u, addr=0x%x, val=0x%x\n",vexp_rom_base->size, vexp_rom_base->addr, vexp_rom_base->val);
- PrintDebug("pexp_rom_base is size=%u, addr=0x%x, val=0x%x\n",pexp_rom_base->size, pexp_rom_base->addr, pexp_rom_base->val);
+ PrintDebug(VM_NONE, VCORE_NONE, "exp_rom update: src=0x%x\n", *src);
+ PrintDebug(VM_NONE, VCORE_NONE, "vrom is size=%u, addr=0x%x, val=0x%x\n", vrom->size, (uint32_t)vrom->addr, vrom->val);
+ PrintDebug(VM_NONE, VCORE_NONE, "prom is size=%u, addr=0x%x, val=0x%x\n", prom->size, (uint32_t)prom->addr, prom->val);
- if (pexp_rom_base->size) {
- // remove old mapping
- struct v3_shadow_region * old_reg = v3_get_shadow_region(dev->vm, V3_MEM_CORE_ANY, vexp_rom_base->addr);
+ // only remove old mapping if present, I.E. if the rom was enabled previously
+ if ((vrom->val & 0x1) == 0x1) {
+ struct v3_mem_region * old_reg = v3_get_mem_region(dev->vm, V3_MEM_CORE_ANY, vrom->addr);
if (old_reg == NULL) {
// uh oh...
- PrintError("Could not find PCI Passthrough exp_rom_base redirection region (addr=0x%x)\n", vexp_rom_base->addr);
-
+ PrintError(VM_NONE, VCORE_NONE, "Could not find PCI Passthrough exp_rom_base redirection region (addr=0x%x)\n", (uint32_t)vrom->addr);
return -1;
}
- v3_delete_shadow_region(dev->vm, old_reg);
- }//if size > 0
+ v3_delete_mem_region(dev->vm, old_reg);
+ }
// clear the low bits to match the size
- *src &= ~(pexp_rom_base->size - 1);
+ *src &= ~(prom->size - 1);
// Set reserved bits
- *src |= (pexp_rom_base->val & ~PCI_MEM_MASK);
+ *src |= (prom->val & ~PCI_EXP_ROM_MASK);
- PrintDebug("Cooked src=0x%x\n", *src);
- vexp_rom_base->addr = PCI_EXP_ROM_BASE(*src);
+ PrintDebug(VM_NONE, VCORE_NONE, "Cooked src=0x%x\n", *src);
+
+ vrom->addr = PCI_EXP_ROM_BASE(*src);
- if (pexp_rom_base->size) {
- PrintDebug("Adding pci Passthrough exp_rom_base remapping: start=0x%x, size=%u, end=0x%x\n",
- vexp_rom_base->addr, vexp_rom_base->size, vexp_rom_base->addr + vexp_rom_base->size);
-
- int ret = -1;
+ if ((prom->val & 0x1) == 0x1) {
+ PrintDebug(VM_NONE, VCORE_NONE, "Adding pci Passthrough exp_rom_base remapping: start=0x%x, size=%u, end=0x%x\n",
+ (uint32_t)vrom->addr, vrom->size, (uint32_t)vrom->addr + vrom->size);
- if ((ret = v3_add_shadow_mem(dev->vm, V3_MEM_CORE_ANY,
- vexp_rom_base->addr,
- vexp_rom_base->addr + vexp_rom_base->size - 1,
- pexp_rom_base->addr))) {
- PrintError("Fail to add pci Passthrough exp_rom_base remapping: start=0x%x, size=%u, end=0x%x\n",
- vexp_rom_base->addr, vexp_rom_base->size, vexp_rom_base->addr + vexp_rom_base->size);
-
+ if (v3_add_shadow_mem(dev->vm, V3_MEM_CORE_ANY, vrom->addr,
+ vrom->addr + vrom->size - 1, prom->addr) == -1) {
+ PrintError(VM_NONE, VCORE_NONE, "Failed to remap pci exp_rom: start=0x%x, size=%u, end=0x%x\n",
+ (uint32_t)vrom->addr, vrom->size, (uint32_t)vrom->addr + vrom->size);
return -1;
}
- } //if size > 0
+ }
-
- vexp_rom_base->val = *src;
+ vrom->val = *src;
return 0;
}
} __attribute__((packed));
} __attribute__((packed)) pci_hdr = {0};
- //PrintDebug("Scanning PCI busses for vendor=%x, device=%x\n", vendor_id, device_id);
+ //PrintDebug(VM_NONE, VCORE_NONE, "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);
+ //PrintDebug(VM_NONE, VCORE_NONE, "\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;
}
- PrintDebug("Found device %x:%x (bus=%d, dev=%d, func=%d)\n",
+ PrintDebug(VM_NONE, VCORE_NONE, "Found device %x:%x (bus=%d, dev=%d, func=%d)\n",
vendor_id, device_id,
pci_addr.bus, pci_addr.dev, pci_addr.func);
bars[i].bar_write = pci_bar_write;
}
- //Zheng:03/19/2010
pci_dev = v3_pci_register_device(state->pci_bus,
PCI_STD_DEVICE,
bus_num, -1, 0,
state->name, bars,
pt_config_update,
+ NULL,
NULL,
- pci_exp_rom_base_write,
- dev);
-#if 0
- pci_dev = v3_pci_register_device(state->pci_bus,
- PCI_STD_DEVICE,
- bus_num, -1, 0,
- state->name, bars,
- pt_config_update, NULL, NULL,
+ pt_exp_rom_write,
dev);
-#endif //if 0 old v3_pci_register_device
+
// 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;
- //Zheng 03/19/2010
- pci_exp_rom_base_init(pci_dev);
+ pci_exp_rom_init(dev, state);
v3_sym_map_pci_passthrough(vm_info, pci_dev->bus_num, pci_dev->dev_num, pci_dev->fn_num);
static struct v3_device_ops dev_ops = {
.free = NULL,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
};
struct pt_dev_state * state = (struct pt_dev_state *)dev->private_data;
-#if 0 //hacking
-static long irq_time = 0;
- if(intr->irq == 64)
- irq_time ++;
- if(irq_time % 10 == 0)
- PrintError("Handling IRQ %d, time: %ld\n", intr->irq, irq_time);
-
- PrintError("Handling IRQ %d, time: %ld\n", intr->irq, irq_time);
-
-#endif
-// PrintDebug("Handling E1000 IRQ %d\n", intr->irq);
-
- v3_pci_raise_irq(state->pci_bus, 0, state->pci_dev);
+ v3_pci_raise_irq(state->pci_bus, state->pci_dev, 0);
V3_ACK_IRQ(intr->irq);
struct pt_dev_state * state = V3_Malloc(sizeof(struct pt_dev_state));
struct vm_device * dev = NULL;
struct vm_device * pci = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
- char * name = v3_cfg_val(cfg, "name");
+ char * dev_id = v3_cfg_val(cfg, "ID");
+ if (!state) {
+ PrintError(vm, VCORE_NONE, "Cannot allocate in init\n");
+ return -1;
+ }
memset(state, 0, sizeof(struct pt_dev_state));
if (!pci) {
- PrintError("Could not find PCI device\n");
+ PrintError(vm, VCORE_NONE, "Could not find PCI device\n");
return -1;
}
state->pci_bus = pci;
- strncpy(state->name, name, 32);
+ strncpy(state->name, dev_id, 32);
- dev = v3_allocate_device(name, &dev_ops, state);
+ dev = v3_add_device(vm, dev_id, &dev_ops, state);
- if (v3_attach_device(vm, dev) == -1) {
- PrintError("Could not attach device %s\n", name);
+ if (dev == NULL) {
+ PrintError(vm, VCORE_NONE, "Could not attach device %s\n", dev_id);
+ V3_Free(state);
return -1;
}
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",
+ PrintError(vm, VCORE_NONE, "Could not find PCI Device %s:%s\n",
v3_cfg_val(cfg, "vendor_id"),
v3_cfg_val(cfg, "device_id"));
+ v3_remove_device(dev);
return 0;
}