Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merging for release RC2
Jack Lange [Fri, 10 Oct 2008 19:55:11 +0000 (14:55 -0500)]
Merge branch 'devel'

Conflicts:
palacios/include/devices/generic.h
palacios/include/devices/ide.h
palacios/include/geekos/debug.h
palacios/include/geekos/net.h
palacios/include/geekos/pci.h
palacios/include/geekos/queue.h
palacios/include/geekos/reboot.h
palacios/include/geekos/ring_buffer.h
palacios/include/geekos/serial.h
palacios/include/geekos/socket.h
palacios/include/geekos/timer.h
palacios/include/geekos/vm.h
palacios/include/palacios/vmcs.h
palacios/include/palacios/vmcs_gen.h
palacios/src/devices/cdrom.c
palacios/src/devices/generic.c
palacios/src/devices/ramdisk.c
palacios/src/geekos/debug.c
palacios/src/geekos/net.c
palacios/src/geekos/queue.c
palacios/src/geekos/testvm.s
palacios/src/palacios/vmm_config.c

1  2 
palacios/include/devices/generic.h
palacios/include/devices/ide.h
palacios/include/palacios/vmcs.h
palacios/include/palacios/vmcs_gen.h
palacios/src/devices/cdrom.c
palacios/src/palacios/vmm_config.c

@@@ -1,5 -1,4 +1,4 @@@
  /* 
   * 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.  
   * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
   */
  
 -
+ #ifndef __GENERIC_H__
+ #define __GENERIC_H__
  
- #ifndef __GENERIC_H
- #define __GENERIC_H
  
  #include <palacios/vm_dev.h>
  
  #define GENERIC_PRINT_AND_PASSTHROUGH 0
  #define GENERIC_PRINT_AND_IGNORE      1
  
- // A port range is low..high, inclusive, third value is one of the above
- typedef uint_t generic_port_range_type[3];
- // A memory range is low..high, inclusive, flags
- typedef void *generic_address_range_type[3];
- // An interrupt ory map range is low..high, inclusive, flags
- typedef uint_t generic_irq_range_type[3];
+ int v3_generic_add_port_range(struct vm_device * dev, uint_t start, uint_t end, uint_t type);
+ int v3_generic_add_mem_range(struct vm_device * dev, void * start, void * end, uint_t type);
+ int v3_generic_add_irq_range(struct vm_device * dev, uint_t start, uint_t end, uint_t type);
  
  // The lists given are null terminated
- struct vm_device *create_generic(generic_port_range_type    port_ranges[], 
-                                generic_address_range_type addess_ranges[],
-                                generic_irq_range_type     irq_ranges[]);  
+ struct vm_device * create_generic();  
  
  #endif
@@@ -41,7 -41,7 +41,7 @@@
  #ifdef __V3VEE__
  #include <palacios/vmm_types.h>
  
- #ifdef __V3_32BIT__
  typedef long off_t;
  typedef sint32_t ssize_t;
  typedef unsigned int rd_bool;
@@@ -49,7 -49,7 +49,7 @@@ typedef uchar_t Bit8u
  typedef ushort_t Bit16u;
  typedef uint32_t Bit32u;
  typedef uint64_t Bit64u;
- #endif
  
  
  #define MAX_ATA_CHANNEL 4
@@@ -132,7 -132,7 +132,7 @@@ struct  cdrom_t 
    rd_bool ready;
    rd_bool locked;
  
-   struct cdrom_interface * cd;
+   struct cdrom_ops * cd;
  
    uint32_t capacity;
    int next_lba;
@@@ -204,6 -204,9 +204,10 @@@ struct  drive_t 
    struct sense_info_t sense;
    struct atapi_t atapi;
    
++
+   /* JRL */
+   void * private_data;
    Bit8u model_no[41];
  };
  
@@@ -239,3 -242,29 +243,30 @@@ struct  ramdisk_t 
  
  #endif
  
++
+ #if 0
+ // FLAT MODE
+ // Open a image. Returns non-negative if successful.
+ //int open (const char* pathname);
+ // Open an image with specific flags. Returns non-negative if successful.
+ int rd_open (const char* pathname, int flags);
+ // Close the image.
+ void rd_close ();
+ // Position ourselves. Return the resulting offset from the
+ // beginning of the file.
+ off_t rd_lseek (off_t offset, int whence);
+ // Read count bytes to the buffer buf. Return the number of
+ // bytes read (count).
+ ssize_t rd_read (void* buf, size_t count);
+ // Write count bytes from buf. Return the number of bytes
+ // written (count).
+ ssize_t rd_write (const void* buf, size_t count);
+ #endif
   * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
   */
  
- #ifndef __VMCS_H
- #define __VMCS_H
++
+ #ifndef __VMCS_H__
+ #define __VMCS_H__
+ #ifdef __V3VEE__
 +
  #include <palacios/vmm_types.h>
  
  
