X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmm_dev_mgr.c;h=6f80ba9255a1aef07195491fe176de85935b9476;hb=16745fa0dd0900263d4d92315cd17e0ed9ccae91;hp=47834926cedfaf0cc5578e0dddc434653582fead;hpb=a0d3be5212e7a5053ba213ce7bd26c7124cf01e3;p=palacios.git diff --git a/palacios/src/palacios/vmm_dev_mgr.c b/palacios/src/palacios/vmm_dev_mgr.c index 4783492..6f80ba9 100644 --- a/palacios/src/palacios/vmm_dev_mgr.c +++ b/palacios/src/palacios/vmm_dev_mgr.c @@ -97,12 +97,12 @@ int v3_init_dev_mgr(struct v3_vm_info * vm) { INIT_LIST_HEAD(&(mgr->blk_list)); INIT_LIST_HEAD(&(mgr->net_list)); INIT_LIST_HEAD(&(mgr->char_list)); - INIT_LIST_HEAD(&(mgr->console_list)); + INIT_LIST_HEAD(&(mgr->cons_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->char_table = v3_create_htable(0, dev_hash_fn, dev_eq_fn); - mgr->console_table = v3_create_htable(0, dev_hash_fn, dev_eq_fn); + mgr->cons_table = v3_create_htable(0, dev_hash_fn, dev_eq_fn); return 0; } @@ -114,13 +114,13 @@ int v3_dev_mgr_deinit(struct v3_vm_info * vm) { struct vm_device * tmp; list_for_each_entry_safe(dev, tmp, &(mgr->dev_list), dev_link) { - v3_detach_device(dev); + v3_remove_device(dev); } v3_free_htable(mgr->blk_table, 0, 0); v3_free_htable(mgr->net_table, 0, 0); v3_free_htable(mgr->char_table, 0, 0); - v3_free_htable(mgr->console_table, 0, 0); + v3_free_htable(mgr->cons_table, 0, 0); v3_free_htable(mgr->dev_table, 0, 0); @@ -149,10 +149,6 @@ int v3_create_device(struct v3_vm_info * vm, const char * dev_name, v3_cfg_tree_ } -void v3_free_device(struct vm_device * dev) { - V3_Free(dev); -} - struct vm_device * v3_find_dev(struct v3_vm_info * vm, const char * dev_name) { @@ -226,11 +222,19 @@ int v3_dev_unhook_io(struct vm_device * dev, uint16_t port) { -int v3_detach_device(struct vm_device * dev) { +int v3_remove_device(struct vm_device * dev) { struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr); + struct dev_io_hook * io_hook = NULL; + struct dev_io_hook * tmp; + + list_for_each_entry_safe(io_hook, tmp, &(dev->io_hooks), node) { + v3_unhook_io_port(dev->vm, io_hook->port); + list_del(&(io_hook->node)); + V3_Free(io_hook); + } if (dev->ops->free) { - dev->ops->free(dev); + dev->ops->free(dev->private_data); } else { PrintError("Error: %s free() not implemented\n", dev->name); } @@ -240,17 +244,23 @@ int v3_detach_device(struct vm_device * dev) { dev->vm = NULL; - v3_free_device(dev); + V3_Free(dev); return -1; } -struct vm_device * v3_allocate_device(char * name, - struct v3_device_ops * ops, - void * private_data) { +struct vm_device * v3_add_device(struct v3_vm_info * vm, + char * name, + struct v3_device_ops * ops, + void * private_data) { + struct vmm_dev_mgr * mgr = &(vm->dev_mgr); struct vm_device * dev = NULL; - dev = (struct vm_device*)V3_Malloc(sizeof(struct vm_device)); + dev = (struct vm_device *)V3_Malloc(sizeof(struct vm_device)); + + if (dev == NULL) { + return NULL; + } INIT_LIST_HEAD(&(dev->io_hooks)); @@ -258,28 +268,17 @@ struct vm_device * v3_allocate_device(char * name, dev->ops = ops; dev->private_data = private_data; - dev->vm = NULL; - - return dev; -} - - -int v3_attach_device(struct v3_vm_info * vm, struct vm_device * dev ) { - struct vmm_dev_mgr * mgr = &(vm->dev_mgr); - dev->vm = vm; list_add(&(dev->dev_link), &(mgr->dev_list)); mgr->num_devs++; - v3_htable_insert(mgr->dev_table, (addr_t)(dev->name), (addr_t)dev); - return 0; + return dev; } - void v3_print_dev_mgr(struct v3_vm_info * vm) { struct vmm_dev_mgr * mgr = &(vm->dev_mgr); struct vm_device * dev; @@ -423,6 +422,67 @@ int v3_dev_connect_net(struct v3_vm_info * vm, } +struct cons_frontend { + int (*connect)(struct v3_vm_info * vm, + void * frontend_data, + struct v3_dev_console_ops * ops, + v3_cfg_tree_t * cfg, + void * priv_data); + + + struct list_head cons_node; + + void * priv_data; +}; + +int v3_dev_add_console_frontend(struct v3_vm_info * vm, + char * name, + int (*connect)(struct v3_vm_info * vm, + void * frontend_data, + struct v3_dev_console_ops * ops, + v3_cfg_tree_t * cfg, + void * private_data), + void * priv_data) +{ + struct cons_frontend * frontend = NULL; + + frontend = (struct cons_frontend *)V3_Malloc(sizeof(struct cons_frontend)); + memset(frontend, 0, sizeof(struct cons_frontend)); + + frontend->connect = connect; + frontend->priv_data = priv_data; + + list_add(&(frontend->cons_node), &(vm->dev_mgr.cons_list)); + v3_htable_insert(vm->dev_mgr.cons_table, (addr_t)(name), (addr_t)frontend); + + return 0; +} + + +int v3_dev_connect_console(struct v3_vm_info * vm, + char * frontend_name, + struct v3_dev_console_ops * ops, + v3_cfg_tree_t * cfg, + void * private_data) +{ + struct cons_frontend * frontend = NULL; + + frontend = (struct cons_frontend *)v3_htable_search(vm->dev_mgr.cons_table, + (addr_t)frontend_name); + + if (frontend == NULL) { + PrintError("Could not find frontend console device %s\n", frontend_name); + return 0; + } + + if (frontend->connect(vm, frontend->priv_data, ops, cfg, private_data) == -1) { + PrintError("Error connecting to console frontend %s\n", frontend_name); + return -1; + } + + return 0; +} + struct char_frontend { int (*connect)(struct v3_vm_info * vm, void * frontend_data, @@ -437,8 +497,6 @@ struct char_frontend { void * priv_data; }; - - int v3_dev_add_char_frontend(struct v3_vm_info * vm, char * name, int (*connect)(struct v3_vm_info * vm,