struct pit * pit_state = NULL;
struct vm_device * dev = NULL;
char * dev_id = v3_cfg_val(cfg, "ID");
-
+ int ret = 0;
+
// PIT is only usable in non-multicore environments
// just hardcode the core context
struct guest_info * info = &(vm->cores[0]);
if (v3_attach_device(vm, dev) == -1) {
PrintError("Could not attach device %s\n", dev_id);
+ V3_Free(pit_state);
return -1;
}
- v3_hook_io_port(vm, CHANNEL0_PORT, &pit_read_channel, &pit_write_channel, dev);
- v3_hook_io_port(vm, CHANNEL1_PORT, &pit_read_channel, &pit_write_channel, dev);
- v3_hook_io_port(vm, CHANNEL2_PORT, &pit_read_channel, &pit_write_channel, dev);
- v3_hook_io_port(vm, COMMAND_PORT, NULL, &pit_write_command, dev);
- v3_hook_io_port(vm, SPEAKER_PORT, &pit_read_channel, &pit_write_channel, dev);
+ ret |= v3_hook_io_port(vm, CHANNEL0_PORT, &pit_read_channel, &pit_write_channel, dev);
+ ret |= v3_hook_io_port(vm, CHANNEL1_PORT, &pit_read_channel, &pit_write_channel, dev);
+ ret |= v3_hook_io_port(vm, CHANNEL2_PORT, &pit_read_channel, &pit_write_channel, dev);
+ ret |= v3_hook_io_port(vm, COMMAND_PORT, NULL, &pit_write_command, dev);
+ ret |= v3_hook_io_port(vm, SPEAKER_PORT, &pit_read_channel, &pit_write_channel, dev);
+
+ if (ret != 0) {
+ PrintError("8254 PIT: Failed to hook IO ports\n");
+ v3_detach_device(dev);
+ return -1;
+ }
#ifdef CONFIG_DEBUG_PIT
PrintDebug("8254 PIT: OSC_HZ=%d, reload_val=", OSC_HZ);
pit_state->pit_reload = reload_val;
-
init_channel(&(pit_state->ch_0));
init_channel(&(pit_state->ch_1));
init_channel(&(pit_state->ch_2));
struct guest_info * core;
+ struct v3_timer * timer;
+
uint32_t eoi;
v3_lock_t lock;
static int apic_free(struct vm_device * dev) {
+ struct apic_dev_state * apic_dev = (struct apic_dev_state *)dev->private_data;
+ int i = 0;
+
+ for (i = 0; i < dev->vm->num_cores; i++) {
+ struct apic_state * apic = &(apic_dev->apics[i]);
+ struct guest_info * core = &(dev->vm->cores[i]);
+
+
+ // unregister intr controller
- /* TODO: This should crosscall to force an unhook on each CPU */
+ if (apic->timer) {
+ v3_remove_timer(core, apic->timer);
+ }
+
+ // unhook memory
- // struct apic_state * apic = (struct apic_state *)dev->private_data;
+ }
v3_unhook_msr(dev->vm, BASE_ADDR_MSR);
+ V3_Free(apic_dev);
return 0;
}
if (v3_attach_device(vm, dev) == -1) {
PrintError("apic: Could not attach device %s\n", dev_id);
+ V3_Free(apic_dev);
return -1;
}
v3_register_intr_controller(core, &intr_ops, apic_dev);
- v3_add_timer(core, &timer_ops, apic_dev);
+ apic->timer = v3_add_timer(core, &timer_ops, apic_dev);
+
+ if (apic->timer == NULL) {
+ PrintError("APIC: Failed to attach timer to core %d\n", i);
+ v3_detach_device(dev);
+ return -1;
+ }
v3_hook_full_mem(vm, core->cpu_id, apic->base_addr, apic->base_addr + PAGE_SIZE_4KB, apic_read, apic_write, apic_dev);
#include <palacios/vmm.h>
#include <palacios/vmm_dev_mgr.h>
+#include <palacios/vmm_io.h>
#define BUF_SIZE 1024
uint_t cons_offset;
};
-static int handle_info_write(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int handle_info_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
+ struct vm_device * dev = priv_data;
struct debug_state * state = (struct debug_state *)dev->private_data;
state->info_buf[state->info_offset++] = *(char*)src;
}
-static int handle_debug_write(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int handle_debug_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
+ struct vm_device * dev = priv_data;
struct debug_state * state = (struct debug_state *)dev->private_data;
state->debug_buf[state->debug_offset++] = *(char*)src;
}
-static int handle_console_write(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int handle_console_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
+ struct vm_device * dev = priv_data;
struct debug_state * state = (struct debug_state *)dev->private_data;
state->cons_buf[state->cons_offset++] = *(char *)src;
}
-static int handle_gen_write(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
-
+static int handle_gen_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
+ //struct vm_device * dev = priv_data;
+
switch (length) {
case 1:
PrintDebug(">0x%.2x\n", *(uchar_t*)src);
static int debug_free(struct vm_device * dev) {
- v3_dev_unhook_io(dev, BOCHS_PORT1);
- v3_dev_unhook_io(dev, BOCHS_PORT2);
- v3_dev_unhook_io(dev, BOCHS_INFO_PORT);
- v3_dev_unhook_io(dev, BOCHS_DEBUG_PORT);
+ struct debug_state * state = dev->private_data;
+
+ v3_unhook_io_port(dev->vm, BOCHS_PORT1);
+ v3_unhook_io_port(dev->vm, BOCHS_PORT2);
+ v3_unhook_io_port(dev->vm, BOCHS_INFO_PORT);
+ v3_unhook_io_port(dev->vm, BOCHS_DEBUG_PORT);
+
+ V3_Free(state);
return 0;
};
static int debug_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
struct debug_state * state = NULL;
char * dev_id = v3_cfg_val(cfg, "ID");
+ int ret = 0;
state = (struct debug_state *)V3_Malloc(sizeof(struct debug_state));
if (v3_attach_device(vm, dev) == -1) {
PrintError("Could not attach device %s\n", dev_id);
+ V3_Free(state);
return -1;
}
memset(state->cons_buf, 0, BUF_SIZE);
- v3_dev_hook_io(dev, BOCHS_PORT1, NULL, &handle_gen_write);
- v3_dev_hook_io(dev, BOCHS_PORT2, NULL, &handle_gen_write);
- v3_dev_hook_io(dev, BOCHS_INFO_PORT, NULL, &handle_info_write);
- v3_dev_hook_io(dev, BOCHS_DEBUG_PORT, NULL, &handle_debug_write);
- v3_dev_hook_io(dev, BOCHS_CONSOLE_PORT, NULL, &handle_console_write);
+ ret |= v3_hook_io_port(vm, BOCHS_PORT1, NULL, &handle_gen_write, dev);
+ ret |= v3_hook_io_port(vm, BOCHS_PORT2, NULL, &handle_gen_write, dev);
+ ret |= v3_hook_io_port(vm, BOCHS_INFO_PORT, NULL, &handle_info_write, dev);
+ ret |= v3_hook_io_port(vm, BOCHS_DEBUG_PORT, NULL, &handle_debug_write, dev);
+ ret |= v3_hook_io_port(vm, BOCHS_CONSOLE_PORT, NULL, &handle_console_write, dev);
+ if (ret != 0) {
+ PrintError("Could not hook Bochs Debug IO Ports\n");
+ v3_detach_device(dev);
+ return -1;
+ }
return 0;
}
static int free_device(struct vm_device * dev) {
+ struct video_internal * video_state = (struct video_internal *)dev->private_data;
+
v3_unhook_mem(dev->vm, V3_MEM_CORE_ANY, START_ADDR);
+
+ V3_Free(video_state);
+
return 0;
}
static struct v3_device_ops dev_ops = {
.free = free_device,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
};
static int cga_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
- struct video_internal * video_state = (struct video_internal *)V3_Malloc(sizeof(struct video_internal));
+ struct video_internal * video_state = NULL;
addr_t frame_buf_pa = 0;
int enable_passthrough = 0;
char * dev_id = v3_cfg_val(cfg, "ID");
PrintDebug("video: init_device\n");
+ video_state = (struct video_internal *)V3_Malloc(sizeof(struct video_internal));
+
struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, video_state);
if (v3_attach_device(vm, dev) == -1) {
PrintError("Could not attach device %s\n", dev_id);
+ V3_Free(video_state);
return -1;
}