int geekos_hook_interrupt(struct guest_info * info, uint_t irq);
-unsigned int get_cpu_khz();
-
-void Init_Stubs();
-
-
+unsigned int get_cpu_khz();
+void Init_Stubs(struct guest_info * info);
+/****
+ *
+ * stubs called by geekos....
+ *
+ ***/
+void send_key_to_vmm(unsigned char status, unsigned char scancode);
+void send_mouse_to_vmm(unsigned char packet[3]);
+void send_tick_to_vmm(unsigned int period_us);
#if 0
#include <geekos/keyboard.h>
+#include <geekos/vmm_stubs.h>
-static enum {TARGET_GEEKOS,TARGET_VMM} target = TARGET_VMM;
+static enum {TARGET_GEEKOS, TARGET_VMM} target = TARGET_VMM;
+
-extern void deliver_key_to_vmm(uchar_t status, uchar_t scancode);
/* ----------------------------------------------------------------------
* Private data and functions
skip_flagchange:
- if (target==TARGET_GEEKOS) {
+ if (target == TARGET_GEEKOS) {
if (raw_scancode==0xc4) { // F10 release
Print("Switching keyboard to VMM\n");
target=TARGET_VMM;
*/
g_needReschedule = true;
}
- } else if (target==TARGET_VMM) {
- if (raw_scancode==0xc4) { // F10 release
+ } else if (target == TARGET_VMM) {
+
+ if (raw_scancode == 0xc4) { // F10 release
Print("Switching keyboard to GeekOS\n");
- target=TARGET_GEEKOS;
+ target = TARGET_GEEKOS;
} else {
- deliver_key_to_vmm(raw_status,raw_scancode);
+ send_key_to_vmm(raw_status, raw_scancode);
}
+
}
}
//Init_PCI();
- Init_Stubs();
+
// Init_Network();
#include <geekos/io_defs.h>
+#include <geekos/vmm_stubs.h>
+
/* PAD this currently is in nvram.c */
/* JRL: This is completely broken
extern void deliver_timer_interrupt_to_vmm(uint_t period_us);
}
- /* JRL: Broken,
- deliver_timer_interrupt_to_vmm(1000000/HZ);
- */
+
+ send_tick_to_vmm(1000000/HZ);
+
End_IRQ(state);
}
#include <palacios/vmm_io.h>
-
extern void * g_ramdiskImage;
extern ulong_t s_ramdiskSize;
struct v3_vm_config vm_config;
-
+
memset(&os_hooks, 0, sizeof(struct vmm_os_hooks));
memset(&vmm_ops, 0, sizeof(struct vmm_ctrl_ops));
memset(&vm_config, 0, sizeof(struct v3_vm_config));
vm_info = (vmm_ops).allocate_guest();
+ Init_Stubs(vm_info);
+
PrintBoth("Allocated Guest\n");
(vmm_ops).config_guest(vm_info, &vm_config);
(vmm_ops).init_guest(vm_info);
PrintBoth("Starting Guest\n");
//Clear_Screen();
+
(vmm_ops).start_guest(vm_info);
return 0;
#include <geekos/serial.h>
#include <geekos/debug.h>
#include <palacios/vmm.h>
+#include <palacios/vmm_host_events.h>
+
+
+struct guest_info * g_vm_guest = NULL;
+
+
+// This is the function the interface code should call to deliver
+// the interrupt to the vmm for handling
+//extern int v3_deliver_interrupt(struct guest_info * vm, struct v3_interrupt *intr);
+
+
+struct guest_info * irq_to_guest_map[256];
+
+void Init_Stubs(struct guest_info * info) {
+ memset(irq_to_guest_map, 0, sizeof(struct guest_info *) * 256);
+ g_vm_guest = info;
+}
+
+
void * Identity(void *addr) { return addr; };
}
-// This is the function the interface code should call to deliver
-// the interrupt to the vmm for handling
-//extern int v3_deliver_interrupt(struct guest_info * vm, struct v3_interrupt *intr);
+void send_key_to_vmm(unsigned char status, unsigned char scancode) {
+ struct v3_keyboard_event evt;
+
+ evt.status = status;
+ evt.scan_code = scancode;
+
+ if (g_vm_guest) {
+ v3_deliver_keyboard_event(g_vm_guest, &evt);
+ }
+}
-struct guest_info * irq_to_guest_map[256];
+void send_mouse_to_vmm(unsigned char packet[3]) {
+ struct v3_mouse_event evt;
+
+ memcpy(evt.data, packet, 3);
+
+ if (g_vm_guest) {
+ v3_deliver_mouse_event(g_vm_guest, &evt);
+ }
+}
+
+void send_tick_to_vmm(unsigned int period_us) {
+ struct v3_timer_event evt;
+
+ evt.period_us = period_us;
+
+ if (g_vm_guest) {
+ v3_deliver_timer_event(g_vm_guest, &evt);
+ }
+}
void translate_intr_handler(struct Interrupt_State *state) {
}
-void Init_Stubs() {
- memset(irq_to_guest_map, 0, sizeof(struct guest_info *) * 256);
-}
unsigned int get_cpu_khz() {
return cpu_khz_freq;
}
+
#include <palacios/vm_dev.h>
-//
-// The underlying driver needs to call this on each key that
-// it wants to inject into the VMM for delivery to a VM
-//
-void deliver_key_to_vmm(uchar_t status, uchar_t scancode);
-// And call this one each streaming mouse event
-// that the VMM should deliver
-void deliver_mouse_to_vmm(uchar_t mouse_packet[3]);
-
struct vm_device *create_keyboard();
#endif
unsigned char data[3];
};
-
struct v3_timer_event {
-
+ unsigned int period_us;
};
#ifdef __V3VEE__
int v3_init_host_events(struct guest_info * info);
-#define V3_HOST_EVENT_HANDLER(cb) ((union v3_host_event_callback)cb)
+#define V3_HOST_EVENT_HANDLER(cb) ((union v3_host_event_handler)cb)
int v3_hook_host_event(struct guest_info * info,
v3_host_evt_type_t event_type,
#endif // ! __V3VEE__
+
+
int v3_deliver_keyboard_event(struct guest_info * info, struct v3_keyboard_event * evt);
int v3_deliver_mouse_event(struct guest_info * info, struct v3_mouse_event * evt);
int v3_deliver_timer_event(struct guest_info * info, struct v3_timer_event * evt);
#define MOUSE 1
-// The currently targetted keyboard
-static struct vm_device * thekeyboard = NULL;
//#define QUEUE_SIZE 32
#endif
-static struct vm_device *demultiplex_injected_key(uchar_t status, uchar_t scancode)
-{
- // this currently does nothing
- return thekeyboard;
-}
-static struct vm_device *demultiplex_injected_mouse(uchar_t mouse_packet[3])
-{
- // this currently does nothing
- return thekeyboard;
-}
-int keyboard_interrupt(uint_t irq, struct vm_device * dev) {
+int keyboard_interrupt(struct vm_device * dev, uint_t irq) {
PrintDebug("keyboard: interrupt 0x%x\n", irq);
- dev->vm->vm_ops.raise_irq(dev->vm, irq);
+ v3_raise_irq(dev->vm, irq);
return 0;
}
-void deliver_key_to_vmm(uchar_t status, uchar_t scancode)
-{
- struct vm_device *dev = demultiplex_injected_key(status, scancode);
+
+
+int key_event_handler(struct guest_info * info,
+ struct v3_keyboard_event * evt,
+ void * private_data) {
+ struct vm_device * dev = (struct vm_device *)private_data;
struct keyboard_internal *state = (struct keyboard_internal *)(dev->private_data);
- PrintDebug("keyboard: injected status 0x%x, and scancode 0x%x\n", status, scancode);
+ PrintDebug("keyboard: injected status 0x%x, and scancode 0x%x\n", evt->status, evt->scan_code);
if ( (state->status_byte & STATUS_ENABLED) // onboard is enabled
&& (!(state->cmd_byte & CMD_DISABLE)) ) { // keyboard is enabled
-
- PushToOutputQueue(dev, scancode, OVERWRITE, DATA, KEYBOARD);
-
+
+ PushToOutputQueue(dev, evt->scan_code, OVERWRITE, DATA, KEYBOARD);
+
if (state->cmd_byte & CMD_INTR) {
- keyboard_interrupt(KEYBOARD_IRQ, dev);
+ keyboard_interrupt(dev, KEYBOARD_IRQ);
}
-
}
+
+ return 0;
}
-void deliver_mouse_to_vmm(uchar_t data[3])
-{
- struct vm_device * dev = demultiplex_injected_mouse(data);
+int mouse_event_handler(struct guest_info * info,
+ struct v3_mouse_event * evt,
+ void * private_data) {
+ struct vm_device * dev = (struct vm_device *)private_data;
struct keyboard_internal * state = (struct keyboard_internal *)(dev->private_data);
PrintDebug("keyboard: injected mouse packet 0x %x %x %x\n",
- data[0], data[1], data[2]);
+ evt->data[0], evt->data[1], evt->data[2]);
- memcpy(state->mouse_packet, data, 3);
+ memcpy(state->mouse_packet, evt->data, 3);
state->status_byte |= STATUS_MOUSE_BUFFER_FULL;
case STREAM2:
case STREAM3:
if (!(state->cmd_byte & CMD_MOUSE_DISABLE)) {
- keyboard_interrupt(MOUSE_IRQ, dev);
+ keyboard_interrupt(dev, MOUSE_IRQ);
}
break;
default:
+ return -1;
break;
}
+ return 0;
}
dev_hook_io(dev, KEYBOARD_64H, &keyboard_read_status, &keyboard_write_command);
dev_hook_io(dev, KEYBOARD_60H, &keyboard_read_input, &keyboard_write_output);
+ v3_hook_host_event(dev->vm, HOST_KEYBOARD_EVT, V3_HOST_EVENT_HANDLER(key_event_handler), dev);
+ v3_hook_host_event(dev->vm, HOST_MOUSE_EVT, V3_HOST_EVENT_HANDLER(mouse_event_handler), dev);
+
+
#if KEYBOARD_DEBUG_80H
dev_hook_io(dev, KEYBOARD_DELAY_80H, &keyboard_read_delay, &keyboard_write_delay);
#endif
struct vm_device *create_keyboard() {
-
- if (thekeyboard != NULL) {
- PrintDebug("keyboard: creating >1 keyboard device. This will probably fail!\n");
- }
-
- struct keyboard_internal * keyboard_state = (struct keyboard_internal *)V3_Malloc(sizeof(struct keyboard_internal));
+ struct keyboard_internal * keyboard_state = NULL;
+
+ keyboard_state = (struct keyboard_internal *)V3_Malloc(sizeof(struct keyboard_internal));
struct vm_device *device = create_device("KEYBOARD", &dev_ops, keyboard_state);
- thekeyboard = device;
-
+
return device;
}
-struct vm_device * thedev = NULL;
-
-/*JRL: A hack and a fatal bug
-static struct vm_device * demultiplex_timer_interrupt(uint_t period_us)
-{
- // hack
- return thedev;
-}
-*/
-/* JRL: Doesn't work
struct bcd_num {
uchar_t bot : 4;
uchar_t top : 4;
-} ;
+};
-static uchar_t add_to(uchar_t * left, uchar_t * right, uchar_t bcd)
-{
+
+
+static uchar_t add_to(uchar_t * left, uchar_t * right, uchar_t bcd) {
uchar_t temp;
if (bcd) {
return 0;
}
}
-
}
-static uchar_t days_in_month(struct vm_device *dev, uchar_t month, uchar_t bcd)
-{
+static uchar_t days_in_month(struct vm_device * dev, uchar_t month, uchar_t bcd) {
// This completely ignores Julian / Gregorian stuff right now
if (bcd) {
}
-static void update_time(struct vm_device *dev, uint_t period_us)
-{
+static void update_time(struct vm_device * dev, uint_t period_us) {
struct nvram_internal * data = (struct nvram_internal *) (dev->private_data);
struct rtc_stata * stata = (struct rtc_stata *) &((data->mem_state[NVRAM_REG_STAT_A]));
struct rtc_statb * statb = (struct rtc_statb *) &((data->mem_state[NVRAM_REG_STAT_B]));
}
}
-*/
-/* JRL: This is completely broken...
-void deliver_timer_interrupt_to_vmm(uint_t period_us)
-{
- struct vm_device * dev = demultiplex_timer_interrupt(period_us);
+int handle_timer_event(struct guest_info * info,
+ struct v3_timer_event * evt,
+ void * priv_data) {
+
+ struct vm_device * dev = (struct vm_device *)priv_data;
if (dev) {
- update_time(dev, period_us);
+ update_time(dev, evt->period_us);
}
+ return 0;
}
-*/
-static int set_nvram_defaults(struct vm_device * dev)
-{
+static int set_nvram_defaults(struct vm_device * dev) {
struct nvram_internal * nvram_state = (struct nvram_internal *)dev->private_data;
-
//
// 2 1.44 MB floppy drives
//
nvram_state->pus = 0;
return 0;
-
}
-int nvram_reset_device(struct vm_device * dev)
-{
+int nvram_reset_device(struct vm_device * dev) {
struct nvram_internal * data = (struct nvram_internal *) dev->private_data;
PrintDebug("nvram: reset device\n");
-
data->dev_state = NVRAM_READY;
data->thereg = 0;
-int nvram_start_device(struct vm_device *dev)
-{
+int nvram_start_device(struct vm_device * dev) {
PrintDebug("nvram: start device\n");
return 0;
}
-int nvram_stop_device(struct vm_device *dev)
-{
+int nvram_stop_device(struct vm_device * dev) {
PrintDebug("nvram: stop device\n");
return 0;
}
int nvram_write_reg_port(ushort_t port,
void * src,
uint_t length,
- struct vm_device * dev)
-{
+ struct vm_device * dev) {
struct nvram_internal * data = (struct nvram_internal *)dev->private_data;
memcpy(&(data->thereg), src, 1);
int nvram_read_data_port(ushort_t port,
void * dst,
uint_t length,
- struct vm_device * dev)
-{
- struct nvram_internal * data = (struct nvram_internal *) dev->private_data;
-
-
+ struct vm_device * dev) {
+ struct nvram_internal * data = (struct nvram_internal *)dev->private_data;
memcpy(dst, &(data->mem_state[data->thereg]), 1);
int nvram_write_data_port(ushort_t port,
void * src,
uint_t length,
- struct vm_device * dev)
-{
+ struct vm_device * dev) {
struct nvram_internal * data = (struct nvram_internal *)dev->private_data;
memcpy(&(data->mem_state[data->thereg]), src, 1);
int nvram_init_device(struct vm_device * dev) {
- struct nvram_internal * data = (struct nvram_internal *) dev->private_data;
+ struct nvram_internal * data = (struct nvram_internal *)dev->private_data;
PrintDebug("nvram: init_device\n");
dev_hook_io(dev, NVRAM_REG_PORT, NULL, &nvram_write_reg_port);
dev_hook_io(dev, NVRAM_DATA_PORT, &nvram_read_data_port, &nvram_write_data_port);
+ v3_hook_host_event(dev->vm, HOST_TIMER_EVT, V3_HOST_EVENT_HANDLER(handle_timer_event), dev);
+
return 0;
}
-int nvram_deinit_device(struct vm_device *dev)
-{
-
-
+int nvram_deinit_device(struct vm_device * dev) {
dev_unhook_io(dev, NVRAM_REG_PORT);
dev_unhook_io(dev, NVRAM_DATA_PORT);
struct vm_device * create_nvram() {
- struct nvram_internal * nvram_state = (struct nvram_internal *)V3_Malloc(sizeof(struct nvram_internal) + 1000);
-
- PrintDebug("nvram: internal at %x\n",nvram_state);
+ struct nvram_internal * nvram_state = NULL;
- struct vm_device * device = create_device("NVRAM", &dev_ops, nvram_state);
+ nvram_state = (struct nvram_internal *)V3_Malloc(sizeof(struct nvram_internal) + 1000);
- if (thedev != NULL) {
- PrintDebug("nvram: warning! overwriting thedev\n");
- }
+ PrintDebug("nvram: internal at %x\n", nvram_state);
- thedev = device;
+ struct vm_device * device = create_device("NVRAM", &dev_ops, nvram_state);
return device;
}
#include <devices/cdrom.h>
+#include <palacios/vmm_host_events.h>
+
#define USE_GENERIC 1
#define MAGIC_CODE 0xf1e2d3c4
}
*/
+
+
+
int config_guest(struct guest_info * info, struct v3_vm_config * config_ptr) {
struct guest_mem_layout * layout = (struct guest_mem_layout *)config_ptr->vm_kernel;
init_emulator(info);
+ v3_init_host_events(info);
+
// SerialPrint("Guest Mem Dump at 0x%x\n", 0x100000);
//PrintDebugMemDump((unsigned char *)(0x100000), 261 * 1024);
print_shadow_map(&(info->mem_map));
-
{
struct vm_device * ramdisk = NULL;