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.


integrated new configuration system
Jack Lange [Tue, 1 Dec 2009 01:04:44 +0000 (19:04 -0600)]
71 files changed:
Kconfig
palacios/include/devices/block_dev.h [deleted file]
palacios/include/devices/cga.h [deleted file]
palacios/include/devices/generic.h [deleted file]
palacios/include/devices/ide.h
palacios/include/devices/lnx_virtio_blk.h [deleted file]
palacios/include/devices/net_cd.h [deleted file]
palacios/include/devices/net_hd.h [deleted file]
palacios/include/devices/pci.h
palacios/include/devices/pci_passthrough.h [deleted file]
palacios/include/devices/ram_cd.h [deleted file]
palacios/include/devices/ram_hd.h [deleted file]
palacios/include/devices/telnet_cons.h [deleted file]
palacios/include/palacios/svm.h
palacios/include/palacios/vm_guest.h
palacios/include/palacios/vmm.h
palacios/include/palacios/vmm_config.h
palacios/include/palacios/vmm_dev_mgr.h
palacios/include/palacios/vmm_string.h
palacios/include/palacios/vmm_sym_iface.h
palacios/include/palacios/vmx.h
palacios/src/devices/8254.c
palacios/src/devices/8259a.c
palacios/src/devices/Kconfig
palacios/src/devices/Makefile
palacios/src/devices/apic.c
palacios/src/devices/ata.h
palacios/src/devices/atapi.h
palacios/src/devices/bochs_debug.c
palacios/src/devices/cga.c
palacios/src/devices/cirrus_gfx_card.c
palacios/src/devices/generic.c
palacios/src/devices/i440fx.c
palacios/src/devices/ide.c
palacios/src/devices/io_apic.c
palacios/src/devices/keyboard.c
palacios/src/devices/lnx_virtio_balloon.c
palacios/src/devices/lnx_virtio_blk.c
palacios/src/devices/lnx_virtio_sym.c
palacios/src/devices/net_cd.c [deleted file]
palacios/src/devices/netdisk.c [moved from palacios/src/devices/net_hd.c with 55% similarity]
palacios/src/devices/nvram.c
palacios/src/devices/os_debug.c
palacios/src/devices/para_net.c
palacios/src/devices/pci.c
palacios/src/devices/pci_passthrough.c
palacios/src/devices/piix3.c
palacios/src/devices/ram_cd.c [deleted file]
palacios/src/devices/ram_hd.c [deleted file]
palacios/src/devices/ramdisk.c [new file with mode: 0644]
palacios/src/devices/sym_swap.c
palacios/src/devices/telnet_cons.c
palacios/src/devices/tmp_blk.c [deleted file]
palacios/src/devices/tmpdisk.c [new file with mode: 0644]
palacios/src/palacios/svm.c
palacios/src/palacios/svm_msr.c
palacios/src/palacios/vmm.c
palacios/src/palacios/vmm_config.c
palacios/src/palacios/vmm_config_class.h [new file with mode: 0644]
palacios/src/palacios/vmm_cpuid.c
palacios/src/palacios/vmm_dev_mgr.c
palacios/src/palacios/vmm_excp.c
palacios/src/palacios/vmm_host_events.c
palacios/src/palacios/vmm_hypercall.c
palacios/src/palacios/vmm_io.c
palacios/src/palacios/vmm_mem.c
palacios/src/palacios/vmm_string.c
palacios/src/palacios/vmm_sym_iface.c
palacios/src/palacios/vmm_sym_swap.c
palacios/src/palacios/vmm_time.c
palacios/src/palacios/vmm_xml.c

diff --git a/Kconfig b/Kconfig
index 1b7c7b7..c6446e5 100644 (file)
--- a/Kconfig
+++ b/Kconfig
@@ -166,6 +166,14 @@ config BUILT_IN_STRCMP
        help 
          This enables Palacios' internal implementation of strcmp
 
+
+config BUILT_IN_STRCASECMP
+       bool "strcasecmp()"
+       default n
+       depends on BUILT_IN_STDLIB
+       help
+         This enables Palacios' internal implementation of strcasecmp
+
 config BUILT_IN_STRNCMP
        bool "strncmp()"
        default n
@@ -173,6 +181,14 @@ config BUILT_IN_STRNCMP
        help 
          This enables Palacios' internal implementation of strncmp
 
+config BUILT_IN_STRNCASECMP
+       bool "strncasecmp()"
+       default n
+       depends on BUILT_IN_STDLIB
+       help
+         This enables Palacios' internal implementation of strncasecmp
+
+
 config BUILT_IN_STRCAT
        bool "strcat()"
        default n
diff --git a/palacios/include/devices/block_dev.h b/palacios/include/devices/block_dev.h
deleted file mode 100644 (file)
index 574c5af..0000000
+++ /dev/null
@@ -1,66 +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) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software.  You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#ifndef __DEVICES_BLOCK_DEV_H__
-#define __DEVICES_BLOCK_DEV_H__
-
-#ifdef __V3VEE__
-
-
-
-#define ATAPI_BLOCK_SIZE 2048
-#define HD_SECTOR_SIZE 512
-
-
-struct v3_hd_ops {
-    uint64_t (*get_capacity)(void * private_data);
-    // Reads always operate on 2048 byte blocks
-    int (*read)(uint8_t * buf, int sector_count, uint64_t lba, void * private_data);
-    int (*write)(uint8_t * buf, int sector_count, uint64_t lba, void * private_data);
-};
-
-
-
-struct v3_cd_ops {
-    uint32_t (*get_capacity)(void * private_data);
-    // Reads always operate on 2048 byte blocks
-    int (*read)(uint8_t * buf, int block_count, uint64_t lba, void * private_data);
-};
-
-
-typedef enum {BLOCK_NONE, BLOCK_DISK, BLOCK_CDROM} v3_block_type_t;
-
-
-
-static const char * block_dev_type_strs[] = {"NONE", "HARDDISK", "CDROM" };
-
-static inline const char * v3_block_type_to_str(v3_block_type_t type) {
-    if (type > BLOCK_CDROM) {
-       return NULL;
-    }
-    return block_dev_type_strs[type];
-}
-
-
-
-#endif
-
-
-#endif
diff --git a/palacios/include/devices/cga.h b/palacios/include/devices/cga.h
deleted file mode 100644 (file)
index b2c168c..0000000
+++ /dev/null
@@ -1,32 +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) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software.  You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#ifndef __DEVICES_CGA_H__
-#define __DEVICES_CGA_H__
-
-#ifdef __V3VEE__
-
-#include <devices/console.h>
-
-
-int v3_console_register_cga(struct vm_device * cga_dev, struct v3_console_ops * ops, void * private_data);
-
-#endif
-
-#endif
diff --git a/palacios/include/devices/generic.h b/palacios/include/devices/generic.h
deleted file mode 100644 (file)
index 77d3822..0000000
+++ /dev/null
@@ -1,61 +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) 2008, Peter Dinda <pdinda@northwestern.edu> 
- * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
- * All rights reserved.
- *
- * Author: Peter Dinda <pdinda@northwestern.edu>
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software.  You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-
-#ifndef __DEVICES_GENERIC_H__
-#define __DEVICES_GENERIC_H__
-
-#ifdef __V3VEE__
-
-#include <palacios/vmm_dev_mgr.h>
-
-
-//
-// The generic device simply hooks ranges of ports, addresses, and irqs
-// if they are not already hooked
-//
-// for each hooked port, it simply executes reads and writes and the same physical port,
-// for each hooked memory range, it simply executes reads and writes on the same
-//    physical memory addresses
-// for each hooked irq, it simply injects the irq into the VM
-//
-// These operations are also logged to serial (optionaly)
-//
-// If you attach a generic device *last*, you can capture all ops that are not
-// already hooked, and capture a log of VM activity with respect to them.
-//
-// The effects of using the generic device should be identical to 
-// doing passthrough I/O, but with logging, and, of course, slower
-//
-
-
-#define GENERIC_PRINT_AND_PASSTHROUGH 0
-#define GENERIC_PRINT_AND_IGNORE      1
-
-
-int v3_generic_add_port_range(struct vm_device * dev, uint_t start, uint_t end, uint_t type);
-
-
-
-#endif // ! __V3VEE__
-
-#endif
index b778f1e..8f8951d 100644 (file)
 
 #ifdef __V3VEE__
 
-#include <devices/block_dev.h>
-
-struct ide_cfg {
-    char pci[32];
-    char southbridge[32];
-};
-
-
-int v3_ide_register_cdrom(struct vm_device * ide, 
-                         uint_t bus_num, 
-                         uint_t drive_num, 
-                         char * drive_name,
-                         struct v3_cd_ops * ops, 
-                         void * private_data);
-
-int v3_ide_register_harddisk(struct vm_device * ide, 
-                            uint_t bus_num, 
-                            uint_t drive_num, 
-                            char * drive_name,
-                            struct v3_hd_ops * ops, 
-                            void * private_data);
-
-
-
 
 
 int v3_ide_get_geometry(struct vm_device * ide_dev, int channel_num, int drive_num, 
diff --git a/palacios/include/devices/lnx_virtio_blk.h b/palacios/include/devices/lnx_virtio_blk.h
deleted file mode 100644 (file)
index 1bcf08c..0000000
+++ /dev/null
@@ -1,40 +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) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software.  You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#ifndef __DEVICES_LNX_VIRTIO_BLK_H__
-#define __DEVICES_LNX_VIRTIO_BLK_H__
-
-#ifdef __V3VEE__
-
-#include <devices/block_dev.h>
-
-int v3_virtio_register_cdrom(struct vm_device * dev, 
-                            struct v3_cd_ops * ops, 
-                            void * private_data);
-
-
-int v3_virtio_register_harddisk(struct vm_device * dev, 
-                               struct v3_hd_ops * ops, 
-                               void * private_data);
-                            
-
-#endif
-
-
-#endif
diff --git a/palacios/include/devices/net_cd.h b/palacios/include/devices/net_cd.h
deleted file mode 100644 (file)
index d1f8a31..0000000
+++ /dev/null
@@ -1,39 +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) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software.  You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#ifndef __DEVICES_NET_CD_H__
-#define __DEVICES_NET_CD_H__
-
-#ifdef __V3VEE__
-
-
-struct net_cd_cfg {
-    char ide[32];
-    uint_t bus;
-    uint_t drive;
-    const char * ip_str;
-    uint16_t port;
-    const char * disk_tag;
-};
-
-
-
-#endif
-
-#endif
diff --git a/palacios/include/devices/net_hd.h b/palacios/include/devices/net_hd.h
deleted file mode 100644 (file)
index 2a57832..0000000
+++ /dev/null
@@ -1,40 +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) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software.  You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#ifndef __DEVICES_NET_HD_H__
-#define __DEVICES_NET_HD_H__
-
-#ifdef __V3VEE__
-
-
-
-struct net_hd_cfg {
-    char ide[32];
-    uint_t bus;
-    uint_t drive;
-    const char * ip_str; 
-    uint16_t port;
-    const char * disk_tag;
-};
-
-
-
-#endif
-
-#endif
index 9e329b8..1da7102 100644 (file)
@@ -30,6 +30,8 @@
 
 #include <devices/pci_types.h>
 
+struct vm_device;
+
 
 typedef enum { PCI_BAR_IO, 
               PCI_BAR_MEM24, 
diff --git a/palacios/include/devices/pci_passthrough.h b/palacios/include/devices/pci_passthrough.h
deleted file mode 100644 (file)
index 8ac8580..0000000
+++ /dev/null
@@ -1,36 +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) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software.  You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#ifndef __DEVICES_PCI_PASSTHROUGH_H__
-#define __DEVICES_PCI_PASSTHROUGH_H__
-
-#ifdef __V3VEE__
-
-struct pci_passthrough_cfg {
-    char pci_bus_name[32];
-
-    char name[32];
-    uint16_t   vendor_id;
-    uint16_t   device_id;
-};
-
-
-#endif
-
-#endif
diff --git a/palacios/include/devices/ram_cd.h b/palacios/include/devices/ram_cd.h
deleted file mode 100644 (file)
index c105394..0000000
+++ /dev/null
@@ -1,39 +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) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software.  You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#ifndef __DEVICES_RAM_CD_H__
-#define __DEVICES_RAM_CD_H__
-
-#ifdef __V3VEE__
-
-
-
-struct ram_cd_cfg {
-    char ide[32]; 
-    uint_t bus;
-    uint_t drive;
-    addr_t ramdisk;
-    uint32_t size;
-};
-
-
-
-#endif
-
-#endif
diff --git a/palacios/include/devices/ram_hd.h b/palacios/include/devices/ram_hd.h
deleted file mode 100644 (file)
index 4c4fdad..0000000
+++ /dev/null
@@ -1,37 +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) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software.  You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#ifndef __DEVICES_RAM_HD_H__
-#define __DEVICES_RAM_HD_H__
-
-#ifdef __V3VEE__
-
-struct ram_hd_cfg {
-    char ide[32];
-    uint_t bus; 
-    uint_t drive;
-    addr_t ramdisk;
-    uint32_t size;
-};
-
-
-
-#endif
-
-#endif
diff --git a/palacios/include/devices/telnet_cons.h b/palacios/include/devices/telnet_cons.h
deleted file mode 100644 (file)
index afca897..0000000
+++ /dev/null
@@ -1,36 +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) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software.  You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#ifndef __DEVICES_TELNET_CONS_H__
-#define __DEVICES_TELNET_CONS_H__
-
-#ifdef __V3VEE__
-
-
-
-struct telnet_cons_cfg {
-    char frontend[32];
-    uint16_t port;
-};
-
-
-
-#endif
-
-#endif
index 3780b95..1a9ecfd 100644 (file)
 
 
 void v3_init_svm_cpu(int cpu_id);
-void v3_init_svm_hooks(struct v3_ctrl_ops * vmm_ops);
 int v3_is_svm_capable();
 
+int v3_init_svm_vmcb(struct guest_info * info, v3_vm_class_t vm_class);
+
 int v3_svm_enter(struct guest_info * info);
+int v3_start_svm_guest(struct guest_info *info);
 
 #endif
 
index b5d481c..6506658 100644 (file)
@@ -48,6 +48,8 @@
 
 
 
