X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fdevices%2Fpci.c;h=cce7aa860fbadc7347b0a3cc203f7406b5fc30a4;hb=ec75f3ad6503e3c7996e7a445404b8813740804d;hp=6b5472dbe156733c60682f3552d6f1b23817eefa;hpb=a0e1d8274aef54adcf50dce0b3843489f2a3cd21;p=palacios.releases.git diff --git a/palacios/src/devices/pci.c b/palacios/src/devices/pci.c index 6b5472d..cce7aa8 100644 --- a/palacios/src/devices/pci.c +++ b/palacios/src/devices/pci.c @@ -121,9 +121,11 @@ static int get_free_dev_num(struct pci_bus * bus) { int i, j; for (i = 0; i < sizeof(bus->dev_map); i++) { + PrintDebug("i=%d\n", i); if (bus->dev_map[i] != 0xff) { // availability for (j = 0; j < 8; j++) { + PrintDebug("\tj=%d\n", j); if (!(bus->dev_map[i] & (0x1 << j))) { return ((i * 8) + j); } @@ -397,6 +399,22 @@ static int bar_update(struct pci_device * pci, int bar_num, uint32_t new_val) { break; } + case PCI_BAR_MEM32: { + v3_unhook_mem(pci->vm_dev->vm, (addr_t)(bar->val)); + + if (bar->mem_read) { + v3_hook_full_mem(pci->vm_dev->vm, PCI_MEM32_BASE(new_val), + PCI_MEM32_BASE(new_val) + (bar->num_pages * PAGE_SIZE_4KB), + bar->mem_read, bar->mem_write, pci->vm_dev); + } else { + PrintError("Write hooks not supported for PCI\n"); + return -1; + } + + bar->val = new_val; + + break; + } case PCI_BAR_NONE: { PrintDebug("Reprogramming an unsupported BAR register (Dev=%s) (bar=%d) (val=%x)\n", pci->name, bar_num, new_val); @@ -540,7 +558,7 @@ static int pci_stop_device(struct vm_device * dev) { -static int pci_deinit_device(struct vm_device * dev) { +static int pci_free(struct vm_device * dev) { int i = 0; for (i = 0; i < 4; i++){ @@ -565,14 +583,30 @@ static void init_pci_busses(struct pci_internal * pci_state) { -static int pci_init_device(struct vm_device * dev) { - struct pci_internal * pci_state = (struct pci_internal *)dev->private_data;; + +static struct v3_device_ops dev_ops = { + .free = pci_free, + .reset = pci_reset_device, + .start = pci_start_device, + .stop = pci_stop_device, +}; + + + + +static int pci_init(struct guest_info * vm, void * cfg_data) { + struct pci_internal * pci_state = V3_Malloc(sizeof(struct pci_internal)); int i = 0; - PrintDebug("pci: init_device\n"); + PrintDebug("PCI internal at %p\n",(void *)pci_state); + + struct vm_device * dev = v3_allocate_device("PCI", &dev_ops, pci_state); + + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", "PCI"); + return -1; + } - // JRL: Fix this.... - // dev->vm->pci = dev; //should be in vmm_config.c pci_state->addr_reg.val = 0; @@ -589,25 +623,7 @@ static int pci_init_device(struct vm_device * dev) { } -static struct vm_device_ops dev_ops = { - .init = pci_init_device, - .deinit = pci_deinit_device, - .reset = pci_reset_device, - .start = pci_start_device, - .stop = pci_stop_device, -}; - - -struct vm_device * v3_create_pci() { - struct pci_internal * pci_state = V3_Malloc(sizeof(struct pci_internal)); - - PrintDebug("PCI internal at %p\n",(void *)pci_state); - - struct vm_device * device = v3_create_device("PCI", &dev_ops, pci_state); - - return device; -} - +device_register("PCI", pci_init) static inline int init_bars(struct pci_device * pci_dev) { @@ -625,10 +641,12 @@ static inline int init_bars(struct pci_device * pci_dev) { for (j = 0; j < pci_dev->bar[i].num_ports; j++) { // hook IO - if (v3_dev_hook_io(pci_dev->vm_dev, pci_dev->bar[i].default_base_port + j, - pci_dev->bar[i].io_read, pci_dev->bar[i].io_write) == -1) { - PrintError("Could not hook default io port %x\n", pci_dev->bar[i].default_base_port + j); - return -1; + if (pci_dev->bar[i].default_base_port != 0xffff) { + if (v3_dev_hook_io(pci_dev->vm_dev, pci_dev->bar[i].default_base_port + j, + pci_dev->bar[i].io_read, pci_dev->bar[i].io_write) == -1) { + PrintError("Could not hook default io port %x\n", pci_dev->bar[i].default_base_port + j); + return -1; + } } } @@ -703,13 +721,16 @@ struct pci_device * v3_pci_register_device(struct vm_device * pci, return NULL; } - if (dev_num == -1) { + if (dev_num == PCI_AUTO_DEV_NUM) { + PrintDebug("Searching for free device number\n"); if ((dev_num = get_free_dev_num(bus)) == -1) { PrintError("No more available PCI slots on bus %d\n", bus->bus_num); return NULL; } } + PrintDebug("Checking for PCI Device\n"); + if (get_device(bus, dev_num, fn_num) != NULL) { PrintError("PCI Device already registered at slot %d on bus %d\n", dev_num, bus->bus_num); @@ -761,11 +782,16 @@ struct pci_device * v3_pci_register_device(struct vm_device * pci, pci_dev->bar[i].default_base_port = bars[i].default_base_port; pci_dev->bar[i].io_read = bars[i].io_read; pci_dev->bar[i].io_write = bars[i].io_write; - } else { + } else if (pci_dev->bar[i].type == PCI_BAR_MEM32) { pci_dev->bar[i].num_pages = bars[i].num_pages; pci_dev->bar[i].default_base_addr = bars[i].default_base_addr; pci_dev->bar[i].mem_read = bars[i].mem_read; pci_dev->bar[i].mem_write = bars[i].mem_write; + } else { + pci_dev->bar[i].num_pages = 0; + pci_dev->bar[i].default_base_addr = 0; + pci_dev->bar[i].mem_read = NULL; + pci_dev->bar[i].mem_write = NULL; } }