@@@ -274,73 -278,67 +280,67 @@@ extern char *exception_type_names[]
  typedef void VMCS;
  
  
- #if __TINYC__
- #define PACKED
- #else
- #define PACKED __attribute__((packed))
- #endif
  
  
  /* VMCS Exit QUALIFICATIONs */
  struct VMExitIOQual {
-   uint_t accessSize : 3     PACKED; // (0: 1 Byte ;; 1: 2 Bytes ;; 3: 4 Bytes)
-   uint_t dir        : 1     PACKED; // (0: Out ;; 1: In)
-   uint_t string     : 1     PACKED; // (0: not string ;; 1: string)
-   uint_t REP        : 1     PACKED; // (0: not REP ;; 1: REP)
-   uint_t opEnc      : 1     PACKED; // (0: DX ;; 1: immediate)
-   uint_t rsvd       : 9     PACKED; // Set to 0
-   uint_t port       : 16    PACKED; // IO Port Number
- };
+   uint_t accessSize : 3; // (0: 1 Byte ;; 1: 2 Bytes ;; 3: 4 Bytes)
+   uint_t dir        : 1; // (0: Out ;; 1: In)
+   uint_t string     : 1; // (0: not string ;; 1: string)
+   uint_t REP        : 1; // (0: not REP ;; 1: REP)
+   uint_t opEnc      : 1; // (0: DX ;; 1: immediate)
+   uint_t rsvd       : 9; // Set to 0
+   uint_t port       : 16; // IO Port Number
+ } __attribute__((packed));
  
  
  
  struct VMExitDBGQual {
-   uint_t B0         : 1     PACKED; // Breakpoint 0 condition met
-   uint_t B1         : 1     PACKED; // Breakpoint 1 condition met
-   uint_t B2         : 1     PACKED; // Breakpoint 2 condition met
-   uint_t B3         : 1     PACKED; // Breakpoint 3 condition met
-   uint_t rsvd       : 9     PACKED; // reserved to 0
-   uint_t BD         : 1     PACKED; // detected DBG reg access
-   uint_t BS         : 1     PACKED; // cause either single instr or taken branch
- };
+   uint_t B0         : 1; // Breakpoint 0 condition met
+   uint_t B1         : 1; // Breakpoint 1 condition met
+   uint_t B2         : 1; // Breakpoint 2 condition met
+   uint_t B3         : 1; // Breakpoint 3 condition met
+   uint_t rsvd       : 9; // reserved to 0
+   uint_t BD         : 1; // detected DBG reg access
+   uint_t BS         : 1; // cause either single instr or taken branch
+ } __attribute__((packed));
  
  
  struct VMExitTSQual {
-   uint_t selector   : 16    PACKED; // selector of destination TSS 
-   uint_t rsvd       : 14    PACKED; // reserved to 0
-   uint_t src        : 2     PACKED; // (0: CALL ; 1: IRET ; 2: JMP ; 3: Task gate in IDT)
- };
+   uint_t selector   : 16; // selector of destination TSS 
+   uint_t rsvd       : 14; // reserved to 0
+   uint_t src        : 2; // (0: CALL ; 1: IRET ; 2: JMP ; 3: Task gate in IDT)
+ } __attribute__((packed));
  
  struct VMExitCRQual {
-   uint_t crID       : 4     PACKED; // cr number (0 for CLTS and LMSW) (bit 3 always 0, on 32bit)
-   uint_t accessType : 2     PACKED; // (0: MOV to CR ; 1: MOV from CR ; 2: CLTS ; 3: LMSW)
-   uint_t lmswOpType : 1     PACKED; // (0: register ; 1: memory)
-   uint_t rsvd1      : 1     PACKED; // reserved to 0
-   uint_t gpr        : 4     PACKED; // (0:RAX+[CLTS/LMSW], 1:RCX, 2:RDX, 3:RBX, 4:RSP, 5:RBP, 6:RSI, 6:RDI, 8-15:64bit regs)
-   uint_t rsvd2      : 4     PACKED; // reserved to 0
-   uint_t lmswSrc    : 16    PACKED; // src data for lmsw
- };
+   uint_t crID       : 4; // cr number (0 for CLTS and LMSW) (bit 3 always 0, on 32bit)
+   uint_t accessType : 2; // (0: MOV to CR ; 1: MOV from CR ; 2: CLTS ; 3: LMSW)
+   uint_t lmswOpType : 1; // (0: register ; 1: memory)
+   uint_t rsvd1      : 1; // reserved to 0
+   uint_t gpr        : 4; // (0:RAX+[CLTS/LMSW], 1:RCX, 2:RDX, 3:RBX, 4:RSP, 5:RBP, 6:RSI, 6:RDI, 8-15:64bit regs)
+   uint_t rsvd2      : 4; // reserved to 0
+   uint_t lmswSrc    : 16; // src data for lmsw
+ } __attribute__((packed));
  
  struct VMExitMovDRQual {
-   uint_t regID      : 3     PACKED; // debug register number
-   uint_t rsvd1      : 1     PACKED; // reserved to 0
-   uint_t dir        : 1     PACKED; // (0: MOV to DR , 1: MOV from DR)
-   uint_t rsvd2      : 3     PACKED; // reserved to 0
-   uint_t gpr        : 4     PACKED; // (0:RAX, 1:RCX, 2:RDX, 3:RBX, 4:RSP, 5:RBP, 6:RSI, 6:RDI, 8-15:64bit regs)
- };
+   uint_t regID      : 3; // debug register number
+   uint_t rsvd1      : 1; // reserved to 0
+   uint_t dir        : 1; // (0: MOV to DR , 1: MOV from DR)
+   uint_t rsvd2      : 3; // reserved to 0
+   uint_t gpr        : 4; // (0:RAX, 1:RCX, 2:RDX, 3:RBX, 4:RSP, 5:RBP, 6:RSI, 6:RDI, 8-15:64bit regs)
+ } __attribute__((packed));
  
  /* End Exit Qualifications */
  
  /* Exit Vector Info */
  struct VMExitIntInfo {
-   uint_t nr         : 8     PACKED; // IRQ number, exception vector, NMI = 2 
-   uint_t type       : 3     PACKED; // (0: ext. IRQ , 2: NMI , 3: hw exception , 6: sw exception
-   uint_t errorCode  : 1     PACKED; // 1: error Code present
-   uint_t iret       : 1     PACKED; // something to do with NMIs and IRETs (Intel 3B, sec. 23.2.2) 
-   uint_t rsvd       : 18    PACKED; // always 0
-   uint_t valid      : 1     PACKED; // always 1 if valid
- };
+   uint_t nr         : 8; // IRQ number, exception vector, NMI = 2 
+   uint_t type       : 3; // (0: ext. IRQ , 2: NMI , 3: hw exception , 6: sw exception
+   uint_t errorCode  : 1; // 1: error Code present
+   uint_t iret       : 1; // something to do with NMIs and IRETs (Intel 3B, sec. 23.2.2) 
+   uint_t rsvd       : 18; // always 0
+   uint_t valid      : 1; // always 1 if valid
+ } __attribute__((packed));
  
  
  
  /* INTEL Manual: 20-4 vol 3B */
  union SegAccess {
    struct {
-     uchar_t  type                PACKED;
-     uint_t   descType    : 1     PACKED; 
-     uint_t   dpl         : 2     PACKED;
-     uint_t   present     : 1     PACKED;
-     uchar_t  rsvd1               PACKED;
-     uint_t   avail       : 1    PACKED ;
-     uint_t   L           : 1    PACKED ; // CS only (64 bit active), reserved otherwise
-     uint_t   DB          : 1    PACKED ; 
-     uint_t   granularity : 1    PACKED ;
-     uint_t   unusable    : 1   PACKED  ; 
-     uint_t   rsvd2       : 15  PACKED ;
-   } as_fields;
+     uchar_t  type;
+     uint_t   descType    : 1; 
+     uint_t   dpl         : 2;
+     uint_t   present     : 1;
+     uchar_t  rsvd1;
+     uint_t   avail       : 1;
+     uint_t   L           : 1; // CS only (64 bit active), reserved otherwise
+     uint_t   DB          : 1; 
+     uint_t   granularity : 1;
+     uint_t   unusable    : 1; 
+     uint_t   rsvd2       : 15;
+   } __attribute__((packed)) as_fields;
    uint_t as_dword;
