X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fdevices%2Fpci.c;h=ab85aea13f10ca7bbe19c5a98557666e8963db5d;hb=a98c81f20b2579d31bb48bf47580809024a7901d;hp=970d73884babe067707852171a343fdd735b9a7a;hpb=37c18b2c2335a41c68c2f0b779fd2b7d51ab216d;p=palacios.git diff --git a/palacios/src/devices/pci.c b/palacios/src/devices/pci.c index 970d738..ab85aea 100644 --- a/palacios/src/devices/pci.c +++ b/palacios/src/devices/pci.c @@ -74,6 +74,10 @@ struct pci_bus { // Bitmap of the allocated device numbers uint8_t dev_map[MAX_BUS_DEVICES / 8]; + + int (*raise_pci_irq)(struct vm_device * dev, struct pci_device * pci_dev); + int (*lower_pci_irq)(struct vm_device * dev, struct pci_device * pci_dev); + struct vm_device * irq_bridge_dev; }; @@ -121,9 +125,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); } @@ -438,9 +444,10 @@ static int data_port_write(ushort_t port, void * src, uint_t length, struct vm_d return length; } - PrintDebug("Writing PCI Data register. bus = %d, dev = %d, reg = %d (%x) addr_reg = %x (val=%x, len=%d)\n", + PrintDebug("Writing PCI Data register. bus = %d, dev = %d, fn = %d, reg = %d (%x) addr_reg = %x (val=%x, len=%d)\n", pci_state->addr_reg.bus_num, pci_state->addr_reg.dev_num, + pci_state->addr_reg.fn_num, reg_num, reg_num, pci_state->addr_reg.val, *(uint32_t *)src, length); @@ -498,6 +505,8 @@ static int data_port_write(ushort_t port, void * src, uint_t length, struct vm_d // BIST update pci_dev->config_header.BIST = 0x00; } + } else { + PrintError("PCI Write to read only register %d\n", cur_reg); } } @@ -639,10 +648,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; + } } } @@ -694,6 +705,34 @@ static inline int init_bars(struct pci_device * pci_dev) { } +int v3_pci_set_irq_bridge(struct vm_device * pci_bus, int bus_num, + int (*raise_pci_irq)(struct vm_device * dev, struct pci_device * pci_dev), + int (*lower_pci_irq)(struct vm_device * dev, struct pci_device * pci_dev), + struct vm_device * bridge_dev) { + struct pci_internal * pci_state = (struct pci_internal *)pci_bus->private_data; + + + pci_state->bus_list[bus_num].raise_pci_irq = raise_pci_irq; + pci_state->bus_list[bus_num].lower_pci_irq = lower_pci_irq; + pci_state->bus_list[bus_num].irq_bridge_dev = bridge_dev; + + return 0; +} + +int v3_pci_raise_irq(struct vm_device * pci_bus, int bus_num, struct pci_device * dev) { + struct pci_internal * pci_state = (struct pci_internal *)pci_bus->private_data; + struct pci_bus * bus = &(pci_state->bus_list[bus_num]); + + return bus->raise_pci_irq(bus->irq_bridge_dev, dev); +} + +int v3_pci_lower_irq(struct vm_device * pci_bus, int bus_num, struct pci_device * dev) { + struct pci_internal * pci_state = (struct pci_internal *)pci_bus->private_data; + struct pci_bus * bus = &(pci_state->bus_list[bus_num]); + + return bus->lower_pci_irq(bus->irq_bridge_dev, dev); +} + // if dev_num == -1, auto assign struct pci_device * v3_pci_register_device(struct vm_device * pci, pci_device_type_t dev_type, @@ -717,13 +756,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);