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.


more device free updates
Jack Lange [Fri, 19 Nov 2010 17:36:48 +0000 (11:36 -0600)]
palacios/include/palacios/vmm_console.h
palacios/src/devices/bochs_debug.c
palacios/src/devices/cga.c
palacios/src/devices/char_stream.c
palacios/src/devices/curses_cons.c
palacios/src/devices/filedisk.c
palacios/src/devices/generic.c
palacios/src/devices/i440fx.c
palacios/src/devices/ide.c
palacios/src/palacios/vmm_console.c
palacios/src/palacios/vmm_dev_mgr.c

index 1315ccd..cab3c4f 100644 (file)
@@ -31,6 +31,7 @@
 typedef void * v3_console_t;
 
 v3_console_t v3_console_open(struct v3_vm_info * vm, uint32_t width, uint32_t height);
+void v3_console_close(v3_console_t cons);
 
 int v3_console_set_cursor(v3_console_t cons, int x, int y);
 int v3_console_set_char(v3_console_t cons, int x, int y, char c, uint8_t style);
@@ -44,6 +45,8 @@ int v3_console_update(v3_console_t cons);
 struct v3_console_hooks {
     /* open console device, mode is a combination of TTY_OPEN_MODE_* flags */
     void *(*open)(void * priv_data, unsigned int width, unsigned int height);
+    
+    void (*close)(void * tty);
 
     /* set cursor position */
     int (*set_cursor)(void * tty, int x, int y);
index adba835..42128b6 100644 (file)
@@ -135,9 +135,7 @@ static int debug_free(struct vm_device * dev) {
 
 static struct v3_device_ops dev_ops = {
     .free = debug_free,
-    .reset = NULL,
-    .start = NULL,
-    .stop = NULL,
+
 };
 
 
index 5adf005..119709f 100644 (file)
@@ -23,6 +23,7 @@
 #include <palacios/vmm_dev_mgr.h>
 #include <palacios/vmm_emulator.h>
 #include <palacios/vm_guest_mem.h>
+#include <palacios/vmm_io.h>
 
 #include <devices/console.h>
 
@@ -51,6 +52,7 @@
 
 struct video_internal {
     uint8_t * framebuf;
+    addr_t framebuf_pa;
 
     // These store the values for unhandled ports, in case of a read op
     uint8_t port_store[44];
@@ -148,7 +150,8 @@ static int video_write_mem(struct guest_info * core, addr_t guest_addr, void * d
     return length;
 }
 
-static int video_read_port(struct guest_info * core, uint16_t port, void * dest, uint_t length, struct vm_device * dev) {
+static int video_read_port(struct guest_info * core, uint16_t port, void * dest, uint_t length, void * priv_data) {
+    struct vm_device * dev = (struct vm_device *)priv_data;
     struct video_internal * video_state = (struct video_internal *)dev->private_data;
 
 
@@ -163,7 +166,8 @@ static int video_read_port(struct guest_info * core, uint16_t port, void * dest,
 
 
 
-static int video_write_port(struct guest_info * core, uint16_t port, void * src, uint_t length, struct vm_device * dev) {
+static int video_write_port(struct guest_info * core, uint16_t port, void * src, uint_t length, void * priv_data) {
+    struct vm_device * dev = (struct vm_device *)priv_data;
     struct video_internal * video_state = (struct video_internal *)dev->private_data;
 
 
@@ -178,7 +182,8 @@ static int video_write_port(struct guest_info * core, uint16_t port, void * src,
 
 
 
-static int crtc_data_write(struct guest_info * core, uint16_t port, void * src, uint_t length, struct vm_device * dev) {
+static int crtc_data_write(struct guest_info * core, uint16_t port, void * src, uint_t length, void * priv_data) {
+    struct vm_device * dev = (struct vm_device *)priv_data;
     struct video_internal * video_state = (struct video_internal *)dev->private_data;
     uint8_t val = *(uint8_t *)src;
     uint_t index = video_state->crtc_index_reg;
@@ -257,7 +262,8 @@ static int crtc_data_write(struct guest_info * core, uint16_t port, void * src,
 }
 
 
-static int crtc_index_write(struct guest_info * core, uint16_t port, void * src, uint_t length, struct vm_device * dev) {
+static int crtc_index_write(struct guest_info * core, uint16_t port, void * src, uint_t length, void * priv_data) {
+    struct vm_device * dev = (struct vm_device *)priv_data;
     struct video_internal * video_state = (struct video_internal *)dev->private_data;
     
     if (length > 2) {
@@ -303,31 +309,78 @@ int v3_cons_get_fb(struct vm_device * frontend_dev, uint8_t * dst, uint_t offset
 
 static int free_device(struct vm_device * dev) {
     struct video_internal * video_state = (struct video_internal *)dev->private_data;
+    struct v3_vm_info * vm = dev->vm;
+
+    if (video_state->framebuf_pa) {
+       V3_FreePages((void *)(video_state->framebuf_pa), (FRAMEBUF_SIZE / 4096));
+    }
 
     v3_unhook_mem(dev->vm, V3_MEM_CORE_ANY, START_ADDR);
 
+    v3_unhook_io_port(vm, 0x3b0);
+    v3_unhook_io_port(vm, 0x3b1);
+    v3_unhook_io_port(vm, 0x3b2);
+    v3_unhook_io_port(vm, 0x3b3);
+    v3_unhook_io_port(vm, 0x3b4);
+    v3_unhook_io_port(vm, 0x3b5);
+    v3_unhook_io_port(vm, 0x3b6);
+    v3_unhook_io_port(vm, 0x3b7);
+    v3_unhook_io_port(vm, 0x3b8);
+    v3_unhook_io_port(vm, 0x3b9);
+    v3_unhook_io_port(vm, 0x3ba);
+    v3_unhook_io_port(vm, 0x3bb);
+    v3_unhook_io_port(vm, 0x3c0);
+    v3_unhook_io_port(vm, 0x3c1);
+    v3_unhook_io_port(vm, 0x3c2);
+    v3_unhook_io_port(vm, 0x3c3);
+    v3_unhook_io_port(vm, 0x3c4);
+    v3_unhook_io_port(vm, 0x3c5);
+    v3_unhook_io_port(vm, 0x3c6);
+    v3_unhook_io_port(vm, 0x3c7);
+    v3_unhook_io_port(vm, 0x3c8);
+    v3_unhook_io_port(vm, 0x3c9);
+    v3_unhook_io_port(vm, 0x3ca);
+    v3_unhook_io_port(vm, 0x3cb);
+    v3_unhook_io_port(vm, 0x3cc);
+    v3_unhook_io_port(vm, 0x3cd);
+    v3_unhook_io_port(vm, 0x3ce);
+    v3_unhook_io_port(vm, 0x3cf);
+    v3_unhook_io_port(vm, 0x3d0);
+    v3_unhook_io_port(vm, 0x3d1);
+    v3_unhook_io_port(vm, 0x3d2);
+    v3_unhook_io_port(vm, 0x3d3);
+    v3_unhook_io_port(vm, 0x3d4);
+    v3_unhook_io_port(vm, 0x3d5);
+    v3_unhook_io_port(vm, 0x3d6);
+    v3_unhook_io_port(vm, 0x3d7);
+    v3_unhook_io_port(vm, 0x3d8);
+    v3_unhook_io_port(vm, 0x3d9);
+    v3_unhook_io_port(vm, 0x3da);
+    v3_unhook_io_port(vm, 0x3db);
+    v3_unhook_io_port(vm, 0x3dc);
+    v3_unhook_io_port(vm, 0x3dd);
+    v3_unhook_io_port(vm, 0x3de);
+    v3_unhook_io_port(vm, 0x3df);
+
     V3_Free(video_state);
 
     return 0;
 }
 
 
-
 static struct v3_device_ops dev_ops = {
     .free = free_device,
 };
 
 static int cga_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct video_internal * video_state = NULL;
-    addr_t frame_buf_pa = 0;
-    int enable_passthrough = 0;
     char * dev_id = v3_cfg_val(cfg, "ID");
-
-    enable_passthrough = (strcasecmp(v3_cfg_val(cfg, "passthrough"), "enable") == 0) ? 1 : 0;
-
+    char * passthrough_str = v3_cfg_val(cfg, "passthrough");
+    
     PrintDebug("video: init_device\n");
 
     video_state = (struct video_internal *)V3_Malloc(sizeof(struct video_internal));
+    memset(video_state, 0, sizeof(struct video_internal));
 
     struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, video_state);
 
@@ -337,75 +390,76 @@ static int cga_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
        return -1;
     }
 
-    frame_buf_pa = (addr_t)V3_AllocPages(FRAMEBUF_SIZE / 4096);
-
-    video_state->framebuf = V3_VAddr((void *)frame_buf_pa);
+    video_state->framebuf_pa = (addr_t)V3_AllocPages(FRAMEBUF_SIZE / 4096);
+    video_state->framebuf = V3_VAddr((void *)(video_state->framebuf_pa));
     memset(video_state->framebuf, 0, FRAMEBUF_SIZE);
 
-    PrintDebug("PA of array: %p\n", (void *)frame_buf_pa);
+    PrintDebug("PA of array: %p\n", (void *)(video_state->framebuf_pa));
 
-    video_state->passthrough = enable_passthrough;
+    if ((passthrough_str != NULL) &&
+       (strcasecmp(passthrough_str, "enable") == 0)) {;
+       video_state->passthrough = 1;
+    }
 
-    video_state->ops = NULL;
-    video_state->private_data = NULL;
 
-    if (enable_passthrough) {
+    if (video_state->passthrough) {
        PrintDebug("Enabling CGA Passthrough\n");
-
-       if (v3_hook_write_mem(vm, V3_MEM_CORE_ANY, START_ADDR, END_ADDR, START_ADDR, &video_write_mem, dev) == -1) {
+       if (v3_hook_write_mem(vm, V3_MEM_CORE_ANY, START_ADDR, END_ADDR, 
+                             START_ADDR, &video_write_mem, dev) == -1) {
            PrintDebug("\n\nVideo Hook failed.\n\n");
        }
     } else {
-       if (v3_hook_write_mem(vm, V3_MEM_CORE_ANY, START_ADDR, END_ADDR, frame_buf_pa, &video_write_mem, dev) == -1) {
+       if (v3_hook_write_mem(vm, V3_MEM_CORE_ANY, START_ADDR, END_ADDR, 
+                             video_state->framebuf_pa, &video_write_mem, dev) == -1) {
            PrintDebug("\n\nVideo Hook failed.\n\n");
        }
     }
 
 
-    v3_dev_hook_io(dev, 0x3b0, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3b1, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3b2, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3b3, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3b4, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3b5, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3b6, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3b7, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3b8, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3b9, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3ba, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3bb, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3c0, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3c1, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3c2, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3c3, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3c4, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3c5, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3c6, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3c7, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3c8, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3c9, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3ca, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3cb, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3cc, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3cd, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3ce, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3cf, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3d0, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3d1, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3d2, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3d3, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3d4, &video_read_port, &crtc_index_write);
-    v3_dev_hook_io(dev, 0x3d5, &video_read_port, &crtc_data_write);
-    v3_dev_hook_io(dev, 0x3d6, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3d7, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3d8, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3d9, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3da, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3db, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3dc, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3dd, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3de, &video_read_port, &video_write_port);
-    v3_dev_hook_io(dev, 0x3df, &video_read_port, &video_write_port);
+    v3_hook_io_port(vm, 0x3b0, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3b1, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3b2, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3b3, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3b4, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3b5, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3b6, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3b7, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3b8, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3b9, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3ba, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3bb, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3c0, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3c1, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3c2, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3c3, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3c4, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3c5, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3c6, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3c7, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3c8, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3c9, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3ca, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3cb, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3cc, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3cd, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3ce, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3cf, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3d0, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3d1, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3d2, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3d3, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3d4, &video_read_port, &crtc_index_write, dev);
+    v3_hook_io_port(vm, 0x3d5, &video_read_port, &crtc_data_write, dev);
+    v3_hook_io_port(vm, 0x3d6, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3d7, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3d8, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3d9, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3da, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3db, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3dc, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3dd, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3de, &video_read_port, &video_write_port, dev);
+    v3_hook_io_port(vm, 0x3df, &video_read_port, &video_write_port, dev);
 
 
     return 0;
index 445194c..52e217e 100644 (file)
@@ -37,41 +37,46 @@ struct stream_state {
 
 static int serial_event_handler(struct v3_vm_info * vm, 
                                struct v3_serial_event * evt, 
-                            void * private_data) {
-    struct stream_state *state = (struct stream_state *)private_data;
+                               void * private_data) {
+    struct stream_state * state = (struct stream_state *)private_data;
 
-    if(state->char_ops.push != NULL){
+    if (state->char_ops.push != NULL){
        state->char_ops.push(vm, evt->data, evt->len, state->push_fn_arg);
     }
 
     return 0;
 }
 
-static int stream_write(uint8_t * buf, uint64_t length, void * private_data) 
-{
-    struct stream_state *state = (struct stream_state *)private_data;
+static int stream_write(uint8_t * buf, uint64_t length, void * private_data) {
+    struct stream_state * state = (struct stream_state *)private_data;
     
     return v3_stream_write(state->stream, buf, length);
 }
 
+static int stream_free(struct vm_device * dev) {
+    struct stream_state * state = (struct stream_state *)(dev->private_data);
+
+    v3_stream_close(state->stream);
+
+    // detach host event
+
+    V3_Free(state);
+
+    return 0;
+}
 
 
 static struct v3_device_ops dev_ops = {
-    .free = NULL,
-    .reset = NULL,
-    .start = NULL,
-    .stop = NULL,
+    .free = stream_free,
 };
 
-static int stream_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) 
-{
+static int stream_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     char * dev_id = v3_cfg_val(cfg, "ID");
     char * stream_name = v3_cfg_val(cfg, "name");
     struct stream_state * state = NULL;
 
     v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend");
 
-
     state = (struct stream_state *)V3_Malloc(sizeof(struct stream_state));
 
     if (state == NULL) {
@@ -81,20 +86,11 @@ static int stream_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg)
 
     memset(state, 0, sizeof(struct stream_state));
 
-    state->stream = v3_stream_open(vm, stream_name);
-
-    if (state->stream == NULL) {
-       PrintError("Could not open stream %s\n", stream_name);
-       V3_Free(state);
-       return -1;
-    }
-    
-    state->char_ops.write = stream_write;
-       
     struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
 
     if (dev == NULL) {
        PrintError("Could not allocate device %s\n", dev_id);
+       V3_Free(state);
        return -1;
     }
 
@@ -104,20 +100,28 @@ static int stream_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg)
        return -1;
     }
 
+    state->stream = v3_stream_open(vm, stream_name);
+
+    if (state->stream == NULL) {
+       PrintError("Could not open stream %s\n", stream_name);
+       v3_detach_device(dev);
+       return -1;
+    }
+
+    state->char_ops.write = stream_write;
+
     if (v3_dev_connect_char(vm, v3_cfg_val(frontend_cfg, "tag"), 
                            &(state->char_ops), frontend_cfg, 
                            state, &(state->push_fn_arg)) == -1) {
        PrintError("Could not connect %s to frontend %s\n", 
                   dev_id, v3_cfg_val(frontend_cfg, "tag"));
+       v3_detach_device(dev);
        return -1;
     }
-    
 
     v3_hook_host_event(vm, HOST_SERIAL_EVT, V3_HOST_EVENT_HANDLER(serial_event_handler), state);
 
-
     return 0;
 }
 
-device_register("CHAR_STREAM", stream_init)
-
+device_register("CHAR_STREAM", stream_init);
index 1461036..90f695d 100644 (file)
@@ -82,8 +82,8 @@ static int cursor_update(uint_t x, uint_t y, void *private_data)
 }
 
 static int screen_update(uint_t x, uint_t y, uint_t length, void * private_data) {
-    struct vm_device *dev = (struct vm_device *)private_data;
-    struct cons_state *state = (struct cons_state *)dev->private_data;
+    struct vm_device * dev = (struct vm_device *)private_data;
+    struct cons_state * state = (struct cons_state *)dev->private_data;
     uint_t offset = (x * BYTES_PER_COL) + (y * BYTES_PER_ROW);
     uint8_t fb_buf[length];
     int i;
@@ -156,6 +156,18 @@ static int scroll(int rows, void * private_data) {
 }
 
 
+static int cons_free(struct vm_device * dev) {
+    struct cons_state * state = (struct cons_state *)dev->private_data;
+
+    v3_console_close(state->cons);
+
+    // remove host event
+
+    V3_Free(state);
+
+    return 0;
+}
+
 static int console_event_handler(struct v3_vm_info * vm, 
                                 struct v3_console_event * evt, 
                                 void * priv_data) {
@@ -171,10 +183,7 @@ static struct v3_console_ops cons_ops = {
 };
 
 static struct v3_device_ops dev_ops = {
-    .free = NULL,
-    .reset = NULL,
-    .start = NULL,
-    .stop = NULL,
+    .free = cons_free,
 };
 
 static int cons_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) 
index f4e6318..928355a 100644 (file)
@@ -112,6 +112,11 @@ static struct v3_dev_blk_ops blk_ops = {
 
 
 static int disk_free(struct vm_device * dev) {
+    struct disk_state * disk = dev->private_data;
+
+    v3_file_close(disk->fd);
+    
+    V3_Free(disk);
     return 0;
 }
 
@@ -129,37 +134,36 @@ static int disk_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct disk_state * disk = NULL;
     char * path = v3_cfg_val(cfg, "path");
     char * dev_id = v3_cfg_val(cfg, "ID");
-
     char * writable = v3_cfg_val(cfg, "writable");
-    char * readable = v3_cfg_val(cfg, "readable");
-    
-    int allowWrite = ( writable && writable[0] == '1' );
-    int allowRead = ( !readable || readable[0] == '1' );
-
     v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend");
+    int flags = FILE_OPEN_MODE_READ;
 
-    disk = (struct disk_state *)V3_Malloc(sizeof(struct disk_state));
-    memset(disk, 0, sizeof(struct disk_state));
-
+    if ( (writable) && (writable[0] == '1') ) {
+       flags |= FILE_OPEN_MODE_WRITE;
+    }
 
     if (path == NULL) {
        PrintError("Missing path (%s) for %s\n", path, dev_id);
        return -1;
+    }
+
+    disk = (struct disk_state *)V3_Malloc(sizeof(struct disk_state));
 
+    if (disk == NULL) {
+       PrintError("Could not allocate disk\n");
+       return -1;
     }
-    
-    if ( (allowRead == 1) && (allowWrite == 1) ) {
-       disk->fd = v3_file_open(vm, path, FILE_OPEN_MODE_READ | FILE_OPEN_MODE_WRITE );
-    } else if ( (allowRead == 1) && (allowWrite == 0) ) {
-       disk->fd = v3_file_open(vm, path, FILE_OPEN_MODE_READ);
-    } else if ( (allowRead == 0) && (allowWrite == 1) ) {
-       disk->fd = v3_file_open(vm, path, FILE_OPEN_MODE_WRITE);
-    } else {
-       PrintError("Error on %s: No file mode specified\n", dev_id );
-       return -1;
 
+    memset(disk, 0, sizeof(struct disk_state));
+
+    disk->fd = v3_file_open(vm, path, flags);
+
+    if (disk->fd == NULL) {
+       PrintError("Could not open file disk:%s\n", path);
+       V3_Free(disk);
+       return -1;
     }
-    
+
     disk->capacity = v3_file_size(disk->fd);
 
     PrintDebug("Registering FILEDISK %s (path=%s, fd=%lu, size=%lu)\n",
@@ -168,19 +172,19 @@ static int disk_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, disk);
 
     if (v3_attach_device(vm, dev) == -1) {
-
        PrintError("Could not attach device %s\n", dev_id);
+       v3_file_close(disk->fd);
+       V3_Free(disk);
        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", 
                   dev_id, v3_cfg_val(frontend_cfg, "tag"));
+       v3_file_close(disk->fd);
+       V3_Free(disk);
        return -1;
-
     }
     
 
index 924de7c..ec78bb9 100644 (file)
@@ -53,54 +53,32 @@ struct port_range {
 
 
 
-static int generic_reset_device(struct vm_device * dev) {
-    PrintDebug("generic: reset device\n");
-    return 0;
-}
-
-
-
-
-
-static int generic_start_device(struct vm_device * dev) {
-    PrintDebug("generic: start device\n");
-    return 0;
-}
-
-
-static int generic_stop_device(struct vm_device * dev) {
-    PrintDebug("generic: stop device\n");
-    return 0;
-}
-
-
-
 
 static int generic_write_port_passthrough(struct guest_info * core, uint16_t port, void * src, 
-                                         uint_t length, struct vm_device * dev) {
+                                         uint_t length, void * priv_data) {
     uint_t i;
 
     PrintDebug("generic: writing 0x");
 
     for (i = 0; i < length; i++) { 
-       PrintDebug("%x", ((uchar_t*)src)[i]);
+       PrintDebug("%x", ((uint8_t *)src)[i]);
     }
   
     PrintDebug(" to port 0x%x ... ", port);
 
     switch (length) {
        case 1:
-           v3_outb(port,((uchar_t*)src)[0]);
+           v3_outb(port, ((uint8_t *)src)[0]);
            break;
        case 2:
-           v3_outw(port,((uint16_t*)src)[0]);
+           v3_outw(port, ((uint16_t *)src)[0]);
            break;
        case 4:
-           v3_outdw(port,((uint32_t *)src)[0]);
+           v3_outdw(port, ((uint32_t *)src)[0]);
            break;
        default:
            for (i = 0; i < length; i++) { 
-               v3_outb(port, ((uchar_t *)src)[i]);
+               v3_outb(port, ((uint8_t *)src)[i]);
            }
     }
 
@@ -110,7 +88,7 @@ static int generic_write_port_passthrough(struct guest_info * core, uint16_t por
 }
 
 static int generic_read_port_passthrough(struct guest_info * core, uint16_t port, void * src, 
-                                        uint_t length, struct vm_device * dev) {
+                                        uint_t length, void * priv_data) {
     uint_t i;
 
     PrintDebug("generic: reading 0x%x bytes from port 0x%x ...", length, port);
@@ -118,24 +96,24 @@ static int generic_read_port_passthrough(struct guest_info * core, uint16_t port
 
     switch (length) {
        case 1:
-           ((uchar_t*)src)[0] = v3_inb(port);
+           ((uint8_t *)src)[0] = v3_inb(port);
            break;
        case 2:
-           ((uint16_t*)src)[0] = v3_inw(port);
+           ((uint16_t *)src)[0] = v3_inw(port);
            break;
        case 4:
-           ((uint_t*)src)[0] = v3_indw(port);
+           ((uint32_t *)src)[0] = v3_indw(port);
            break;
        default:
            for (i = 0; i < length; i++) { 
-               ((uchar_t*)src)[i] = v3_inb(port);
+               ((uint8_t *)src)[i] = v3_inb(port);
            }
     }
 
     PrintDebug(" done ... read 0x");
 
     for (i = 0; i < length; i++) { 
-       PrintDebug("%x", ((uchar_t*)src)[i]);
+       PrintDebug("%x", ((uint8_t *)src)[i]);
     }
 
     PrintDebug("\n");
@@ -144,13 +122,13 @@ static int generic_read_port_passthrough(struct guest_info * core, uint16_t port
 }
 
 static int generic_write_port_ignore(struct guest_info * core, uint16_t port, void * src, 
-                                    uint_t length, struct vm_device * dev) {
-    uint_t i;
+                                    uint_t length, void * priv_data) {
+    int i;
 
     PrintDebug("generic: writing 0x");
 
     for (i = 0; i < length; i++) { 
-       PrintDebug("%x", ((uchar_t*)src)[i]);
+       PrintDebug("%x", ((uint8_t *)src)[i]);
     }
   
     PrintDebug(" to port 0x%x ... ignored\n", port);
@@ -159,11 +137,11 @@ static int generic_write_port_ignore(struct guest_info * core, uint16_t port, vo
 }
 
 static int generic_read_port_ignore(struct guest_info * core, uint16_t port, void * src, 
-                                   uint_t length, struct vm_device * dev) {
+                                   uint_t length, void * priv_data) {
 
     PrintDebug("generic: reading 0x%x bytes from port 0x%x ...", length, port);
 
-    memset((char*)src, 0, length);
+    memset((uint8_t *)src, 0, length);
     PrintDebug(" ignored (return zeroed buffer)\n");
 
     return length;
@@ -187,7 +165,7 @@ static int generic_free(struct vm_device * dev) {
                   cur->start, cur->end);
        
        for (i = cur->start; i <= cur->end; i++) {
-           if (v3_dev_unhook_io(dev, i)) {
+           if (v3_unhook_io_port(dev->vm, i)) {
                PrintDebug("generic: can't unhook port 0x%x (already unhooked?)\n", i);
            }
        }
@@ -197,7 +175,7 @@ static int generic_free(struct vm_device * dev) {
        V3_Free(cur);
     }
 
-    generic_reset_device(dev);
+    V3_Free(state);
     return 0;
 }
 
@@ -207,9 +185,6 @@ static int generic_free(struct vm_device * dev) {
 
 static struct v3_device_ops dev_ops = { 
     .free = generic_free, 
-    .reset = generic_reset_device,
-    .start = generic_start_device,
-    .stop = generic_stop_device,
 };
 
 
@@ -230,12 +205,16 @@ static int add_port_range(struct vm_device * dev, uint_t start, uint_t end, gene
     
     for (i = start; i <= end; i++) { 
        if (mode == GENERIC_PRINT_AND_PASSTHROUGH) { 
-           if (v3_dev_hook_io(dev, i, &generic_read_port_passthrough, &generic_write_port_passthrough) == -1) { 
+           if (v3_hook_io_port(dev->vm, i, 
+                               &generic_read_port_passthrough, 
+                               &generic_write_port_passthrough, dev) == -1) { 
                PrintError("generic: can't hook port 0x%x (already hooked?)\n", i);
                return -1;
            }
        } else if (mode == GENERIC_PRINT_AND_IGNORE) { 
-           if (v3_dev_hook_io(dev, i, &generic_read_port_ignore, &generic_write_port_ignore) == -1) { 
+           if (v3_hook_io_port(dev->vm, i, 
+                               &generic_read_port_ignore, 
+                               &generic_write_port_ignore, dev) == -1) { 
                PrintError("generic: can't hook port 0x%x (already hooked?)\n", i);
                return -1;
            }
@@ -253,25 +232,32 @@ static int add_port_range(struct vm_device * dev, uint_t start, uint_t end, gene
 
 
 static int generic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
-    struct generic_internal * state = (struct generic_internal *)V3_Malloc(sizeof(struct generic_internal));
+    struct generic_internal * state = NULL;
     char * dev_id = v3_cfg_val(cfg, "ID");
-
     v3_cfg_tree_t * port_cfg = v3_cfg_subtree(cfg, "ports");
 
 
+    state = (struct generic_internal *)V3_Malloc(sizeof(struct generic_internal));
+
+    if (state == NULL) {
+       PrintError("Could not allocate generic state\n");
+       return -1;
+    }
+    
+    memset(state, 0, sizeof(struct generic_internal));
+
     INIT_LIST_HEAD(&(state->port_list));
     state->num_port_ranges = 0;
-
     
     struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
 
     if (v3_attach_device(vm, dev) == -1) {
        PrintError("Could not attach device %s\n", dev_id);
+       V3_Free(state);
        return -1;
     }
 
     PrintDebug("generic: init_device\n");
-    generic_reset_device(dev);
 
     // scan port list....
     while (port_cfg) {
@@ -286,11 +272,13 @@ static int generic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
            mode = GENERIC_PRINT_AND_PASSTHROUGH;
        } else {
            PrintError("Invalid Mode %s\n", mode_str);
+           v3_detach_device(dev);
            return -1;
        }
        
        if (add_port_range(dev, start, end, mode) == -1) {
            PrintError("Could not add port range %d-%d\n", start, end);
+           v3_detach_device(dev);
            return -1;
        }
 
index ddd169c..9b52eed 100644 (file)
@@ -21,6 +21,8 @@
 #include <palacios/vmm_dev_mgr.h>
 #include <devices/pci.h>
 
+#include <palacios/vmm_io.h>
+
 
 // We Have to setup some sort of PIC interrupt mapping here....
 
@@ -29,12 +31,14 @@ struct i440_state {
 };
 
 
-static int io_read(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+static int io_read(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * priv_data) {
+    //    struct vm_device * dev = priv_data;
     PrintError("Unhandled read on port %x\n", port);
     return -1;
 }
 
-static int io_write(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int io_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
+    //    struct vm_device * dev = priv_data;
     PrintError("Unhandled write on port %x\n", port);
     return -1;
 }
@@ -44,6 +48,18 @@ static int io_write(struct guest_info * core, ushort_t port, void * src, uint_t
 
 
 static int i440_free(struct vm_device * dev) {
+    struct i440_state * state = dev->private_data;
+    int i;
+
+    for (i = 0; i < 4; i++) {
+       v3_unhook_io_port(dev->vm, 0x0cf8 + i);
+       v3_unhook_io_port(dev->vm, 0x0cfc + i);
+    }
+
+    // unregister from PCI
+
+    V3_Free(state);
+
     return 0;
 }
 
@@ -78,15 +94,13 @@ static int i440_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
     if (v3_attach_device(vm, dev) == -1) {
        PrintError("Could not attach device %s\n", dev_id);
+       V3_Free(state);
        return -1;
     }
 
-
     for (i = 0; i < 4; i++) {
-       v3_dev_hook_io(dev, 0x0cf8 + i,
-                      &io_read, &io_write);
-       v3_dev_hook_io(dev, 0x0cfc + i,
-                      &io_read, &io_write);
+       v3_hook_io_port(vm, 0x0cf8 + i, &io_read, &io_write, dev);
+       v3_hook_io_port(vm, 0x0cfc + i, &io_read, &io_write, dev);
     }
 
     for (i = 0; i < 6; i++) {
@@ -98,6 +112,7 @@ static int i440_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
                                     NULL, NULL, NULL, dev);
 
     if (!pci_dev) {
+       v3_detach_device(dev);
        return -1;
     }
 
@@ -112,4 +127,4 @@ static int i440_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     return 0;
 }
 
-device_register("i440FX", i440_init)
+device_register("i440FX", i440_init);
index 4ad0fa9..8577e09 100644 (file)
@@ -1433,16 +1433,19 @@ static int init_ide_state(struct vm_device * dev) {
 
 static int ide_free(struct vm_device * dev) {
     // unhook io ports....
+
+
     // deregister from PCI?
+
+
+
     return 0;
 }
 
 
 static struct v3_device_ops dev_ops = {
     .free = ide_free,
-    .reset = NULL,
-    .start = NULL,
-    .stop = NULL,
+
 };
 
 
@@ -1520,10 +1523,18 @@ static int connect_fn(struct v3_vm_info * vm,
 
 
 static int ide_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
-    struct ide_internal * ide  = (struct ide_internal *)V3_Malloc(sizeof(struct ide_internal));  
+    struct ide_internal * ide  = NULL;
     char * dev_id = v3_cfg_val(cfg, "ID");
 
     PrintDebug("IDE: Initializing IDE\n");
+
+    ide = (struct ide_internal *)V3_Malloc(sizeof(struct ide_internal));
+
+    if (ide == NULL) {
+       PrintError("Error allocating IDE state\n");
+       return -1;
+    }
+
     memset(ide, 0, sizeof(struct ide_internal));
 
 
@@ -1534,6 +1545,7 @@ static int ide_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
        if (!southbridge) {
            PrintError("Could not find southbridge\n");
+           V3_Free(ide);
            return -1;
        }
 
@@ -1546,11 +1558,14 @@ static int ide_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
     if (v3_attach_device(vm, dev) == -1) {
        PrintError("Could not attach device %s\n", dev_id);
+       v3_free_device(dev);
+       V3_Free(ide);
        return -1;
     }
 
     if (init_ide_state(dev) == -1) {
        PrintError("Failed to initialize IDE state\n");
+       v3_detach_device(dev);
        return -1;
     }
 
@@ -1662,6 +1677,7 @@ static int ide_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
     if (v3_dev_add_blk_frontend(vm, dev_id, connect_fn, (void *)ide) == -1) {
        PrintError("Could not register %s as frontend\n", dev_id);
+       v3_detach_device(dev);
        return -1;
     }
     
index 9ecf780..f461606 100644 (file)
@@ -35,6 +35,12 @@ v3_console_t v3_console_open(struct v3_vm_info * vm, uint32_t width, uint32_t he
     return console_hooks->open(vm->host_priv_data, width, height);
 }
 
+void v3_console_close(v3_console_t cons) {
+    V3_ASSERT(console_hooks);
+    V3_ASSERT(console_hooks->close);
+
+    console_hooks->close(cons);
+}
 
 int v3_console_set_cursor(v3_console_t cons, int x, int y) {
     V3_ASSERT(console_hooks != NULL);
index 5561cec..cd6857d 100644 (file)
@@ -115,7 +115,6 @@ int v3_dev_mgr_deinit(struct v3_vm_info * vm) {
 
     list_for_each_entry_safe(dev, tmp, &(mgr->dev_list), dev_link) {
        v3_detach_device(dev);
-       v3_free_device(dev);
     }
 
     v3_free_htable(mgr->blk_table, 0, 0);
@@ -145,7 +144,6 @@ int v3_core_dev_mgr_deinit(struct v3_vm_info * vm) {
 
     list_for_each_entry_safe(dev, tmp, &(mgr->dev_list), dev_link) {
        v3_detach_device(dev);
-       v3_free_device(dev);
     }
 
     // TODO: Clear hash tables 
@@ -226,6 +224,7 @@ int v3_detach_device(struct vm_device * dev) {
 
     dev->vm = NULL;
 
+    v3_free_device(dev);
     return -1;
 }