- };
+ } __attribute__((packed));
  
  
  struct VMCSSegment {
@@@ -424,8 -422,8 +424,8 @@@ struct VMCSGuestStateArea 
  };
  
  
- int CopyOutVMCSGuestStateArea(struct VMCSGuestStateArea *p);
- int CopyInVMCSGuestStateArea(struct VMCSGuestStateArea *p);
+ int CopyOutVMCSGuestStateArea(struct VMCSGuestStateArea * p);
+ int CopyInVMCSGuestStateArea(struct VMCSGuestStateArea * p);
  
  
  
@@@ -600,4 -598,7 +600,7 @@@ extern uint_t VMCS_READ()
  
  #include <palacios/vmcs_gen.h>
  
+ #endif // ! __V3VEE__
  #endif 
@@@ -1,5 -1,4 +1,4 @@@
  /*
   * 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.  
@@@ -23,7 -22,6 +22,6 @@@
  #ifdef __V3VEE__
  
  
  #include <palacios/vmcs.h>
  #include <palacios/vmm.h>
  
@@@ -801,6 -799,11 +799,10 @@@ uint_t  Get_HOST_RIP()
  void    PrintTrace_HOST_RIP();
  
  void PrintTrace_VMCS_ALL();
- #endif
+ #endif // !__V3VEE
  
  #endif
 -
@@@ -1,5 -1,4 +1,4 @@@
  /*
   * 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.  
   * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
   */
  
