From: Jack Lange Date: Sat, 14 Mar 2009 05:19:23 +0000 (-0500) Subject: PCI updates X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=b35cb9f7d22a06d849820c8d4487c66f74ec42e2 PCI updates --- diff --git a/palacios/build/Makefile b/palacios/build/Makefile index ed91e6d..d90715c 100644 --- a/palacios/build/Makefile +++ b/palacios/build/Makefile @@ -320,7 +320,7 @@ DEVICES_OBJS := \ devices/os_debug.o \ devices/apic.o \ devices/io_apic.o \ - devices/vpci.o \ + devices/pci.o \ devices/para_net.o \ # devices/vnic.o \ diff --git a/palacios/include/devices/pci.h b/palacios/include/devices/pci.h index a646232..5f58120 100644 --- a/palacios/include/devices/pci.h +++ b/palacios/include/devices/pci.h @@ -61,10 +61,8 @@ struct pci_device { struct vm_device * v3_create_pci(); -struct pci_bus * v3_get_pcibus(struct guest_info *vm, int bus_no); - struct pci_device * -v3_pci_register_device(struct vm_device * dev, +v3_pci_register_device(struct vm_device * pci, uint_t bus_num, const char * name, int dev_num, diff --git a/palacios/include/devices/pci_types.h b/palacios/include/devices/pci_types.h index 05fcf1c..2f6882d 100644 --- a/palacios/include/devices/pci_types.h +++ b/palacios/include/devices/pci_types.h @@ -138,51 +138,49 @@ struct pci_config_header { /* -struct pci_class_desc { - uint16_t class; - const char * desc; -}; - -static struct pci_class_desc pci_class_descriptions[] = { - { 0x0100, "SCSI controller"}, - { 0x0101, "IDE controller"}, - { 0x0102, "Floppy controller"}, - { 0x0103, "IPI controller"}, - { 0x0104, "RAID controller"}, - { 0x0106, "SATA controller"}, - { 0x0107, "SAS controller"}, - { 0x0180, "Storage controller"}, - { 0x0200, "Ethernet controller"}, - { 0x0201, "Token Ring controller"}, - { 0x0202, "FDDI controller"}, - { 0x0203, "ATM controller"}, - { 0x0280, "Network controller"}, - { 0x0300, "VGA controller"}, - { 0x0301, "XGA controller"}, - { 0x0302, "3D controller"}, - { 0x0380, "Display controller"}, - { 0x0400, "Video controller"}, - { 0x0401, "Audio controller"}, - { 0x0402, "Phone"}, - { 0x0480, "Multimedia controller"}, - { 0x0500, "RAM controller"}, - { 0x0501, "Flash controller"}, - { 0x0580, "Memory controller"}, - { 0x0600, "Host bridge"}, - { 0x0601, "ISA bridge"}, - { 0x0602, "EISA bridge"}, - { 0x0603, "MC bridge"}, - { 0x0604, "PCI bridge"}, - { 0x0605, "PCMCIA bridge"}, - { 0x0606, "NUBUS bridge"}, - { 0x0607, "CARDBUS bridge"}, - { 0x0608, "RACEWAY bridge"}, - { 0x0680, "Bridge"}, - { 0x0c03, "USB controller"}, - { 0, NULL} -}; - - + struct pci_class_desc { + uint16_t class; + const char * desc; + }; + + static struct pci_class_desc pci_class_descriptions[] = { + { 0x0100, "SCSI controller"}, + { 0x0101, "IDE controller"}, + { 0x0102, "Floppy controller"}, + { 0x0103, "IPI controller"}, + { 0x0104, "RAID controller"}, + { 0x0106, "SATA controller"}, + { 0x0107, "SAS controller"}, + { 0x0180, "Storage controller"}, + { 0x0200, "Ethernet controller"}, + { 0x0201, "Token Ring controller"}, + { 0x0202, "FDDI controller"}, + { 0x0203, "ATM controller"}, + { 0x0280, "Network controller"}, + { 0x0300, "VGA controller"}, + { 0x0301, "XGA controller"}, + { 0x0302, "3D controller"}, + { 0x0380, "Display controller"}, + { 0x0400, "Video controller"}, + { 0x0401, "Audio controller"}, + { 0x0402, "Phone"}, + { 0x0480, "Multimedia controller"}, + { 0x0500, "RAM controller"}, + { 0x0501, "Flash controller"}, + { 0x0580, "Memory controller"}, + { 0x0600, "Host bridge"}, + { 0x0601, "ISA bridge"}, + { 0x0602, "EISA bridge"}, + { 0x0603, "MC bridge"}, + { 0x0604, "PCI bridge"}, + { 0x0605, "PCMCIA bridge"}, + { 0x0606, "NUBUS bridge"}, + { 0x0607, "CARDBUS bridge"}, + { 0x0608, "RACEWAY bridge"}, + { 0x0680, "Bridge"}, + { 0x0c03, "USB controller"}, + { 0, NULL} + }; */ #endif diff --git a/palacios/src/devices/pci.c b/palacios/src/devices/pci.c index 44b0e9c..148a038 100644 --- a/palacios/src/devices/pci.c +++ b/palacios/src/devices/pci.c @@ -227,14 +227,30 @@ static int write_pci_header(struct pci_device * pci_dev, int reg_num, void * src static int addr_port_read(ushort_t port, void * dst, uint_t length, struct vm_device * dev) { struct pci_internal * pci_state = (struct pci_internal *)dev->private_data; - - if (length != 4) { + int reg_offset = port & 0x3; + uint8_t * reg_addr = ((uint8_t *)&(pci_state->addr_reg.val)) + reg_offset; + + PrintDebug("Reading PCI Address Port (%x): %x\n", port, pci_state->addr_reg.val); + + if (length == 4) { + if (reg_offset != 0) { + PrintError("Invalid Address Port Read\n"); + return -1; + } + *(uint32_t *)dst = *(uint32_t *)reg_addr; + } else if (length == 2) { + if (reg_offset > 2) { + PrintError("Invalid Address Port Read\n"); + return -1; + } + *(uint16_t *)dst = *(uint16_t *)reg_addr; + } else if (length == 1) { + *(uint8_t *)dst = *(uint8_t *)reg_addr; + } else { PrintError("Invalid read length (%d) for PCI address register\n", length); return -1; } - PrintDebug("Reading PCI Address Port: %x\n", pci_state->addr_reg.val); - *(uint32_t *)dst = pci_state->addr_reg.val; return length; } @@ -242,14 +258,32 @@ static int addr_port_read(ushort_t port, void * dst, uint_t length, struct vm_de static int addr_port_write(ushort_t port, void * src, uint_t length, struct vm_device * dev) { struct pci_internal * pci_state = (struct pci_internal *)dev->private_data; + int reg_offset = port & 0x3; + uint8_t * reg_addr = ((uint8_t *)&(pci_state->addr_reg.val)) + reg_offset; - if (length != 4) { + if (length == 4) { + if (reg_offset != 0) { + PrintError("Invalid Address Port Write\n"); + return -1; + } + + *(uint32_t *)reg_addr = *(uint32_t *)src; + } else if (length == 2) { + if (reg_offset > 2) { + PrintError("Invalid Address Port Write\n"); + return -1; + } + + *(uint16_t *)reg_addr = *(uint16_t *)src; + } else if (length == 1) { + *(uint8_t *)reg_addr = *(uint8_t *)src; + } else { PrintError("Invalid write length (%d) for PCI address register\n", length); return -1; } - pci_state->addr_reg.val = *(uint32_t *)src; - PrintDebug("Writing PCI Address Port: %x\n", pci_state->addr_reg.val); + PrintDebug("Writing PCI Address Port(%x): %x\n", port, pci_state->addr_reg.val); + return length; } @@ -267,6 +301,11 @@ static int data_port_read(ushort_t port, void * dst, uint_t length, struct vm_de reg_num); + if (port != CONFIG_DATA_PORT) { + PrintError("Weird Data port Read: %x\n", port); + return -1; + } + pci_dev = get_device(&(pci_state->bus_list[0]), pci_state->addr_reg.dev_num); if (pci_dev == NULL) { @@ -314,6 +353,12 @@ static int data_port_write(ushort_t port, void * src, uint_t length, struct vm_d pci_state->addr_reg.dev_num, reg_num); + if (port != CONFIG_DATA_PORT) { + PrintError("Weird Data port Write: %x\n", port); + return -1; + } + + pci_dev = get_device(&(pci_state->bus_list[0]), pci_state->addr_reg.dev_num); if (pci_dev == NULL) { @@ -382,23 +427,22 @@ static int pci_deinit_device(struct vm_device * dev) { -static int init_i440fx(struct pci_internal * pci_state) { - - struct pci_device * dev = v3_pci_register_device(NULL, 0, "i440FX", 0, - NULL, NULL, NULL, NULL); +static int init_i440fx(struct vm_device * dev) { + struct pci_device * pci_dev = v3_pci_register_device(dev, 0, "i440FX", 0, + NULL, NULL, NULL, NULL); - if (!dev) { + if (!pci_dev) { return -1; } - dev->header.vendor_id = 0x8086; - dev->header.device_id = 0x1237; - dev->header.revision = 0x0002; - dev->header.subclass = 0x00; // SubClass: host2pci - dev->header.class = 0x06; // Class: PCI bridge - dev->header.header_type = 0x00; - - dev->bus_num = 0; + pci_dev->header.vendor_id = 0x8086; + pci_dev->header.device_id = 0x1237; + pci_dev->header.revision = 0x0002; + pci_dev->header.subclass = 0x00; // SubClass: host2pci + pci_dev->header.class = 0x06; // Class: PCI bridge + pci_dev->header.header_type = 0x00; + + pci_dev->bus_num = 0; return 0; } @@ -430,7 +474,7 @@ static int pci_init_device(struct vm_device * dev) { init_pci_busses(pci_state); - if (init_i440fx(pci_state) == -1) { + if (init_i440fx(dev) == -1) { PrintError("Could not intialize i440fx\n"); return -1; } @@ -467,30 +511,8 @@ struct vm_device * v3_create_pci() { -/* JRL: TODO This needs to be completely rethought... */ -struct pci_bus * v3_get_pcibus(struct guest_info * vm, int bus_no) { - // struct pci_internal * pci_state = NULL; - - /* - if (vm->pci == NULL) { - PrintError("There is no PCI bus in guest %p\n", vm); - return NULL; - } - - pci_state = (struct pci_internal *)vm->pci->private_data; - - if ((bus_no >= 0) && (bus_no < PCI_BUS_COUNT)) { - return &(pci_state->bus_list[bus_no]); - } - */ - return NULL; -} - - - - // if dev_num == -1, auto assign -struct pci_device * v3_pci_register_device(struct vm_device * dev, +struct pci_device * v3_pci_register_device(struct vm_device * pci, uint_t bus_num, const char * name, int dev_num, @@ -499,7 +521,7 @@ struct pci_device * v3_pci_register_device(struct vm_device * dev, int (*bar_update)(struct pci_device * pci_dev, uint_t bar_reg, uint32_t val), void * private_data) { - struct pci_internal * pci_state = (struct pci_internal *)dev->private_data; + struct pci_internal * pci_state = (struct pci_internal *)pci->private_data; struct pci_bus * bus = &(pci_state->bus_list[bus_num]); struct pci_device * pci_dev = NULL; @@ -535,7 +557,7 @@ struct pci_device * v3_pci_register_device(struct vm_device * dev, pci_dev->dev_num = dev_num; strncpy(pci_dev->name, name, sizeof(pci_dev->name)); - pci_dev->vm_dev = dev; + pci_dev->vm_dev = pci; pci_dev->config_read = config_read; pci_dev->config_write = config_write; diff --git a/palacios/src/palacios/vmm_config.c b/palacios/src/palacios/vmm_config.c index db9aa8b..9c8d73a 100644 --- a/palacios/src/palacios/vmm_config.c +++ b/palacios/src/palacios/vmm_config.c @@ -40,6 +40,7 @@ #include #include #include +#include @@ -278,6 +279,7 @@ static int setup_memory_map(struct guest_info * info, struct v3_vm_config * conf static int setup_devices(struct guest_info * info, struct v3_vm_config * config_ptr) { struct vm_device * ramdisk = NULL; struct vm_device * cdrom = NULL; + struct vm_device * pci = v3_create_pci(); struct vm_device * nvram = v3_create_nvram(); //struct vm_device * timer = v3_create_timer(); struct vm_device * pic = v3_create_pic(); @@ -307,6 +309,7 @@ static int setup_devices(struct guest_info * info, struct v3_vm_config * config_ generic = configure_generic(info, config_ptr); } + v3_attach_device(info, pci); v3_attach_device(info, nvram); //v3_attach_device(info, timer);