int v3_create_device(struct v3_vm_info * vm, const char * dev_name, v3_cfg_tree_t * cfg);
-
-void v3_free_device(struct vm_device * dev);
-
-
struct vm_device * v3_find_dev(struct v3_vm_info * info, const char * dev_name);
ushort_t port);
+
+struct vm_device * v3_add_device(struct v3_vm_info * vm, char * name,
+ struct v3_device_ops * ops, void * private_data);
+int v3_remove_device(struct vm_device * dev);
+
+
int v3_attach_device(struct v3_vm_info * vm, struct vm_device * dev);
int v3_detach_device(struct vm_device * dev);
-
struct vm_device * v3_allocate_device(char * name, struct v3_device_ops * ops, void * private_data);
V3_ASSERT(pit_state != NULL);
pit_state->speaker = 0;
- dev = v3_allocate_device(dev_id, &dev_ops, pit_state);
+ dev = v3_add_device(vm, dev_id, &dev_ops, pit_state);
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
V3_Free(pit_state);
return -1;
if (ret != 0) {
PrintError("8254 PIT: Failed to hook IO ports\n");
- v3_detach_device(dev);
+ v3_remove_device(dev);
return -1;
}
pit_state->timer = v3_add_timer(info, &timer_ops, pit_state);
if (pit_state->timer == NULL) {
- v3_detach_device(dev);
+ v3_remove_device(dev);
return -1;
}
static int pic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
struct pic_internal * state = NULL;
- state = (struct pic_internal *)V3_Malloc(sizeof(struct pic_internal));
char * dev_id = v3_cfg_val(cfg, "ID");
+ int ret = 0;
// PIC is only usable in non-multicore environments
// just hardcode the core context
struct guest_info * core = &(vm->cores[0]);
V3_ASSERT(state != NULL);
+
+ state = (struct pic_internal *)V3_Malloc(sizeof(struct pic_internal));
+
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, state);
- if (v3_attach_device(vm, dev) == -1) {
- PrintError("Could not attach device %s\n", dev_id);
+ if (dev == NULL) {
+ PrintError("Could not add device %s\n", dev_id);
+ V3_Free(state);
return -1;
}
state->slave_state = ICW1;
- v3_dev_hook_io(dev, MASTER_PORT1, &read_master_port1, &write_master_port1);
- v3_dev_hook_io(dev, MASTER_PORT2, &read_master_port2, &write_master_port2);
- v3_dev_hook_io(dev, SLAVE_PORT1, &read_slave_port1, &write_slave_port1);
- v3_dev_hook_io(dev, SLAVE_PORT2, &read_slave_port2, &write_slave_port2);
+ ret |= v3_dev_hook_io(dev, MASTER_PORT1, &read_master_port1, &write_master_port1);
+ ret |= v3_dev_hook_io(dev, MASTER_PORT2, &read_master_port2, &write_master_port2);
+ ret |= v3_dev_hook_io(dev, SLAVE_PORT1, &read_slave_port1, &write_slave_port1);
+ ret |= v3_dev_hook_io(dev, SLAVE_PORT2, &read_slave_port2, &write_slave_port2);
- v3_dev_hook_io(dev, ELCR1_PORT, &read_elcr_port, &write_elcr_port);
- v3_dev_hook_io(dev, ELCR2_PORT, &read_elcr_port, &write_elcr_port);
+ ret |= v3_dev_hook_io(dev, ELCR1_PORT, &read_elcr_port, &write_elcr_port);
+ ret |= v3_dev_hook_io(dev, ELCR2_PORT, &read_elcr_port, &write_elcr_port);
+
+ if (ret != 0) {
+ PrintError("Error hooking io ports\n");
+ v3_remove_device(dev);
+ return -1;
+ }
return 0;
}
apic_dev->num_apics = vm->num_cores;
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, apic_dev);
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, apic_dev);
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("apic: Could not attach device %s\n", dev_id);
V3_Free(apic_dev);
return -1;
if (apic->timer == NULL) {
PrintError("APIC: Failed to attach timer to core %d\n", i);
- v3_detach_device(dev);
+ v3_remove_device(dev);
return -1;
}
state = (struct debug_state *)V3_Malloc(sizeof(struct debug_state));
- V3_ASSERT(state != NULL);
+ if (state == NULL) {
+ PrintError("Could not allocate bochs debug state\n");
+ return -1;
+ }
PrintDebug("Creating Bochs Debug Device\n");
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, state);
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
V3_Free(state);
return -1;
if (ret != 0) {
PrintError("Could not hook Bochs Debug IO Ports\n");
- v3_detach_device(dev);
+ v3_remove_device(dev);
return -1;
}
struct video_internal * video_state = NULL;
char * dev_id = v3_cfg_val(cfg, "ID");
char * passthrough_str = v3_cfg_val(cfg, "passthrough");
+ int ret = 0;
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);
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, video_state);
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
V3_Free(video_state);
return -1;
}
- 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);
-
+ ret |= v3_dev_hook_io(dev, 0x3b0, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3b1, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3b2, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3b3, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3b4, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3b5, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3b6, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3b7, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3b8, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3b9, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3ba, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3bb, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3c0, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3c1, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3c2, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3c3, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3c4, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3c5, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3c6, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3c7, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3c8, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3c9, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3ca, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3cb, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3cc, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3cd, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3ce, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3cf, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3d0, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3d1, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3d2, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3d3, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3d4, &video_read_port, &crtc_index_write);
+ ret |= v3_dev_hook_io(dev, 0x3d5, &video_read_port, &crtc_data_write);
+ ret |= v3_dev_hook_io(dev, 0x3d6, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3d7, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3d8, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3d9, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3da, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3db, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3dc, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3dd, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3de, &video_read_port, &video_write_port);
+ ret |= v3_dev_hook_io(dev, 0x3df, &video_read_port, &video_write_port);
+
+ if (ret != 0) {
+ PrintError("Error allocating cga io port\n");
+ v3_remove_device(dev);
+ return -1;
+ }
return 0;
}
memset(state, 0, sizeof(struct stream_state));
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, state);
if (dev == NULL) {
PrintError("Could not allocate device %s\n", dev_id);
return -1;
}
- if (v3_attach_device(vm, dev) == -1) {
- PrintError("Could not attach device %s\n", dev_id);
- V3_Free(state);
- 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);
+ v3_remove_device(dev);
return -1;
}
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);
+ v3_remove_device(dev);
return -1;
}
}
/* allocate device */
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
- V3_ASSERT(dev);
-
- /* attach device to virtual machine */
- if (v3_attach_device(vm, dev) == -1) {
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, state);
+
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
V3_Free(state);
return -1;
char * dev_id = v3_cfg_val(cfg, "ID");
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, NULL);
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, NULL);
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
return -1;
}
if (v3_dev_add_blk_frontend(vm, dev_id, connect_fn, NULL) == -1) {
PrintError("Could not register %s as block frontend\n", dev_id);
+ v3_remove_device(dev);
return -1;
}
memset(disk, 0, sizeof(struct disk_state));
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, disk);
+
+ if (dev == NULL) {
+ PrintError("Could not attach device %s\n", dev_id);
+ V3_Free(disk);
+ return -1;
+ }
+
+
disk->fd = v3_file_open(vm, path, flags);
if (disk->fd == NULL) {
PrintError("Could not open file disk:%s\n", path);
- V3_Free(disk);
+ v3_remove_device(dev);
return -1;
}
PrintDebug("Registering FILEDISK %s (path=%s, fd=%lu, size=%lu)\n",
dev_id, path, file->fd, file->capacity);
- 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);
+ v3_remove_device(dev);
return -1;
}
memset(state, 0, sizeof(struct generic_internal));
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, state);
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
V3_Free(state);
return -1;
mode = GENERIC_PRINT_AND_PASSTHROUGH;
} else {
PrintError("Invalid Mode %s\n", mode_str);
- v3_detach_device(dev);
+ v3_remove_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);
+ v3_remove_device(dev);
return -1;
}
struct i440_state * state = NULL;
struct vm_device * pci = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
char * dev_id = v3_cfg_val(cfg, "ID");
+ int ret = 0;
if (!pci) {
PrintError("could not find PCI Device\n");
state->pci = pci;
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, state);
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
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);
+ ret |= v3_dev_hook_io(dev, 0x0cf8 + i, &io_read, &io_write);
+ ret |= v3_dev_hook_io(dev, 0x0cfc + i, &io_read, &io_write);
+ }
+
+ if (ret != 0) {
+ PrintError("Error hooking i440FX io ports\n");
+ v3_remove_device(dev);
+ return -1;
}
for (i = 0; i < 6; i++) {
NULL, NULL, NULL, state);
if (!pci_dev) {
- v3_detach_device(dev);
+ v3_remove_device(dev);
return -1;
}
static int ide_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
struct ide_internal * ide = NULL;
char * dev_id = v3_cfg_val(cfg, "ID");
+ int ret = 0;
PrintDebug("IDE: Initializing IDE\n");
memset(ide, 0, sizeof(struct ide_internal));
ide->vm = vm;
-
ide->pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
if (ide->pci_bus != NULL) {
PrintDebug("IDE: Creating IDE bus x 2\n");
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, ide);
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, ide);
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
- v3_free_device(dev);
V3_Free(ide);
return -1;
}
if (init_ide_state(ide) == -1) {
PrintError("Failed to initialize IDE state\n");
- v3_detach_device(dev);
+ v3_remove_device(dev);
return -1;
}
PrintDebug("Connecting to IDE IO ports\n");
- v3_dev_hook_io(dev, PRI_DATA_PORT,
- &ide_read_data_port, &write_data_port);
- v3_dev_hook_io(dev, PRI_FEATURES_PORT,
- &read_port_std, &write_port_std);
- v3_dev_hook_io(dev, PRI_SECT_CNT_PORT,
- &read_port_std, &write_port_std);
- v3_dev_hook_io(dev, PRI_SECT_NUM_PORT,
- &read_port_std, &write_port_std);
- v3_dev_hook_io(dev, PRI_CYL_LOW_PORT,
- &read_port_std, &write_port_std);
- v3_dev_hook_io(dev, PRI_CYL_HIGH_PORT,
- &read_port_std, &write_port_std);
- v3_dev_hook_io(dev, PRI_DRV_SEL_PORT,
- &read_port_std, &write_port_std);
- v3_dev_hook_io(dev, PRI_CMD_PORT,
- &read_port_std, &write_cmd_port);
-
- v3_dev_hook_io(dev, SEC_DATA_PORT,
- &ide_read_data_port, &write_data_port);
- v3_dev_hook_io(dev, SEC_FEATURES_PORT,
- &read_port_std, &write_port_std);
- v3_dev_hook_io(dev, SEC_SECT_CNT_PORT,
- &read_port_std, &write_port_std);
- v3_dev_hook_io(dev, SEC_SECT_NUM_PORT,
- &read_port_std, &write_port_std);
- v3_dev_hook_io(dev, SEC_CYL_LOW_PORT,
- &read_port_std, &write_port_std);
- v3_dev_hook_io(dev, SEC_CYL_HIGH_PORT,
- &read_port_std, &write_port_std);
- v3_dev_hook_io(dev, SEC_DRV_SEL_PORT,
- &read_port_std, &write_port_std);
- v3_dev_hook_io(dev, SEC_CMD_PORT,
- &read_port_std, &write_cmd_port);
+ ret |= v3_dev_hook_io(dev, PRI_DATA_PORT,
+ &ide_read_data_port, &write_data_port);
+ ret |= v3_dev_hook_io(dev, PRI_FEATURES_PORT,
+ &read_port_std, &write_port_std);
+ ret |= v3_dev_hook_io(dev, PRI_SECT_CNT_PORT,
+ &read_port_std, &write_port_std);
+ ret |= v3_dev_hook_io(dev, PRI_SECT_NUM_PORT,
+ &read_port_std, &write_port_std);
+ ret |= v3_dev_hook_io(dev, PRI_CYL_LOW_PORT,
+ &read_port_std, &write_port_std);
+ ret |= v3_dev_hook_io(dev, PRI_CYL_HIGH_PORT,
+ &read_port_std, &write_port_std);
+ ret |= v3_dev_hook_io(dev, PRI_DRV_SEL_PORT,
+ &read_port_std, &write_port_std);
+ ret |= v3_dev_hook_io(dev, PRI_CMD_PORT,
+ &read_port_std, &write_cmd_port);
+
+ ret |= v3_dev_hook_io(dev, SEC_DATA_PORT,
+ &ide_read_data_port, &write_data_port);
+ ret |= v3_dev_hook_io(dev, SEC_FEATURES_PORT,
+ &read_port_std, &write_port_std);
+ ret |= v3_dev_hook_io(dev, SEC_SECT_CNT_PORT,
+ &read_port_std, &write_port_std);
+ ret |= v3_dev_hook_io(dev, SEC_SECT_NUM_PORT,
+ &read_port_std, &write_port_std);
+ ret |= v3_dev_hook_io(dev, SEC_CYL_LOW_PORT,
+ &read_port_std, &write_port_std);
+ ret |= v3_dev_hook_io(dev, SEC_CYL_HIGH_PORT,
+ &read_port_std, &write_port_std);
+ ret |= v3_dev_hook_io(dev, SEC_DRV_SEL_PORT,
+ &read_port_std, &write_port_std);
+ ret |= v3_dev_hook_io(dev, SEC_CMD_PORT,
+ &read_port_std, &write_cmd_port);
- v3_dev_hook_io(dev, PRI_CTRL_PORT,
- &read_port_std, &write_port_std);
+ ret |= v3_dev_hook_io(dev, PRI_CTRL_PORT,
+ &read_port_std, &write_port_std);
- v3_dev_hook_io(dev, SEC_CTRL_PORT,
- &read_port_std, &write_port_std);
+ ret |= v3_dev_hook_io(dev, SEC_CTRL_PORT,
+ &read_port_std, &write_port_std);
- v3_dev_hook_io(dev, SEC_ADDR_REG_PORT,
- &read_port_std, &write_port_std);
+ ret |= v3_dev_hook_io(dev, SEC_ADDR_REG_PORT,
+ &read_port_std, &write_port_std);
- v3_dev_hook_io(dev, PRI_ADDR_REG_PORT,
- &read_port_std, &write_port_std);
+ ret |= v3_dev_hook_io(dev, PRI_ADDR_REG_PORT,
+ &read_port_std, &write_port_std);
+ if (ret != 0) {
+ PrintError("Error hooking IDE IO port\n");
+ v3_remove_device(dev);
+ return -1;
+ }
if (ide->pci_bus) {
if (pci_dev == NULL) {
PrintError("Failed to register IDE BUS %d with PCI\n", i);
+ v3_remove_device(dev);
return -1;
}
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);
+ v3_remove_device(dev);
return -1;
}
ioapic->apic_dev_data = apic_dev;
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, ioapic);
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, ioapic);
-
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("ioapic: Could not attach device %s\n", dev_id);
+ V3_Free(ioapic);
return -1;
}
-
v3_register_intr_router(vm, &router_ops, ioapic);
init_ioapic_state(ioapic, vm->num_cores);
static int keyboard_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
struct keyboard_internal * kbd = NULL;
char * dev_id = v3_cfg_val(cfg, "ID");
+ int ret = 0;
PrintDebug("keyboard: init_device\n");
kbd->vm = vm;
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, kbd);
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, kbd);
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
+ V3_Free(kbd);
return -1;
}
// hook ports
- v3_dev_hook_io(dev, KEYBOARD_64H, &keyboard_read_status, &keyboard_write_command);
- v3_dev_hook_io(dev, KEYBOARD_60H, &keyboard_read_input, &keyboard_write_output);
+ ret |= v3_dev_hook_io(dev, KEYBOARD_64H, &keyboard_read_status, &keyboard_write_command);
+ ret |= v3_dev_hook_io(dev, KEYBOARD_60H, &keyboard_read_input, &keyboard_write_output);
+
+ if (ret != 0) {
+ PrintError("Error hooking keyboard IO ports\n");
+ v3_remove_device(dev);
+ return -1;
+ }
v3_hook_host_event(vm, HOST_KEYBOARD_EVT, V3_HOST_EVENT_HANDLER(key_event_handler), kbd);
v3_hook_host_event(vm, HOST_MOUSE_EVT, V3_HOST_EVENT_HANDLER(mouse_event_handler), kbd);
}
- virtio_state = (struct virtio_balloon_state *)V3_Malloc(sizeof(struct virtio_balloon_state));
+ virtio_state = (struct virtio_balloon_state *)V3_Malloc(sizeof(struct virtio_balloon_state));
memset(virtio_state, 0, sizeof(struct virtio_balloon_state));
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, virtio_state);
- if (v3_attach_device(vm, dev) == -1) {
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, virtio_state);
+
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
+ V3_Free(virtio_state);
return -1;
}
-
-
-
// PCI initialization
{
struct v3_pci_bar bars[6];
if (!pci_dev) {
PrintError("Could not register PCI Device\n");
+ v3_remove_device(dev);
return -1;
}
virtio_state->pci_bus = pci_bus;
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, virtio_state);
- if (v3_attach_device(vm, dev) == -1) {
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, virtio_state);
+
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
+ V3_Free(virtio_state);
return -1;
}
if (v3_dev_add_blk_frontend(vm, dev_id, connect_fn, (void *)virtio_state) == -1) {
PrintError("Could not register %s as block frontend\n", dev_id);
+ v3_remove_device(dev);
return -1;
}
virtio_state->pci_bus = pci_bus;
virtio_state->vm = vm;
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, virtio_state);
- if (v3_attach_device(vm, dev) == -1) {
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, virtio_state);
+
+ if (dev == NULL) {
PrintError("Virtio NIC: Could not attach device %s\n", dev_id);
+ V3_Free(virtio_state);
return -1;
}
if (v3_dev_add_net_frontend(vm, dev_id, connect_fn, (void *)virtio_state) == -1) {
PrintError("Virtio NIC: Could not register %s as net frontend\n", dev_id);
+ v3_remove_device(dev);
return -1;
}
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, virtio_state);
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, virtio_state);
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
+ V3_Free(virtio_state);
return -1;
}
if (!pci_dev) {
PrintError("Could not register PCI Device\n");
+ v3_remove_device(dev);
return -1;
}
}
-
V3_Print("SYMMOD: %d available sym modules\n", virtio_state->sym_cfg.avail_mods);
virtio_reset(virtio_state);
vnet_state->vm = vm;
- struct vm_device * dev = v3_allocate_device(name, &dev_ops, vnet_state);
+ struct vm_device * dev = v3_add_device(vm, name, &dev_ops, vnet_state);
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", name);
+ V3_Free(vnet_state);
return -1;
}
if (!pci_dev) {
PrintError("Could not register PCI Device\n");
+ v3_remove_device(dev);
return -1;
}
brg_ops.poll = vnet_virtio_poll;
V3_Print("Registering Virtio device as vnet bridge\n");
+
v3_vnet_add_bridge(vm, &brg_ops, CTL_VM_BRIDGE, (void *)vnet_state);
return 0;
disk->port = atoi(port_str);
disk->vm = vm;
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, disk);
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, disk);
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
+ V3_Free(disk);
return -1;
}
if (socket_init(disk) == -1) {
PrintError("could not initialize network connection\n");
+ v3_remove_device(dev);
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\n", dev_id);
+ v3_remove_device(dev);
return -1;
}
bridge = (struct nic_bridge_state *)V3_Malloc(sizeof(struct nic_bridge_state));
memset(bridge, 0, sizeof(struct nic_bridge_state));
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, bridge);
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, bridge);
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
+ V3_Free(bridge);
return -1;
}
&(bridge->net_ops), frontend_cfg, bridge) == -1) {
PrintError("Could not connect %s to frontend %s\n",
dev_id, v3_cfg_val(frontend_cfg, "tag"));
+ v3_remove_device(dev);
return -1;
}
struct nvram_internal * nvram_state = NULL;
struct vm_device * ide = v3_find_dev(vm, v3_cfg_val(cfg, "storage"));
char * dev_id = v3_cfg_val(cfg, "ID");
+ int ret = 0;
if (!ide) {
PrintError("Could not find IDE device\n");
nvram_state->ide = ide;
nvram_state->vm = vm;
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, nvram_state);
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, nvram_state);
-
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
+ V3_Free(nvram_state);
return -1;
}
init_nvram_state(vm, nvram_state);
// hook ports
- v3_dev_hook_io(dev, NVRAM_REG_PORT, NULL, &nvram_write_reg_port);
- v3_dev_hook_io(dev, NVRAM_DATA_PORT, &nvram_read_data_port, &nvram_write_data_port);
+ ret |= v3_dev_hook_io(dev, NVRAM_REG_PORT, NULL, &nvram_write_reg_port);
+ ret |= v3_dev_hook_io(dev, NVRAM_DATA_PORT, &nvram_read_data_port, &nvram_write_data_port);
+ if (ret != 0) {
+ PrintError("Error hooking NVRAM IO ports\n");
+ v3_remove_device(dev);
+ return -1;
+ }
+
v3_hook_host_event(vm, HOST_TIMER_EVT, V3_HOST_EVENT_HANDLER(handle_timer_event), nvram_state);
return 0;
PrintDebug("Creating OS Debug Device\n");
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, state);
-
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
+ V3_Free(state);
+ return -1;
+ }
+
+ if (v3_dev_hook_io(dev, DEBUG_PORT1, NULL, &handle_gen_write) == -1) {
+ PrintError("Error hooking OS debug IO port\n");
+ v3_remove_device(dev);
return -1;
}
- v3_dev_hook_io(dev, DEBUG_PORT1, NULL, &handle_gen_write);
v3_register_hypercall(vm, OS_DEBUG_HCALL, handle_hcall, state);
state->debug_offset = 0;
struct pci_internal * pci_state = V3_Malloc(sizeof(struct pci_internal));
int i = 0;
char * dev_id = v3_cfg_val(cfg, "ID");
+ int ret = 0;
PrintDebug("PCI internal at %p\n",(void *)pci_state);
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, pci_state);
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, pci_state);
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
+ V3_Free(pci_state);
return -1;
}
PrintDebug("Sizeof config header=%d\n", (int)sizeof(struct pci_config_header));
for (i = 0; i < 4; i++) {
- v3_dev_hook_io(dev, CONFIG_ADDR_PORT + i, &addr_port_read, &addr_port_write);
- v3_dev_hook_io(dev, CONFIG_DATA_PORT + i, &data_port_read, &data_port_write);
+ ret |= v3_dev_hook_io(dev, CONFIG_ADDR_PORT + i, &addr_port_read, &addr_port_write);
+ ret |= v3_dev_hook_io(dev, CONFIG_DATA_PORT + i, &data_port_read, &data_port_write);
+ }
+
+ if (ret != 0) {
+ PrintError("Error hooking PCI IO ports\n");
+ v3_remove_device(dev);
+ return -1;
}
return 0;
struct pci_internal * pci_state = (struct pci_internal *)pci_bus->private_data;
struct pci_bus * bus = &(pci_state->bus_list[bus_num]);
- return bus->raise_pci_irq(bus->irq_dev_data, dev);
+ return bus->raise_pci_irq(dev, bus->irq_dev_data);
}
int v3_pci_lower_irq(struct vm_device * pci_bus, int bus_num, struct pci_device * dev) {
struct pci_internal * pci_state = (struct pci_internal *)pci_bus->private_data;
struct pci_bus * bus = &(pci_state->bus_list[bus_num]);
- return bus->lower_pci_irq(bus->irq_dev_data, dev);
+ return bus->lower_pci_irq(dev, bus->irq_dev_data);
}
// if dev_num == -1, auto assign
strncpy(state->name, dev_id, 32);
- dev = v3_allocate_device(dev_id, &dev_ops, state);
+ dev = v3_add_device(vm, dev_id, &dev_ops, state);
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
+ V3_Free(state);
return -1;
}
PrintError("Could not find PCI Device %s:%s\n",
v3_cfg_val(cfg, "vendor_id"),
v3_cfg_val(cfg, "device_id"));
+ v3_remove_device(dev);
return 0;
}
piix3->pci_bus = pci;
piix3->type = V3_SB_PIIX3;
- dev = v3_allocate_device(dev_id, &dev_ops, piix3);
+ dev = v3_add_device(vm, dev_id, &dev_ops, piix3);
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
+ V3_Free(piix3);
return -1;
}
PrintDebug("Created PIIX3\n");
- return setup_pci(piix3);
+ if (setup_pci(piix3) == -1) {
+ v3_remove_device(dev);
+ return -1;
+ }
+
+ return 0;
}
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, dev_id);
return -1;
return -1;
}
+
+ disk = (struct disk_state *)V3_Malloc(sizeof(struct disk_state));
+ memset(disk, 0, sizeof(struct disk_state));
+
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(dev_id, &dev_ops, disk);
- if (v3_attach_device(vm, dev) == -1) {
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, disk);
+
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
+ 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_remove_device(dev);
return -1;
}
static int serial_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
struct serial_state * state = NULL;
char * dev_id = v3_cfg_val(cfg, "ID");
+ int ret = 0;
state = (struct serial_state *)V3_Malloc(sizeof(struct serial_state));
memset(state, 0, sizeof(struct serial_state));
-
-
init_serial_port(&(state->coms[0]));
init_serial_port(&(state->coms[1]));
init_serial_port(&(state->coms[2]));
state->coms[3].irq_number = COM4_IRQ;
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, state);
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
+ V3_Free(state);
return -1;
}
PrintDebug("Serial device attached\n");
- v3_dev_hook_io(dev, COM1_DATA_PORT, &read_data_port, &write_data_port);
- v3_dev_hook_io(dev, COM1_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
- v3_dev_hook_io(dev, COM1_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
- v3_dev_hook_io(dev, COM1_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
- v3_dev_hook_io(dev, COM1_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
- v3_dev_hook_io(dev, COM1_LINE_STATUS_PORT, &read_status_port, &write_status_port);
- v3_dev_hook_io(dev, COM1_MODEM_STATUS_PORT, &read_status_port, &write_status_port);
- v3_dev_hook_io(dev, COM1_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
-
- v3_dev_hook_io(dev, COM2_DATA_PORT, &read_data_port, &write_data_port);
- v3_dev_hook_io(dev, COM2_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
- v3_dev_hook_io(dev, COM2_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
- v3_dev_hook_io(dev, COM2_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
- v3_dev_hook_io(dev, COM2_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
- v3_dev_hook_io(dev, COM2_LINE_STATUS_PORT, &read_status_port, &write_status_port);
- v3_dev_hook_io(dev, COM2_MODEM_STATUS_PORT, &read_status_port, &write_status_port);
- v3_dev_hook_io(dev, COM2_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
-
- v3_dev_hook_io(dev, COM3_DATA_PORT, &read_data_port, &write_data_port);
- v3_dev_hook_io(dev, COM3_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
- v3_dev_hook_io(dev, COM3_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
- v3_dev_hook_io(dev, COM3_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
- v3_dev_hook_io(dev, COM3_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
- v3_dev_hook_io(dev, COM3_LINE_STATUS_PORT, &read_status_port, &write_status_port);
- v3_dev_hook_io(dev, COM3_MODEM_STATUS_PORT, &read_status_port, &write_status_port);
- v3_dev_hook_io(dev, COM3_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
-
- v3_dev_hook_io(dev, COM4_DATA_PORT, &read_data_port, &write_data_port);
- v3_dev_hook_io(dev, COM4_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
- v3_dev_hook_io(dev, COM4_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
- v3_dev_hook_io(dev, COM4_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
- v3_dev_hook_io(dev, COM4_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
- v3_dev_hook_io(dev, COM4_LINE_STATUS_PORT, &read_status_port, &write_status_port);
- v3_dev_hook_io(dev, COM4_MODEM_STATUS_PORT, &read_status_port, &write_status_port);
- v3_dev_hook_io(dev, COM4_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
+ ret |= v3_dev_hook_io(dev, COM1_DATA_PORT, &read_data_port, &write_data_port);
+ ret |= v3_dev_hook_io(dev, COM1_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
+ ret |= v3_dev_hook_io(dev, COM1_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
+ ret |= v3_dev_hook_io(dev, COM1_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
+ ret |= v3_dev_hook_io(dev, COM1_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
+ ret |= v3_dev_hook_io(dev, COM1_LINE_STATUS_PORT, &read_status_port, &write_status_port);
+ ret |= v3_dev_hook_io(dev, COM1_MODEM_STATUS_PORT, &read_status_port, &write_status_port);
+ ret |= v3_dev_hook_io(dev, COM1_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
+
+ ret |= v3_dev_hook_io(dev, COM2_DATA_PORT, &read_data_port, &write_data_port);
+ ret |= v3_dev_hook_io(dev, COM2_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
+ ret |= v3_dev_hook_io(dev, COM2_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
+ ret |= v3_dev_hook_io(dev, COM2_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
+ ret |= v3_dev_hook_io(dev, COM2_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
+ ret |= v3_dev_hook_io(dev, COM2_LINE_STATUS_PORT, &read_status_port, &write_status_port);
+ ret |= v3_dev_hook_io(dev, COM2_MODEM_STATUS_PORT, &read_status_port, &write_status_port);
+ ret |= v3_dev_hook_io(dev, COM2_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
+
+ ret |= v3_dev_hook_io(dev, COM3_DATA_PORT, &read_data_port, &write_data_port);
+ ret |= v3_dev_hook_io(dev, COM3_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
+ ret |= v3_dev_hook_io(dev, COM3_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
+ ret |= v3_dev_hook_io(dev, COM3_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
+ ret |= v3_dev_hook_io(dev, COM3_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
+ ret |= v3_dev_hook_io(dev, COM3_LINE_STATUS_PORT, &read_status_port, &write_status_port);
+ ret |= v3_dev_hook_io(dev, COM3_MODEM_STATUS_PORT, &read_status_port, &write_status_port);
+ ret |= v3_dev_hook_io(dev, COM3_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
+
+ ret |= v3_dev_hook_io(dev, COM4_DATA_PORT, &read_data_port, &write_data_port);
+ ret |= v3_dev_hook_io(dev, COM4_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port);
+ ret |= v3_dev_hook_io(dev, COM4_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
+ ret |= v3_dev_hook_io(dev, COM4_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
+ ret |= v3_dev_hook_io(dev, COM4_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port);
+ ret |= v3_dev_hook_io(dev, COM4_LINE_STATUS_PORT, &read_status_port, &write_status_port);
+ ret |= v3_dev_hook_io(dev, COM4_MODEM_STATUS_PORT, &read_status_port, &write_status_port);
+ ret |= v3_dev_hook_io(dev, COM4_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port);
+
+ if (ret != 0) {
+ PrintError("Error hooking Serial IO ports\n");
+ v3_remove_device(dev);
+ return -1;
+ }
PrintDebug("Serial ports hooked\n");
if (v3_dev_add_char_frontend(vm, dev_id, connect_fn, (void *)state) == -1) {
PrintError("Could not register %s as frontend\n", dev_id);
+ v3_remove_device(dev);
return -1;
}
v3_lock_init(&(state->cons_lock));
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, state);
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
+ V3_Free(state);
return -1;
}
memset(blk->blk_space, 0, capacity);
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, blk);
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, blk);
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
+ V3_Free(blk);
return -1;
}
&blk_ops, frontend_cfg, blk) == -1) {
PrintError("Could not connect %s to frontend %s\n",
dev_id, v3_cfg_val(frontend_cfg, "tag"));
+ v3_remove_device(dev);
return -1;
}
vnetnic = (struct vnet_nic_state *)V3_Malloc(sizeof(struct vnet_nic_state));
memset(vnetnic, 0, sizeof(struct vnet_nic_state));
- struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, vnetnic);
+ struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, vnetnic);
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", dev_id);
+ V3_Free(vnetnic);
return -1;
}
&(vnetnic->net_ops), frontend_cfg, vnetnic) == -1) {
PrintError("Could not connect %s to frontend %s\n",
dev_id, v3_cfg_val(frontend_cfg, "tag"));
+ v3_remove_device(vnetnic);
return -1;
}
if ((vnet_dev_id = register_to_vnet(vm, vnetnic, dev_id, vnetnic->mac)) == -1) {
PrintError("Vnet-nic device %s (mac: %s) fails to registered to VNET\n", dev_id, macstr);
+ v3_remove_device(vnetnic);
+ return 0;
}
+
vnetnic->vnet_dev_id = vnet_dev_id;
PrintDebug("Vnet-nic device %s (mac: %s, %ld) registered to VNET\n",
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);
}
-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) {
-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->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));
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;