++
  #include <devices/cdrom.h>
+ #include <devices/ide.h>
  #include <palacios/vmm.h>
  
- #ifdef DEBUG_RAMDISK
- #define Ramdisk_Print_CD(_f, _a...) PrintTrace("cdrom.c(%d) "_f, __LINE__, ## _a)
- #else
- #define Ramdisk_Print_CD(_f, _a...)
+ #ifndef DEBUG_RAMDISK
+ #undef PrintDebug
+ #define PrintDebug(fmt, args...)
  #endif
  
  
- extern ulong_t g_ramdiskImage;
- extern ulong_t s_ramdiskSize;
  
- static
- void cdrom_init(struct cdrom_interface * cdrom)
- {
+ struct cdrom_state {
+   uchar_t * image_addr; //memory address
+   ulong_t capacity_in_bytes;
+   ulong_t head; //current position
+   struct vm_device * ide_dev;
+   uchar_t lba;
+ };
  
-   Ramdisk_Print_CD("[cdrom_init]\n");
-   V3_ASSERT(g_ramdiskImage);
-   cdrom->fd = g_ramdiskImage;
-   cdrom->capacity_B = s_ramdiskSize; 
-   //FIXME:lba
-   cdrom->lba = 1; 
-   return;
- }
  
  /* 
   * Load CD-ROM. Returns false if CD is not ready.
   */
   
