struct v3_vm_info * v3_create_vm(void * cfg, void * priv_data, char * name);
int v3_start_vm(struct v3_vm_info * vm, unsigned int cpu_mask);
int v3_stop_vm(struct v3_vm_info * vm);
+int v3_free_vm(struct v3_vm_info * vm);
int v3_deliver_irq(struct v3_vm_info * vm, struct v3_interrupt * intr);
struct v3_device_ops {
- int (*free)(struct vm_device * dev);
+ int (*free)(void * private_data);
//int (*save)(struct vm_device *dev, struct *iostream);
//int (*restore)(struct vm_device *dev, struct *iostream);
struct v3_timer * timer;
+ struct v3_vm_info * vm;
+
struct channel ch_0;
struct channel ch_1;
struct channel ch_2;
-static int pit_free(struct vm_device * dev) {
- struct pit * state = (struct pit *)dev->private_data;
- struct guest_info * info = &(dev->vm->cores[0]);
+static int pit_free(void * private_data) {
+ struct pit * state = (struct pit *)private_data;
+ struct guest_info * info = &(state->vm->cores[0]);
if (state->timer) {
static struct v3_device_ops dev_ops = {
- .free = pit_free,
+ .free = (int (*)(void *))pit_free,
};
-static int pic_free(struct vm_device * dev) {
+static int pic_free(struct pic_internal * state) {
+
+ // unregister intr_controller
+ // unregister intr router
+
+ V3_Free(state);
return 0;
}
static struct v3_device_ops dev_ops = {
- .free = pic_free,
+ .free = (int (*)(void *))pic_free,
};
-static int apic_free(struct vm_device * dev) {
- struct apic_dev_state * apic_dev = (struct apic_dev_state *)dev->private_data;
+static int apic_free(struct apic_dev_state * apic_dev) {
int i = 0;
+ struct v3_vm_info * vm = NULL;
- for (i = 0; i < dev->vm->num_cores; i++) {
+ for (i = 0; i < apic_dev->num_apics; i++) {
struct apic_state * apic = &(apic_dev->apics[i]);
- struct guest_info * core = &(dev->vm->cores[i]);
+ struct guest_info * core = apic->core;
+ vm = core->vm_info;
// unregister intr controller
}
- v3_unhook_msr(dev->vm, BASE_ADDR_MSR);
+ v3_unhook_msr(vm, BASE_ADDR_MSR);
V3_Free(apic_dev);
return 0;
static struct v3_device_ops dev_ops = {
- .free = apic_free,
+ .free = (int (*)(void *))apic_free,
};
-static int debug_free(struct vm_device * dev) {
- struct debug_state * state = dev->private_data;
+static int debug_free(struct debug_state * state) {
V3_Free(state);
-
return 0;
};
static struct v3_device_ops dev_ops = {
- .free = debug_free,
+ .free = (int (*)(void *))debug_free,
};
// so we need a temp variable to hold the partial update
uint16_t tmp_screen_offset;
+ struct vm_device * dev;
+
uint8_t passthrough;
-static int free_device(struct vm_device * dev) {
- struct video_internal * video_state = (struct video_internal *)dev->private_data;
+static int free_device(struct video_internal * video_state) {
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_mem(video_state->dev->vm, V3_MEM_CORE_ANY, START_ADDR);
V3_Free(video_state);
static struct v3_device_ops dev_ops = {
- .free = free_device,
+ .free = (int (*)(void *))free_device,
};
static int cga_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
V3_Free(video_state);
return -1;
}
+
+ video_state->dev = dev;
video_state->framebuf_pa = (addr_t)V3_AllocPages(FRAMEBUF_SIZE / 4096);
video_state->framebuf = V3_VAddr((void *)(video_state->framebuf_pa));
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);
-
+static int stream_free(struct stream_state * state) {
v3_stream_close(state->stream);
// detach host event
static struct v3_device_ops dev_ops = {
- .free = stream_free,
+ .free = (int (*)(void *))stream_free,
};
static int stream_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
}
-static int cons_free(struct vm_device * dev) {
- struct cons_state * state = (struct cons_state *)dev->private_data;
-
+static int cons_free(struct cons_state * state) {
v3_console_close(state->cons);
// remove host event
};
static struct v3_device_ops dev_ops = {
- .free = cons_free,
+ .free = (int (*)(void *))cons_free,
};
static int cons_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg)
return model->ops->get_capacity(model->private_data);
}
-static int model_free(struct vm_device * dev) {
- return -1;
+static int model_free(struct disk_state * model) {
+
+ // unhook from frontend
+
+ V3_Free(model);
+ return 0;
}
static struct v3_device_ops dev_ops = {
- .free = model_free,
+ .free = (int (*)(void *))model_free,
};
-static int disk_free(struct vm_device * dev) {
- struct disk_state * disk = dev->private_data;
-
+static int disk_free(struct disk_state * disk) {
v3_file_close(disk->fd);
V3_Free(disk);
}
static struct v3_device_ops dev_ops = {
- .free = disk_free,
+ .free = (int (*)(void *))disk_free,
};
-static int generic_free(struct vm_device * dev) {
- struct generic_internal * state = (struct generic_internal *)(dev->private_data);
-
+static int generic_free(struct generic_internal * state) {
PrintDebug("generic: deinit_device\n");
V3_Free(state);
static struct v3_device_ops dev_ops = {
- .free = generic_free,
+ .free = (int (*)(void *))generic_free,
};
-static int i440_free(struct vm_device * dev) {
- struct i440_state * state = dev->private_data;
+static int i440_free(struct i440_state * state) {
// unregister from PCI
}
static struct v3_device_ops dev_ops = {
- .free = i440_free,
+ .free = (int (*)(void *))i440_free,
};
-static int ide_free(struct vm_device * dev) {
- // unhook io ports....
-
+static int ide_free(struct ide_internal * ide) {
// deregister from PCI?
-
+ V3_Free(ide);
return 0;
}
static struct v3_device_ops dev_ops = {
- .free = ide_free,
+ .free = (int (*)(void *))ide_free,
};
-static int io_apic_free(struct vm_device * dev) {
- // struct guest_info * info = dev->vm;
+static int io_apic_free(struct io_apic_state * ioapic) {
+
+ // unregister intr router
+
+ // unhook memory
+
+ V3_Free(ioapic);
return 0;
}
static struct v3_device_ops dev_ops = {
- .free = io_apic_free,
+ .free = (int (*)(void *))io_apic_free,
};
-static int keyboard_free(struct vm_device * dev) {
+static int keyboard_free(struct keyboard_internal * kbd) {
+
+ // unhook host events
+
+ V3_Free(kbd);
return 0;
}
}
static struct v3_device_ops dev_ops = {
- .free = keyboard_free,
+ .free = (int (*)(void *))keyboard_free,
};
};
-static int virtio_free(struct vm_device * dev) {
- return -1;
-}
+
static int virtio_reset(struct virtio_balloon_state * virtio) {
}
+static int virtio_free(struct virtio_balloon_state * virtio) {
+
+ // unregister from PCI
+
+ V3_Free(virtio);
+ return 0;
+}
static struct v3_device_ops dev_ops = {
- .free = virtio_free,
+ .free = (int (*)(void *))virtio_free,
};
};
-static int virtio_free(struct vm_device * dev) {
- return -1;
-}
+
static int blk_reset(struct virtio_blk_state * virtio) {
}
+static int virtio_free(struct virtio_dev_state * virtio) {
+
+ V3_Free(virtio);
+
+ return 0;
+}
+
static struct v3_device_ops dev_ops = {
- .free = virtio_free,
+ .free = (int (*)(void *))virtio_free,
};
#define ERR_VIRTIO_TXQ_DISABLED 6
-static int virtio_free(struct vm_device * dev)
-{
-
- return 0;
-}
+
static int virtio_init_state(struct virtio_net_state * virtio)
{
return ret_val;
}
+static int virtio_free(struct virtio_net_state * virtio) {
+
+ // unregister from PCI
+
+ V3_Free(virtio);
+ return 0;
+}
+
static struct v3_device_ops dev_ops = {
- .free = virtio_free,
+ .free = (int (*)(void *))virtio_free,
};
}
+int virtio_free(struct virtio_sym_state * virtio_state) {
+
+ // unregister from PCI
+
+ V3_Free(virtio_state);
+ return 0;
+}
static struct v3_device_ops dev_ops = {
- .free = NULL,
+ .free = (int (*)(void *))virtio_free,
};
memset(virtio_state, 0, sizeof(struct virtio_sym_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;
}
if (!pci_dev) {
PrintError("Could not register PCI Device\n");
+ v3_remove_device(dev);
return -1;
}
}
-static int virtio_free(struct vm_device * dev)
-{
-
+static int virtio_free(struct virtio_sym_state * virtio_state) {
+ // unregister from PCI
+
+ V3_Free(virtio_state);
return 0;
}
static struct v3_device_ops dev_ops = {
- .free = virtio_free,
+ .free = (int (*)(void *))virtio_free,
};
}
+static int virtio_free(struct virtio_vnet_state * vnet_state) {
+
+ // unregister from PCI
+
+ V3_Free(vnet_state);
+ return 0;
+}
+
static struct v3_device_ops dev_ops = {
- .free = NULL,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
+ .free = (int (*)(void *))virtio_free,
};
static int dev_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
-static int disk_free(struct vm_device * dev) {
+static int disk_free(struct disk_state * disk) {
+
+ v3_socket_close(disk->socket);
+
+ V3_Free(disk);
return 0;
}
static struct v3_device_ops dev_ops = {
- .free = disk_free,
+ .free = (int (*)(void *))disk_free,
};
}
-static int vnet_nic_free(struct vm_device * dev) {
- struct nic_bridge_state * bridge = dev->private_data;
+static int vnet_nic_free(struct nic_bridge_state * bridge) {
/*detach from front device */
}
static struct v3_device_ops dev_ops = {
- .free = vnet_nic_free,
+ .free = (int (*)(void *))vnet_nic_free,
};
-static int nvram_free(struct vm_device * dev) {
+static int nvram_free(struct nvram_internal * nvram_state) {
+
+ // unregister host events
+
+ V3_Free(nvram_state);
return 0;
}
static struct v3_device_ops dev_ops = {
- .free = nvram_free,
+ .free = (int (*)(void *))nvram_free,
};
-static int debug_free(struct vm_device * dev) {
+static int debug_free(struct debug_state * state) {
+ // unregister hypercall
+
+ V3_Free(state);
return 0;
};
static struct v3_device_ops dev_ops = {
- .free = debug_free,
+ .free = (int (*)(void *))debug_free,
};
-static int pci_free(struct vm_device * dev) {
-
- return 0;
-}
-
static void init_pci_busses(struct pci_internal * pci_state) {
}
+static int pci_free(struct pci_internal * pci_state) {
+
+ // cleanup devices (?)
+
+ V3_Free(pci_state);
+ return 0;
+}
static struct v3_device_ops dev_ops = {
- .free = pci_free,
+ .free = (int (*)(void *))pci_free,
};
-static int piix_free(struct vm_device * dev) {
+static int piix_free(struct v3_southbridge * piix3) {
+
+ // unregister pci
+
+ V3_Free(piix3);
return 0;
}
static struct v3_device_ops dev_ops = {
- .free = piix_free,
+ .free = (int (*)(void *))piix_free,
};
-static int disk_free(struct vm_device * dev) {
+static int disk_free(struct disk_state * state) {
+
+ V3_Free(state);
return 0;
}
static struct v3_device_ops dev_ops = {
- .free = disk_free,
+ .free = (int (*)(void *))disk_free,
};
return length;
}
-static int serial_free(struct vm_device * dev) {
+static int serial_free(struct serial_state * state) {
+
+ V3_Free(state);
return 0;
}
static struct v3_device_ops dev_ops = {
- .free = serial_free,
+ .free = (int (*)(void *))serial_free,
};
.scroll = scroll,
};
-static int cons_free(struct vm_device * dev) {
- return -1;
+static int cons_free(struct cons_state * state) {
+
+ // kill thread... ?
+
+ V3_Free(state);
+ return 0;
}
static struct v3_device_ops dev_ops = {
- .free = cons_free,
+ .free = (int (*)(void *))cons_free,
};
}
-static int blk_free(struct vm_device * dev) {
- return -1;
+static int blk_free(struct blk_state * blk) {
+ V3_FreePages((void *)blk->blk_base_addr, blk->capacity / 4096);
+
+ V3_Free(blk);
+ return 0;
}
static struct v3_device_ops dev_ops = {
- .free = blk_free,
+ .free = (int (*)(void *))blk_free,
};
}
-static int vnet_nic_free(struct vm_device * dev) {
+static int vnet_nic_free(struct vnet_nic_state * vnetnic) {
+
+
+ V3_Free(vnetnic);
return 0;
}
static struct v3_device_ops dev_ops = {
- .free = vnet_nic_free,
+ .free = (int (*)(void *))vnet_nic_free,
};
// Wait for all cores to enter CORE_STOPPED state
+
+
+ return 0;
+}
+
+
+int v3_free_vm(struct v3_vm_info * vm) {
// deinitialize guest (free memory, etc...)
+ v3_dev_mgr_deinit(vm);
+
return 0;
}
}
if (dev->ops->free) {
- dev->ops->free(dev);
+ dev->ops->free(dev->private_data);
} else {
PrintError("Error: %s free() not implemented\n", dev->name);
}