From: Jack Lange Date: Fri, 10 Apr 2009 19:41:30 +0000 (-0500) Subject: removed old pci implementation X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=eed2bbeb750b15b7cc975ba213e5707168e9c932 removed old pci implementation --- diff --git a/palacios/include/devices/vpci.h b/palacios/include/devices/vpci.h deleted file mode 100644 index e4f893b..0000000 --- a/palacios/include/devices/vpci.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * This file is part of the Palacios Virtual Machine Monitor developed - * by the V3VEE Project with funding from the United States National - * Science Foundation and the Department of Energy. - * - * The V3VEE Project is a joint project between Northwestern University - * and the University of New Mexico. You can find out more at - * http://www.v3vee.org - * - * Copyright (c) 2009, Lei Xia - * Copyright (c) 2009, Chang Seok Bae - * Copyright (c) 2009, The V3VEE Project - * All rights reserved. - * - * Author: Lei Xia - * Chang Seok Bae - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#ifndef _VPCI_H__ -#define _VPCI_H__ - -#include -#include - -#define PROG_INTERFACE(x) ((x)[0]) -#define SUBCLASS(x) ((x)[1]) -#define CLASSCODE(x) ((x)[2]) - -#define HEADER_TYPE(x) ((x)&0x7f) - -#define PCI_DEVICE 0x0 - -#define IS_DEVICE(x) (HEADER_TYPE(x)==0x0) - -#define IS_IO_ADDR(x) ((x)&0x1) -#define IS_MEM_ADDR(x) (!((x)&0x1)) -#define GET_IO_ADDR(x) (((uint_t)(x))&0xfffffffc) -#define GET_MEM_ADDR(x) (((uint_t)(x))&0xfffffff0) -#define GET_MEM_TYPE(x) (((x)&0x6)>>2) - -#define PCI_CONFIG_ADDRESS 0xcf8 // 32 bit, little endian -#define PCI_CONFIG_DATA 0xcfc // 32 bit, little endian - -#define PCI_IO_REGIONS 6 - -struct pci_device_config { - uint16_t vendor_id; - uint16_t device_id; - uint16_t command; - uint16_t status; - uchar_t revision; - uchar_t class_code[3]; // in order: programming interface, subclass, class code - uchar_t cache_line_size; - uchar_t latency_time; - uchar_t header_type; // bits 6-0: 00: other, 01: pci-pci bridge, 02: pci-cardbus; bit 7: 1=multifunction - uchar_t BIST; - uint32_t BAR[6]; - uint32_t cardbus_cis_pointer; - uint16_t subsystem_vendor_id; - uint16_t subsystem_id; - uint32_t expansion_rom_address; - uchar_t cap_ptr; // capabilities list offset in config space - uchar_t reserved[7]; - uchar_t intr_line; // 00=none, 01=IRQ1, etc. - uchar_t intr_pin; // 00=none, otherwise INTA# to INTD# - uchar_t min_grant; // min busmaster time - units of 250ns - uchar_t max_latency; // units of 250ns - busmasters - uint32_t device_data[48]; -}; - -struct pci_device; - - typedef void pci_mapioregion_fn(struct pci_device *pci_dev, int region_num, - uint32_t addr, uint32_t size, int type); - -typedef int port_read_fn(ushort_t port, void * dst, uint_t length, struct vm_device *vmdev); -typedef int port_write_fn(ushort_t port, void * src, uint_t length, struct vm_device *vmdev); - -#define PCI_ADDRESS_SPACE_MEM 0x00 -#define PCI_ADDRESS_SPACE_IO 0x01 -#define PCI_ADDRESS_SPACE_MEM_PREFETCH 0x08 - -struct pci_ioregion { - uint32_t addr; //current PCI mapping address. -1 means not mapped - uint32_t size; //actual ports/memories needed by device - uint32_t mapped_size; //mapped size, usually bigger than needed size, -1 not mapped - uint8_t type; - uchar_t reg_num; //correponding to which BAR register it is - pci_mapioregion_fn *map_func; - - port_read_fn **port_reads; //array of read functions, hooked for each port in order, if NULL, do not hook that port - port_write_fn **port_writes; -}; - - -struct pci_device { - struct pci_device_config config; - struct pci_bus *bus; - struct pci_device *next; - - int dev_num; - char name[64]; - int irqline; - - struct pci_ops { - void (*raise_irq)(struct pci_device *dev, void *data); - void (*config_write)(struct pci_device *pci_dev, uchar_t addr, uint32_t val, int len); - uint32_t (*config_read)(struct pci_device *pci_dev, uchar_t addr, int len); - }ops; - - struct pci_ioregion *ioregion[PCI_IO_REGIONS]; -}; - - -/* -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 vm_device *v3_create_vpci(); - -#endif - diff --git a/palacios/src/devices/vpci.c b/palacios/src/devices/vpci.c deleted file mode 100644 index be6832d..0000000 --- a/palacios/src/devices/vpci.c +++ /dev/null @@ -1,730 +0,0 @@ -/* - * This file is part of the Palacios Virtual Machine Monitor developed - * by the V3VEE Project with funding from the United States National - * Science Foundation and the Department of Energy. - * - * The V3VEE Project is a joint project between Northwestern University - * and the University of New Mexico. You can find out more at - * http://www.v3vee.org - * - * Copyright (c) 2009, Lei Xia - * Copyright (c) 2009, Chang Seok Bae - * Copyright (c) 2009, The V3VEE Project - * All rights reserved. - * - * Author: Lei Xia - * Chang Seok Bae - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -/* - * Virtual PCI - */ - -#include -#include -#include -#include -#include -#include - - -// TODO: Add Debugging directives to Makefiles - -#ifndef DEBUG_PCI -#undef PrintDebug -#define PrintDebug(fmt, args...) -#endif - -#define NUM_DEVICES 255 -#define NUM_BUS 1 - -struct pci_bus { - int bus_num; - struct pci_device * device_list[NUM_DEVICES]; - struct pci_bus * next; - struct vm_device * vm_dev; -}; - -struct pci_internal { - uint_t num_buses; - uint32_t config_address; //current value of corresponding to configure port - struct pci_bus * bus_list[NUM_BUS]; -}; - - -struct port_ops_map { - uint32_t port; - int (*port_read)(ushort_t port, void * dst, uint_t length, struct vm_device * vdev); - int (*port_write)(ushort_t port, void * src, uint_t length, struct vm_device * vdev); -}; - - -//Lei -struct pci_device * get_device (struct vm_device * vmdev, uchar_t bus_no, uchar_t devfn_no) -{ - struct pci_device * dev = NULL; - struct pci_bus * bus = NULL; - struct pci_internal * pci_state = NULL; - - if ((bus_no >= NUM_BUS) || (devfn_no >= NUM_DEVICES)) { - return dev; - } - - pci_state = (struct pci_internal *)vmdev->private_data; - bus = pci_state->bus_list[bus_no]; - - if (bus != NULL) { - dev = bus->device_list[devfn_no]; - } - - return dev; -} - - -//Lei -// TODO: Should this be static? If not it should be v3_pci_... -int pci_hook_ports(struct pci_device * dev, - int reg_num, - int num_ports, - port_read_fn * port_reads[], - port_write_fn * port_writes[]) { - struct pci_ioregion * ioreg = NULL; - - ioreg = dev->ioregion[reg_num]; - - if (ioreg == NULL) { - PrintError("No Device registered at ioregion %d\n", reg_num); - return -1; - } - - if (ioreg->size != num_ports) { - // TODO: What does this error mean? - PrintError("IO registration size mismatch\n"); - return -1; - } - - ioreg->port_reads = port_reads; - ioreg->port_writes = port_writes; - - return 0; -} - -//Lei -// TODO: should return 'int' to indicate success or error? -// TODO: add error checking -static inline void hook_ioregion(struct pci_device * dev, struct pci_ioregion * ioreg) { - int i = 0; - - if (ioreg->addr == -1) { - // TODO: Is this an error? - return; - } - - if (ioreg->type != PCI_ADDRESS_SPACE_IO) { - // TODO: is this an error? - return; - } - - for (i = 0; i < ioreg->size; i++) { - if ( (ioreg->port_reads[i]) || - (ioreg->port_writes[i]) ) { - v3_dev_hook_io(dev->bus->vm_dev, ioreg->addr + i, ioreg->port_reads[i], ioreg->port_writes[i]); - } - } - - // TODO: return 0; -} - - -//Chang -static uint32_t vpci_read_config(struct pci_device * pdev, uchar_t offset, int len) { - uint32_t val = 0; - - switch(len) { - case 4: - if (offset <= 0xfc) { - val = *(uint32_t *)(&(pdev->config) + offset); - break; - } - // TODO: Shouldn't this break unconditionally? - case 2: - if (offset <= 0xfe) { - val = *(uint16_t *)(&(pdev->config) + offset); - break; - } - // TODO: Shouldn't this break unconditionally? - case 1: - val = *(uint8_t *)(&(pdev->config) + offset); - break; - default: - break; - } - - return val; -} - -//Lei -// TODO: Should this return 'int'? -static void vpci_write_config(struct pci_device * dev, uchar_t offset, uint32_t val, int len) { - uchar_t * dev_config = NULL; - - dev_config = (uchar_t *)&(dev->config); - dev_config += offset; - - - // TODO: cast 'val' instead of masking it - switch(len) { - case 1: - *dev_config = (val & 0xff); - break; - case 2: - *(uint16_t *)dev_config = (val & 0xffff); - break; - case 4: - *(uint32_t *)dev_config = val; - break; - default: - PrintDebug("pci_write_config: wrong length %d\n", len); - break; - } -} - -//Lei -// TODO: If this is not static, it should be v3_pci_raise_irq -void vpci_raise_irq(struct pci_device * pdev, void * data) { - struct guest_info * vm = NULL; - int irq_line = 0; - - vm = pdev->bus->vm_dev->vm; - irq_line = pdev->config.intr_line; - - v3_raise_irq(vm, irq_line); -} - -#if 0 -//Chang -static void pci_write_config(struct pci_device *dev, uint32_t address, uint32_t val, int len) -{ - int can_write, i, reg_num; - uint32_t addr; - - if(len == 4 && ((address >= 0x10 && address < 0x10 + 4 * 6) || //base address registers - (address >= 0x30 && address < 0x34))) { //expansion rom base address - - struct pci_ioregion * ioregion; - if(address >= 0x30) { - reg_num = PCI_ROM_SLOT; - }else { - reg_num = ((address - 0x10) >>2); - } - - ioregion = &dev->io_regions[reg_num]; - - if(ioregion->size == 0) {//default config - - addr = address; - for (i=0;iconfig)+0x0e)) { - case 0x00: - case 0x80: - switch(addr) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x0e: - case 0x10 ... 0x27: - case 0x3d: - can_write = 0; - break; - default: - can_write = 1; - break; - } - break; - default: - case 0x01: - switch(addr) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x0e: - case 0x38 ... 0x3b: - case 0x3d: - can_write = 0; - break; - default: - can_write = 1; - break; - } - break; - } - if (can_write) { - *(uint32_t *)(&(dev->config)+addr) = val; - } - if(++addr > 0xff) break; - val >>= 8; - } - - return; - - }else { - if(reg_num== PCI_ROM_SLOT) { - val &= (~(ioregion->size -1 )) | 1; - } else { - val &= ~(ioregion->size -1); - val |= ioregion->type; - } - } - //pci_update_mappings(); - return; - } -} -#endif - -/* -1 for dev_num means auto assign */ -// TODO: Should be v3_pci_register_device -struct pci_device * -pci_register_device(struct pci_bus * bus, const char * name, - int instance_size, int dev_num, - uint32_t (*config_read)(struct pci_device * pci_dev, uchar_t addr, int len), - void (*config_write)(struct pci_device * pci_dev, uchar_t addr, uint32_t val, int len)) { - - struct pci_device * pci_dev = NULL; - int found = 0; - int i = 0; - - if (dev_num < 0) { - for (dev_num = 0; dev_num < 256; dev_num++) { - if (!bus->device_list[dev_num]) { - found = 1; - break; - } - } - } - - if (found == 0) { - return NULL; - } - - pci_dev = (struct pci_device *)V3_Malloc(sizeof(struct pci_device)); - - if (pci_dev == NULL) { - return NULL; - } - - pci_dev->bus = bus; - pci_dev->dev_num = dev_num; - pci_dev->irqline = -1; - - strcpy(pci_dev->name, name); - - if (config_read != NULL) { - pci_dev->ops.config_read = config_read; - } else { - pci_dev->ops.config_read = &vpci_read_config; - } - - if (config_write != NULL) { - pci_dev->ops.config_write = config_write; - } else { - pci_dev->ops.config_write = &vpci_write_config; - } - - - pci_dev->ops.raise_irq = &vpci_raise_irq; - - for (i = 0; i < PCI_IO_REGIONS; i++) { - pci_dev->ioregion[i] = NULL; - } - - //config space initiate - - bus->device_list[dev_num] = pci_dev; - - return pci_dev; -} - -//Chang -static void init_fake_device(struct pci_internal * pci_state) { - //maybe need table to map device, but just - //bus_num=0, dev_num=0 - - //int i=0; - struct pci_device *fake_device; - - //fake dev - fake_device = pci_register_device(pci_state->bus_list[0], - "fake ide", sizeof(struct pci_device), - -1, - NULL,NULL); - - if (!fake_device) { - return; - } - - /* - intel, ide ctroller - vendor id:0x8086 - device id: 0x1222 - */ - fake_device->config.vendor_id = 0x8086; - fake_device->config.device_id = 0x1222; - fake_device->config.command = 0x0; - fake_device->config.status = 0x0; - fake_device->config.revision = 0x07; - fake_device->config.class_code[0] = 0x1; - fake_device->config.class_code[1] = 0x1; - fake_device->config.class_code[2] = 0x1; - fake_device->config.header_type = 0x0; - - //base address - fake_device->config.BAR[0] = 0x1F0; - fake_device->config.BAR[1] = 0; - fake_device->config.BAR[2] = 0; - fake_device->config.BAR[3] = 0; - fake_device->config.BAR[4] = 0; - fake_device->config.BAR[5] = 0; - - //fake dev end - - //need to register io regions - - pci_state->bus_list[0]->device_list[0] = fake_device; - fake_device->bus = pci_state->bus_list[0]; - fake_device->next = NULL; - - return; -} - - - -// Lei -/* if region_num == -1, assign automatically - */ -//TODO: Should be v3_pci_register... -int -pci_register_io_region(struct pci_device * pci_dev, int region_num, - uint32_t size, int type, - pci_mapioregion_fn * map_func) { - int found = 0; - struct pci_ioregion * region = NULL; - - if (region_num < 0) { - for (region_num = 0; region_num < 256; region_num++) { - if (pci_dev->ioregion[region_num] == NULL) { - found = 1; - break; - } - } - } - - if (found == 0) { - return -1; - } - - if (pci_dev->ioregion[region_num] != NULL) { - return -1; - } - - region = (struct pci_ioregion *)V3_Malloc(sizeof(struct pci_ioregion)); - if (region == NULL) { - return -1; - } - - region->addr = -1; - region->reg_num = region_num; - region->size = size; - region->mapped_size = -1; - region->type = type; - region->map_func = map_func; - region->port_reads = NULL; - region->port_writes = NULL; - - pci_dev->ioregion[region_num] = region; - - return region_num; -} - - - - -//Chang -static int -vpci_addrport_read(ushort_t port, void * dst, uint_t length, struct vm_device * dev) { - - struct pci_internal *pci_state = (struct pci_internal *)dev->private_data; - int start = 0; - uchar_t * addr = NULL; - int i = 0; - - start = port - PCI_CONFIG_ADDRESS; - - if ((length + start) > 4) { - //cross port boundary, is memory mapped IO style - return length; - } - - addr = (uchar_t *)&(pci_state->config_address); - addr += start; - - memcpy(dst, addr, length); //be careful, PCI is little endian - - PrintDebug("PCI Address: reading %d bytes from port %x: 0x", length, port); - for (i = (length - 1); i >= 0; i--) { - PrintDebug("%.2x", ((uchar_t*)dst)[i]); - } - PrintDebug("\n"); - - return length; -} - -//Lei -static int -vpci_addrport_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 start = 0; - uchar_t * addr = NULL; - int i = 0; - - start = port - PCI_CONFIG_ADDRESS; - - if ((length + start) > 4){ - //cross port boundary, is memory mapped IO style - return length; - } - - addr = (uchar_t *)&(pci_state->config_address); - addr += start; - memcpy(addr, src, length); //be careful, PCI is little endian - - PrintDebug("PCI Address: writing %d bytes to port %x: 0x", length, port); - - for (i = (length - 1); i >= 0; i--) { - PrintDebug("%.2x", ((uchar_t*)src)[i]); - } - PrintDebug("\n"); - - return length; -} - -//Chang -static int -vpci_dataport_read(ushort_t port, void * dst, uint_t length, struct vm_device * vmdev) { - /* - decode address of config_address - bus num = config_address[23:16] - device num = config_address[15:11] - func num = config_address[10:08] - reg num = config_address[07:02] - */ - - struct pci_internal * pci_state = NULL; - struct pci_device * pci_dev = NULL; - int bus_num = 0; - int devfn = 0; - int offset = 0; - uint32_t address = 0; - uint32_t val = 0; - int i = 0; - - if (length > 4){ - PrintDebug("Read more than 4 bytes from port 0x%x\n", (int)port); - return length; - } - - pci_state = (struct pci_internal *)vmdev->private_data; - - address = pci_state->config_address; - offset = address & 0xff; - devfn = (address >> 8) & 0xff; - bus_num = (address >> 16) & 0xff; - - pci_dev = get_device(vmdev, bus_num, devfn); - - if (pci_dev == NULL) { - val = 0xffffffff; - } else { - val = 0x0; - val = pci_dev->ops.config_read(pci_dev, offset, length); - } - - memcpy(dst, &val, length); - - PrintDebug("PCI Data: reading %d bytes from port %x: 0x", length, port); - - for (i = (length - 1); i >= 0; i--) { - PrintDebug("%.2x", ((uchar_t*)dst)[i]); - } - PrintDebug("\n"); - - return length; -} - -static int -vpci_dataport_write(ushort_t port, void * src, uint_t length, struct vm_device * vmdev) { - struct pci_internal * pci_state = NULL; - uint32_t val = 0; - uint32_t address = 0; - struct pci_device * pdev = NULL; - // TODO: Why are these 'char', but the read variables 'int' - char bus = 0; - char devfn = 0; - char offset = 0; - int i = 0; - - if (length > 4){ - PrintDebug("Write more than 4 bytes to port 0x%x\n", (int)port); - return length; - } - - pci_state = (struct pci_internal *)vmdev->private_data; - - address = pci_state->config_address; - offset = address & 0xff; - devfn = (address >> 8) & 0xff; - bus = (address >> 16) & 0xff; - - pdev = get_device(vmdev, bus, devfn); - - if (pdev == NULL){ - // not sure what to do here, just ignore it - return length; - } - - val = 0x0; - memcpy(&val, src, length); - - pdev->ops.config_write(pdev, offset, val, length); - - PrintDebug("PCI Data: writing %d bytes to port %x: 0x", length, port); - - for (i = (length - 1); i >= 0; i--) { - PrintDebug("%.2x", ((uchar_t*)src)[i]); - } - PrintDebug("\n"); - - return length; -} - - -//Lei -static void init_pci_bus(struct pci_internal * pci_state) { - int i = 0; - struct pci_bus * first_bus = NULL; - - first_bus = (struct pci_bus *)V3_Malloc(sizeof(struct pci_bus)); - - first_bus->bus_num = 0; //?? not sure - - for (i = 0; i < NUM_DEVICES; i++) { - first_bus->device_list[i] = NULL; - } - - first_bus->next = NULL; - - pci_state->num_buses = 1; - pci_state->bus_list[0] = first_bus; - - for (i = 1; i < NUM_BUS; i++) { - pci_state->bus_list[i] = NULL; - } -} - -//Lei -static void init_pci_internal(struct pci_internal * pci_state) { - pci_state->config_address = 0x00; //Not sure???? - init_pci_bus(pci_state); -} - - -static int vpci_set_defaults(struct vm_device * dev) { - PrintDebug("vpci: set defaults\n"); - return 0; -} - - -static int vpci_reset_device(struct vm_device * dev) { - PrintDebug("vpci: reset device\n"); - - vpci_set_defaults(dev); - - return 0; -} - - -static int vpci_start_device(struct vm_device * dev) { - PrintDebug("vpci: start device\n"); - return 0; -} - - -// TODO: This should be static -int vpci_stop_device(struct vm_device * dev) { - PrintDebug("vpci: stop device\n"); - return 0; -} - -// TODO: this should be static? -int vpci_init_device(struct vm_device * dev) { - struct pci_internal *pci_state = NULL; - int i = 0; - - PrintDebug("vpci: init_device\n"); - - pci_state = (struct pci_internal *)dev->private_data; - - init_pci_internal(pci_state); - - init_fake_device(pci_state); //Chang - - for (i = 0; i < 4; i++){ - v3_dev_hook_io(dev, PCI_CONFIG_ADDRESS + i, &vpci_addrport_read, &vpci_addrport_write); - v3_dev_hook_io(dev, PCI_CONFIG_DATA + i, &vpci_dataport_read, &vpci_dataport_write); - } - - return 0; -} - -// TODO: This should be static -int vpci_deinit_device(struct vm_device * dev) { - int i = 0; - - for (i = 0; i < 4; i++){ - v3_dev_unhook_io(dev, PCI_CONFIG_ADDRESS + i); - v3_dev_unhook_io(dev, PCI_CONFIG_DATA + i); - } - - vpci_reset_device(dev); - return 0; -} - -static struct vm_device_ops dev_ops = { - .init = vpci_init_device, - .deinit = vpci_deinit_device, - .reset = vpci_reset_device, - .start = vpci_start_device, - .stop = vpci_stop_device, -}; - -struct vm_device * v3_create_vpci() { - 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; -}