struct list_head timers;
};
-struct vm_timer_ops {
+struct v3_timer_ops {
void (*update_timer)(struct guest_info * info, ullong_t cpu_cycles, ullong_t cpu_freq, void * priv_data);
void (*advance_timer)(struct guest_info * info, void * private_data);
};
-struct vm_timer {
+struct v3_timer {
void * private_data;
- struct vm_timer_ops * ops;
+ struct v3_timer_ops * ops;
struct list_head timer_link;
};
int v3_adjust_time(struct guest_info * info);
// Basic functions for attaching timers to the passage of time
-int v3_add_timer(struct guest_info * info, struct vm_timer_ops * ops, void * private_data);
-int v3_remove_timer(struct guest_info * info, struct vm_timer * timer);
+struct v3_timer * v3_add_timer(struct guest_info * info, struct v3_timer_ops * ops, void * private_data);
+int v3_remove_timer(struct guest_info * info, struct v3_timer * timer);
void v3_update_timers(struct guest_info * info);
// Functions to return the different notions of time in Palacios.
#include <palacios/vmm_util.h>
#include <palacios/vmm_intr.h>
#include <palacios/vmm_config.h>
+#include <palacios/vmm_io.h>
#ifndef CONFIG_DEBUG_PIT
ullong_t pit_counter;
ullong_t pit_reload;
+ struct v3_timer * timer;
struct channel ch_0;
struct channel ch_1;
-static int pit_read_channel(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
+static int pit_read_channel(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * priv_data) {
+ struct vm_device * dev = (struct vm_device *)priv_data;
struct pit * state = (struct pit *)dev->private_data;
char * val = (char *)dst;
-static int pit_write_channel(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int pit_write_channel(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
+ struct vm_device * dev = (struct vm_device *)priv_data;
struct pit * state = (struct pit *)dev->private_data;
char val = *(char *)src;
-static int pit_write_command(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) {
+static int pit_write_command(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) {
+ struct vm_device * dev = (struct vm_device *)priv_data;
struct pit * state = (struct pit *)dev->private_data;
struct pit_cmd_word * cmd = (struct pit_cmd_word *)src;
-static struct vm_timer_ops timer_ops = {
+static struct v3_timer_ops timer_ops = {
.update_timer = pit_update_timer,
};
static int pit_free(struct vm_device * dev) {
+ struct pit * state = (struct pit *)dev->private_data;
+ struct guest_info * info = &(dev->vm->cores[0]);
+
+ if (state->timer) {
+ v3_remove_timer(info, state->timer);
+ }
+
+ v3_unhook_io_port(dev->vm, CHANNEL0_PORT);
+ v3_unhook_io_port(dev->vm, CHANNEL1_PORT);
+ v3_unhook_io_port(dev->vm, CHANNEL2_PORT);
+ v3_unhook_io_port(dev->vm, COMMAND_PORT);
+ v3_unhook_io_port(dev->vm, SPEAKER_PORT);
+
+ V3_Free(state);
return 0;
}
return -1;
}
- v3_dev_hook_io(dev, CHANNEL0_PORT, &pit_read_channel, &pit_write_channel);
- v3_dev_hook_io(dev, CHANNEL1_PORT, &pit_read_channel, &pit_write_channel);
- v3_dev_hook_io(dev, CHANNEL2_PORT, &pit_read_channel, &pit_write_channel);
- v3_dev_hook_io(dev, COMMAND_PORT, NULL, &pit_write_command);
- v3_dev_hook_io(dev, SPEAKER_PORT, &pit_read_channel, &pit_write_channel);
+ 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);
#ifdef CONFIG_DEBUG_PIT
PrintDebug("8254 PIT: OSC_HZ=%d, reload_val=", OSC_HZ);
#endif
- v3_add_timer(info, &timer_ops, dev);
+
+ pit_state->timer = v3_add_timer(info, &timer_ops, dev);
+
+ if (pit_state->timer == NULL) {
+ v3_detach_device(dev);
+ return -1;
+ }
// Get cpu frequency and calculate the global pit oscilattor counter/cycle
return 0;
}
-int v3_add_timer(struct guest_info * info, struct vm_timer_ops * ops,
- void * private_data) {
- struct vm_timer * timer = NULL;
- timer = (struct vm_timer *)V3_Malloc(sizeof(struct vm_timer));
+struct v3_timer * v3_add_timer(struct guest_info * info,
+ struct v3_timer_ops * ops,
+ void * private_data) {
+ struct v3_timer * timer = NULL;
+ timer = (struct v3_timer *)V3_Malloc(sizeof(struct v3_timer));
V3_ASSERT(timer != NULL);
timer->ops = ops;
list_add(&(timer->timer_link), &(info->time_state.timers));
info->time_state.num_timers++;
- return 0;
+ return timer;
}
-int v3_remove_timer(struct guest_info * info, struct vm_timer * timer) {
+int v3_remove_timer(struct guest_info * info, struct v3_timer * timer) {
list_del(&(timer->timer_link));
info->time_state.num_timers--;
}
void v3_update_timers(struct guest_info * info) {
- struct vm_timer * tmp_timer;
+ struct v3_timer * tmp_timer;
uint64_t old_time = info->time_state.last_update;
uint64_t cycles;