- static
- rd_bool cdrom_insert(struct cdrom_interface * cdrom, char *dev /*= NULL*/)
- {
-   Ramdisk_Print_CD("[cdrom_insert]\n");
+ static rd_bool cdrom_insert(void * private_data) {
+   PrintDebug("[cdrom_insert]\n");
    return 1;
  }
  
  /*
   * Logically eject the CD.
   */
- static
- void cdrom_eject(struct cdrom_interface *cdrom)
- {
-   Ramdisk_Print_CD("[cdrom_eject]\n");
+ static void cdrom_eject(void * private_data) {
+   PrintDebug("[cdrom_eject]\n");
    return;
  }
  
  /*
   * Read CD TOC. Returns false if start track is out of bounds.
   */
- static
- rd_bool cdrom_read_toc(struct cdrom_interface *cdrom, uint8* buf, int* length, rd_bool msf, int start_track)
+ static rd_bool cdrom_read_toc(void * private_data, uint8_t* buf, int* length, rd_bool msf, int start_track)
  {
-   Ramdisk_Print_CD("[cdrom_read_toc]\n");
+   PrintDebug("[cdrom_read_toc]\n");
    return 1;
  }
  
  /*
   * Return CD-ROM capacity (in 2048 byte frames)
   */
- static
- uint32 cdrom_capacity(struct cdrom_interface *cdrom)
- {
-   Ramdisk_Print_CD("[cdrom_capacity] s_ramdiskSize = %d\n", cdrom->capacity_B);
+ static uint32_t cdrom_capacity(void * private_data) {
+   struct cdrom_state * cdrom = (struct cdrom_state *)private_data;
+   PrintDebug("[cdrom_capacity] s_ramdiskSize = %d\n", cdrom->capacity_in_bytes);
    if (cdrom->lba) {
-     if (cdrom->capacity_B % 2048) {
-       Ramdisk_Print_CD("\t\t capacity in LBA is %d\n", cdrom->capacity_B/2048 + 1);
-       return cdrom->capacity_B/2048 + 1;
+     if (cdrom->capacity_in_bytes % 2048) {
+       PrintDebug("\t\t capacity in LBA is %d\n", (cdrom->capacity_in_bytes / 2048) + 1);
+       return (cdrom->capacity_in_bytes / 2048) + 1;
      } else {
-       Ramdisk_Print_CD("\t\t capacity in LBA is %d\n", cdrom->capacity_B/2048);
-       return cdrom->capacity_B/2048;
+       PrintDebug("\t\t capacity in LBA is %d\n", cdrom->capacity_in_bytes / 2048);
+       return cdrom->capacity_in_bytes / 2048;
      }
    } else {
+     PrintError("Unsupported CDROM mode in capacity query\n");
      //FIXME CHS mode
      return 0;
    }
  /*
   * Read a single block from the CD
   */
- static
- void cdrom_read_block(struct cdrom_interface *cdrom, uint8* buf, int lba)// __attribute__(regparm(2));
- {
+ static void cdrom_read_block(void * private_data, uint8_t * buf, int lba)/* __attribute__(regparm(2)); */ {
+   struct cdrom_state * cdrom = (struct cdrom_state *)private_data;
  
    V3_ASSERT(lba != 0);
-     
-   Ramdisk_Print_CD("[cdrom_read_block] lba = %d\n", lba);
-   memcpy(buf, (uint8 *)(cdrom->fd + lba*2048), 2048);
-     return;
+   
+   PrintDebug("[cdrom_read_block] lba = %d (cdrom_image_start=%x)\n", lba, cdrom->image_addr);
+   memcpy(buf, (uchar_t *)(cdrom->image_addr + lba * 2048), 2048);
+   PrintDebug("Returning from read block\n");
+   return;
  }
  
+ static void set_LBA(void * private_data, uchar_t lba) {
+   struct cdrom_state * cdrom = (struct cdrom_state *)private_data;
+   cdrom->lba = lba;
+ }
  /*
   * Start (spin up) the CD.
   */
- static
- int cdrom_start(struct cdrom_interface *cdrom)
- {
-   Ramdisk_Print_CD("[cdrom_start]\n");
+ static int cdrom_start(void * private_data) {
+   PrintDebug("[cdrom_start]\n");
    return 1;
  }
  
  
- void init_cdrom(struct cdrom_interface *cdrom)
- {
-   V3_ASSERT(cdrom != NULL);
+ static struct cdrom_ops cd_ops = {
+   .insert_cdrom = cdrom_insert,
+   .eject_cdrom = cdrom_eject,
+   .read_toc = cdrom_read_toc,
+   .capacity = cdrom_capacity,
+   .read_block = cdrom_read_block,
+   .start_cdrom = cdrom_start,
+   .set_LBA = set_LBA,
+ };
+ static int cdrom_device_init(struct vm_device * dev) {
+   struct cdrom_state * cdrom = (struct cdrom_state *)dev->private_data;
+   PrintDebug("[cdrom_init]\n");
+   PrintDebug("CDIMAGE located at: %x\n", cdrom->image_addr);
+   //FIXME:lba
+   cdrom->lba = 1; 
+   v3_ramdisk_register_cdrom(cdrom->ide_dev, 1, 0, &cd_ops, cdrom);
+   return 0;
+ }
+ static int cdrom_device_deinit(struct vm_device * dev) {
+   return 0;
+ }
+ static struct vm_device_ops dev_ops = {
+   .init = cdrom_device_init,
+   .deinit = cdrom_device_deinit,
+   .reset = NULL,
+   .start = NULL,
+   .stop = NULL,
+ };
+ struct vm_device *  v3_create_cdrom(struct vm_device * ramdisk_dev, void * ramdisk, uint_t ramdisk_size){
+   struct cdrom_state * cd = (struct cdrom_state *)V3_Malloc(sizeof(struct cdrom_state));
+   V3_ASSERT(cd != NULL);
+   memset(cd, 0, sizeof(struct cdrom_state));
+   cd->image_addr = (uchar_t *)ramdisk;
+   cd->capacity_in_bytes = ramdisk_size;
+   cd->ide_dev = ramdisk_dev;
    
-   cdrom->ops.init = &cdrom_init;
-   cdrom->ops.insert_cdrom = &cdrom_insert;
-   cdrom->ops.eject_cdrom = &cdrom_eject;
-   cdrom->ops.read_toc = &cdrom_read_toc;
-   cdrom->ops.capacity = &cdrom_capacity;
-   cdrom->ops.read_block = &cdrom_read_block;
-   cdrom->ops.start_cdrom = &cdrom_start;
+   PrintDebug("Creating RamDISK CDROM\n");
  
-   return;
+   struct vm_device * cd_dev = create_device("Ram Based CD", &dev_ops, cd);
+   return cd_dev;
  }
  
@@@ -17,7 -17,6 +17,7 @@@
   * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
   */
  
 +
  #include <palacios/vmm_config.h>
  #include <palacios/vmm.h>
  #include <palacios/vmm_debug.h>
  #include <devices/8254.h>
  #include <devices/nvram.h>
  #include <devices/generic.h>
+ #include <devices/ramdisk.h>
+ #include <devices/cdrom.h>
+ #define USE_GENERIC 1
+ #define MAGIC_CODE 0xf1e2d3c4
+ struct layout_region {
+   ulong_t length;
+   ulong_t final_addr;
+ };
+ struct guest_mem_layout {
+   ulong_t magic;
+   ulong_t num_regions;
+   struct layout_region regions[0];
+ };
  
  
  
@@@ -72,14 -92,17 +93,17 @@@ static int passthrough_mem_write(addr_
  }
  */
  
- int config_guest(struct guest_info * info, void * config_ptr) {
+ int config_guest(struct guest_info * info, struct v3_vm_config * config_ptr) {
  
-   struct guest_mem_layout * layout = (struct guest_mem_layout *)config_ptr;
+   struct guest_mem_layout * layout = (struct guest_mem_layout *)config_ptr->vm_kernel;
    extern v3_cpu_arch_t v3_cpu_type;
    void * region_start;
    int i;
  
-   
+   int use_ramdisk = config_ptr->use_ramdisk;
+   int use_generic = USE_GENERIC;
    v3_init_time(info);
    init_shadow_map(info);
    
  
    
    {
-     
+     struct vm_device * ramdisk = NULL;
+     struct vm_device * cdrom = NULL;
      struct vm_device * nvram = create_nvram();
      //struct vm_device * timer = create_timer();
      struct vm_device * pic = create_pic();
      struct vm_device * keyboard = create_keyboard();
      struct vm_device * pit = create_pit(); 
      //struct vm_device * serial = create_serial();
+     struct vm_device * generic = NULL;
+     if (use_ramdisk) {
+       PrintDebug("Creating Ramdisk\n");
+       ramdisk = create_ramdisk();
+       cdrom = v3_create_cdrom(ramdisk, config_ptr->ramdisk, config_ptr->ramdisk_size); 
+     }
      
      
- #define GENERIC 1
-     
- #if GENERIC
-     generic_port_range_type range[] = {
- #if 1
+     if (use_generic) {
+       PrintDebug("Creating Generic Device\n");
+       generic = create_generic();
+       
        // Make the DMA controller invisible
-       {0x00, 0x07, GENERIC_PRINT_AND_IGNORE},   // DMA 1 channels 0,1,2,3 (address, counter)
-       {0xc0, 0xc7, GENERIC_PRINT_AND_IGNORE},   // DMA 2 channels 4,5,6,7 (address, counter)
-       {0x87, 0x87, GENERIC_PRINT_AND_IGNORE},   // DMA 1 channel 0 page register
-       {0x83, 0x83, GENERIC_PRINT_AND_IGNORE},   // DMA 1 channel 1 page register
-       {0x81, 0x81, GENERIC_PRINT_AND_IGNORE},   // DMA 1 channel 2 page register
-       {0x82, 0x82, GENERIC_PRINT_AND_IGNORE},   // DMA 1 channel 3 page register
-       {0x8f, 0x8f, GENERIC_PRINT_AND_IGNORE},   // DMA 2 channel 4 page register
-       {0x8b, 0x8b, GENERIC_PRINT_AND_IGNORE},   // DMA 2 channel 5 page register
-       {0x89, 0x89, GENERIC_PRINT_AND_IGNORE},   // DMA 2 channel 6 page register
-       {0x8a, 0x8a, GENERIC_PRINT_AND_IGNORE},   // DMA 2 channel 7 page register
-       {0x08, 0x0f, GENERIC_PRINT_AND_IGNORE},   // DMA 1 misc registers (csr, req, smask,mode,clearff,reset,enable,mmask)
-       {0xd0, 0xde, GENERIC_PRINT_AND_IGNORE},   // DMA 2 misc registers
- #endif
+       v3_generic_add_port_range(generic, 0x00, 0x07, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channels 0,1,2,3 (address, counter)
+       v3_generic_add_port_range(generic, 0xc0, 0xc7, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channels 4,5,6,7 (address, counter)
+       v3_generic_add_port_range(generic, 0x87, 0x87, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 0 page register
+       v3_generic_add_port_range(generic, 0x83, 0x83, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 1 page register
+       v3_generic_add_port_range(generic, 0x81, 0x81, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 2 page register
+       v3_generic_add_port_range(generic, 0x82, 0x82, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 3 page register
+       v3_generic_add_port_range(generic, 0x8f, 0x8f, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 4 page register
+       v3_generic_add_port_range(generic, 0x8b, 0x8b, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 5 page register
+       v3_generic_add_port_range(generic, 0x89, 0x89, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 6 page register
+       v3_generic_add_port_range(generic, 0x8a, 0x8a, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 7 page register
+       v3_generic_add_port_range(generic, 0x08, 0x0f, GENERIC_PRINT_AND_IGNORE);   // DMA 1 misc registers (csr, req, smask,mode,clearff,reset,enable,mmask)
+       v3_generic_add_port_range(generic, 0xd0, 0xde, GENERIC_PRINT_AND_IGNORE);   // DMA 2 misc registers
+       
+       
+       
        
- #if 1      
        // Make the Serial ports invisible 
+       
+       v3_generic_add_port_range(generic, 0x3f8, 0x3f8+7, GENERIC_PRINT_AND_IGNORE);      // COM 1
+       v3_generic_add_port_range(generic, 0x2f8, 0x2f8+7, GENERIC_PRINT_AND_IGNORE);      // COM 2
+       
  
-       {0x3f8, 0x3f8+7, GENERIC_PRINT_AND_IGNORE},      // COM 1
-       {0x2f8, 0x2f8+7, GENERIC_PRINT_AND_IGNORE},      // COM 2
-       {0x3e8, 0x3e8+7, GENERIC_PRINT_AND_IGNORE},      // COM 3
-       {0x2e8, 0x2e8+7, GENERIC_PRINT_AND_IGNORE},      // COM 4
- #endif
+       
  
+       v3_generic_add_port_range(generic, 0x3e8, 0x3e8+7, GENERIC_PRINT_AND_IGNORE);      // COM 3
+       v3_generic_add_port_range(generic, 0x2e8, 0x2e8+7, GENERIC_PRINT_AND_IGNORE);      // COM 4
  
- #if 1
-       // Make the PCI bus invisible (at least it's configuration)
+       
+       
  
-       {0xcf8, 0xcf8, GENERIC_PRINT_AND_IGNORE}, // PCI Config Address
-       {0xcfc, 0xcfc, GENERIC_PRINT_AND_IGNORE}, // PCI Config Data
- #endif
-  
- #if 1
+       // Make the PCI bus invisible (at least it's configuration)
+       
+       v3_generic_add_port_range(generic, 0xcf8, 0xcf8, GENERIC_PRINT_AND_IGNORE); // PCI Config Address
+       v3_generic_add_port_range(generic, 0xcfc, 0xcfc, GENERIC_PRINT_AND_IGNORE); // PCI Config Data
  
-       // Monitor the IDE controllers (very slow)
+       
+       
+ #if 0
+       if (!use_ramdisk) {
+       // Monitor the IDE controllers (very slow)
+       v3_generic_add_port_range(generic, 0x170, 0x178, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 1
+       v3_generic_add_port_range(generic, 0x376, 0x377, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 1
+       }
+       
  
-       {0x170, 0x178, GENERIC_PRINT_AND_PASSTHROUGH}, // IDE 1
-       {0x376, 0x377, GENERIC_PRINT_AND_PASSTHROUGH}, // IDE 1
-       {0x1f0, 0x1f8, GENERIC_PRINT_AND_PASSTHROUGH}, // IDE 0
-       {0x3f6, 0x3f7, GENERIC_PRINT_AND_PASSTHROUGH}, // IDE 0
+       v3_generic_add_port_range(generic, 0x1f0, 0x1f8, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 0
+       v3_generic_add_port_range(generic, 0x3f6, 0x3f7, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 0
  #endif
        
+       
  #if 0
+       
        // Make the floppy controllers invisible
-       {0x3f0, 0x3f2, GENERIC_PRINT_AND_IGNORE}, // Primary floppy controller (base,statusa/statusb,DOR)
-       {0x3f4, 0x3f5, GENERIC_PRINT_AND_IGNORE}, // Primary floppy controller (mainstat/datarate,data)
-       {0x3f7, 0x3f7, GENERIC_PRINT_AND_IGNORE}, // Primary floppy controller (DIR)
-       {0x370, 0x372, GENERIC_PRINT_AND_IGNORE}, // Secondary floppy controller (base,statusa/statusb,DOR)
-       {0x374, 0x375, GENERIC_PRINT_AND_IGNORE}, // Secondary floppy controller (mainstat/datarate,data)
-       {0x377, 0x377, GENERIC_PRINT_AND_IGNORE}, // Secondary floppy controller (DIR)
+       
+       v3_generic_add_port_range(generic, 0x3f0, 0x3f2, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (base,statusa/statusb,DOR)
+       v3_generic_add_port_range(generic, 0x3f4, 0x3f5, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (mainstat/datarate,data)
+       v3_generic_add_port_range(generic, 0x3f7, 0x3f7, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (DIR)
+       v3_generic_add_port_range(generic, 0x370, 0x372, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (base,statusa/statusb,DOR)
+       v3_generic_add_port_range(generic, 0x374, 0x375, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (mainstat/datarate,data)
+       v3_generic_add_port_range(generic, 0x377, 0x377, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (DIR)
        
  #endif
  
  
        // Make the parallel port invisible
        
-       {0x378, 0x37f, GENERIC_PRINT_AND_IGNORE},
+       v3_generic_add_port_range(generic, 0x378, 0x37f, GENERIC_PRINT_AND_IGNORE);
  
  #endif
  
  
        // Monitor graphics card operations
  
-       {0x3b0, 0x3bb, GENERIC_PRINT_AND_PASSTHROUGH},
-       {0x3c0, 0x3df, GENERIC_PRINT_AND_PASSTHROUGH},
+       v3_generic_add_port_range(generic, 0x3b0, 0x3bb, GENERIC_PRINT_AND_PASSTHROUGH);
+       v3_generic_add_port_range(generic, 0x3c0, 0x3df, GENERIC_PRINT_AND_PASSTHROUGH);
        
  #endif
  
  #if 1
        // Make the ISA PNP features invisible
  
-       {0x274, 0x277, GENERIC_PRINT_AND_IGNORE},
-       {0x279, 0x279, GENERIC_PRINT_AND_IGNORE},
-       {0xa79, 0xa79, GENERIC_PRINT_AND_IGNORE},
+       v3_generic_add_port_range(generic, 0x274, 0x277, GENERIC_PRINT_AND_IGNORE);
+       v3_generic_add_port_range(generic, 0x279, 0x279, GENERIC_PRINT_AND_IGNORE);
+       v3_generic_add_port_range(generic, 0xa79, 0xa79, GENERIC_PRINT_AND_IGNORE);
  #endif
  
  
  #if 1
        // Monitor any network card (realtek ne2000) operations 
-       {0xc100, 0xc1ff, GENERIC_PRINT_AND_PASSTHROUGH},
+       v3_generic_add_port_range(generic, 0xc100, 0xc1ff, GENERIC_PRINT_AND_PASSTHROUGH);
  #endif
  
  
  #if 1
        // Make any Bus master ide controller invisible
        
-       {0xc000, 0xc00f, GENERIC_PRINT_AND_IGNORE},
+       v3_generic_add_port_range(generic, 0xc000, 0xc00f, GENERIC_PRINT_AND_IGNORE);
  #endif
-       //        {0x378, 0x400, GENERIC_PRINT_AND_IGNORE}
        
-       {0,0,0},  // sentinal - must be last
+     }
+       //  v3_generic_add_port_range(generic, 0x378, 0x400, GENERIC_PRINT_AND_IGNORE);
        
-     };
-     
  
-     struct vm_device * generic = create_generic(range, NULL, NULL);
-     
- #endif
      
      v3_attach_device(info, nvram);
      //v3_attach_device(info, timer);
      v3_attach_device(info, pic);
      v3_attach_device(info, keyboard);
      // v3_attach_device(info, serial);
  
+     if (use_ramdisk) {
+       v3_attach_device(info, ramdisk);
+       v3_attach_device(info, cdrom);
+     }
  
- #if GENERIC
-     // Important that this be attached last!
-     v3_attach_device(info, generic);
-     
- #endif
+     if (use_generic) {
+       // Important that this be attached last!
+       v3_attach_device(info, generic);
+     }
      
      PrintDebugDevMgr(info);
    }
    // no longer needed since we have a keyboard device
    //hook_irq(&vm_info, 1);
    
- #if 1
+ #if 0
    // give floppy controller to vm
-   v3_hook_irq_for_guest_injection(info, 6);
+   v3_hook_passthrough_irq(info, 6);
  #endif
    
- #if 1
-   //primary ide
-   v3_hook_irq_for_guest_injection(info, 14);
-   
-   // secondary ide
-   v3_hook_irq_for_guest_injection(info, 15);
- #endif
+   if (!use_ramdisk) {
+     //primary ide
+     v3_hook_passthrough_irq(info, 14);
    
+     // secondary ide
+     v3_hook_passthrough_irq(info, 15);    
+   }  
  
    //v3_hook_io_port(info, 1234, &IO_Read, NULL, info);
  
  
    return 0;
  }
- #if 0
-     
-     if (0) {
-       
-       //    add_shared_mem_range(&(vm_info.mem_layout), 0, 0x800000, 0x10000);    
-       //    add_shared_mem_range(&(vm_info.mem_layout), 0, 0x1000000, 0);
-       
-       rip = (ulong_t)(void*)&BuzzVM;
-       //  rip -= 0x10000;
-       //    rip = (addr_t)(void*)&exit_test;
-       //  rip -= 0x2000;
-       vm_info.rip = rip;
-       rsp = (addr_t)Alloc_Page();
-       
-       vm_info.vm_regs.rsp = (rsp +4092 );// - 0x2000;
-       
-             
-     } else if (0) {
-       //add_shared_mem_range(&(vm_info.mem_layout), 0x0, 0x1000, 0x100000);
-       //      add_shared_mem_range(&(vm_info.mem_layout), 0x0, 0x100000, 0x0);
-       
-       /*
-       shadow_region_t *ent = Malloc(sizeof(shadow_region_t));;
-       init_shadow_region_physical(ent,0,0x100000,GUEST_REGION_PHYSICAL_MEMORY,
-       0x100000, HOST_REGION_PHYSICAL_MEMORY);
-       add_shadow_region(&(vm_info.mem_map),ent);
-       */
-       add_shadow_region_passthrough(&vm_info, 0x0, 0x100000, 0x100000);
-       v3_hook_io_port(&vm_info, 0x61, &IO_Read, &IO_Write, NULL);
-       v3_hook_io_port(&vm_info, 0x05, &IO_Read, &IO_Write_to_Serial, NULL);
-       
-       /*
-       vm_info.cr0 = 0;
-       vm_info.cs.base=0xf000;
-       vm_info.cs.limit=0xffff;
-       */
-       //vm_info.rip = 0xfff0;
-       vm_info.rip = 0;
-       vm_info.vm_regs.rsp = 0x0;
-     } else {
-    
-     }
- #endif