+
+
 struct v3_gprs {
     v3_reg_t rdi;
     v3_reg_t rsi;
@@ -124,6 +126,8 @@ struct v3_segments {
 #include <palacios/vmm_sym_iface.h>
 #endif
 
+#include <palacios/vmm_config.h>
+
 struct shadow_page_state;
 struct v3_intr_state;
 
@@ -147,6 +151,8 @@ struct guest_info {
     addr_t mem_size; // In bytes for now
     v3_shdw_map_t mem_map;
 
+    struct v3_config * cfg_data;
+    v3_vm_class_t vm_class;
 
     struct vm_time time_state;
 
index 6fbbe7d..87d50ed 100644 (file)
 #define __VMM_H__
 
 
-#include <palacios/vm_guest.h>
+//#include <palacios/vm_guest.h>
 #include <palacios/vmm_mem.h>
 #include <palacios/vmm_types.h>
 
+struct guest_info;
 
 
 #ifdef __V3VEE__
 
 
 
-#define VMM_INVALID_CPU 0
-#define VMM_VMX_CPU 1
-#define VMM_SVM_CPU 2
+
+typedef enum v3_vm_class {V3_INVALID_VM, V3_PC_VM, V3_CRAY_VM} v3_vm_class_t;
 
 
 // Maybe make this a define....
@@ -200,6 +200,11 @@ void v3_yield_cond(struct guest_info * info);
 
 void v3_interrupt_cpu(struct guest_info * vm, int logical_cpu);
 
+unsigned int v3_get_cpu_id();
+
+v3_cpu_arch_t v3_get_cpu_type(int cpu_id);
+
+
 int v3_vm_enter(struct guest_info * info);
 
 
@@ -238,6 +243,7 @@ struct v3_os_hooks {
     void (*mutex_lock)(void * mutex, int must_spin);
     void (*mutex_unlock)(void * mutex);
 
+    unsigned int (*get_cpu)(void);
     void (*interrupt_cpu)(struct guest_info * vm, int logical_cpu);
     void (*call_on_cpu)(int logical_cpu, void (*fn)(void * arg), void * arg);
     void (*start_thread_on_cpu)(int logical_cpu, int (*fn)(void * arg), void * arg, char * thread_name);
@@ -245,62 +251,6 @@ struct v3_os_hooks {
 
 
 
-typedef enum {NONE, HARDDRIVE, CDROM, VIRTIO} v3_disk_type_t;
-typedef enum {RAM, NETWORK} v3_disk_connection_t;
-
-union v3_disk_info {
-    struct {
-       void * data_ptr;
-       int size;
-    } ram;
-
-    struct {
-       char * ip_str;
-       int port;
-       char * disk_name;
-    } net;
-};
-
-struct v3_vm_config {
-
-    unsigned long mem_size; // in bytes, var should be natural size of cpu
-    // so we can specify maximum physical address size
-    // (We're screwed if we want to do 32 bit host/64 bit guest)
-
-    int enable_telemetry;
-    int enable_nested_paging;
-
-    int enable_pci;
-
-    int enable_swap;
-
-    int guest_cpu;
-
-    unsigned long schedule_freq; // in HZ
-
-    v3_disk_type_t pri_disk_type;
-    v3_disk_connection_t pri_disk_con;
-    union v3_disk_info pri_disk_info;
-   
-    v3_disk_type_t sec_disk_type;
-    v3_disk_connection_t sec_disk_con;
-    union v3_disk_info sec_disk_info;
-};
-
-
-
-/* This will contain Function pointers that control the VMs */
-struct v3_ctrl_ops {
-    struct guest_info *(*allocate_guest)(void);
-
-    int (*init_guest)(struct guest_info * info, struct v3_vm_config * config_ptr);
-    int (*start_guest)(struct guest_info * info);
-    //  int (*stop_vm)(uint_t vm_id);
-
-    int (*has_nested_paging)(void);
-
-    //  v3_cpu_arch_t (*get_cpu_arch)();
-};
 
 
 
@@ -320,7 +270,11 @@ struct v3_interrupt {
 
 
 
-void Init_V3(struct v3_os_hooks * hooks, struct v3_ctrl_ops * vmm_ops, int num_cpus);
+void Init_V3(struct v3_os_hooks * hooks,  int num_cpus);
+
+
+int v3_start_vm(struct guest_info * info, unsigned int cpu_mask);
+struct guest_info * v3_create_vm(void * cfg);
 
 int v3_deliver_irq(struct guest_info * vm, struct v3_interrupt * intr);
 
index 716e5b6..a719cf5 100644 (file)
 
 #ifdef __V3VEE__
 
-#include <palacios/vm_guest.h>
+//#include <palacios/vm_guest.h>
 #include <palacios/vmm.h>
+#include <palacios/vmm_xml.h>
+#include <palacios/vmm_list.h>
+#include <palacios/vmm_hashtable.h>
+//#include <palacios/svm.h>
 
 
-int v3_pre_config_guest(struct guest_info * info, struct v3_vm_config * config_ptr);
-int v3_post_config_guest(struct guest_info * info, struct v3_vm_config * config_ptr);
+struct guest_info;
 
+int v3_config_guest(struct guest_info * info, void * cfg_blob);
 
+struct v3_cfg_file {
+    void * data;
+    uint64_t size;
 
-#endif // ! __V3VEE__
+    char tag[256];
+
+    struct list_head file_node;
+};
+
+
+
+typedef struct v3_xml v3_cfg_tree_t;
+
+struct v3_config {
+    v3_cfg_tree_t * cfg;
 
+    struct list_head file_list;
+    struct hashtable * file_table;
 
+    void * blob;
+};
+
+
+struct v3_cfg_file * v3_cfg_get_file(struct guest_info * info, char * tag);
+
+char * v3_cfg_val(v3_cfg_tree_t * tree, char * tag);
+v3_cfg_tree_t * v3_cfg_subtree(v3_cfg_tree_t * tree, char * tag);
+v3_cfg_tree_t * v3_cfg_next_branch(v3_cfg_tree_t * tree);
+
+#endif // ! __V3VEE__
 
 #endif
index 9495861..dd62093 100644 (file)
@@ -26,6 +26,7 @@
 #include <palacios/vmm_list.h>
 #include <palacios/vmm_string.h>
 #include <palacios/vmm_hashtable.h>
+#include <palacios/vmm_config.h>
 
 
 struct guest_info;
@@ -53,14 +54,23 @@ struct vm_device {
 struct vmm_dev_mgr {
     uint_t num_devs;
     struct list_head dev_list;
-
     struct hashtable * dev_table;
+
+    struct list_head blk_list;
+    struct hashtable * blk_table;
+
+    struct list_head net_list;
+    struct hashtable * net_table;
+
+    struct list_head console_list;
+    struct hashtable * console_table;
+
 };
 
 
 
 
-int v3_create_device(struct guest_info * info, const char * dev_name, void * cfg_data);
+int v3_create_device(struct guest_info * info, const char * dev_name, v3_cfg_tree_t * cfg);
 void v3_free_device(struct vm_device * dev);
 
 
@@ -121,7 +131,7 @@ struct vm_device * v3_allocate_device(char * name, struct v3_device_ops * ops, v
 
 struct v3_device_info {
     char * name;
-    int (*init)(struct guest_info * info, void * cfg_data);
+    int (*init)(struct guest_info * info, v3_cfg_tree_t * cfg);
 };
 
 
@@ -136,11 +146,51 @@ struct v3_device_info {
 
 
 
-void PrintDebugDevMgr(struct guest_info * info);
-void PrintDebugDev(struct vm_device * dev);
+void v3_print_dev_mgr(struct guest_info * info);
+
 
+struct v3_dev_blk_ops {
+    uint64_t (*get_capacity)(void * private_data);
+    // Reads always operate on 2048 byte blocks
+    int (*read)(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * private_data);
+    int (*write)(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * private_data);
+};
+
+struct v3_dev_net_ops {
+
+};
+
+struct v3_dev_console_ops {
 
+};
 
+int v3_dev_add_blk_frontend(struct guest_info * info, 
+                           char * name, 
+                           int (*connect)(struct guest_info * info, 
+                                           void * frontend_data, 
+                                           struct v3_dev_blk_ops * ops, 
+                                           v3_cfg_tree_t * cfg, 
+                                           void * private_data), 
+                           void * priv_data);
+int v3_dev_connect_blk(struct guest_info * info, 
+                      char * frontend_name, 
+                      struct v3_dev_blk_ops * ops, 
+                      v3_cfg_tree_t * cfg, 
+                      void * private_data);
+
+int v3_dev_add_net_frontend(struct guest_info * info, 
+                           char * name, 
+                           int (*connect)(struct guest_info * info, 
+                                           void * frontend_data, 
+                                           struct v3_dev_net_ops * ops, 
+                                           v3_cfg_tree_t * cfg, 
+                                           void * private_data), 
+                           void * priv_data);
+int v3_dev_connect_net(struct guest_info * info, 
+                      char * frontend_name, 
+                      struct v3_dev_net_ops * ops, 
+                      v3_cfg_tree_t * cfg, 
+                      void * private_data);
 
 
 #endif // ! __V3VEE__
index 0b5d270..78c3cf0 100644 (file)
@@ -44,7 +44,9 @@ int memcmp(const void *s1, const void *s2, size_t n);
 size_t strlen(const char* s);
 size_t strnlen(const char *s, size_t maxlen);
 int strcmp(const char* s1, const char* s2);
+int strcasecmp(const char* s1, const char* s2);
 int strncmp(const char* s1, const char* s2, size_t limit);
+int strncasecmp(const char* s1, const char* s2, size_t limit);
 char *strcat(char *s1, const char *s2);
 char *strncat(char *s1, const char *s2, size_t limit);
 char *strcpy(char *dest, const char *src);
@@ -62,8 +64,12 @@ size_t strspn(const char * s, const char * accept);
 size_t strcspn(const char * s, const char * reject);
 char * strstr(const char * haystack, const char * needle);
 
+void str_tolower(char * s);
+void str_toupper(char * s);
 
-#define isspace(c)           (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v')
+
+
+#define isspace(c)      (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v')
 #define isascii(c)     (((c) & ~0x7f) == 0)
 #define isupper(c)     ((c) >= 'A' && (c) <= 'Z')
 #define islower(c)     ((c) >= 'a' && (c) <= 'z')
index 6c96dab..5de9720 100644 (file)
 
 #ifdef __V3VEE__
 
-#include <palacios/vm_guest.h>
-
 
 
 struct v3_sym_interface {
     uint64_t magic;
 
-
     union {
        uint32_t feature_flags;
        struct {
-           uint_t pci_map_valid          : 1;
+           uint_t pci_map_valid            : 1;
            uint32_t sym_call_enabled       : 1;
        } __attribute__((packed));
     } __attribute__((packed));
@@ -51,13 +48,12 @@ struct v3_sym_interface {
     
     uint8_t pci_pt_map[(4 * 256) / 8]; // we're hardcoding this: (4 busses, 256 max devs)
 
-
-
-
 } __attribute__((packed));
 
 
 
+#include <palacios/vm_guest.h>
+
 
 struct v3_sym_context {
     struct v3_gprs vm_regs;
@@ -71,7 +67,6 @@ struct v3_sym_context {
 };
 
 
-
 struct v3_sym_state {
     
     struct v3_sym_interface * sym_page;
@@ -97,6 +92,12 @@ struct v3_sym_state {
     uint64_t sym_call_fs;
 };
 
+
+
+
+
+
+
 int v3_init_sym_iface(struct guest_info * info);
 
 
index 67e546b..a34cd46 100644 (file)
@@ -1,4 +1,5 @@
 
+
 /* 
  * This file is part of the Palacios Virtual Machine Monitor developed
  * by the V3VEE Project with funding from the United States National 
@@ -230,7 +231,6 @@ struct vmx_data {
 };
 
 int v3_is_vmx_capable();
-void v3_init_vmx_hooks(struct v3_ctrl_ops * vm_ops);
 void v3_init_vmx_cpu(int cpu_id);
 
 
index c205752..4b2f4c0 100644 (file)
@@ -23,7 +23,7 @@
 #include <palacios/vmm_time.h>
 #include <palacios/vmm_util.h>
 #include <palacios/vmm_intr.h>
-
+#include <palacios/vmm_config.h>
 
 
 #ifndef CONFIG_DEBUG_PIT
@@ -631,9 +631,10 @@ static struct v3_device_ops dev_ops = {
 };
 
 
-static int pit_init(struct guest_info * info, void * cfg_data) {
+static int pit_init(struct guest_info * info, v3_cfg_tree_t * cfg) {
     struct pit * pit_state = NULL;
     struct vm_device * dev = NULL;
+    char * name = v3_cfg_val(cfg, "name");
 
     uint_t cpu_khz = V3_CPU_KHZ();
     ullong_t reload_val = (ullong_t)cpu_khz * 1000;
@@ -641,10 +642,10 @@ static int pit_init(struct guest_info * info, void * cfg_data) {
     pit_state = (struct pit *)V3_Malloc(sizeof(struct pit));
     V3_ASSERT(pit_state != NULL);
 
-    dev = v3_allocate_device("PIT", &dev_ops, pit_state);
+    dev = v3_allocate_device(name, &dev_ops, pit_state);
 
     if (v3_attach_device(info, dev) == -1) {
-       PrintError("Could not attach device %s\n", "PIT");
+       PrintError("Could not attach device %s\n", name);
        return -1;
     }
 
index d1944f6..443fb0a 100644 (file)
@@ -715,15 +715,17 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int pic_init(struct guest_info * vm, void * cfg_data) {
+static int pic_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
     struct pic_internal * state = NULL;
     state = (struct pic_internal *)V3_Malloc(sizeof(struct pic_internal));
+    char * name = v3_cfg_val(cfg, "name");
+
     V3_ASSERT(state != NULL);
 
-    struct vm_device * dev = v3_allocate_device("8259A", &dev_ops, state);
+    struct vm_device * dev = v3_allocate_device(name, &dev_ops, state);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", "8259A");
+       PrintError("Could not attach device %s\n", name);
        return -1;
     }
 
index dde39ab..4a51101 100644 (file)
@@ -150,19 +150,7 @@ config DEBUG_NE2k
          Enable debugging for the NE2K
 
 
-config NET_CD
-       bool "Networked CD backend"
-       default y
-       depends on SOCKET && (IDE || LINUX_VIRTIO_BLOCK)
-       help 
-         Includes the Network CD backend
 
-config NET_HD
-       bool "Networked HD backend"
-       default y
-       depends on SOCKET && (IDE || LINUX_VIRTIO_BLOCK)
-       help 
-         Includes the Network HD backend
 
 
 config NVRAM
@@ -240,24 +228,27 @@ config DEBUG_PIT
          Enable debugging for the PIT  
 
 
-
-
-config RAM_CD
-       bool "RAM based CD backend"
+config NETDISK
+       bool "NETDISK storage backend"
        default y
-       depends on IDE || LINUX_VIRTIO_BLOCK
+       depends on SOCKET && (IDE || LINUX_VIRTIO_BLOCK)
        help 
-         Includes the RAM based CD backend
+         Includes the Network based disk backend
 
-config RAM_HD
-       bool "RAM based HD backend"
+config RAMDISK
+       bool "RAMDISK storage backend"
        default y
        depends on IDE || LINUX_VIRTIO_BLOCK
        help 
-         Includes the RAM based HD backend
-
+         Includes the RAM based disk backend
 
 
+config TMPDISK
+       bool "TMPDISK storage backend"
+       default y
+       depends on IDE || LINUX_VIRTIO_BLOCK
+       help 
+         Includes the temporary RAM disk 
 
 config SYM_SWAP
        bool "Symbiotic Swap disk"
index 515b088..894a1f2 100644 (file)
@@ -14,14 +14,13 @@ obj-$(CONFIG_NVRAM) += nvram.o
 obj-$(CONFIG_OS_DEBUG) += os_debug.o
 obj-$(CONFIG_PCI) += pci.o
 obj-$(CONFIG_PIIX3) += piix3.o
-obj-$(CONFIG_RAM_CD) += ram_cd.o
-obj-$(CONFIG_RAM_HD) += ram_hd.o
-obj-$(CONFIG_SYM_SWAP) += sym_swap.o tmp_blk.o
+obj-$(CONFIG_SYM_SWAP) += sym_swap.o
 
 obj-$(CONFIG_NE2K) += ne2k.o
 
-obj-$(CONFIG_NET_CD) += net_cd.o 
-obj-$(CONFIG_NET_HD) += net_hd.o 
+obj-$(CONFIG_TMPDISK) += tmpdisk.o
+obj-$(CONFIG_RAMDISK) += ramdisk.o 
+obj-$(CONFIG_NETDISK) += netdisk.o 
 
 obj-$(CONFIG_CGA) += cga.o
 obj-$(CONFIG_TELNET_CONSOLE) += telnet_cons.o
index bbef7e2..ccb89e3 100644 (file)
@@ -22,7 +22,7 @@
 #include <devices/apic_regs.h>
 #include <palacios/vmm.h>
 #include <palacios/vmm_msr.h>
-
+#include <palacios/vm_guest.h>
 
 #ifndef CONFIG_DEBUG_APIC
 #undef PrintDebug
@@ -1072,15 +1072,16 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int apic_init(struct guest_info * vm, void * cfg_data) {
+static int apic_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
     PrintDebug("Creating APIC\n");
+    char * name = v3_cfg_val(cfg, "name");
 
     struct apic_state * apic = (struct apic_state *)V3_Malloc(sizeof(struct apic_state));
 
-    struct vm_device * dev = v3_allocate_device("LAPIC", &dev_ops, apic);
+    struct vm_device * dev = v3_allocate_device(name, &dev_ops, apic);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", "LAPIC");
+       PrintError("Could not attach device %s\n", name);
        return -1;
     }
 
index 5cdb737..4cf6cd2 100644 (file)
@@ -64,10 +64,10 @@ static void ata_identify_device(struct ide_drive * drive) {
     drive_id->lba_enable = 1;
     
     // Drive Capacity (28 bit LBA)
-    drive_id->lba_capacity = drive->hd_ops->get_capacity(drive->private_data);
+    drive_id->lba_capacity = drive->ops->get_capacity(drive->private_data);
     
     // Drive Capacity (48 bit LBA)
-    drive_id->lba_capacity_2 = drive->hd_ops->get_capacity(drive->private_data);
+    drive_id->lba_capacity_2 = drive->ops->get_capacity(drive->private_data);
 
 
     // lower byte is the maximum multiple sector size...
@@ -116,7 +116,7 @@ static int ata_read(struct vm_device * dev, struct ide_channel * channel, uint8_
 
     PrintDebug("Reading Drive LBA=%d (count=%d)\n", (uint32_t)(drive->current_lba), sect_cnt);
 
-    int ret = drive->hd_ops->read(dst, sect_cnt, drive->current_lba, drive->private_data);
+    int ret = drive->ops->read(dst, drive->current_lba * HD_SECTOR_SIZE, sect_cnt * HD_SECTOR_SIZE, drive->private_data);
     
     if (ret == -1) {
        PrintError("IDE: Error reading HD block (LBA=%p)\n", (void *)(addr_t)(drive->current_lba));
@@ -132,7 +132,7 @@ static int ata_write(struct vm_device * dev, struct ide_channel * channel, uint8
 
     PrintDebug("Writing Drive LBA=%d (count=%d)\n", (uint32_t)(drive->current_lba), sect_cnt);
 
-    int ret = drive->hd_ops->write(src, sect_cnt, drive->current_lba, drive->private_data);
+    int ret = drive->ops->write(src, drive->current_lba * HD_SECTOR_SIZE, sect_cnt * HD_SECTOR_SIZE, drive->private_data);
 
     if (ret == -1) {
        PrintError("IDE: Error writing HD block (LBA=%p)\n", (void *)(addr_t)(drive->current_lba));
@@ -168,11 +168,11 @@ static int ata_get_lba(struct vm_device * dev, struct ide_channel * channel, uin
 
 
     if ((lba_addr.addr + sect_cnt) > 
-       drive->hd_ops->get_capacity(drive->private_data)) {
+       drive->ops->get_capacity(drive->private_data)) {
        PrintError("IDE: request size exceeds disk capacity (lba=%d) (sect_cnt=%d) (ReadEnd=%d) (capacity=%p)\n", 
                   lba_addr.addr, sect_cnt, 
                   lba_addr.addr + (sect_cnt * HD_SECTOR_SIZE),
-                  (void *)(addr_t)(drive->hd_ops->get_capacity(drive->private_data)));
+                  (void *)(addr_t)(drive->ops->get_capacity(drive->private_data)));
        return -1;
     }
 
index 27bed29..ad03ee9 100644 (file)
@@ -128,7 +128,8 @@ static void atapi_cmd_nop(struct vm_device * dev, struct ide_channel * channel)
 static int atapi_read_chunk(struct vm_device * dev, struct ide_channel * channel) {
     struct ide_drive * drive = get_selected_drive(channel);
 
-    int ret = drive->cd_ops->read(drive->data_buf, 1, drive->current_lba, drive->private_data);
+    int ret = drive->ops->read(drive->data_buf, drive->current_lba * ATAPI_BLOCK_SIZE, ATAPI_BLOCK_SIZE, 
+drive->private_data);
     
     if (ret == -1) {
        PrintError("IDE: Error reading CD block (LBA=%p)\n", (void *)(addr_t)(drive->current_lba));
@@ -177,10 +178,10 @@ static int atapi_read10(struct vm_device * dev, struct ide_channel * channel) {
        return 0;
     }
     
-    if (lba + xfer_len > drive->cd_ops->get_capacity(drive->private_data)) {
+    if (lba + xfer_len > drive->ops->get_capacity(drive->private_data)) {
        PrintError("IDE: xfer len exceeded capacity (lba=%d) (xfer_len=%d) (ReadEnd=%d) (capacity=%d)\n", 
                   lba, xfer_len, lba + xfer_len, 
-                  drive->cd_ops->get_capacity(drive->private_data));
+                  (uint32_t)drive->ops->get_capacity(drive->private_data));
        atapi_cmd_error(dev, channel, ATAPI_SEN_ILL_REQ, ASC_LOG_BLK_OOR);
        ide_raise_irq(dev, channel);
        return 0;
@@ -238,7 +239,7 @@ static void atapi_req_sense(struct vm_device * dev, struct ide_channel * channel
 static int atapi_get_capacity(struct vm_device * dev, struct ide_channel * channel) {
     struct ide_drive * drive = get_selected_drive(channel);
     struct atapi_rd_capacity_resp * resp = (struct atapi_rd_capacity_resp *)(drive->data_buf);
-    uint32_t capacity = drive->cd_ops->get_capacity(drive->private_data);
+    uint32_t capacity = drive->ops->get_capacity(drive->private_data);
 
     resp->lba = le_to_be_32(capacity);
     resp->block_len = le_to_be_32(ATAPI_BLOCK_SIZE);
index 12f22c9..4c1ab08 100644 (file)
@@ -134,18 +134,19 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int debug_init(struct guest_info * vm, void * cfg_data) {
-   struct debug_state * state = NULL;
+static int debug_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+    struct debug_state * state = NULL;
+    char * name = v3_cfg_val(cfg, "name");
 
     state = (struct debug_state *)V3_Malloc(sizeof(struct debug_state));
 
     V3_ASSERT(state != NULL);
 
     PrintDebug("Creating Bochs Debug Device\n");
-    struct vm_device * dev = v3_allocate_device("BOCHS_DEBUG", &dev_ops, state);
+    struct vm_device * dev = v3_allocate_device(name, &dev_ops, state);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", "BOCHS_DEBUG");
+       PrintError("Could not attach device %s\n", name);
        return -1;
     }
 
index 3a77563..ee94f84 100644 (file)
@@ -310,18 +310,20 @@ static struct v3_device_ops dev_ops = {
     .stop = NULL,
 };
 
-static int cga_init(struct guest_info * vm, void * cfg_data) {
+static int cga_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
     struct video_internal * video_state = (struct video_internal *)V3_Malloc(sizeof(struct video_internal));
     addr_t frame_buf_pa = 0;
-    uint32_t enable_passthrough = (uint32_t)(addr_t)cfg_data;
+    int enable_passthrough = 0;
+    char * name = v3_cfg_val(cfg, "name");
 
+    enable_passthrough = (strcasecmp(v3_cfg_val(cfg, "passthrough"), "enable") == 0) ? 1 : 0;
 
     PrintDebug("video: init_device\n");
 
-    struct vm_device * dev = v3_allocate_device("CGA_VIDEO", &dev_ops, video_state);
+    struct vm_device * dev = v3_allocate_device(name, &dev_ops, video_state);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", "CGA_VIDEO");
+       PrintError("Could not attach device %s\n", name);
        return -1;
     }
 
index a768007..25bf720 100644 (file)
@@ -420,9 +420,11 @@ static struct v3_device_ops dev_ops = {
     .stop = cirrus_gfx_card_stop_device,
 };
 
-static int cirrus_gfx_card_init(struct guest_info * vm, void * cfg_data){
+static int cirrus_gfx_card_init(struct guest_info * vm, v3_cfg_tree_t * cfg){
     struct video_internal * video_state = (struct video_internal *)V3_Malloc(sizeof(struct video_internal));
     struct vm_device * pci_bus = v3_find_dev(vm, (char *)cfg_data);
+    char * name = v3_cfg_val(cfg, "name");
+
     struct vm_device * dev = v3_allocate_device("TEXT_GFX_CARD", &dev_ops, video_state);
 
     if (v3_attach_device(vm, dev) == -1) {
index c6dd8d6..e4a00ff 100644 (file)
  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
  */
 
-#include <devices/generic.h>
 #include <palacios/vmm.h>
 #include <palacios/vmm_types.h>
 #include <palacios/vmm_list.h>
-
-
+#include <palacios/vmm_io.h>
+#include <palacios/vmm_dev_mgr.h>
 
 #ifndef CONFIG_DEBUG_GENERIC
 #undef PrintDebug
 #endif
 
 
+typedef enum {GENERIC_IGNORE, 
+             GENERIC_PASSTHROUGH, 
+             GENERIC_PRINT_AND_PASSTHROUGH, 
+             GENERIC_PRINT_AND_IGNORE} generic_mode_t;
+
 struct generic_internal {
     struct list_head port_list;
     uint_t num_port_ranges;
@@ -42,7 +46,7 @@ struct generic_internal {
 struct port_range {
     uint_t start;
     uint_t end;
-    uint_t type;
+    generic_mode_t mode;
     struct list_head range_link;
 };
 
@@ -211,26 +215,26 @@ static struct v3_device_ops dev_ops = {
 
 
 
-int v3_generic_add_port_range(struct vm_device * dev, uint_t start, uint_t end, uint_t type) {
+static int add_port_range(struct vm_device * dev, uint_t start, uint_t end, generic_mode_t mode) {
     struct generic_internal * state = (struct generic_internal *)(dev->private_data);
     struct port_range * range = (struct port_range *)V3_Malloc(sizeof(struct port_range));
     uint_t i = 0;
 
     range->start = start;
     range->end = end;
-    range->type = type;
+    range->mode = mode;
       
     PrintDebug("generic: Adding Port Range: 0x%x to 0x%x as %s\n", 
-              range->start, range->end, 
-              (range->type == GENERIC_PRINT_AND_PASSTHROUGH) ? "print-and-passthrough" : "print-and-ignore");
+              start, end, 
+              (mode == GENERIC_PRINT_AND_PASSTHROUGH) ? "print-and-passthrough" : "print-and-ignore");
     
     for (i = start; i <= end; i++) { 
-       if (type == GENERIC_PRINT_AND_PASSTHROUGH) { 
+       if (mode == GENERIC_PRINT_AND_PASSTHROUGH) { 
            if (v3_dev_hook_io(dev, i, &generic_read_port_passthrough, &generic_write_port_passthrough) == -1) { 
                PrintError("generic: can't hook port 0x%x (already hooked?)\n", i);
                return -1;
            }
-       } else if (type == GENERIC_PRINT_AND_IGNORE) { 
+       } else if (mode == GENERIC_PRINT_AND_IGNORE) { 
            if (v3_dev_hook_io(dev, i, &generic_read_port_ignore, &generic_write_port_ignore) == -1) { 
                PrintError("generic: can't hook port 0x%x (already hooked?)\n", i);
                return -1;
@@ -248,22 +252,52 @@ int v3_generic_add_port_range(struct vm_device * dev, uint_t start, uint_t end,
 
 
 
-static int generic_init(struct guest_info * vm, void * cfg_data) {
+static int generic_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
     struct generic_internal * state = (struct generic_internal *)V3_Malloc(sizeof(struct generic_internal));
-  
+    char * name = v3_cfg_val(cfg, "name");
+
+    v3_cfg_tree_t * port_cfg = v3_cfg_subtree(cfg, "ports");
+
+
     INIT_LIST_HEAD(&(state->port_list));
     state->num_port_ranges = 0;
+
     
-    struct vm_device * dev = v3_allocate_device("GENERIC", &dev_ops, state);
+    struct vm_device * dev = v3_allocate_device(name, &dev_ops, state);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", "GENERIC");
+       PrintError("Could not attach device %s\n", name);
        return -1;
     }
 
     PrintDebug("generic: init_device\n");
     generic_reset_device(dev);
 
+    // scan port list....
+    while (port_cfg) {
+       uint16_t start = atox(v3_cfg_val(port_cfg, "start"));
+       uint16_t end = atox(v3_cfg_val(port_cfg, "end"));
+       char * mode_str = v3_cfg_val(port_cfg, "mode");
+       generic_mode_t mode = GENERIC_IGNORE;
+
+       if (strcasecmp(mode_str, "print_and_ignore") == 0) {
+           mode = GENERIC_PRINT_AND_IGNORE;
+       } else if (strcasecmp(mode_str, "print_and_passthrough") == 0) {
+           mode = GENERIC_PRINT_AND_PASSTHROUGH;
+       } else {
+           PrintError("Invalid Mode %s\n", mode_str);
+           return -1;
+       }
+       
+       if (add_port_range(dev, start, end, mode) == -1) {
+           PrintError("Could not add port range %d-%d\n", start, end);
+           return -1;
+       }
+
+       port_cfg = v3_cfg_next_branch(port_cfg);
+    }
+
+
     return 0;
 }
 
index 2408cdd..ee4dc80 100644 (file)
@@ -57,12 +57,13 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int i440_init(struct guest_info * vm, void * cfg_data) {
+static int i440_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
     struct pci_device * pci_dev = NULL;
     struct v3_pci_bar bars[6];
     int i;
     struct i440_state * state = NULL;
-    struct vm_device * pci = v3_find_dev(vm, (char *)cfg_data);
+    struct vm_device * pci = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
+    char * name = v3_cfg_val(cfg, "name");
 
     if (!pci) {
        PrintError("could not find PCI Device\n");
@@ -73,10 +74,10 @@ static int i440_init(struct guest_info * vm, void * cfg_data) {
 
     state->pci = pci;
        
-    struct vm_device * dev = v3_allocate_device("i440FX", &dev_ops, state);
+    struct vm_device * dev = v3_allocate_device(name, &dev_ops, state);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", "i440FX");
+       PrintError("Could not attach device %s\n", name);
        return -1;
     }
 
index bf95245..7b13e5b 100644 (file)
  */
 
 #include <palacios/vmm.h>
+#include <palacios/vmm_dev_mgr.h>
 #include <palacios/vm_guest_mem.h>
 #include <devices/ide.h>
 #include <devices/pci.h>
 #include <devices/southbridge.h>
-#include <devices/block_dev.h>
 #include "ide-types.h"
 #include "atapi-types.h"
 
 
 #define DATA_BUFFER_SIZE 2048
 
+#define ATAPI_BLOCK_SIZE 2048
+#define HD_SECTOR_SIZE 512
+
+
 static const char * ide_pri_port_strs[] = {"PRI_DATA", "PRI_FEATURES", "PRI_SECT_CNT", "PRI_SECT_NUM", 
                                          "PRI_CYL_LOW", "PRI_CYL_HIGH", "PRI_DRV_SEL", "PRI_CMD",
                                           "PRI_CTRL", "PRI_ADDR_REG"};
@@ -76,6 +80,7 @@ static const char * ide_dma_port_strs[] = {"DMA_CMD", NULL, "DMA_STATUS", NULL,
                                           "DMA_PRD0", "DMA_PRD1", "DMA_PRD2", "DMA_PRD3"};
 
 
+typedef enum {BLOCK_NONE, BLOCK_DISK, BLOCK_CDROM} v3_block_type_t;
 
 static inline const char * io_port_to_str(uint16_t port) {
     if ((port >= PRI_DATA_PORT) && (port <= PRI_CMD_PORT)) {
@@ -122,11 +127,7 @@ struct ide_drive {
 
     v3_block_type_t drive_type;
 
-    union {
-       struct v3_cd_ops * cd_ops;
-       struct v3_hd_ops * hd_ops;
-    };
-
+    struct v3_dev_blk_ops * ops;
 
     union {
        struct ide_cd_state cd_state;
@@ -1372,7 +1373,7 @@ static void init_drive(struct ide_drive * drive) {
     
 
     drive->private_data = NULL;
-    drive->cd_ops = NULL;
+    drive->ops = NULL;
 }
 
 static void init_channel(struct ide_channel * channel) {
@@ -1442,28 +1443,91 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int ide_init(struct guest_info * vm, void * cfg_data) {
-    struct ide_internal * ide  = (struct ide_internal *)V3_Malloc(sizeof(struct ide_internal));  
-    struct ide_cfg * cfg = (struct ide_cfg *)(cfg_data);
+
+static int connect_fn(struct guest_info * info, 
+                     void * frontend_data, 
+                     struct v3_dev_blk_ops * ops, 
+                     v3_cfg_tree_t * cfg, 
+                     void * private_data) {
+    struct ide_internal * ide  = (struct ide_internal *)(frontend_data);  
+    struct ide_channel * channel = NULL;
+    struct ide_drive * drive = NULL;
+
+    char * bus_str = v3_cfg_val(cfg, "bus_num");
+    char * drive_str = v3_cfg_val(cfg, "drive_num");
+    char * type_str = v3_cfg_val(cfg, "type");
+    char * model_str = v3_cfg_val(cfg, "model");
+    uint_t bus_num = 0;
+    uint_t drive_num = 0;
+
+
+    if ((!type_str) || (!drive_str) || (!bus_str)) {
+       PrintError("Incomplete IDE Configuration\n");
+       return -1;
+    }
+
+    bus_num = atoi(bus_str);
+    drive_num = atoi(drive_str);
+
+    channel = &(ide->channels[bus_num]);
+    drive = &(channel->drives[drive_num]);
+
+    if (drive->drive_type != BLOCK_NONE) {
+       PrintError("Device slot (bus=%d, drive=%d) already occupied\n", bus_num, drive_num);
+       return -1;
+    }
+
+    strncpy(drive->model, model_str, sizeof(drive->model) - 1);
     
+    if (strcasecmp(type_str, "cdrom") == 0) {
+       drive->drive_type = BLOCK_CDROM;
+
+       while (strlen((char *)(drive->model)) < 40) {
+           strcat((char*)(drive->model), " ");
+       }
+
+    } else if (strcasecmp(type_str, "hd") == 0) {
+       drive->drive_type = BLOCK_DISK;
+
+       drive->hd_state.accessed = 0;
+       drive->hd_state.mult_sector_num = 1;
+
+       drive->num_sectors = 63;
+       drive->num_heads = 16;
+       drive->num_cylinders = ops->get_capacity(private_data)  / (drive->num_sectors * drive->num_heads);
+    } else {
+       PrintError("invalid IDE drive type\n");
+       return -1;
+    }
+
+    drive->ops = ops;
+
+    if (ide->ide_pci) {
+       // Hardcode this for now, but its not a good idea....
+       ide->ide_pci->config_space[0x41 + (bus_num * 2)] = 0x80;
+    }
+    drive->private_data = private_data;
+
+    return 0;
+}
+
+
+
+
+static int ide_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+    struct ide_internal * ide  = (struct ide_internal *)V3_Malloc(sizeof(struct ide_internal));  
+    char * name = v3_cfg_val(cfg, "name");
+
     PrintDebug("IDE: Initializing IDE\n");
     memset(ide, 0, sizeof(struct ide_internal));
 
 
-    if (cfg->pci != NULL) {
-       if (cfg->southbridge == NULL) {
-           PrintError("PCI Enabled BUT southbridge is NULL\n");
-           return -1;
-       }
-
-       ide->pci_bus = v3_find_dev(vm, (char *)cfg->pci);
-       
-       if (ide->pci_bus == NULL) {
-           PrintError("Could not find PCI device\n");
-           return -1;
-       }
+    ide->pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
 
-       struct vm_device * southbridge = v3_find_dev(vm, cfg->southbridge);
+    if (ide->pci_bus != NULL) {
+       struct vm_device * southbridge = v3_find_dev(vm, v3_cfg_val(cfg, "controller"));
 
        if (!southbridge) {
            PrintError("Could not find southbridge\n");
@@ -1473,17 +1537,15 @@ static int ide_init(struct guest_info * vm, void * cfg_data) {
        ide->southbridge = (struct v3_southbridge *)(southbridge->private_data);
     }
 
-
     PrintDebug("IDE: Creating IDE bus x 2\n");
 
-    struct vm_device * dev = v3_allocate_device("IDE", &dev_ops, ide);
+    struct vm_device * dev = v3_allocate_device(name, &dev_ops, ide);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", "IDE");
+       PrintError("Could not attach device %s\n", name);
        return -1;
     }
 
-
     if (init_ide_state(dev) == -1) {
        PrintError("Failed to initialize IDE state\n");
        return -1;
@@ -1595,6 +1657,12 @@ static int ide_init(struct guest_info * vm, void * cfg_data) {
 
     }
 
+    if (v3_dev_add_blk_frontend(vm, name, connect_fn, (void *)ide) == -1) {
+       PrintError("Could not register %s as frontend\n", name);
+       return -1;
+    }
+    
+
     PrintDebug("IDE Initialized\n");
 
     return 0;
@@ -1606,11 +1674,6 @@ device_register("IDE", ide_init)
 
 
 
-
-
-
-
-
 int v3_ide_get_geometry(struct vm_device * ide_dev, int channel_num, int drive_num, 
                        uint32_t * cylinders, uint32_t * heads, uint32_t * sectors) {
 
@@ -1631,98 +1694,3 @@ int v3_ide_get_geometry(struct vm_device * ide_dev, int channel_num, int drive_n
 
 
 
-
-int v3_ide_register_cdrom(struct vm_device * ide_dev, 
-                         uint_t bus_num, 
-                         uint_t drive_num,
-                         char * dev_name, 
-                         struct v3_cd_ops * ops, 
-                         void * private_data) {
-
-    struct ide_internal * ide  = (struct ide_internal *)(ide_dev->private_data);  
-    struct ide_channel * channel = NULL;
-    struct ide_drive * drive = NULL;
-
-    V3_ASSERT((bus_num >= 0) && (bus_num < 2));
-    V3_ASSERT((drive_num >= 0) && (drive_num < 2));
-
-    channel = &(ide->channels[bus_num]);
-    drive = &(channel->drives[drive_num]);
-    
-    if (drive->drive_type != BLOCK_NONE) {
-       PrintError("Device slot (bus=%d, drive=%d) already occupied\n", bus_num, drive_num);
-       return -1;
-    }
-
-    strncpy(drive->model, dev_name, sizeof(drive->model) - 1);
-
-    while (strlen((char *)(drive->model)) < 40) {
-       strcat((char*)(drive->model), " ");
-    }
-
-
-    drive->drive_type = BLOCK_CDROM;
-
-    drive->cd_ops = ops;
-
-    if (ide->ide_pci) {
-       // Hardcode this for now, but its not a good idea....
-       ide->ide_pci->config_space[0x41 + (bus_num * 2)] = 0x80;
-    }
-
-    drive->private_data = private_data;
-
-    return 0;
-}
-
-
-int v3_ide_register_harddisk(struct vm_device * ide_dev, 
-                            uint_t bus_num, 
-                            uint_t drive_num, 
-                            char * dev_name, 
-                            struct v3_hd_ops * ops, 
-                            void * private_data) {
-
-    struct ide_internal * ide  = (struct ide_internal *)(ide_dev->private_data);  
-    struct ide_channel * channel = NULL;
-    struct ide_drive * drive = NULL;
-
-    V3_ASSERT((bus_num >= 0) && (bus_num < 2));
-    V3_ASSERT((drive_num >= 0) && (drive_num < 2));
-
-    channel = &(ide->channels[bus_num]);
-    drive = &(channel->drives[drive_num]);
-    
-    if (drive->drive_type != BLOCK_NONE) {
-       PrintError("Device slot (bus=%d, drive=%d) already occupied\n", bus_num, drive_num);
-       return -1;
-    }
-
-    strncpy(drive->model, dev_name, sizeof(drive->model) - 1);
-
-    drive->drive_type = BLOCK_DISK;
-
-    drive->hd_state.accessed = 0;
-    drive->hd_state.mult_sector_num = 1;
-
-    drive->hd_ops = ops;
-
-    /* this is something of a hack... */
-    drive->num_sectors = 63;
-    drive->num_heads = 16;
-    drive->num_cylinders = ops->get_capacity(private_data)  / (drive->num_sectors * drive->num_heads);
-
-    if (ide->ide_pci) {
-       // Hardcode this for now, but its not a good idea....
-       ide->ide_pci->config_space[0x41 + (bus_num * 2)] = 0x80;
-    }
-
-
-
-    drive->private_data = private_data;
-
-    return 0;
-}
-
-
-
index 3bd5902..95392d0 100644 (file)
@@ -21,7 +21,7 @@
 #include <palacios/vmm.h>
 #include <palacios/vmm_dev_mgr.h>
 #include <devices/apic.h>
-
+#include <palacios/vm_guest.h>
 
 #ifndef CONFIG_DEBUG_IO_APIC
 #undef PrintDebug
@@ -319,11 +319,12 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int ioapic_init(struct guest_info * vm, void * cfg_data) {
-    struct vm_device * apic = v3_find_dev(vm, (char *)cfg_data);
+static int ioapic_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+    struct vm_device * apic = v3_find_dev(vm, v3_cfg_val(cfg, "irq_bus"));
+    char * name = v3_cfg_val(cfg, "name");
 
     if (!apic) {
-       PrintError("Could not locate APIC device (%s)\n", (char *)cfg_data);
+       PrintError("Could not locate APIC device (%s)\n", v3_cfg_val(cfg, "irq_bus"));
        return -1;
     }
 
@@ -333,11 +334,11 @@ static int ioapic_init(struct guest_info * vm, void * cfg_data) {
 
     ioapic->apic = apic;
 
-    struct vm_device * dev = v3_allocate_device("IOAPIC", &dev_ops, ioapic);
+    struct vm_device * dev = v3_allocate_device(name, &dev_ops, ioapic);
 
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", "IOAPIC");
+       PrintError("Could not attach device %s\n", name);
        return -1;
     }
 
index c05b00e..cf61967 100644 (file)
@@ -23,6 +23,9 @@
 
 #include <palacios/vmm_ringbuffer.h>
 #include <palacios/vmm_lock.h>
+#include <palacios/vmm_intr.h>
+#include <palacios/vmm_host_events.h>
+#include <palacios/vm_guest.h>
 
 
 #ifndef CONFIG_DEBUG_KEYBOARD
@@ -981,9 +984,9 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int keyboard_init(struct guest_info * vm, void * cfg_data) {
+static int keyboard_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
     struct keyboard_internal * keyboard_state = NULL;
-
+    char * name = v3_cfg_val(cfg, "name");
 
     PrintDebug("keyboard: init_device\n");
 
@@ -999,10 +1002,10 @@ static int keyboard_init(struct guest_info * vm, void * cfg_data) {
 
     keyboard_state->mouse_enabled = 0;
 
-    struct vm_device * dev = v3_allocate_device("KEYBOARD", &dev_ops, keyboard_state);
+    struct vm_device * dev = v3_allocate_device(name, &dev_ops, keyboard_state);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", "KEYBOARD");
+       PrintError("Could not attach device %s\n", name);
        return -1;
     }
 
index fed0c83..088cea4 100644 (file)
@@ -415,10 +415,11 @@ static int handle_query_hcall(struct guest_info * info, uint_t hcall_id, void *
 
 
 
-static int virtio_init(struct guest_info * vm, void * cfg_data) {
-    struct vm_device * pci_bus = v3_find_dev(vm, (char *)cfg_data);
+static int virtio_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+    struct vm_device * pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
     struct virtio_balloon_state * virtio_state = NULL;
     struct pci_device * pci_dev = NULL;
+    char * name = v3_cfg_val(cfg, "name");
 
     PrintDebug("Initializing VIRTIO Balloon device\n");
 
@@ -432,9 +433,9 @@ static int virtio_init(struct guest_info * vm, void * cfg_data) {
     memset(virtio_state, 0, sizeof(struct virtio_balloon_state));
 
 
-    struct vm_device * dev = v3_allocate_device("LNX_VIRTIO_BALLOON", &dev_ops, virtio_state);
+    struct vm_device * dev = v3_allocate_device(name, &dev_ops, virtio_state);
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", "LNX_VIRTIO_BALLOON");
+       PrintError("Could not attach device %s\n", name);
        return -1;
     }
 
index 69187cc..7bc41a6 100644 (file)
@@ -20,8 +20,6 @@
 #include <palacios/vmm.h>
 #include <palacios/vmm_dev_mgr.h>
 #include <devices/lnx_virtio_pci.h>
-#include <devices/lnx_virtio_blk.h>
-#include <devices/block_dev.h>
 #include <palacios/vm_guest_mem.h>
 
 #include <devices/pci.h>
@@ -93,12 +91,8 @@ struct virtio_blk_state {
     
     struct virtio_queue queue;
 
-    union {
-       struct v3_cd_ops * cd_ops;
-       struct v3_hd_ops * hd_ops;
-    };
+    struct v3_dev_blk_ops * ops;
 
-    v3_block_type_t block_type;
     void * backend_data;
 
     int io_range_size;
@@ -138,52 +132,23 @@ static int virtio_reset(struct vm_device * dev) {
     return 0;
 }
 
-static int handle_read_op(struct virtio_blk_state * blk_state, uint8_t * buf, uint64_t * sector, uint32_t len) {
+static int handle_read_op(struct virtio_blk_state * blk_state, uint8_t * buf, uint64_t * sector, uint64_t len) {
     int ret = -1;
 
-    if (blk_state->block_type == BLOCK_DISK) {
-       if (len % HD_SECTOR_SIZE) {
-           PrintError("Write of something that is not a sector len %d, mod=%d\n", len, len % HD_SECTOR_SIZE);
-           return -1;
-       }
-
-
-       PrintDebug("Reading Disk\n");
-           
-       ret = blk_state->hd_ops->read(buf, len / HD_SECTOR_SIZE, *sector, blk_state->backend_data);
-
-       *sector += len / HD_SECTOR_SIZE;
-
-    } else if (blk_state->block_type == BLOCK_CDROM) {
-       if (len % ATAPI_BLOCK_SIZE) {
-           PrintError("Write of something that is not an ATAPI block len %d, mod=%d\n", len, len % ATAPI_BLOCK_SIZE);
-           return -1;
-       }
-
-       ret = blk_state->cd_ops->read(buf, len / ATAPI_BLOCK_SIZE, *sector , blk_state->backend_data);
-
-       *sector += len / ATAPI_BLOCK_SIZE;
-    }
+    PrintDebug("Reading Disk\n");
+    ret = blk_state->ops->read(buf, *sector, len, (void *)(blk_state->backend_data));
+    *sector += len;
 
     return ret;
 }
 
 
-static int handle_write_op(struct virtio_blk_state * blk_state, uint8_t * buf, uint64_t * sector, uint32_t len) {
+static int handle_write_op(struct virtio_blk_state * blk_state, uint8_t * buf, uint64_t * sector, uint64_t len) {
     int ret = -1;
 
-    if (blk_state->block_type == BLOCK_DISK) {
-       if (len % HD_SECTOR_SIZE) {
-           PrintError("Write of something that is not a sector len %d, mod=%d\n", len, len % HD_SECTOR_SIZE);
-           return -1;
-       }
-
-       PrintDebug("Writing Disk\n");
-
-       ret = blk_state->hd_ops->write(buf, len / HD_SECTOR_SIZE, *sector, blk_state->backend_data);
-
-       *sector += len / HD_SECTOR_SIZE;        
-    }
+    PrintDebug("Writing Disk\n");
+    ret = blk_state->ops->write(buf, *sector, len, (void *)(blk_state->backend_data));
+    *sector += len;
 
     return ret;
 }
@@ -197,50 +162,33 @@ static int handle_block_op(struct virtio_blk_state * blk_state, struct blk_op_hd
     uint8_t * buf = NULL;
 
     PrintDebug("Handling Block op\n");
-
-
-
     if (guest_pa_to_host_va(blk_state->virtio_dev->vm, buf_desc->addr_gpa, (addr_t *)&(buf)) == -1) {
        PrintError("Could not translate buffer address\n");
        return -1;
     }
 
-
     PrintDebug("Sector=%p Length=%d\n", (void *)(addr_t)(hdr->sector), buf_desc->length);
 
     if (hdr->type == BLK_IN_REQ) {
-       if (blk_state->block_type != BLOCK_NONE) {
-           if (handle_read_op(blk_state, buf, &(hdr->sector), buf_desc->length) == -1) {
-               *status = BLK_STATUS_ERR;
-               return -1;
-           } else {
-               *status = BLK_STATUS_OK;
-           }
+       if (handle_read_op(blk_state, buf, &(hdr->sector), buf_desc->length) == -1) {
+           *status = BLK_STATUS_ERR;
+           return -1;
        } else {
-           *status = BLK_STATUS_NOT_SUPPORTED;
+           *status = BLK_STATUS_OK;
        }
-
     } else if (hdr->type == BLK_OUT_REQ) {
-       if (blk_state->block_type == BLOCK_DISK) {
-           if (handle_write_op(blk_state, buf, &(hdr->sector), buf_desc->length) == -1) {
-               *status = BLK_STATUS_ERR;
-               return -1;
-           } else {
-               *status = BLK_STATUS_OK;
-           }
-
+       if (handle_write_op(blk_state, buf, &(hdr->sector), buf_desc->length) == -1) {
+           *status = BLK_STATUS_ERR;
+           return -1;
        } else {
-           *status = BLK_STATUS_NOT_SUPPORTED;
+           *status = BLK_STATUS_OK;
        }
-
     } else if (hdr->type == BLK_SCSI_CMD) {
        PrintError("VIRTIO: SCSI Command Not supported!!!\n");
        *status = BLK_STATUS_NOT_SUPPORTED;
        return -1;
     }
 
-
-
     PrintDebug("Returning Status: %d\n", *status);
 
     return 0;
@@ -629,49 +577,35 @@ static int register_dev(struct virtio_dev_state * virtio, struct virtio_blk_stat
 }
 
 
-int v3_virtio_register_cdrom(struct vm_device * dev, struct v3_cd_ops * ops, void * private_data) {
-    struct virtio_dev_state * virtio = (struct virtio_dev_state *)dev->private_data;
-    struct virtio_blk_state * blk_state  = (struct virtio_blk_state *)V3_Malloc(sizeof(struct virtio_blk_state));
-    memset(blk_state, 0, sizeof(struct virtio_blk_state));
-    
-    register_dev(virtio, blk_state);
-
-    blk_state->block_type = BLOCK_CDROM;
-    blk_state->cd_ops = ops;
-    blk_state->backend_data = private_data;
-
-    blk_state->block_cfg.capacity = ops->get_capacity(private_data);
-
-    return 0;
-}
+static int connect_fn(struct guest_info * info, 
+                     void * frontend_data, 
+                     struct v3_dev_blk_ops * ops, 
+                     v3_cfg_tree_t * cfg, 
+                     void * private_data) {
 
+    struct virtio_dev_state * virtio = (struct virtio_dev_state *)frontend_data;
 
-int v3_virtio_register_harddisk(struct vm_device * dev, struct v3_hd_ops * ops, void * private_data) {
-    struct virtio_dev_state * virtio = (struct virtio_dev_state *)dev->private_data;
     struct virtio_blk_state * blk_state  = (struct virtio_blk_state *)V3_Malloc(sizeof(struct virtio_blk_state));
     memset(blk_state, 0, sizeof(struct virtio_blk_state));
 
     register_dev(virtio, blk_state);
 
-    blk_state->block_type = BLOCK_DISK;
-    blk_state->hd_ops = ops;
+    blk_state->ops = ops;
     blk_state->backend_data = private_data;
 
     blk_state->block_cfg.capacity = ops->get_capacity(private_data);
 
     PrintDebug("Virtio Capacity = %d -- 0x%p\n", (int)(virtio->block_cfg.capacity), 
-       (void *)(addr_t)(virtio->block_cfg.capacity));
+              (void *)(addr_t)(virtio->block_cfg.capacity));
 
     return 0;
 }
 
 
-
-
-static int virtio_init(struct guest_info * vm, void * cfg_data) {
-    struct vm_device * pci_bus = v3_find_dev(vm, (char *)cfg_data);
+static int virtio_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+    struct vm_device * pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
     struct virtio_dev_state * virtio_state = NULL;
-
+    char * name = v3_cfg_val(cfg, "name");
 
     PrintDebug("Initializing VIRTIO Block device\n");
 
@@ -688,16 +622,19 @@ static int virtio_init(struct guest_info * vm, void * cfg_data) {
     virtio_state->pci_bus = pci_bus;
     virtio_state->vm = vm;
 
-    struct vm_device * dev = v3_allocate_device("LNX_VIRTIO_BLK", &dev_ops, virtio_state);
+    struct vm_device * dev = v3_allocate_device(name, &dev_ops, virtio_state);
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", "LNX_VIRTIO_BLK");
+       PrintError("Could not attach device %s\n", name);
+       return -1;
+    }
+
+    if (v3_dev_add_blk_frontend(vm, name, connect_fn, (void *)virtio_state) == -1) {
+       PrintError("Could not register %s as block frontend\n", name);
        return -1;
     }
 
     return 0;
 }
-    
 
 
 device_register("LNX_VIRTIO_BLK", virtio_init)
index 8f4401e..d27429b 100644 (file)
@@ -351,10 +351,11 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int virtio_init(struct guest_info * vm, void * cfg_data) {
-    struct vm_device * pci_bus = v3_find_dev(vm, (char *)cfg_data);
+static int virtio_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+    struct vm_device * pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
     struct virtio_sym_state * virtio_state = NULL;
     struct pci_device * pci_dev = NULL;
+    char * name = v3_cfg_val(cfg, "name");
 
     PrintDebug("Initializing VIRTIO Symbiotic device\n");
 
@@ -368,9 +369,9 @@ static int virtio_init(struct guest_info * vm, void * cfg_data) {
     memset(virtio_state, 0, sizeof(struct virtio_sym_state));
 
 
-    struct vm_device * dev = v3_allocate_device("LNX_VIRTIO_SYM", &dev_ops, virtio_state);
+    struct vm_device * dev = v3_allocate_device(name, &dev_ops, virtio_state);
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", "LNX_VIRTIO_SYM");
+       PrintError("Could not attach device %s\n", name);
        return -1;
     }
 
diff --git a/palacios/src/devices/net_cd.c b/palacios/src/devices/net_cd.c
deleted file mode 100644 (file)
index f980bab..0000000
+++ /dev/null
@@ -1,277 +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) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software.  You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#include <palacios/vmm.h>
-#include <devices/net_cd.h>
-#include <devices/ide.h>
-#include <palacios/vmm_socket.h>
-
-#ifndef CONFIG_DEBUG_IDE
-#undef PrintDebug
-#define PrintDebug(fmt, args...)
-#endif 
-
-
-#define NBD_READ_CMD 0x1
-#define NBD_WRITE_CMD 0x2
-#define NBD_CAPACITY_CMD 0x3
-
-#define NBD_STATUS_OK 0x00
-#define NBD_STATUS_ERR 0xff
-
-struct cd_state {
-    uint64_t capacity; // in bytes
-
-    int socket;
-
-    uint32_t ip_addr;
-    uint16_t port;
-
-    char disk_name[32];
-
-    struct vm_device * ide;
-
-    uint_t bus;
-    uint_t drive;
-};
-
-
-static int send_all(int socket, char * buf, int length) {
-    int bytes_sent = 0;
-    
-    PrintDebug("Sending %d bytes\n", length - bytes_sent);
-    while (bytes_sent < length) {
-       int tmp_bytes = V3_Send(socket, buf + bytes_sent, length - bytes_sent);
-       PrintDebug("Sent %d bytes\n", tmp_bytes);
-       
-       if (tmp_bytes == 0) {
-           PrintError("Connection Closed unexpectedly\n");
-           return -1;
-       }
-       
-       bytes_sent += tmp_bytes;
-    }
-    
-    return 0;
-}
-
-
-static int recv_all(int socket, char * buf, int length) {
-    int bytes_read = 0;
-    
-    PrintDebug("Reading %d bytes\n", length - bytes_read);
-    while (bytes_read < length) {
-       int tmp_bytes = V3_Recv(socket, buf + bytes_read, length - bytes_read);
-       PrintDebug("Received %d bytes\n", tmp_bytes);
-       
-       if (tmp_bytes == 0) {
-           PrintError("Connection Closed unexpectedly\n");
-           return -1;
-       }
-       
-       bytes_read += tmp_bytes;
-    }
-    
-    return 0;
-}
-
-// CDs always read 2048 byte blocks... ?
-static int cd_read(uint8_t * buf, int block_count, uint64_t lba,  void * private_data) {
-    struct vm_device * cd_dev = (struct vm_device *)private_data;
-    struct cd_state * cd = (struct cd_state *)(cd_dev->private_data);
-    uint64_t offset = lba * ATAPI_BLOCK_SIZE;
-    int length = block_count * ATAPI_BLOCK_SIZE;
-    uint8_t status;
-    uint32_t ret_len = 0;
-    char nbd_cmd[4] = {0,0,0,0};
-
-    nbd_cmd[0] = NBD_READ_CMD;
-    
-    if (send_all(cd->socket, nbd_cmd, 4) == -1) {
-       PrintError("Error sending capacity command\n");
-       return -1;
-    }
-    
-    if (send_all(cd->socket, (char *)&offset, 8) == -1) {
-       PrintError("Error sending read offset\n");
-       return -1;
-    }
-
-    if (send_all(cd->socket, (char *)&length, 4) == -1) {
-       PrintError("Error sending read length\n");
-       return -1;
-    }
-
-    if (recv_all(cd->socket, (char *)&status, 1) == -1) {
-       PrintError("Error receiving status\n");
-       return -1;
-    }
-
-    if (status != NBD_STATUS_OK) {
-       PrintError("NBD Error....\n");
-       return -1;
-    }
-
-    PrintDebug("Reading Data Ret Length\n");
-
-    if (recv_all(cd->socket, (char *)&ret_len, 4) == -1) {
-       PrintError("Error receiving Return read length\n");
-       return -1;
-    }
-
-    if (ret_len != length) {
-       PrintError("Read length mismatch (req=%d) (result=%d)\n", length, ret_len);
-       return -1;
-    }
-
-    PrintDebug("Reading Data (%d bytes)\n", ret_len);
-
-    if (recv_all(cd->socket, (char *)buf, ret_len) == -1) {
-       PrintError("Read Data Error\n");
-       return -1;
-    }
-    
-    return 0;
-}
-
-
-static uint32_t cd_get_capacity(void * private_data) {
-    struct vm_device * cd_dev = (struct vm_device *)private_data;
-    struct cd_state * cd = (struct cd_state *)(cd_dev->private_data);
-
-    return cd->capacity / ATAPI_BLOCK_SIZE;
-}
-
-static struct v3_cd_ops cd_ops = {
-    .read = cd_read, 
-    .get_capacity = cd_get_capacity,
-};
-
-
-
-
-static int cd_free(struct vm_device * dev) {
-    return 0;
-}
-
-static struct v3_device_ops dev_ops = {
-    .free = cd_free,
-    .reset = NULL,
-    .start = NULL,
-    .stop = NULL,
-};
-
-
-
-static int socket_init(struct cd_state * cd) {
-    char header[64];
-    
-    PrintDebug("Intializing Net CD\n");
-
-    cd->socket = V3_Create_TCP_Socket();
-
-    PrintDebug("CD socket: %d\n", cd->socket);
-    PrintDebug("Connecting to: %s:%d\n", v3_inet_ntoa(cd->ip_addr), cd->port);
-
-    V3_Connect_To_IP(cd->socket, v3_ntohl(cd->ip_addr), cd->port);
-
-
-    PrintDebug("Connected to NBD server\n");
-
-    //snprintf(header, 64, "V3_NBD_1 %s\n", cd->disk_name);
-    strcpy(header, "V3_NBD_1 ");
-    strncat(header, cd->disk_name, 32);
-    strncat(header, "\n", 1);
-
-
-    if (send_all(cd->socket, header, strlen(header)) == -1) {
-       PrintError("Error connecting to Network Block Device: %s\n", cd->disk_name);
-       return -1;
-    }
-
-    // Cache Capacity
-    {
-       char nbd_cmd[4] = {0,0,0,0};
-
-       nbd_cmd[0] = NBD_CAPACITY_CMD;
-       
-       if (send_all(cd->socket, nbd_cmd, 4) == -1) {
-           PrintError("Error sending capacity command\n");
-           return -1;
-       }
-
-       if (recv_all(cd->socket, (char *)&(cd->capacity), 8) == -1) {
-           PrintError("Error Receiving Capacity\n");
-           return -1;
-       }       
-
-       PrintDebug("Capacity: %p\n", (void *)(cd->capacity));
-    }
-
-    return 0;
-}
-
-static int cd_init(struct guest_info * vm, void * cfg_data) {
-    struct net_cd_cfg * cfg = (struct net_cd_cfg *)cfg_data;
-    struct cd_state * cd = (struct cd_state *)V3_Malloc(sizeof(struct cd_state));
-
-    PrintDebug("Registering Net CD at %s:%d disk=%s\n", cfg->ip_str, cfg->port, cfg->disk_tag);
-
-    strncpy(cd->disk_name, cfg->disk_tag, sizeof(cd->disk_name));
-    cd->ip_addr = v3_inet_addr(cfg->ip_str);
-    cd->port = cfg->port;
-
-    cd->ide = (struct vm_device * )v3_find_dev(vm, cfg->ide);
-
-    if (cd->ide == 0) {
-       PrintError("Could not find backend %s\n", cfg->ide);
-       return -1;
-    }
-
-    cd->bus = cfg->bus;
-    cd->drive = cfg->drive;
-       
-    struct vm_device * dev = v3_allocate_device("NET-CD", &dev_ops, cd);
-
-
-    if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", "NET-CD");
-       return -1;
-    }
-
-    if (socket_init(cd) == -1) {
-       PrintError("Could not initialize socket connection\n");
-       return -1;
-    }
-
-    PrintDebug("Registering CD\n");
-
-    if (v3_ide_register_cdrom(cd->ide, cd->bus, cd->drive, "NET-CD", &cd_ops, dev) == -1) {
-       return -1;
-    }
-
-    PrintDebug("intialization done\n");
-
-    return 0;
-}
-
-
-
-
-device_register("NET-CD", cd_init)
similarity index 55%
rename from palacios/src/devices/net_hd.c
rename to palacios/src/devices/netdisk.c
index 0894797..552de56 100644 (file)
@@ -18,8 +18,7 @@
  */
 
 #include <palacios/vmm.h>
-#include <devices/net_hd.h>
-#include <devices/ide.h>
+#include <palacios/vmm_dev_mgr.h>
 #include <palacios/vmm_socket.h>
 
 #ifndef CONFIG_DEBUG_IDE
@@ -36,7 +35,7 @@
 #define NBD_STATUS_ERR 0xff
 
 
-struct hd_state {
+struct disk_state {
     uint64_t capacity; // in bytes
 
     int socket;
@@ -46,10 +45,6 @@ struct hd_state {
 
     char disk_name[32];
 
-    struct vm_device * ide;
-
-    uint_t bus;
-    uint_t drive;
 };
 
 
@@ -94,33 +89,32 @@ static int recv_all(int socket, char * buf, int length) {
 
 
 // HDs always read 512 byte blocks... ?
-static int hd_read(uint8_t * buf, int sector_count, uint64_t lba,  void * private_data) {
-    struct vm_device * hd_dev = (struct vm_device *)private_data;
-    struct hd_state * hd = (struct hd_state *)(hd_dev->private_data);
-    int offset = lba * HD_SECTOR_SIZE;
-    int length = sector_count * HD_SECTOR_SIZE;
+static int read(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * private_data) {
+    struct disk_state * disk = (struct disk_state *)private_data ;
     uint8_t status;
     uint32_t ret_len = 0;
     char nbd_cmd[4] = {0,0,0,0};
+    uint64_t offset = lba;
+    uint64_t length = num_bytes;
 
     nbd_cmd[0] = NBD_READ_CMD;
     
-    if (send_all(hd->socket, nbd_cmd, 4) == -1) {
+    if (send_all(disk->socket, nbd_cmd, 4) == -1) {
        PrintError("Error sending read command\n");
        return -1;
     }
     
-    if (send_all(hd->socket, (char *)&offset, 8) == -1) {
+    if (send_all(disk->socket, (char *)&offset, 8) == -1) {
        PrintError("Error sending read offset\n");
        return -1;
     }
 
-    if (send_all(hd->socket, (char *)&length, 4) == -1) {
+    if (send_all(disk->socket, (char *)&length, 4) == -1) {
        PrintError("Error sending read length\n");
        return -1;
     }
 
-    if (recv_all(hd->socket, (char *)&status, 1) == -1) {
+    if (recv_all(disk->socket, (char *)&status, 1) == -1) {
        PrintError("Error receiving status\n");
        return -1;
     }
@@ -132,7 +126,7 @@ static int hd_read(uint8_t * buf, int sector_count, uint64_t lba,  void * privat
 
     PrintDebug("Reading Data Ret Length\n");
 
-    if (recv_all(hd->socket, (char *)&ret_len, 4) == -1) {
+    if (recv_all(disk->socket, (char *)&ret_len, 4) == -1) {
        PrintError("Error receiving Return read length\n");
        return -1;
     }
@@ -144,7 +138,7 @@ static int hd_read(uint8_t * buf, int sector_count, uint64_t lba,  void * privat
 
     PrintDebug("Reading Data (%d bytes)\n", ret_len);
 
-    if (recv_all(hd->socket, (char *)buf, ret_len) == -1) {
+    if (recv_all(disk->socket, (char *)buf, ret_len) == -1) {
        PrintError("Read Data Error\n");
        return -1;
     }
@@ -153,39 +147,38 @@ static int hd_read(uint8_t * buf, int sector_count, uint64_t lba,  void * privat
 }
 
 
-static int hd_write(uint8_t * buf, int sector_count, uint64_t lba, void * private_data) {
-    struct vm_device * hd_dev = (struct vm_device *)private_data;
-    struct hd_state * hd = (struct hd_state *)(hd_dev->private_data);
-    int offset = lba * HD_SECTOR_SIZE;
-    int length = sector_count * HD_SECTOR_SIZE;
+static int write(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * private_data) {
+    struct disk_state * disk = (struct disk_state *)private_data ;
+    uint64_t offset = lba;
+    int length = num_bytes;
     uint8_t status;
     char nbd_cmd[4] = {0,0,0,0};
 
     nbd_cmd[0] = NBD_WRITE_CMD;
 
-    if (send_all(hd->socket, nbd_cmd, 4) == -1) {
+    if (send_all(disk->socket, nbd_cmd, 4) == -1) {
        PrintError("Error sending write command\n");
        return -1;
     }
 
-    if (send_all(hd->socket, (char *)&offset, 8) == -1) {
+    if (send_all(disk->socket, (char *)&offset, 8) == -1) {
        PrintError("Error sending write offset\n");
        return -1;
     }
 
-    if (send_all(hd->socket, (char *)&length, 4) == -1) {
+    if (send_all(disk->socket, (char *)&length, 4) == -1) {
        PrintError("Error sending write length\n");
        return -1;
     }
 
     PrintDebug("Writing Data (%d bytes)\n", length);
 
-    if (send_all(hd->socket, (char *)buf, length) == -1) {
+    if (send_all(disk->socket, (char *)buf, length) == -1) {
        PrintError("Write Data Error\n");
        return -1;
     }
 
-    if (recv_all(hd->socket, (char *)&status, 1) == -1) {
+    if (recv_all(disk->socket, (char *)&status, 1) == -1) {
        PrintError("Error receiving status\n");
        return -1;
     }
@@ -199,77 +192,76 @@ static int hd_write(uint8_t * buf, int sector_count, uint64_t lba, void * privat
 }
 
 
-static uint64_t hd_get_capacity(void * private_data) {
-    struct vm_device * hd_dev = (struct vm_device *)private_data;
-    struct hd_state * hd = (struct hd_state *)(hd_dev->private_data);
+static uint64_t get_capacity(void * private_data) {
+    struct disk_state * disk = (struct disk_state *)private_data;
 
-    return hd->capacity / HD_SECTOR_SIZE;
+    return disk->capacity;
 }
 
-static struct v3_hd_ops hd_ops = {
-    .read = hd_read, 
-    .write = hd_write,
-    .get_capacity = hd_get_capacity,
+static struct v3_dev_blk_ops blk_ops = {
+    .read = read, 
+    .write = write,
+    .get_capacity = get_capacity,
 };
 
 
 
 
 
-static int hd_free(struct vm_device * dev) {
+static int disk_free(struct vm_device * dev) {
     return 0;
 }
 
 static struct v3_device_ops dev_ops = {
-    .free = hd_free,
+    .free = disk_free,
     .reset = NULL,
     .start = NULL,
     .stop = NULL,
 };
 
 
-static int socket_init(struct hd_state * hd) {
+static int socket_init(struct disk_state * disk) {
     char header[64];
     
-    PrintDebug("Intializing Net HD\n");
+    PrintDebug("Intializing Net Disk\n");
 
-    hd->socket = V3_Create_TCP_Socket();
+    disk->socket = V3_Create_TCP_Socket();
 
-    PrintDebug("HD socket: %d\n", hd->socket);
-    PrintDebug("Connecting to: %s:%d\n", v3_inet_ntoa(hd->ip_addr), hd->port);
+    PrintDebug("DISK socket: %d\n", disk->socket);
+    PrintDebug("Connecting to: %s:%d\n", v3_inet_ntoa(disk->ip_addr), disk->port);
 
-    V3_Connect_To_IP(hd->socket, v3_ntohl(hd->ip_addr), hd->port);
+    V3_Connect_To_IP(disk->socket, v3_ntohl(disk->ip_addr), disk->port);
 
     PrintDebug("Connected to NBD server\n");
 
     //snprintf(header, 64, "V3_NBD_1 %s\n", cd->disk_name);
     strcpy(header, "V3_NBD_1 ");
-    strncat(header, hd->disk_name, 32);
+    strncat(header, disk->disk_name, 32);
     strncat(header, "\n", 1);
 
 
-    if (send_all(hd->socket, header, strlen(header)) == -1) {
-       PrintError("Error connecting to Network Block Device: %s\n", hd->disk_name);
+    if (send_all(disk->socket, header, strlen(header)) == -1) {
+       PrintError("Error connecting to Network Block Device: %s\n", disk->disk_name);
        return -1;
     }
 
-    // Cache Capacity
+    // store local copy of capacity
     {
        char nbd_cmd[4] = {0,0,0,0};
 
        nbd_cmd[0] = NBD_CAPACITY_CMD;
        
-       if (send_all(hd->socket, nbd_cmd, 4) == -1) {
+       if (send_all(disk->socket, nbd_cmd, 4) == -1) {
            PrintError("Error sending capacity command\n");
            return -1;
        }
 
-       if (recv_all(hd->socket, (char *)&(hd->capacity), 8) == -1) {
+       if (recv_all(disk->socket, (char *)&(disk->capacity), 8) == -1) {
            PrintError("Error Receiving Capacity\n");
            return -1;
        }       
 
-       PrintDebug("Capacity: %p\n", (void *)(hd->capacity));
+       PrintDebug("Capacity: %p\n", (void *)(disk->capacity));
     }
 
 
@@ -278,49 +270,46 @@ static int socket_init(struct hd_state * hd) {
 }
 
 
-static int hd_init(struct guest_info * vm, void * cfg_data) {
-    struct hd_state * hd = (struct hd_state *)V3_Malloc(sizeof(struct hd_state));
-    struct net_hd_cfg * cfg = (struct net_hd_cfg *)cfg_data;
-
-    PrintDebug("Registering Net HD at %s:%d disk=%s\n", cfg->ip_str, cfg->port, cfg->disk_tag);
+static int disk_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+    struct disk_state * disk = (struct disk_state *)V3_Malloc(sizeof(struct disk_state));
 
-    strncpy(hd->disk_name, cfg->disk_tag, sizeof(hd->disk_name));
-    hd->ip_addr = v3_inet_addr(cfg->ip_str);
-    hd->port = cfg->port;
+    char * ip_str = v3_cfg_val(cfg, "IP");
+    char * port_str = v3_cfg_val(cfg, "port");
+    char * disk_tag = v3_cfg_val(cfg, "tag");
+    char * name = v3_cfg_val(cfg, "name");
 
-    hd->ide = v3_find_dev(vm, cfg->ide);
+    v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend");
 
-    if (hd->ide == 0) {
-       PrintError("Could not find backend %s\n", cfg->ide);
-       return -1;
-    }
+    PrintDebug("Registering Net disk at %s:%s disk=%s\n", ip_str, port_str, disk_tag);
 
-    hd->bus = cfg->bus;
-    hd->drive = cfg->drive;
+    strncpy(disk->disk_name, disk_tag, sizeof(disk->disk_name));
+    disk->ip_addr = v3_inet_addr(ip_str);
+    disk->port = atoi(port_str);
        
-    struct vm_device * dev = v3_allocate_device("NET-HD", &dev_ops, hd);
+    struct vm_device * dev = v3_allocate_device(name, &dev_ops, disk);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", "NET-HD");
+       PrintError("Could not attach device %s\n", name);
        return -1;
     }
 
-    if (socket_init(hd) == -1) {
+    if (socket_init(disk) == -1) {
        PrintError("could not initialize network connection\n");
        return -1;
     }
 
+    PrintDebug("Registering Disk\n");
 
-    PrintDebug("Registering HD\n");
-
-    if (v3_ide_register_harddisk(hd->ide, hd->bus, hd->drive, "V3-NET-HD", &hd_ops, dev) == -1) {
+    if (v3_dev_connect_blk(vm, v3_cfg_val(frontend_cfg, "tag"), 
+                          &blk_ops, frontend_cfg, disk) == -1) {
+       PrintError("Could not connect %s to frontend\n", name);
        return -1;
     }
-    
+
     PrintDebug("intialization done\n");
 
     return 0;
 }
 
 
-device_register("NET-HD", hd_init)
+device_register("NETDISK", disk_init)
index 36da2aa..565c183 100644 (file)
@@ -25,6 +25,9 @@
 #include <palacios/vmm_lock.h>
 
 #include <devices/ide.h>
+#include <palacios/vmm_intr.h>
+#include <palacios/vmm_host_events.h>
+#include <palacios/vm_guest.h>
 
 #ifndef CONFIG_DEBUG_NVRAM
 #undef PrintDebug
@@ -791,9 +794,10 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int nvram_init(struct guest_info * vm, void * cfg_data) {
+static int nvram_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
     struct nvram_internal * nvram_state = NULL;
-    struct vm_device * ide = v3_find_dev(vm, (char *)cfg_data);
+    struct vm_device * ide = v3_find_dev(vm, v3_cfg_val(cfg, "storage"));
+    char * name = v3_cfg_val(cfg, "name");
 
     if (!ide) {
        PrintError("Could not find IDE device\n");
@@ -807,11 +811,11 @@ static int nvram_init(struct guest_info * vm, void * cfg_data) {
 
     nvram_state->ide = ide;
 
-    struct vm_device * dev = v3_allocate_device("NVRAM", &dev_ops, nvram_state);
+    struct vm_device * dev = v3_allocate_device(name, &dev_ops, nvram_state);
 
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", "NVRAM");
+       PrintError("Could not attach device %s\n", name);
        return -1;
     }
 
index 7abdeb0..a51dc19 100644 (file)
@@ -103,18 +103,19 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int debug_init(struct guest_info * vm, void * cfg_data) {
+static int debug_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
     struct debug_state * state = NULL;
+    char * name = v3_cfg_val(cfg, "name");
 
     state = (struct debug_state *)V3_Malloc(sizeof(struct debug_state));
 
     PrintDebug("Creating OS Debug Device\n");
 
-    struct vm_device * dev = v3_allocate_device("OS_DEBUG", &dev_ops, state);
+    struct vm_device * dev = v3_allocate_device(name, &dev_ops, state);
 
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", "OS_DEBUG");
+       PrintError("Could not attach device %s\n", name);
        return -1;
     }
 
index 13c5524..0bb7698 100644 (file)
@@ -100,17 +100,18 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int net_init(struct guest_info * vm, void * cfg_data) {
+static int net_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
     struct nic_state * state = NULL;
+    char * name = v3_cfg_val(cfg, "name");
 
     state = (struct nic_state *)V3_Malloc(sizeof(struct nic_state));
 
     PrintDebug("Creating VMNet Device\n");
 
-    struct vm_device * dev = v3_allocate_device("VMNET", &dev_ops, state);
+    struct vm_device * dev = v3_allocate_device(name, &dev_ops, state);
 
     if (v3_attach_device(vm, dev) == -1) {
-        PrintError("Could not attach device %s\n", "VMNET");
+        PrintError("Could not attach device %s\n", name);
         return -1;
     }
 
index 29c5435..06ccb6b 100644 (file)
 #include <palacios/vmm_io.h>
 #include <palacios/vmm_intr.h>
 #include <palacios/vmm_rbtree.h>
+#include <palacios/vmm_dev_mgr.h>
 
 #include <devices/pci.h>
 #include <devices/pci_types.h>
 
+
+
 #ifndef CONFIG_DEBUG_PCI
 #undef PrintDebug
 #define PrintDebug(fmt, args...)
@@ -648,16 +651,17 @@ static struct v3_device_ops dev_ops = {
 
 
 
-static int pci_init(struct guest_info * vm, void * cfg_data) {
+static int pci_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
     struct pci_internal * pci_state = V3_Malloc(sizeof(struct pci_internal));
     int i = 0;
+    char * name = v3_cfg_val(cfg, "name");
     
     PrintDebug("PCI internal at %p\n",(void *)pci_state);
     
-    struct vm_device * dev = v3_allocate_device("PCI", &dev_ops, pci_state);
+    struct vm_device * dev = v3_allocate_device(name, &dev_ops, pci_state);
     
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", "PCI");
+       PrintError("Could not attach device %s\n", name);
        return -1;
     }
 
index 25b2262..ce4b334 100644 (file)
 #include <palacios/vmm_dev_mgr.h>
 #include <palacios/vmm_sprintf.h>
 #include <palacios/vmm_lowlevel.h>
+#include <palacios/vm_guest.h> // must include this to avoid dependency issue
 #include <palacios/vmm_sym_iface.h>
 
 #include <devices/pci.h>
 #include <devices/pci_types.h>
-#include <devices/pci_passthrough.h>
 
 
 // Hardcoded... Are these standard??
@@ -545,12 +545,11 @@ static int irq_handler(struct guest_info * info, struct v3_interrupt * intr, voi
 
 
 
-static int passthrough_init(struct guest_info * info, void * cfg_data) {
-    struct pci_passthrough_cfg * cfg = (struct pci_passthrough_cfg *)cfg_data;
+static int passthrough_init(struct guest_info * info, v3_cfg_tree_t * cfg) {
     struct pt_dev_state * state = V3_Malloc(sizeof(struct pt_dev_state));
     struct vm_device * dev = NULL;
-    struct vm_device * pci = v3_find_dev(info, cfg->pci_bus_name);
-    
+    struct vm_device * pci = v3_find_dev(info, v3_cfg_val(cfg, "bus"));
+    char * name = v3_cfg_val(cfg, "name");    
 
     memset(state, 0, sizeof(struct pt_dev_state));
 
@@ -560,28 +559,30 @@ static int passthrough_init(struct guest_info * info, void * cfg_data) {
     }
     
     state->pci_bus = pci;
-    strncpy(state->name, cfg->name, 32);
-
-
+    strncpy(state->name, name, 32);
 
 
-    dev = v3_allocate_device("PCI_PASSTHROUGH", &dev_ops, state);
+    dev = v3_allocate_device(name, &dev_ops, state);
 
     if (v3_attach_device(info, dev) == -1) {
-       PrintError("Could not attach device %s\n", "PCI_PASSTHROUGH");
+       PrintError("Could not attach device %s\n", name);
        return -1;
     }
 
 
-    if (find_real_pci_dev(cfg->vendor_id, cfg->device_id, state) == -1) {
-       PrintError("Could not find PCI Device %x:%x\n", cfg->vendor_id, cfg->device_id);
+    if (find_real_pci_dev(atox(v3_cfg_val(cfg, "vendor_id")), 
+                         atox(v3_cfg_val(cfg, "device_id")), 
+                         state) == -1) {
+       PrintError("Could not find PCI Device %s:%s\n", 
+                  v3_cfg_val(cfg, "vendor_id"), 
+                  v3_cfg_val(cfg, "device_id"));
        return 0;
     }
 
     setup_virt_pci_dev(info, dev);
 
-    v3_hook_irq(info, 59, irq_handler, dev);
-    v3_hook_irq(info, 64, irq_handler, dev);
+    v3_hook_irq(info, atoi(v3_cfg_val(cfg, "irq")), irq_handler, dev);
+    //    v3_hook_irq(info, 64, irq_handler, dev);
 
     return 0;
 }
index 8c2872d..377c845 100644 (file)
  
 
 #include <palacios/vmm.h>
+#include <palacios/vmm_dev_mgr.h>
+#include <palacios/vmm_intr.h>
+
 #include <devices/pci.h>
 #include <devices/southbridge.h>
 
+
 struct iort_reg {
     union {
        uint8_t value;
@@ -441,10 +445,11 @@ static int setup_pci(struct vm_device * dev) {
     return 0;
 }
 
-static int piix3_init(struct guest_info * vm, void * cfg_data) {
+static int piix3_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
     struct v3_southbridge * piix3 = (struct v3_southbridge *)V3_Malloc(sizeof(struct v3_southbridge));
     struct vm_device * dev = NULL;
-    struct vm_device * pci = v3_find_dev(vm, (char *)cfg_data);
+    struct vm_device * pci = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
+    char * name = v3_cfg_val(cfg, "name");
 
     if (!pci) {
        PrintError("Could not find PCI device\n");
@@ -454,10 +459,10 @@ static int piix3_init(struct guest_info * vm, void * cfg_data) {
     piix3->pci_bus = pci;
     piix3->type = V3_SB_PIIX3;
     
-    dev = v3_allocate_device("PIIX3", &dev_ops, piix3);
+    dev = v3_allocate_device(name, &dev_ops, piix3);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", "PIIX3");
+       PrintError("Could not attach device %s\n", name);
        return -1;
     }
 
diff --git a/palacios/src/devices/ram_cd.c b/palacios/src/devices/ram_cd.c
deleted file mode 100644 (file)
index 4a3baac..0000000
+++ /dev/null
@@ -1,128 +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) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software.  You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#include <palacios/vmm.h>
-#include <devices/ram_cd.h>
-#include <palacios/vmm_dev_mgr.h>
-#include <devices/ide.h>
-
-#ifndef CONFIG_DEBUG_IDE
-#undef PrintDebug
-#define PrintDebug(fmt, args...)
-#endif
-
-
-struct cd_state {
-    addr_t disk_image;
-    uint32_t capacity; // in bytes
-
-    struct vm_device * ide;
-
-    uint_t bus;
-    uint_t drive;
-};
-
-
-// CDs always read 2048 byte blocks... ?
-static int cd_read(uint8_t * buf, int block_count, uint64_t lba,  void * private_data) {
-    struct vm_device * cd_dev = (struct vm_device *)private_data;
-    struct cd_state * cd = (struct cd_state *)(cd_dev->private_data);
-    int offset = lba * ATAPI_BLOCK_SIZE;
-    int length = block_count * ATAPI_BLOCK_SIZE;
-
-    PrintDebug("Reading RAM CD at (LBA=%d) offset %d (length=%d)\n", (uint32_t)lba, offset, length);
-
-    memcpy(buf, (uint8_t *)(cd->disk_image + offset), length);
-
-    return 0;
-}
-
-
-static uint32_t cd_get_capacity(void * private_data) {
-    struct vm_device * cd_dev = (struct vm_device *)private_data;
-    struct cd_state * cd = (struct cd_state *)(cd_dev->private_data);
-    PrintDebug("Querying RAM CD capacity (bytes=%d) (ret = %d)\n", 
-              cd->capacity, cd->capacity  / ATAPI_BLOCK_SIZE);
-    return cd->capacity / ATAPI_BLOCK_SIZE;
-}
-
-static struct v3_cd_ops cd_ops = {
-    .read = cd_read, 
-    .get_capacity = cd_get_capacity,
-};
-
-
-
-
-static int cd_free(struct vm_device * dev) {
-    return 0;
-}
-
-static struct v3_device_ops dev_ops = {
-    .free = cd_free,
-    .reset = NULL,
-    .start = NULL,
-    .stop = NULL,
-};
-
-
-static int cd_init(struct guest_info * vm, void * cfg_data) {
-    struct cd_state * cd = NULL;
-    struct ram_cd_cfg * cfg = (struct ram_cd_cfg *)cfg_data;
-
-    if (cfg->size % ATAPI_BLOCK_SIZE) {
-       PrintError("CD image must be an integral of block size (ATAPI_BLOCK_SIZE=%d)\n", ATAPI_BLOCK_SIZE);
-       return -1;
-    }
-
-    cd = (struct cd_state *)V3_Malloc(sizeof(struct cd_state));
-
-    PrintDebug("Registering Ram CD at %p (size=%d)\n", (void *)cfg->ramdisk, cfg->size);
-
-  
-    cd->disk_image = cfg->ramdisk;
-    cd->capacity = cfg->size;
-
-    cd->ide = v3_find_dev(vm, cfg->ide);
-
-    if (cd->ide == 0) {
-       PrintError("Could not find backend %s\n", cfg->ide);
-       return -1;
-    }
-
-    cd->bus = cfg->bus;
-    cd->drive = cfg->drive;
-       
-    struct vm_device * dev = v3_allocate_device("RAM-CD", &dev_ops, cd);
-
-    if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", "RAM-CD");
-       return -1;
-    }
-
-
-    if (v3_ide_register_cdrom(cd->ide, cd->bus, cd->drive, "RAM-CD", &cd_ops, dev) == -1) {
-       return -1;
-    }
-    
-    return 0;
-}
-
-
-device_register("RAM-CD", cd_init)
diff --git a/palacios/src/devices/ram_hd.c b/palacios/src/devices/ram_hd.c
deleted file mode 100644 (file)
index c90e5be..0000000
+++ /dev/null
@@ -1,142 +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) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software.  You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#include <palacios/vmm.h>
-#include <devices/ram_hd.h>
-#include <devices/ide.h>
-
-
-
-#ifndef CONFIG_DEBUG_IDE
-#undef PrintDebug
-#define PrintDebug(fmt, args...)
-#endif
-
-struct hd_state {
-    addr_t disk_image;
-    uint32_t capacity; // in bytes
-
-    struct vm_device * ide;
-
-    uint_t bus;
-    uint_t drive;
-};
-
-
-// HDs always read 512 byte blocks... ?
-static int hd_read(uint8_t * buf, int sector_count, uint64_t lba,  void * private_data) {
-    struct vm_device * hd_dev = (struct vm_device *)private_data;
-    struct hd_state * hd = (struct hd_state *)(hd_dev->private_data);
-    int offset = lba * HD_SECTOR_SIZE;
-    int length = sector_count * HD_SECTOR_SIZE;
-
-    //    PrintDebug("Reading RAM HD at (LBA=%d) offset %d (length=%d)\n", (uint32_t)lba, offset, length);
-
-    memcpy(buf, (uint8_t *)(hd->disk_image + offset), length);
-
-    return 0;
-}
-
-
-static int hd_write(uint8_t * buf, int sector_count, uint64_t lba, void * private_data) {
-    struct vm_device * hd_dev = (struct vm_device *)private_data;
-    struct hd_state * hd = (struct hd_state *)(hd_dev->private_data);
-    int offset = lba * HD_SECTOR_SIZE;
-    int length = sector_count * HD_SECTOR_SIZE;
-
-    memcpy((uint8_t *)(hd->disk_image + offset), buf, length);
-
-    return 0;
-}
-
-
-static uint64_t hd_get_capacity(void * private_data) {
-    struct vm_device * hd_dev = (struct vm_device *)private_data;
-    struct hd_state * hd = (struct hd_state *)(hd_dev->private_data);
-    PrintDebug("Querying RAM HD capacity (bytes=%d) (ret = %d)\n", 
-              hd->capacity, hd->capacity  / HD_SECTOR_SIZE);
-    return hd->capacity / HD_SECTOR_SIZE;
-}
-
-static struct v3_hd_ops hd_ops = {
-    .read = hd_read, 
-    .write = hd_write,
-    .get_capacity = hd_get_capacity,
-};
-
-
-
-
-static int hd_free(struct vm_device * dev) {
-    return 0;
-}
-
-static struct v3_device_ops dev_ops = {
-    .free = hd_free,
-    .reset = NULL,
-    .start = NULL,
-    .stop = NULL,
-};
-
-
-
-
-static int hd_init(struct guest_info * vm, void * cfg_data) {
-    struct hd_state * hd = NULL;
-    struct ram_hd_cfg * cfg = (struct ram_hd_cfg *)cfg_data;
-
-    if (cfg->size % HD_SECTOR_SIZE) {
-       PrintError("HD image must be an integral of sector size (HD_SECTOR_SIZE=%d)\n", HD_SECTOR_SIZE);
-       return -1;
-    }
-
-    hd = (struct hd_state *)V3_Malloc(sizeof(struct hd_state));
-
-    PrintDebug("Registering Ram HDD at %p (size=%d)\n", (void *)cfg->ramdisk, cfg->size);
-
-    hd->disk_image = cfg->ramdisk;
-    hd->capacity = cfg->size;
-
-    hd->ide = v3_find_dev(vm, cfg->ide);
-
-    if (hd->ide == 0) {
-       PrintError("Could not find backend %s\n", cfg->ide);
-       return -1;
-    }
-
-    hd->bus = cfg->bus;
-    hd->drive = cfg->drive;
-       
-    struct vm_device * dev = v3_allocate_device("RAM-HD", &dev_ops, hd);
-
-    if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", "RAM-HD");
-       return -1;
-    }
-
-
-    if (v3_ide_register_harddisk(hd->ide, hd->bus, hd->drive, "RAM-HD", &hd_ops, dev) == -1) {
-       return -1;
-    }
-    
-    return 0;
-}
-
-
-device_register("RAM-HD", hd_init)
diff --git a/palacios/src/devices/ramdisk.c b/palacios/src/devices/ramdisk.c
new file mode 100644 (file)
index 0000000..9a2e716
--- /dev/null
@@ -0,0 +1,137 @@
+/* 
+ * 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) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software.  You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#include <palacios/vmm.h>
+#include <palacios/vmm_dev_mgr.h>
+
+
+#ifndef CONFIG_DEBUG_RAMDISK
+#undef PrintDebug
+#define PrintDebug(fmt, args...)
+#endif
+
+struct disk_state {
+    uint8_t * disk_image;
+    uint32_t capacity; // in bytes
+};
+
+
+static int read(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * private_data) {
+    struct disk_state * disk = (struct disk_state *)private_data;
+
+    PrintDebug("Reading %d bytes from %p to %p\n", (uint32_t)num_bytes, (uint8_t *)(disk->disk_image + lba), buf);
+
+    memcpy(buf, (uint8_t *)(disk->disk_image + lba), num_bytes);
+
+    return 0;
+}
+
+
+static int write(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * private_data) {
+    struct disk_state * disk = (struct disk_state *)private_data;
+
+    PrintDebug("Writing %d bytes from %p to %p\n", (uint32_t)num_bytes,  buf, (uint8_t *)(disk->disk_image + lba));
+
+    memcpy((uint8_t *)(disk->disk_image + lba), buf, num_bytes);
+
+    return 0;
+}
+
+
+static uint64_t get_capacity(void * private_data) {
+    struct disk_state * disk = (struct disk_state *)private_data;
+
+    PrintDebug("Querying RAMDISK capacity %d\n", 
+              (uint32_t)(disk->capacity));
+
+    return disk->capacity;
+}
+
+static struct v3_dev_blk_ops blk_ops = {
+    .read = read, 
+    .write = write,
+    .get_capacity = get_capacity,
+};
+
+
+
+
+static int disk_free(struct vm_device * dev) {
+    return 0;
+}
+
+static struct v3_device_ops dev_ops = {
+    .free = disk_free,
+    .reset = NULL,
+    .start = NULL,
+    .stop = NULL,
+};
+
+
+
+
+static int disk_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+    struct disk_state * disk = NULL;
+    struct v3_cfg_file * file = NULL;
+    char * name = v3_cfg_val(cfg, "name");
+    char * filename = v3_cfg_val(cfg, "file");
+
+    v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend");
+
+    disk = (struct disk_state *)V3_Malloc(sizeof(struct disk_state));
+    memset(disk, 0, sizeof(struct disk_state));
+
+
+    if (!filename) {
+       PrintError("Missing filename (%s) for %s\n", filename, name);
+       return -1;
+    }
+
+    file = v3_cfg_get_file(vm, filename);
+
+    if (!file) {
+       PrintError("Invalid ramdisk file: %s\n", filename);
+       return -1;
+    }
+
+    disk->disk_image = file->data;
+    disk->capacity = file->size;
+    PrintDebug("Registering RAMDISK at %p (size=%d)\n", 
+              (void *)file->data, (uint32_t)file->size);
+
+    struct vm_device * dev = v3_allocate_device(name, &dev_ops, disk);
+
+    if (v3_attach_device(vm, dev) == -1) {
+       PrintError("Could not attach device %s\n", name);
+       return -1;
+    }
+
+    if (v3_dev_connect_blk(vm, v3_cfg_val(frontend_cfg, "tag"), 
+                          &blk_ops, frontend_cfg, disk) == -1) {
+       PrintError("Could not connect %s to frontend %s\n", 
+                  name, v3_cfg_val(frontend_cfg, "tag"));
+       return -1;
+    }
+    
+
+    return 0;
+}
+
+
+device_register("RAMDISK", disk_init)
index d6740c4..dad0419 100644 (file)
 
 #include <palacios/vmm.h>
 #include <palacios/vmm_dev_mgr.h>
-#include <devices/lnx_virtio_blk.h>
 #include <palacios/vmm_sym_swap.h>
 
-#define SWAP_CAPACITY (150 * 1024 * 1024)
 
 #ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY
 #include <palacios/vmm_telemetry.h>
@@ -55,8 +53,6 @@ union swap_header {
 struct swap_state {
     int active;
 
-    struct vm_device * blk_dev;
-
     uint_t swapped_pages;
     uint_t unswapped_pages;
 
@@ -134,7 +130,7 @@ static uint64_t swap_get_capacity(void * private_data) {
 
     PrintDebug("SymSwap: Getting Capacity %d\n", (uint32_t)(swap->capacity));
 
-    return swap->capacity / HD_SECTOR_SIZE;
+    return swap->capacity;
 }
 
 
@@ -144,11 +140,11 @@ static struct v3_swap_ops swap_ops = {
 
 
 
-static int swap_read(uint8_t * buf, int sector_count, uint64_t lba,  void * private_data) {
+static int swap_read(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * private_data) {
     struct vm_device * dev = (struct vm_device *)private_data;
     struct swap_state * swap = (struct swap_state *)(dev->private_data);
-    uint32_t offset = lba * HD_SECTOR_SIZE;
-    uint32_t length = sector_count * HD_SECTOR_SIZE;
+    uint32_t offset = lba;
+    uint32_t length = num_bytes;
 
   
     /*  
@@ -184,11 +180,11 @@ static int swap_read(uint8_t * buf, int sector_count, uint64_t lba,  void * priv
 
 
 
-static int swap_write(uint8_t * buf, int sector_count, uint64_t lba, void * private_data) {
+static int swap_write(uint8_t * buf,  uint64_t lba, uint64_t num_bytes, void * private_data) {
     struct vm_device * dev = (struct vm_device *)private_data;
     struct swap_state * swap = (struct swap_state *)(dev->private_data);
-    uint32_t offset = lba * HD_SECTOR_SIZE;
-    uint32_t length = sector_count * HD_SECTOR_SIZE;
+    uint32_t offset = lba;
+    uint32_t length = num_bytes;
 
     /*
       PrintDebug("SymSwap: Writing %d bytes to %p from %p\n", length, 
@@ -242,7 +238,7 @@ static int swap_free(struct vm_device * dev) {
 }
 
 
-static struct v3_hd_ops hd_ops = {
+static struct v3_dev_blk_ops blk_ops = {
     .read = swap_read, 
     .write = swap_write, 
     .get_capacity = swap_get_capacity,
@@ -274,26 +270,22 @@ static void telemetry_cb(struct guest_info * info, void * private_data, char * h
 
 
 
-static int swap_init(struct guest_info * vm, void * cfg_data) {
+static int swap_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
     struct swap_state * swap = NULL;
-    struct vm_device * virtio_blk = v3_find_dev(vm, (char *)cfg_data);
+    v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend");
+    uint32_t capacity = atoi(v3_cfg_val(cfg, "size")) * 1024 * 1024;
+    char * name = v3_cfg_val(cfg, "name");
 
-    if (!virtio_blk) {
-       PrintError("could not find Virtio backend\n");
+    if (!frontend_cfg) {
+       PrintError("Initializing sym swap without a frontend device\n");
        return -1;
     }
 
     PrintDebug("Creating Swap Device\n");
 
-    if (virtio_blk == NULL) {
-       PrintError("Swap device requires a virtio block device\n");
-       return -1;
-    }
-
-    swap = (struct swap_state *)V3_Malloc(sizeof(struct swap_state) + ((SWAP_CAPACITY / 4096) / 8));
+    swap = (struct swap_state *)V3_Malloc(sizeof(struct swap_state) + ((capacity / 4096) / 8));
 
-    swap->blk_dev = virtio_blk;
-    swap->capacity = SWAP_CAPACITY;
+    swap->capacity = capacity;
 
     swap->swapped_pages = 0;
     swap->unswapped_pages = 0;
@@ -301,22 +293,25 @@ static int swap_init(struct guest_info * vm, void * cfg_data) {
     swap->active = 0;
     swap->hdr = (union swap_header *)swap;
 
-
     swap->swap_base_addr = (addr_t)V3_AllocPages(swap->capacity / 4096);
     swap->swap_space = (uint8_t *)V3_VAddr((void *)(swap->swap_base_addr));
-    memset(swap->swap_space, 0, SWAP_CAPACITY);
+    memset(swap->swap_space, 0, swap->capacity);
 
-    memset(swap->usage_map, 0, ((SWAP_CAPACITY / 4096) / 8));
+    memset(swap->usage_map, 0, ((swap->capacity / 4096) / 8));
 
-    struct vm_device * dev = v3_allocate_device("SYM_SWAP", &dev_ops, swap);
+    struct vm_device * dev = v3_allocate_device(name, &dev_ops, swap);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", "SYM_SWAP");
+       PrintError("Could not attach device %s\n", name);
        return -1;
     }
 
-
-    v3_virtio_register_harddisk(virtio_blk, &hd_ops, dev);
+    if (v3_dev_connect_blk(vm, v3_cfg_val(frontend_cfg, "tag"), 
+                          &blk_ops, frontend_cfg, swap) == -1) {
+       PrintError("Could not connect %s to frontend %s\n", 
+                  name, v3_cfg_val(frontend_cfg, "tag"));
+       return -1;
+    }
 
 #ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY
     if (vm->enable_telemetry) {
index 4abe5a0..30e07d1 100644 (file)
@@ -519,23 +519,24 @@ static int cons_server(void * arg) {
 }
 
 
-static int cons_init(struct guest_info * vm, void * cfg_data) {
-    struct telnet_cons_cfg * cfg = (struct telnet_cons_cfg *)cfg_data;
+static int cons_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
     struct cons_state * state = (struct cons_state *)V3_Malloc(sizeof(struct cons_state));
-    struct vm_device * frontend = v3_find_dev(vm, cfg->frontend);
+    v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend");
+    struct vm_device * frontend = v3_find_dev(vm, v3_cfg_val(frontend_cfg, "id"));
+    char * name = v3_cfg_val(cfg, "name");
 
 
     state->server_fd = 0;
     state->client_fd = 0;
     state->frontend_dev = frontend;
-    state->port = cfg->port;
+    state->port = atoi(v3_cfg_val(cfg, "port"));
     v3_lock_init(&(state->cons_lock));
 
 
-    struct vm_device * dev = v3_allocate_device("TELNET_CONS", &dev_ops, state);
+    struct vm_device * dev = v3_allocate_device(name, &dev_ops, state);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", "TELNET_CONS");
+       PrintError("Could not attach device %s\n", name);
        return -1;
     }
 
diff --git a/palacios/src/devices/tmp_blk.c b/palacios/src/devices/tmp_blk.c
deleted file mode 100644 (file)
index b8e08b2..0000000
+++ /dev/null
@@ -1,141 +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) 2008, Jack Lange <jarusl@cs.northwestern.edu>
- * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
- * All rights reserved.
- *
- * Author: Jack Lange <jarusl@cs.northwestern.edu>
- *
- * This is free software.  You are permitted to use,
- * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
- */
-
-#include <palacios/vmm.h>
-#include <palacios/vmm_dev_mgr.h>
-#include <devices/lnx_virtio_blk.h>
-
-
-#define BLK_CAPACITY (500 * 1024 * 1024)
-
-
-
-
-struct blk_state {
-
-    struct vm_device * blk_dev;
-
-    uint64_t capacity;
-    uint8_t * blk_space;
-    addr_t blk_base_addr;
-};
-
-
-
-static uint64_t blk_get_capacity(void * private_data) {
-    struct vm_device * dev = (struct vm_device *)private_data;
-    struct blk_state * blk = (struct blk_state *)(dev->private_data);
-
-    PrintDebug("SymBlk: Getting Capacity %d\n", (uint32_t)(blk->capacity));
-
-    return blk->capacity / HD_SECTOR_SIZE;
-}
-
-
-
-static int blk_read(uint8_t * buf, int sector_count, uint64_t lba,  void * private_data) {
-    struct vm_device * dev = (struct vm_device *)private_data;
-    struct blk_state * blk = (struct blk_state *)(dev->private_data);
-    uint32_t offset = lba * HD_SECTOR_SIZE;
-    uint32_t length = sector_count * HD_SECTOR_SIZE;
-
-    memcpy(buf, blk->blk_space + offset, length);
-
-    return 0;
-}
-
-
-
-
-static int blk_write(uint8_t * buf, int sector_count, uint64_t lba, void * private_data) {
-    struct vm_device * dev = (struct vm_device *)private_data;
-    struct blk_state * blk = (struct blk_state *)(dev->private_data);
-    uint32_t offset = lba * HD_SECTOR_SIZE;
-    uint32_t length = sector_count * HD_SECTOR_SIZE;
-
-    memcpy(blk->blk_space + offset, buf, length);
-
-    return 0;
-}
-
-
-static int blk_free(struct vm_device * dev) {
-    return -1;
-}
-
-
-static struct v3_hd_ops hd_ops = {
-    .read = blk_read, 
-    .write = blk_write, 
-    .get_capacity = blk_get_capacity,
-};
-
-
-
-static struct v3_device_ops dev_ops = {
-    .free = blk_free,
-    .reset = NULL,
-    .start = NULL,
-    .stop = NULL,
-};
-
-
-
-
-static int blk_init(struct guest_info * vm, void * cfg_data) {
-    struct blk_state * blk = NULL;
-    struct vm_device * virtio_blk = v3_find_dev(vm, (char *)cfg_data);
-
-    if (!virtio_blk) {
-       PrintError("could not find Virtio backend\n");
-       return -1;
-    }
-
-    PrintDebug("Creating Blk Device\n");
-
-    if (virtio_blk == NULL) {
-       PrintError("Blk device requires a virtio block device\n");
-       return -1;
-    }
-
-    blk = (struct blk_state *)V3_Malloc(sizeof(struct blk_state) + ((BLK_CAPACITY / 4096) / 8));
-
-    blk->blk_dev = virtio_blk;
-    blk->capacity = BLK_CAPACITY;
-
-    blk->blk_base_addr = (addr_t)V3_AllocPages(blk->capacity / 4096);
-    blk->blk_space = (uint8_t *)V3_VAddr((void *)(blk->blk_base_addr));
-    memset(blk->blk_space, 0, BLK_CAPACITY);
-
-
-    struct vm_device * dev = v3_allocate_device("TMP_BLK", &dev_ops, blk);
-
-    if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", "TMP_BLK");
-       return -1;
-    }
-
-
-    v3_virtio_register_harddisk(virtio_blk, &hd_ops, dev);
-
-
-    return 0;
-}
-
-device_register("TMP_BLK", blk_init)
diff --git a/palacios/src/devices/tmpdisk.c b/palacios/src/devices/tmpdisk.c
new file mode 100644 (file)
index 0000000..a40aa55
--- /dev/null
@@ -0,0 +1,126 @@
+/* 
+ * 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) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software.  You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#include <palacios/vmm.h>
+#include <palacios/vmm_dev_mgr.h>
+
+
+struct blk_state {
+    uint64_t capacity;
+    uint8_t * blk_space;
+    addr_t blk_base_addr;
+};
+
+
+
+static uint64_t blk_get_capacity(void * private_data) {
+    struct blk_state * blk = (struct blk_state *)private_data;
+
+    PrintDebug("SymBlk: Getting Capacity %d\n", (uint32_t)(blk->capacity));
+
+    return blk->capacity;
+}
+
+
+
+static int blk_read(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * private_data) {
+    struct blk_state * blk = (struct blk_state *)private_data;
+
+    memcpy(buf, blk->blk_space + lba, num_bytes);
+
+    return 0;
+}
+
+
+
+
+static int blk_write(uint8_t * buf,  uint64_t lba, uint64_t num_bytes, void * private_data) {
+    struct blk_state * blk = (struct blk_state *)private_data;
+
+    memcpy(blk->blk_space + lba, buf, num_bytes);
+
+    return 0;
+}
+
+
+static int blk_free(struct vm_device * dev) {
+    return -1;
+}
+
+
+static struct v3_dev_blk_ops blk_ops = {
+    .read = blk_read, 
+    .write = blk_write, 
+    .get_capacity = blk_get_capacity,
+};
+
+
+
+static struct v3_device_ops dev_ops = {
+    .free = blk_free,
+    .reset = NULL,
+    .start = NULL,
+    .stop = NULL,
+};
+
+
+
+
+static int blk_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+    struct blk_state * blk = NULL;
+    v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend");
+    char * name = v3_cfg_val(cfg, "name");
+    uint64_t capacity = atoi(v3_cfg_val(cfg, "size"));
+    
+    if (!frontend_cfg) {
+       PrintError("Frontend Configuration not present\n");
+       return -1;
+    }
+
+    PrintDebug("Creating Blk Device\n");
+
+
+    blk = (struct blk_state *)V3_Malloc(sizeof(struct blk_state) + ((capacity / 4096) / 8));
+
+    blk->capacity = capacity;
+
+    blk->blk_base_addr = (addr_t)V3_AllocPages(capacity / 4096);
+    blk->blk_space = (uint8_t *)V3_VAddr((void *)(blk->blk_base_addr));
+    memset(blk->blk_space, 0, capacity);
+
+
+    struct vm_device * dev = v3_allocate_device(name, &dev_ops, blk);
+
+    if (v3_attach_device(vm, dev) == -1) {
+       PrintError("Could not attach device %s\n", name);
+       return -1;
+    }
+
+    if (v3_dev_connect_blk(vm, v3_cfg_val(frontend_cfg, "tag"), 
+                          &blk_ops, frontend_cfg, blk) == -1) {
+       PrintError("Could not connect %s to frontend %s\n", 
+                  name, v3_cfg_val(frontend_cfg, "tag"));
+       return -1;
+    }
+
+
+    return 0;
+}
+
+device_register("TMPDISK", blk_init)
index ba7f5b3..09fe744 100644 (file)
@@ -39,7 +39,6 @@
 #include <palacios/vmm_direct_paging.h>
 
 #include <palacios/vmm_ctrl_regs.h>
-#include <palacios/vmm_config.h>
 #include <palacios/svm_io.h>
 
 #include <palacios/vmm_sprintf.h>
@@ -267,18 +266,18 @@ static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info * vm_info) {
 }
 
 
-static int init_svm_guest(struct guest_info * info, struct v3_vm_config * config_ptr) {
-
-
-    v3_pre_config_guest(info, config_ptr);
+int v3_init_svm_vmcb(struct guest_info * info, v3_vm_class_t vm_class) {
 
     PrintDebug("Allocating VMCB\n");
     info->vmm_data = (void*)Allocate_VMCB();
-
-    PrintDebug("Initializing VMCB (addr=%p)\n", (void *)info->vmm_data);
-    Init_VMCB_BIOS((vmcb_t*)(info->vmm_data), info);
-
-    v3_post_config_guest(info, config_ptr);
+    
+    if (vm_class == V3_PC_VM) {
+       PrintDebug("Initializing VMCB (addr=%p)\n", (void *)info->vmm_data);
+       Init_VMCB_BIOS((vmcb_t*)(info->vmm_data), info);
+    } else {
+       PrintError("Invalid VM class\n");
+       return -1;
+    }
 
     return 0;
 }
@@ -530,7 +529,7 @@ int v3_svm_enter(struct guest_info * info) {
 }
 
 
-static int start_svm_guest(struct guest_info *info) {
+int v3_start_svm_guest(struct guest_info *info) {
     //    vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
     //  vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
 
@@ -690,15 +689,6 @@ void v3_init_svm_cpu(int cpu_id) {
 }
 
 
-void v3_init_svm_hooks(struct v3_ctrl_ops * vmm_ops) {
-
-    // Setup the SVM specific vmm operations
-    vmm_ops->init_guest = &init_svm_guest;
-    vmm_ops->start_guest = &start_svm_guest;
-    vmm_ops->has_nested_paging = &has_svm_nested_paging;
-
-    return;
-}
 
 
 
index 82614f1..dabe82d 100644 (file)
@@ -21,7 +21,7 @@
 #include <palacios/vmm_msr.h>
 #include <palacios/vmm_sprintf.h>
 #include <palacios/vmm_list.h>
-
+#include <palacios/vm_guest.h>
 
 #define PENTIUM_MSRS_START            0x00000000
 #define PENTIUM_MSRS_END              0x00001fff
index 1571c48..0a53a7f 100644 (file)
@@ -38,6 +38,9 @@ struct v3_os_hooks * os_hooks = NULL;
 
 
 
+
+
+
 static struct guest_info * allocate_guest() {
     void * info = V3_Malloc(sizeof(struct guest_info));
     memset(info, 0, sizeof(struct guest_info));
@@ -45,24 +48,14 @@ static struct guest_info * allocate_guest() {
 }
 
 
-struct vmm_init_arg {
-    int cpu_id;
-    struct v3_ctrl_ops * vmm_ops;
-};
-
 static void init_cpu(void * arg) {
-    struct vmm_init_arg * vmm_arg = (struct vmm_init_arg *)arg;
-    int cpu_id = vmm_arg->cpu_id;
-    struct v3_ctrl_ops * vmm_ops = vmm_arg->vmm_ops;
+    uint32_t cpu_id = (uint32_t)(addr_t)arg;
 
 #ifdef CONFIG_SVM
     if (v3_is_svm_capable()) {
         PrintDebug("Machine is SVM Capable\n");
         v3_init_svm_cpu(cpu_id);
        
-       if (cpu_id == 0) {
-           v3_init_svm_hooks(vmm_ops);
-       }
     } else 
 #endif
 #ifdef CONFIG_VMX
@@ -70,9 +63,6 @@ static void init_cpu(void * arg) {
        PrintDebug("Machine is VMX Capable\n");
        v3_init_vmx_cpu(cpu_id);
 
-       if (cpu_id == 0) {
-           v3_init_vmx_hooks(vmm_ops);
-       }       
     } else 
 #endif
     {
@@ -82,10 +72,10 @@ static void init_cpu(void * arg) {
 
 
 
-void Init_V3(struct v3_os_hooks * hooks, struct v3_ctrl_ops * vmm_ops, int num_cpus) {
+
+
+void Init_V3(struct v3_os_hooks * hooks, int num_cpus) {
     int i;
-    struct vmm_init_arg arg;
-    arg.vmm_ops = vmm_ops;    
 
     // Set global variables. 
     os_hooks = hooks;
@@ -97,27 +87,68 @@ void Init_V3(struct v3_os_hooks * hooks, struct v3_ctrl_ops * vmm_ops, int num_c
     // Register all the possible device types
     v3_init_devices();
 
-
 #ifdef INSTRUMENT_VMM
     v3_init_instrumentation();
 #endif
 
-    vmm_ops->allocate_guest = &allocate_guest;
-
-
     if ((hooks) && (hooks->call_on_cpu)) {
 
        for (i = 0; i < num_cpus; i++) {
-           arg.cpu_id = i;
 
            V3_Print("Initializing VMM extensions on cpu %d\n", i);
-           hooks->call_on_cpu(i, &init_cpu, &arg);
+           hooks->call_on_cpu(i, &init_cpu, (void *)(addr_t)i);
        }
     }
+}
+
+v3_cpu_arch_t v3_get_cpu_type(int cpu_id) {
+    return v3_cpu_types[cpu_id];
+}
 
 
+struct guest_info * v3_create_vm(void * cfg) {
+    struct guest_info * info = allocate_guest();
+    
+    if (!info) {
+       PrintError("Could not allocate Guest\n");
+       return NULL;
+    }
+
+    if (v3_config_guest(info, cfg) == -1) {
+       PrintError("Could not configure guest\n");
+       return NULL;
+    }
+
+    return info;
 }
 
+int v3_start_vm(struct guest_info * info, unsigned int cpu_mask) {
+    
+    info->cpu_id = v3_get_cpu_id();
+
+    V3_Print("V3 --  Starting VM\n");
+
+    switch (v3_cpu_types[info->cpu_id]) {
+#ifdef CONFIG_SVM
+       case V3_SVM_CPU:
+       case V3_SVM_REV3_CPU:
+           return v3_start_svm_guest(info);
+           break;
+#endif
+#if CONFIG_VMX && 0
+       case V3_VMX_CPU:
+       case V3_VMX_EPT_CPU:
+           return v3_start_vmx_guest(info);
+           break;
+#endif
+       default:
+           PrintError("Attemping to enter a guest on an invalid CPU\n");
+           return -1;
+    }
+
+
+    return 0;
+}
 
 
 #ifdef __V3_32BIT__
@@ -199,6 +230,21 @@ void v3_interrupt_cpu(struct guest_info * info, int logical_cpu) {
 
 
 
+unsigned int v3_get_cpu_id() {
+    extern struct v3_os_hooks * os_hooks;
+    unsigned int ret = (unsigned int)-1;
+
+    if ((os_hooks) && (os_hooks)->get_cpu) {
+       ret = os_hooks->get_cpu();
+    }
+
+    return ret;
+}
+
+
+
+
+
 int v3_vm_enter(struct guest_info * info) {
     switch (v3_cpu_types[info->cpu_id]) {
 #ifdef CONFIG_SVM
@@ -218,3 +264,6 @@ int v3_vm_enter(struct guest_info * info) {
            return -1;
     }
 }
+
+
+
index 886aee7..627bb84 100644 (file)
@@ -29,6 +29,9 @@
 #include <palacios/vmm_cpuid.h>
 #include <palacios/vmm_xml.h>
 
+#include <palacios/svm.h>
+#include <palacios/vmx.h>
+
 #ifdef CONFIG_SYMBIOTIC
 #include <palacios/vmm_sym_iface.h>
 
 
 #endif
 
-#include <devices/generic.h>
-#include <devices/ide.h>
-#include <devices/ram_cd.h>
-#include <devices/net_cd.h>
-#include <devices/ram_hd.h>
-#include <devices/net_hd.h>
 
-#include <devices/telnet_cons.h>
-#include <devices/pci_passthrough.h>
+#include <palacios/vmm_host_events.h>
+#include <palacios/vmm_socket.h>
 
+#include "vmm_config_class.h"
 
-/*
-static const char * test_cfg_xml = \
-"<root>\n \
-<memory>2048</memory>\n\
-<devices>\n\
-<device id=\"PCI\" />\n\
-<device id=\"IDE\"  />\n\
-</devices>\n\
-</root>";
-*/
+// This is used to access the configuration file index table
+struct file_hdr {
+    uint32_t index;
+    uint32_t size;
+    uint64_t offset;
+};
 
+struct file_idx_table {
+    uint64_t num_files;
+    struct file_hdr hdrs[0];
+};
 
 
-#include <palacios/vmm_host_events.h>
 
 
+static int setup_memory_map(struct guest_info * info, struct v3_config * config_ptr);
+static int setup_devices(struct guest_info * info, struct v3_config * config_ptr);
 
-#include <palacios/vmm_socket.h>
+
+char * v3_cfg_val(v3_cfg_tree_t * tree, char * tag) {
+    char * attrib = (char *)v3_xml_attr(tree, tag);
+    v3_cfg_tree_t * child_entry = v3_xml_child(tree, tag);
+    char * val = NULL;
+
+    if ((child_entry != NULL) && (attrib != NULL)) {
+       PrintError("Duplicate Configuration parameters present for %s\n", tag);
+       return NULL;
+    }
+
+    val = (attrib == NULL) ? v3_xml_txt(child_entry): attrib;
+
+    return val; 
+}
+
+v3_cfg_tree_t * v3_cfg_subtree(v3_cfg_tree_t * tree, char * tag) {
+    return v3_xml_child(tree, tag);
+}
+
+v3_cfg_tree_t * v3_cfg_next_branch(v3_cfg_tree_t * tree) {
+    return v3_xml_next(tree);
+}
 
 
-static int setup_memory_map(struct guest_info * info, struct v3_vm_config * config_ptr);
-static int setup_devices(struct guest_info * info, struct v3_vm_config * config_ptr);
-static int configure_generic(struct guest_info * info, struct v3_vm_config * config_ptr);
 
+struct v3_cfg_file * v3_cfg_get_file(struct guest_info * info, char * tag) {
+    struct v3_cfg_file * file = NULL;
 
+    file = (struct v3_cfg_file *)v3_htable_search(info->cfg_data->file_table, (addr_t)tag);
+
+    return file;
+}
+
+
+static uint_t file_hash_fn(addr_t key) {
+    char * name = (char *)key;
+    return v3_hash_buffer((uchar_t *)name, strlen(name));
+}
 
-#ifdef CONFIG_PASSTHROUGH_VIDEO
-static int passthrough_mem_write(addr_t guest_addr, void * src, uint_t length, void * priv_data) {
+static int file_eq_fn(addr_t key1, addr_t key2) {
+    char * name1 = (char *)key1;
+    char * name2 = (char *)key2;
 
-    return length;
-    //  memcpy((void*)guest_addr, src, length);
-    PrintDebug("Write of %d bytes to %p\n", length, (void *)guest_addr);
-    PrintDebug("Write Value = %p\n", (void *)*(addr_t *)src);
+    return (strcmp(name1, name2) == 0);
+}
+
+static struct v3_config * parse_config(void * cfg_blob) {
+    struct v3_config * cfg = NULL;
+    int offset = 0;
+    uint_t xml_len = 0; 
+    struct file_idx_table * files = NULL;
+    v3_cfg_tree_t * file_tree = NULL;
+
+    V3_Print("cfg data at %p\n", cfg_blob);
+
+    if (memcmp(cfg_blob, "v3vee\0\0\0", 8) != 0) {
+       PrintError("Invalid Configuration Header\n");
+       return NULL;
+    }
+
+    offset += 8;
+
+    cfg = (struct v3_config *)V3_Malloc(sizeof(struct v3_config));
+    memset(cfg, 0, sizeof(struct v3_config));
+
+    cfg->blob = cfg_blob;
+    INIT_LIST_HEAD(&(cfg->file_list));
+    cfg->file_table = v3_create_htable(0, file_hash_fn, file_eq_fn);
     
-    return length;
+    xml_len = *(uint32_t *)(cfg_blob + offset);
+    offset += 4;
+
+    cfg->cfg = (v3_cfg_tree_t *)v3_xml_parse((uint8_t *)(cfg_blob + offset));
+    offset += xml_len;
+   
+    offset += 8;
+
+    files = (struct file_idx_table *)(cfg_blob + offset);
+
+    V3_Print("Number of files in cfg: %d\n", (uint32_t)(files->num_files));
+
+    file_tree = v3_cfg_subtree(v3_cfg_subtree(cfg->cfg, "files"), "file");
+
+    while (file_tree) {
+       char * id = v3_cfg_val(file_tree, "id");
+       char * index = v3_cfg_val(file_tree, "index");
+       int idx = atoi(index);
+       struct file_hdr * hdr = &(files->hdrs[idx]);
+       struct v3_cfg_file * file = NULL;
+
+       file = (struct v3_cfg_file *)V3_Malloc(sizeof(struct v3_cfg_file));
+       
+       if (!file) {
+           PrintError("Could not allocate file structure\n");
+           return NULL;
+       }
+
+
+       V3_Print("File index=%d id=%s\n", idx, id);
+
+       strncpy(file->tag, id, 256);
+       file->size = hdr->size;
+       file->data = cfg_blob + hdr->offset;
+
+       V3_Print("Storing file data offset = %d, size=%d\n", (uint32_t)hdr->offset, hdr->size);
+       V3_Print("file data at %p\n", file->data);
+       list_add( &(file->file_node), &(cfg->file_list));
+
+       V3_Print("Keying file to name\n");
+       v3_htable_insert(cfg->file_table, (addr_t)(file->tag), (addr_t)(file));
+
+       V3_Print("Iterating to next file\n");
+
+       file_tree = v3_cfg_next_branch(file_tree);
+    }
+
+    V3_Print("Configuration parsed successfully\n");
+
+    return cfg;
 }
-#endif
 
-int v3_pre_config_guest(struct guest_info * info, struct v3_vm_config * config_ptr) {
-   extern v3_cpu_arch_t v3_cpu_types[];
-
-
-   /*
-   {
-       struct v3_xml * cfg = v3_xml_parse((char *)test_cfg_xml);
-       struct v3_xml * devs = NULL;
-       struct v3_xml * tmp = NULL;
-       PrintError("Parsed XML COnfig %s\n", v3_xml_name(cfg));
-       
-       PrintError("memory=%s\n", v3_xml_txt(v3_xml_child(cfg, "memory")));
-       
-       devs = v3_xml_child(cfg, "devices");
-       
-       for (tmp = v3_xml_child(devs, "device"); tmp; tmp = v3_xml_next(tmp)) {
-          PrintError("Device: %s, id=%s\n", 
-                     v3_xml_name(tmp), 
-                     v3_xml_attr(tmp, "id"));
-       }
-       v3_xml_free(cfg);
-       
-       return -1;
-   }
-   */
-
-    // Amount of ram the Guest will have, rounded to a 4K page boundary
-    info->mem_size = config_ptr->mem_size & ~(addr_t)0xfff;
-
-    info->cpu_id = config_ptr->guest_cpu;
+
+static int pre_config_guest(struct guest_info * info, struct v3_config * config_ptr) {
+    extern v3_cpu_arch_t v3_cpu_types[];
+    char * memory_str = v3_cfg_val(config_ptr->cfg, "memory");
+    char * paging = v3_cfg_val(config_ptr->cfg, "paging");
+    char * schedule_hz_str = v3_cfg_val(config_ptr->cfg, "schedule_hz");
+    char * vm_class = v3_cfg_val(config_ptr->cfg, "class");
+    uint32_t sched_hz = 100;   // set the schedule frequency to 100 HZ
+    
+    if (!memory_str) {
+       PrintError("Memory is a required configuration parameter\n");
+       return -1;
+    }
+    
+    PrintDebug("Memory=%s\n", memory_str);
+
+    // Amount of ram the Guest will have, always in MB
+    info->mem_size = atoi(memory_str) * 1024 * 1024;
+    
+    if (strcasecmp(vm_class, "PC") == 0) {
+       info->vm_class = V3_PC_VM;
+    } else {
+       PrintError("Invalid VM class\n");
+       return -1;
+    }
+
 
     /*
      * Initialize the subsystem data strutures
      */
 #ifdef CONFIG_TELEMETRY
-    // This should go first, because other subsystems will depend on the guest_info flag
-    if (config_ptr->enable_telemetry) {
-       info->enable_telemetry = 1;
-       v3_init_telemetry(info);
-    } else {
-       info->enable_telemetry = 0;
+    {
+       char * telemetry = v3_cfg_val(config_ptr->cfg, "telemetry");
+
+       // This should go first, because other subsystems will depend on the guest_info flag    
+       if ((telemetry) && (strcasecmp(telemetry, "enable") == 0)) {
+           info->enable_telemetry = 1;
+           v3_init_telemetry(info);
+       } else {
+           info->enable_telemetry = 0;
+       }
     }
 #endif
 
@@ -144,7 +244,7 @@ int v3_pre_config_guest(struct guest_info * info, struct v3_vm_config * config_p
     }
     
     if ((v3_cpu_types[info->cpu_id] == V3_SVM_REV3_CPU) && 
-       (config_ptr->enable_nested_paging == 1)) {
+       (paging) && (strcasecmp(paging, "nested") == 0)) {
        PrintDebug("Guest Page Mode: NESTED_PAGING\n");
        info->shdw_pg_mode = NESTED_PAGING;
     } else {
@@ -168,25 +268,22 @@ int v3_pre_config_guest(struct guest_info * info, struct v3_vm_config * config_p
     v3_init_sym_swap(info);
 #endif
 
-
-    if (config_ptr->schedule_freq == 0) {
-       // set the schedule frequency to 100 HZ
-       config_ptr->schedule_freq = 100;
+    if (schedule_hz_str) {
+       sched_hz = atoi(schedule_hz_str);
     }
 
-    PrintDebug("CPU_KHZ = %d, schedule_freq=%p\n", V3_CPU_KHZ(), (void *)config_ptr->schedule_freq);
+    PrintDebug("CPU_KHZ = %d, schedule_freq=%p\n", V3_CPU_KHZ(), 
+              (void *)(addr_t)sched_hz);
 
-    info->yield_cycle_period = (V3_CPU_KHZ() * 1000) / config_ptr->schedule_freq;
+    info->yield_cycle_period = (V3_CPU_KHZ() * 1000) / sched_hz;
     
-    // Initial CPU operating mode
-    info->cpu_mode = REAL;
-    info->mem_mode = PHYSICAL_MEM;
+
 
     return 0;
 }
 
 
-int v3_post_config_guest(struct guest_info * info, struct v3_vm_config * config_ptr) {
+static int post_config_guest(struct guest_info * info, struct v3_config * config_ptr) {
 
     // Configure the memory map for the guest
     if (setup_memory_map(info, config_ptr) == -1) {
@@ -206,346 +303,134 @@ int v3_post_config_guest(struct guest_info * info, struct v3_vm_config * config_
 
     info->run_state = VM_STOPPED;
 
-    info->vm_regs.rdi = 0;
-    info->vm_regs.rsi = 0;
-    info->vm_regs.rbp = 0;
-    info->vm_regs.rsp = 0;
-    info->vm_regs.rbx = 0;
-    info->vm_regs.rdx = 0;
-    info->vm_regs.rcx = 0;
-    info->vm_regs.rax = 0;
-
-    return 0;
-}
-
-
-
-
-
-/* TODO:
- * The amount of guest memory is stored in info->mem_size
- * We need to make sure the memory map extends to cover it
- */
-static int setup_memory_map(struct guest_info * info, struct v3_vm_config * config_ptr) {
-
-#ifdef CONFIG_PASSTHROUGH_VIDEO
-    PrintDebug("Setting up memory map (memory size=%dMB)\n", (uint_t)(info->mem_size / (1024 * 1024)));
-    
-    // VGA frame buffer
-    if (1) {
-       if (v3_add_shadow_mem(info, 0xa0000, 0xc0000, 0xa0000) == -1) {
-           PrintError("Could not map VGA framebuffer\n");
+    if (info->vm_class == V3_PC_VM) {
+       if (post_config_pc(info, config_ptr) == -1) {
+           PrintError("PC Post configuration failure\n");
            return -1;
        }
     } else {
-       v3_hook_write_mem(info, 0xa0000, 0xc0000, 0xa0000,  passthrough_mem_write, NULL);
-    }
-#endif
-
-#define VGABIOS_START 0x000c0000
-#define ROMBIOS_START 0x000f0000
-
-    /* layout vgabios */
-    {
-       extern uint8_t v3_vgabios_start[];
-       extern uint8_t v3_vgabios_end[];
-
-       addr_t vgabios_dst = v3_get_shadow_addr(&(info->mem_map.base_region), VGABIOS_START);
-       memcpy(V3_VAddr((void *)vgabios_dst), v3_vgabios_start, v3_vgabios_end - v3_vgabios_start);     
-    }
-    
-    /* layout rombios */
-    {
-       extern uint8_t v3_rombios_start[];
-       extern uint8_t v3_rombios_end[];
-
-       addr_t rombios_dst = v3_get_shadow_addr(&(info->mem_map.base_region), ROMBIOS_START);
-       memcpy(V3_VAddr((void *)rombios_dst), v3_rombios_start, v3_rombios_end - v3_rombios_start);
-    }
-
-#ifdef CONFIG_CRAY_XT
-    {
-#define SEASTAR_START 0xffe00000 
-#define SEASTAR_END 0xffffffff 
-       // Map the Seastar straight through
-       if (v3_add_shadow_mem(info, SEASTAR_START, SEASTAR_END, SEASTAR_START) == -1) {
-           PrintError("Could not map through the seastar\n");
-           return -1;
-       }
+       PrintError("Invalid VM Class\n");
+       return -1;
     }
-#endif
 
-    v3_print_mem_map(info);
 
     return 0;
 }
 
 
 
-static int setup_devices(struct guest_info * info, struct v3_vm_config * config_ptr) {
-
-    v3_create_device(info, "8259A", NULL);
-    v3_create_device(info, "KEYBOARD", NULL);
-    v3_create_device(info, "8254_PIT", NULL); 
-    v3_create_device(info, "BOCHS_DEBUG", NULL);
-    v3_create_device(info, "OS_DEBUG", NULL);
-    v3_create_device(info, "LAPIC", NULL);
-    v3_create_device(info, "IOAPIC", "LAPIC");
-    v3_create_device(info, "VMNET", NULL);
-    
+int v3_config_guest(struct guest_info * info, void * cfg_blob) {
+    v3_cpu_arch_t cpu_type = v3_get_cpu_type(v3_get_cpu_id());
 
-    v3_create_device(info, "CGA_VIDEO", (void *)1);
-    {
-       struct telnet_cons_cfg cons_cfg = {"CGA_VIDEO", 19997};
-       v3_create_device(info, "TELNET_CONSOLE", &cons_cfg);
+    if (cpu_type == V3_INVALID_CPU) {
+       PrintError("Configuring guest on invalid CPU\n");
+       return -1;
     }
 
-    if (config_ptr->enable_pci == 1) {
-       struct ide_cfg ide_config = {"PCI", "PIIX3"};
-       struct pci_passthrough_cfg pci_qemu_pt_cfg = {"PCI", "E1000", 0x8086, 0x100e};
-       struct pci_passthrough_cfg pci_hw_pt_cfg = {"PCI", "E1000", 0x8086, 0x107c};
-       
-       v3_create_device(info, "PCI", NULL);
-       v3_create_device(info, "i440FX", "PCI");
-       v3_create_device(info, "PIIX3", "PCI");
-       
-
-       v3_create_device(info, "LNX_VIRTIO_SYM", "PCI");
-       v3_create_device(info, "LNX_VIRTIO_BLK", "PCI");
-       v3_create_device(info, "LNX_VIRTIO_BALLOON", "PCI");
-       v3_create_device(info, "SYM_SWAP", "LNX_VIRTIO_BLK");
-       //      v3_create_device(info, "TMP_BLK", "LNX_VIRTIO_BLK");
+    info->cfg_data = parse_config(cfg_blob);
 
-       v3_create_device(info, "IDE", &ide_config);
-       
-       v3_create_device(info, "PCI_PASSTHROUGH", &pci_qemu_pt_cfg);
-       v3_create_device(info, "PCI_PASSTHROUGH", &pci_hw_pt_cfg);
+    if (!info->cfg_data) {
+       PrintError("Could not parse configuration\n");
+       return -1;
+    }
 
+    V3_Print("Preconfiguration\n");
 
-    } else {
-       v3_create_device(info, "IDE", NULL);
+    if (pre_config_guest(info, info->cfg_data) == -1) {
+       PrintError("Error in preconfiguration\n");
+       return -1;
     }
 
+    V3_Print("Arch dependent configuration\n");
 
-    if (config_ptr->pri_disk_type != NONE) {
-       if (config_ptr->pri_disk_type == CDROM) {
-           if (config_ptr->pri_disk_con == RAM) {
-               struct ram_cd_cfg cfg = {"IDE", 0, 0, 
-                                        (addr_t)(config_ptr->pri_disk_info.ram.data_ptr), 
-                                        config_ptr->pri_disk_info.ram.size};
-
-               PrintDebug("Creating RAM CD\n");
-
-               v3_create_device(info, "RAM-CD", &cfg);
-           } else if (config_ptr->pri_disk_con == NETWORK) {
-               struct net_cd_cfg cfg = {"IDE", 0, 0, 
-                                        config_ptr->pri_disk_info.net.ip_str,
-                                        config_ptr->pri_disk_info.net.port, 
-                                        config_ptr->pri_disk_info.net.disk_name};
-               PrintDebug("Creating NET CD\n");
-
-               v3_create_device(info, "NET-CD", &cfg);
-           }
-       } else if (config_ptr->pri_disk_type == HARDDRIVE) {
-           if (config_ptr->pri_disk_con == RAM) {
-               struct ram_hd_cfg cfg = {"IDE", 0, 0, 
-                                        (addr_t)(config_ptr->pri_disk_info.ram.data_ptr), 
-                                        config_ptr->pri_disk_info.ram.size};
-
-               PrintDebug("Creating RAM HD\n");
-
-               v3_create_device(info, "RAM-HD", &cfg);
-           } else if (config_ptr->pri_disk_con == NETWORK) {
-               struct net_hd_cfg cfg  = {"IDE", 0, 0, 
-                                         config_ptr->pri_disk_info.net.ip_str,
-                                         config_ptr->pri_disk_info.net.port, 
-                                         config_ptr->pri_disk_info.net.disk_name};
-               PrintDebug("Creating NET HD\n");
-               v3_create_device(info, "NET-HD", &cfg);
-           }
-
-       } else if (config_ptr->pri_disk_type == VIRTIO) {
-           if (config_ptr->pri_disk_con == RAM) {
-               struct ram_hd_cfg cfg = {"LNX_VIRTIO_BLK", 0, 0,
-                                        (addr_t)(config_ptr->pri_disk_info.ram.data_ptr), 
-                                        config_ptr->pri_disk_info.ram.size};
-
-               PrintDebug("Creating Virtio RAM HD\n");
-
-               v3_create_device(info, "RAM-HD", &cfg);
-           } 
-
+    // init SVM/VMX
+#ifdef CONFIG_SVM
+    if ((cpu_type == V3_SVM_CPU) || (cpu_type == V3_SVM_REV3_CPU)) {
+       if (v3_init_svm_vmcb(info, info->vm_class) == -1) {
+           PrintError("Error in SVM initialization\n");
+           return -1;
+       }
+    } 
+#endif
+#ifdef CONFIG_VMX
+    else if ((cpu_type == V3_VMX_CPU) || (cpu_type == V3_VMX_EPT_CPU)) {
+       if (v3_init_vmx_vmcs(info, info->vm_class) == -1) {
+           PrintError("Error in VMX initialization\n");
+           return -1;
        }
     }
+#endif
+    else {
+       PrintError("Invalid CPU Type\n");
+       return -1;
+    }
 
+    V3_Print("Post Configuration\n");
 
-
-    if (config_ptr->sec_disk_type != NONE) {
-       if (config_ptr->sec_disk_type == CDROM) {
-           if (config_ptr->sec_disk_con == RAM) {
-               struct ram_cd_cfg cfg = {"IDE", 0, 1, 
-                                        (addr_t)(config_ptr->sec_disk_info.ram.data_ptr), 
-                                        config_ptr->sec_disk_info.ram.size};
-
-               PrintDebug("Creating RAM CD\n");
-               v3_create_device(info, "RAM-CD", &cfg);
-           } else if (config_ptr->sec_disk_con == NETWORK) {
-               struct net_cd_cfg cfg = {"IDE", 0, 1, 
-                                        config_ptr->sec_disk_info.net.ip_str,
-                                        config_ptr->sec_disk_info.net.port, 
-                                        config_ptr->sec_disk_info.net.disk_name};
-
-               PrintDebug("Creating NET CD\n");
-               v3_create_device(info, "NET-CD", &cfg);    
-           }
-       } else if (config_ptr->sec_disk_type == HARDDRIVE) {
-           if (config_ptr->sec_disk_con == RAM) {
-               struct ram_hd_cfg cfg = {"IDE", 0, 1, 
-                                        (addr_t)(config_ptr->sec_disk_info.ram.data_ptr), 
-                                        config_ptr->sec_disk_info.ram.size};
-               PrintDebug("Creating RAM HD\n");
-               v3_create_device(info, "RAM-HD", &cfg);
-           } else if (config_ptr->sec_disk_con == NETWORK) {
-               struct net_hd_cfg cfg = {"IDE", 0, 1, 
-                                        config_ptr->sec_disk_info.net.ip_str,
-                                        config_ptr->sec_disk_info.net.port, 
-                                        config_ptr->sec_disk_info.net.disk_name};
-               PrintDebug("Creating NET HD\n");
-               v3_create_device(info, "NET-HD", &cfg);
-           }
-       }
+    if (post_config_guest(info, info->cfg_data) == -1) {
+       PrintError("Error in postconfiguration\n");
+       return -1;
     }
 
+    V3_Print("Configuration successfull\n");
 
+    return 0;
+}
 
-#ifdef CONFIG_GENERIC
-       configure_generic(info, config_ptr);
-#endif
 
-    // This should go last because it requires information about the Harddrives
-    v3_create_device(info, "NVRAM", "IDE");
-    
-    PrintDebugDevMgr(info);
 
-    return 0;
-}
 
 
+static int setup_memory_map(struct guest_info * info, struct v3_config * config_ptr) {
+    v3_cfg_tree_t * mem_region = v3_cfg_subtree(v3_cfg_subtree(config_ptr->cfg, "memmap"), "region");
 
-#ifdef CONFIG_GENERIC
-static int configure_generic(struct guest_info * info, struct v3_vm_config * config_ptr) {
-    PrintDebug("Creating Generic Device\n");
-    v3_create_device(info, "GENERIC", NULL);
-    
+    while (mem_region) {
+       addr_t start_addr = atox(v3_cfg_val(mem_region, "start"));
+       addr_t end_addr = atox(v3_cfg_val(mem_region, "end"));
+       addr_t host_addr = atox(v3_cfg_val(mem_region, "host_addr"));
 
-    struct vm_device * generic = v3_find_dev(info, "GENERIC");
+    
+       if (v3_add_shadow_mem(info, start_addr, end_addr, host_addr) == -1) {
+           PrintError("Could not map memory region: %p-%p => %p\n", 
+                      (void *)start_addr, (void *)end_addr, (void *)host_addr);
+           return -1;
+       }
 
-    if (!generic) {
-       PrintError("Could not find generic device\n");
-       return -1;
+       mem_region = v3_cfg_next_branch(mem_region);
     }
 
-    // port 0x92: A20 enable/disable (bit 2) (This causes an MMU flush)
-
-
-    // Make the DMA controller invisible
-    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
-    
-    
-    
-    
-    // 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
-    
+    return 0;
+}
 
-      
 
-    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
 
-      
-      
 
-    // 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
-    
-    
-    
-#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
-    }
-      
 
-    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
-    
-    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
 
-#if 1
 
-    // Make the parallel port invisible
-      
-    v3_generic_add_port_range(generic, 0x378, 0x37f, GENERIC_PRINT_AND_IGNORE);
 
-#endif
 
-#ifdef CONFIG_PASTHROUGH_VIDEO
+static int setup_devices(struct guest_info * info, struct v3_config * config_ptr) {
+    v3_cfg_tree_t * device = v3_cfg_subtree(v3_cfg_subtree(config_ptr->cfg, "devices"), "device");
 
-    // Monitor graphics card operations
     
-    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
+    while (device) {
+       char * id = v3_cfg_val(device, "id");
 
+       V3_Print("configuring device %s\n", id);
 
-#if 1
-    // Make the ISA PNP features invisible
-    
-    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 (v3_create_device(info, id, device) == -1) {
+           PrintError("Error creating device %s\n", id);
+           return -1;
+       }
+       
+       device = v3_cfg_next_branch(device);
+    }
 
 
-#if 1
-    // Monitor any network card (realtek ne2000) operations 
-    v3_generic_add_port_range(generic, 0xc100, 0xc1ff, GENERIC_PRINT_AND_PASSTHROUGH);
-#endif
+   v3_print_dev_mgr(info);
 
-    //  v3_generic_add_port_range(generic, 0x378, 0x400, GENERIC_PRINT_AND_IGNORE);
-    
     return 0;
 }
-#endif
+
+
diff --git a/palacios/src/palacios/vmm_config_class.h b/palacios/src/palacios/vmm_config_class.h
new file mode 100644 (file)
index 0000000..36fee9b
--- /dev/null
@@ -0,0 +1,63 @@
+ /* 
+ * 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) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software.  You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
+static int post_config_pc(struct guest_info * info, struct v3_config * config_ptr) {
+
+
+    info->cpu_mode = REAL;
+    info->mem_mode = PHYSICAL_MEM;
+
+
+    info->vm_regs.rdi = 0;
+    info->vm_regs.rsi = 0;
+    info->vm_regs.rbp = 0;
+    info->vm_regs.rsp = 0;
+    info->vm_regs.rbx = 0;
+    info->vm_regs.rdx = 0;
+    info->vm_regs.rcx = 0;
+    info->vm_regs.rax = 0;
+
+
+#define VGABIOS_START 0x000c0000
+#define ROMBIOS_START 0x000f0000
+    
+    /* layout vgabios */
+    {
+       extern uint8_t v3_vgabios_start[];
+       extern uint8_t v3_vgabios_end[];
+       
+       addr_t vgabios_dst = v3_get_shadow_addr(&(info->mem_map.base_region), VGABIOS_START);
+       memcpy(V3_VAddr((void *)vgabios_dst), v3_vgabios_start, v3_vgabios_end - v3_vgabios_start);     
+    }
+    
+    /* layout rombios */
+    {
+       extern uint8_t v3_rombios_start[];
+       extern uint8_t v3_rombios_end[];
+
+       addr_t rombios_dst = v3_get_shadow_addr(&(info->mem_map.base_region), ROMBIOS_START);
+       memcpy(V3_VAddr((void *)rombios_dst), v3_rombios_start, v3_rombios_end - v3_rombios_start);
+    }
+
+    v3_print_mem_map(info);
+
+    return 0;
+}
+
index d0c3a32..34040d8 100644 (file)
@@ -20,7 +20,7 @@
 #include <palacios/vmm.h>
 #include <palacios/vmm_cpuid.h>
 #include <palacios/vmm_lowlevel.h>
-
+#include <palacios/vm_guest.h>
 
 
 void v3_init_cpuid_map(struct guest_info * info) {
index c212958..c7a8f95 100644 (file)
@@ -94,6 +94,14 @@ int v3_init_dev_mgr(struct guest_info * info) {
 
     mgr->dev_table = v3_create_htable(0, dev_hash_fn, dev_eq_fn);
 
+    INIT_LIST_HEAD(&(mgr->blk_list));
+    INIT_LIST_HEAD(&(mgr->net_list));
+    INIT_LIST_HEAD(&(mgr->console_list));
+
+    mgr->blk_table = v3_create_htable(0, dev_hash_fn, dev_eq_fn);
+    mgr->net_table = v3_create_htable(0, dev_hash_fn, dev_eq_fn);
+    mgr->console_table = v3_create_htable(0, dev_hash_fn, dev_eq_fn);
+    
     return 0;
 }
 
@@ -113,7 +121,7 @@ int v3_dev_mgr_deinit(struct guest_info * info) {
 
 
 
-int v3_create_device(struct guest_info * info, const char * dev_name, void * cfg_data) {
+int v3_create_device(struct guest_info * info, const char * dev_name, v3_cfg_tree_t * cfg) {
     int (*dev_init)(struct guest_info * info, void * cfg_data);
 
     dev_init = (void *)v3_htable_search(master_dev_table, (addr_t)dev_name);
@@ -124,7 +132,7 @@ int v3_create_device(struct guest_info * info, const char * dev_name, void * cfg
     }
 
 
-    if (dev_init(info, cfg_data) == -1) {
+    if (dev_init(info, cfg) == -1) {
        PrintError("Could not initialize Device %s\n", dev_name);
        return -1;
     }
@@ -142,6 +150,10 @@ void v3_free_device(struct vm_device * dev) {
 struct vm_device * v3_find_dev(struct guest_info * info, const char * dev_name) {
     struct vmm_dev_mgr * mgr = &(info->dev_mgr);
 
+    if (!dev_name) {
+       return NULL;
+    }
+
     return (struct vm_device *)v3_htable_search(mgr->dev_table, (addr_t)dev_name);
 }
 
@@ -213,31 +225,81 @@ int v3_attach_device(struct guest_info * vm, struct vm_device * dev ) {
 }
 
 
-#ifdef CONFIG_DEBUG_DEV_MGR
 
-void PrintDebugDevMgr(struct guest_info * info) {
+void v3_print_dev_mgr(struct guest_info * info) {
     struct vmm_dev_mgr * mgr = &(info->dev_mgr);
     struct vm_device * dev;
 
-    PrintDebug("%d devices registered with manager\n", mgr->num_devs);
+    V3_Print("%d devices registered with manager\n", mgr->num_devs);
 
     list_for_each_entry(dev, &(mgr->dev_list), dev_link) {
-       PrintDebugDev(dev);
-       PrintDebug("next..\n");
+       V3_Print("Device: %s\n", dev->name);
     }
 
     return;
 }
 
 
-void PrintDebugDev(struct vm_device * dev) {
-    PrintDebug("Device: %s\n", dev->name);
+
+
+struct blk_frontend {
+    int (*connect)(struct guest_info * info, 
+                   void * frontend_data, 
+                   struct v3_dev_blk_ops * ops, 
+                   v3_cfg_tree_t * cfg, 
+                   void * priv_data);
+       
+
+    struct list_head blk_node;
+
+    void * priv_data;
+};
+
+
+
+int v3_dev_add_blk_frontend(struct guest_info * info, 
+                           char * name, 
+                           int (*connect)(struct guest_info * info, 
+                                           void * frontend_data, 
+                                           struct v3_dev_blk_ops * ops, 
+                                           v3_cfg_tree_t * cfg, 
+                                           void * priv_data), 
+                           void * priv_data) {
+
+    struct blk_frontend * frontend = NULL;
+
+    frontend = (struct blk_frontend *)V3_Malloc(sizeof(struct blk_frontend));
+    memset(frontend, 0, sizeof(struct blk_frontend));
+    
+    frontend->connect = connect;
+    frontend->priv_data = priv_data;
+       
+    list_add(&(frontend->blk_node), &(info->dev_mgr.blk_list));
+    v3_htable_insert(info->dev_mgr.blk_table, (addr_t)(name), (addr_t)frontend);
+
+    return 0;
 }
 
+int v3_dev_connect_blk(struct guest_info * info, 
+                      char * frontend_name, 
+                      struct v3_dev_blk_ops * ops, 
+                      v3_cfg_tree_t * cfg, 
+                      void * private_data) {
+
+    struct blk_frontend * frontend = NULL;
 
+    frontend = (struct blk_frontend *)v3_htable_search(info->dev_mgr.blk_table,
+                                                      (addr_t)frontend_name);
+    
+    if (frontend == NULL) {
+       PrintError("Could not find frontend blk device %s\n", frontend_name);
+       return 0;
+    }
 
+    if (frontend->connect(info, frontend->priv_data, ops, cfg, private_data) == -1) {
+       PrintError("Error connecting to block frontend %s\n", frontend_name);
+       return -1;
+    }
 
-#else 
-void PrintDebugDevMgr(struct guest_info * info) {}
-void PrintDebugDev(struct vm_device * dev) {}
-#endif
+    return 0;
+}
index 61a1a6f..f1f9411 100644 (file)
@@ -20,6 +20,7 @@
 #include <palacios/vmm_excp.h>
 #include <palacios/vmm.h>
 #include <palacios/vmm_types.h>
+#include <palacios/vm_guest.h>
 
 void v3_init_exception_state(struct guest_info * info) {
     info->excp_state.excp_pending = 0;
index 90eb032..791898c 100644 (file)
@@ -19,7 +19,7 @@
 
 #include <palacios/vmm.h>
 #include <palacios/vmm_host_events.h>
-
+#include <palacios/vm_guest.h>
 
 int v3_init_host_events(struct guest_info * info) {
     struct v3_host_events * host_evts = &(info->host_event_hooks);
index 3dc49f2..65749c1 100644 (file)
@@ -19,7 +19,7 @@
 
 #include <palacios/vmm_hypercall.h>
 #include <palacios/vmm.h>
-
+#include <palacios/vm_guest.h>
 
 void v3_init_hypercall_map(struct guest_info * info) {
     info->hcall_map.rb_node = NULL;
index 77308d9..0211b99 100644 (file)
@@ -20,7 +20,7 @@
 #include <palacios/vmm_io.h>
 #include <palacios/vmm_string.h>
 #include <palacios/vmm.h>
-
+#include <palacios/vm_guest.h>
 
 
 
index 8494f47..4248845 100644 (file)
 #include <palacios/vmm.h>
 #include <palacios/vmm_util.h>
 #include <palacios/vmm_emulator.h>
+#include <palacios/vm_guest.h>
 
 #include <palacios/vmm_shadow_paging.h>
 #include <palacios/vmm_direct_paging.h>
 
-
 #define MEM_OFFSET_HCALL 0x1000
 
 
index 9160e41..effaf32 100644 (file)
@@ -152,6 +152,22 @@ int strcmp(const char * s1, const char * s2) {
 }
 #endif
 
+#ifdef CONFIG_BUILT_IN_STRCASECMP
+int strcasecmp(const char * s1, const char * s2) {
+    while (1) {
+       int cmp = (tolower(*s1) - tolower(*s2));
+
+       if ((cmp != 0) || (*s1 == '\0') || (*s2 == '\0')) {
+           return cmp;
+       }
+
+       ++s1;
+       ++s2;
+    }
+}
+
+#endif
+
 
 #ifdef CONFIG_BUILT_IN_STRNCMP
 int strncmp(const char * s1, const char * s2, size_t limit) {
@@ -174,6 +190,26 @@ int strncmp(const char * s1, const char * s2, size_t limit) {
 }
 #endif
 
+#ifdef CONFIG_BUILT_IN_STRNCASECMP
+int strncasecmp(const char * s1, const char * s2, size_t limit) {
+    size_t i = 0;
+
+    while (i < limit) {
+       int cmp = (tolower(*s1) - tolower(*s2));
+
+       if ((cmp != 0) || (*s1 == '\0') || (*s2 == '\0')) {
+           return cmp;
+       }
+
+       ++s1;
+       ++s2;
+       ++i;
+    }
+
+    return 0;
+}
+#endif
+
 
 #ifdef CONFIG_BUILT_IN_STRCAT
 char * strcat(char * s1, const char * s2) {
@@ -294,6 +330,10 @@ int strtoi(const char * nptr, char ** endptr) {
 uint64_t atox(const char * buf) {
     uint64_t ret = 0;
 
+    if (*(buf + 1) == 'x') {
+       buf += 2;
+    }
+
     while (isxdigit(*buf)) {
        ret <<= 4;
        
@@ -313,6 +353,10 @@ uint64_t strtox(const char * nptr, char ** endptr) {
     uint64_t ret = 0;
     char * buf = (char *)nptr;
 
+    if (*(buf + 1) == 'x') {
+       buf += 2;
+    }
+
     while (isxdigit(*buf)) {
        ret <<= 4;
        
@@ -445,3 +489,23 @@ char *strstr(const char *haystack, const char *needle)
         return NULL;
 }
 #endif
+
+
+void str_tolower(char * s) {
+    while (isalpha(*s)) {
+       if (!islower(*s)) {
+           *s = tolower(*s);
+       }
+       s++;
+    }
+}
+
+
+void str_toupper(char * s) {
+    while (isalpha(*s)) {
+       if (!isupper(*s)) {
+           *s = toupper(*s);
+       }
+       s++;
+    }
+}
index 2a3caf0..1242cb4 100644 (file)
@@ -22,6 +22,7 @@
 #include <palacios/vmm_msr.h>
 #include <palacios/vmm_mem.h>
 #include <palacios/vmm_hypercall.h>
+#include <palacios/vm_guest.h>
 
 #define SYM_PAGE_MSR 0x535
 
index a4117b8..5c8cad8 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <palacios/vmm_sym_swap.h>
 #include <palacios/vmm_list.h>
-
+#include <palacios/vm_guest.h>
 
 #ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY
 #include <palacios/vmm_telemetry.h>
index 86eaa02..319d158 100644 (file)
@@ -17,9 +17,9 @@
  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
  */
 
-#include "palacios/vmm_time.h"
-#include "palacios/vmm.h"
-
+#include <palacios/vmm_time.h>
+#include <palacios/vmm.h>
+#include <palacios/vm_guest.h>
 
 void v3_init_time(struct guest_info * info) {
     struct vm_time * time_state = &(info->time_state);
index 2201ad9..e632a4f 100644 (file)
@@ -112,12 +112,10 @@ struct v3_xml * v3_xml_child(struct v3_xml * xml, const char * name) {
 
     if (xml != NULL) {
        child = xml->child;
-    } 
+    }
 
-    if (child != NULL) {
-       while (strcmp(name, child->name) != 0) {
-           child = child->sibling;
-       }
+    while ((child) && (strcasecmp(name, child->name) != 0)) {
+       child = child->sibling;
     }
 
     return child;
@@ -143,7 +141,7 @@ const char * v3_xml_attr(struct v3_xml * xml, const char * attr) {
        return NULL;
     }
 
-    while ((xml->attr[i]) && (strcmp(attr, xml->attr[i]) != 0)) {
+    while ((xml->attr[i]) && (strcasecmp(attr, xml->attr[i]) != 0)) {
        i += 2;
     }
 
@@ -157,14 +155,14 @@ const char * v3_xml_attr(struct v3_xml * xml, const char * attr) {
 
     for (i = 0; 
         ( (root->attr[i] != NULL) && 
-          (strcmp(xml->name, root->attr[i][0]) != 0) ); 
+          (strcasecmp(xml->name, root->attr[i][0]) != 0) ); 
         i++);
 
     if (! root->attr[i]) {
        return NULL; // no matching default attributes
     }
 
-    while ((root->attr[i][j] != NULL) && (strcmp(attr, root->attr[i][j]) != 0)) {
+    while ((root->attr[i][j] != NULL) && (strcasecmp(attr, root->attr[i][j]) != 0)) {
        j += 3;
     }
 
@@ -356,7 +354,7 @@ static void v3_xml_char_content(struct v3_xml_root * root, char * s, size_t len,
 static int v3_xml_close_tag(struct v3_xml_root * root, char * name, char * s) {
     if ( (root->cur == NULL) || 
         (root->cur->name == NULL) || 
-        (strcmp(name, root->cur->name))) {
+        (strcasecmp(name, root->cur->name))) {
        v3_xml_err(root, s, "unexpected closing tag </%s>", name);
        return -1;
     }
@@ -484,7 +482,7 @@ static struct v3_xml * v3_xml_insert(struct v3_xml * xml, struct v3_xml * dest,
 
        // find tag type
         for (cur = head, prev = NULL; 
-            ((cur) && (strcmp(cur->name, xml->name) != 0));
+            ((cur) && (strcasecmp(cur->name, xml->name) != 0));
              prev = cur, cur = cur->sibling); 
 
 
@@ -628,7 +626,7 @@ static struct v3_xml * parse_str(char * buf, size_t len) {
                // find attributes for correct tag
                 for ((i = 0); 
                     ((tmp_attr = root->attr[i]) && 
-                     (strcmp(tmp_attr[0], tag_ptr) != 0)); 
+                     (strcasecmp(tmp_attr[0], tag_ptr) != 0)); 
                     (i++)) ;
                
                // 'tmp_attr' now points to the attribute list associated with 'tag_ptr'
@@ -700,7 +698,7 @@ static struct v3_xml * parse_str(char * buf, size_t len) {
 
                         for (j = 1; 
                             ( (tmp_attr) && (tmp_attr[j]) && 
-                              (strcmp(tmp_attr[j], attr[attr_idx]) != 0)); 
+                              (strcasecmp(tmp_attr[j], attr[attr_idx]) != 0)); 
                             j += 3);
 
                         attr[val_idx] = v3_xml_decode(attr[val_idx], root->ent,