From: Jack Lange <jarusl@cs.northwestern.edu>
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?a=commitdiff_plain;h=eed2bbeb750b15b7cc975ba213e5707168e9c932;p=palacios.releases.git

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 <lxia@northwestern.edu>
- * Copyright (c) 2009, Chang Seok Bae <jhuell@gmail.com>
- * Copyright (c) 2009, The V3VEE Project <http://www.v3vee.org> 
- * All rights reserved.
- *
- * Author:  Lei Xia <lxia@northwestern.edu>
- *             Chang Seok Bae <jhuell@gmail.com>
- *
- * 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 <palacios/vm_dev.h>
-#include <palacios/vmm_types.h>
-
-#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 <lxia@northwestern.edu>
- * Copyright (c) 2009, Chang Seok Bae <jhuell@gmail.com>
- * Copyright (c) 2009, The V3VEE Project <http://www.v3vee.org> 
- * All rights reserved.
- *
- * Author:  Lei Xia <lxia@northwestern.edu>
- *          Chang Seok Bae <jhuell@gmail.com>
- *
- * This is free software.  You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */ 
- 
-/*
- * Virtual PCI
- */
- 
-#include <devices/vpci.h>
-#include <palacios/vmm.h>
-#include <palacios/vmm_types.h>
-#include <palacios/vmm_io.h>
-#include <palacios/vmm_string.h>
-#include <palacios/vmm_intr.h>
-
-
-// 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;i<len;i++) {
-		switch(*(uint8_t *)(&(dev->config)+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;
-}