From: Jack Lange Date: Wed, 15 Oct 2008 03:48:25 +0000 (-0500) Subject: updated devices to use new host event interface X-Git-Tag: 1.0^2~50 X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=a46778669bb94bcf6b0a05646123ff748cfe86be updated devices to use new host event interface updated GeekOS to use new host event interface --- diff --git a/geekos/include/geekos/vmm_stubs.h b/geekos/include/geekos/vmm_stubs.h index b56c114..d2d0ce4 100644 --- a/geekos/include/geekos/vmm_stubs.h +++ b/geekos/include/geekos/vmm_stubs.h @@ -49,17 +49,22 @@ int ack_irq(int irq); 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 diff --git a/geekos/src/geekos/keyboard.c b/geekos/src/geekos/keyboard.c index e33e989..501359e 100644 --- a/geekos/src/geekos/keyboard.c +++ b/geekos/src/geekos/keyboard.c @@ -36,13 +36,14 @@ #include +#include -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 @@ -264,7 +265,7 @@ noflagchange: 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; @@ -284,13 +285,15 @@ skip_flagchange: */ 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); } + } } diff --git a/geekos/src/geekos/main.c b/geekos/src/geekos/main.c index 29c2dde..5d71341 100644 --- a/geekos/src/geekos/main.c +++ b/geekos/src/geekos/main.c @@ -220,7 +220,7 @@ void Main(struct Boot_Info* bootInfo) //Init_PCI(); - Init_Stubs(); + // Init_Network(); diff --git a/geekos/src/geekos/timer.c b/geekos/src/geekos/timer.c index 964f50b..8409fd7 100644 --- a/geekos/src/geekos/timer.c +++ b/geekos/src/geekos/timer.c @@ -22,6 +22,8 @@ #include +#include + /* PAD this currently is in nvram.c */ /* JRL: This is completely broken extern void deliver_timer_interrupt_to_vmm(uint_t period_us); @@ -218,9 +220,9 @@ static void Timer_Interrupt_Handler(struct Interrupt_State* state) } - /* JRL: Broken, - deliver_timer_interrupt_to_vmm(1000000/HZ); - */ + + send_tick_to_vmm(1000000/HZ); + End_IRQ(state); } diff --git a/geekos/src/geekos/vm.c b/geekos/src/geekos/vm.c index 10c34ca..ceb0ac0 100644 --- a/geekos/src/geekos/vm.c +++ b/geekos/src/geekos/vm.c @@ -30,7 +30,6 @@ #include - extern void * g_ramdiskImage; extern ulong_t s_ramdiskSize; @@ -213,7 +212,7 @@ int RunVMM(struct Boot_Info * bootInfo) { 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)); @@ -254,6 +253,8 @@ int RunVMM(struct Boot_Info * bootInfo) { vm_info = (vmm_ops).allocate_guest(); + Init_Stubs(vm_info); + PrintBoth("Allocated Guest\n"); (vmm_ops).config_guest(vm_info, &vm_config); @@ -273,6 +274,7 @@ int RunVMM(struct Boot_Info * bootInfo) { (vmm_ops).init_guest(vm_info); PrintBoth("Starting Guest\n"); //Clear_Screen(); + (vmm_ops).start_guest(vm_info); return 0; diff --git a/geekos/src/geekos/vmm_stubs.c b/geekos/src/geekos/vmm_stubs.c index e40c8dd..e6b2610 100644 --- a/geekos/src/geekos/vmm_stubs.c +++ b/geekos/src/geekos/vmm_stubs.c @@ -21,6 +21,19 @@ #include #include #include +#include + + +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]; + @@ -51,6 +64,12 @@ static inline uchar_t VM_In_Byte(ushort_t port) +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; }; @@ -95,13 +114,38 @@ void VMM_Free(void * 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) { @@ -144,9 +188,6 @@ int ack_irq(int irq) { } -void Init_Stubs() { - memset(irq_to_guest_map, 0, sizeof(struct guest_info *) * 256); -} unsigned int get_cpu_khz() { @@ -159,3 +200,4 @@ unsigned int get_cpu_khz() { return cpu_khz_freq; } + diff --git a/palacios/include/devices/keyboard.h b/palacios/include/devices/keyboard.h index 64ad387..2349d00 100644 --- a/palacios/include/devices/keyboard.h +++ b/palacios/include/devices/keyboard.h @@ -22,15 +22,6 @@ #include -// -// 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 diff --git a/palacios/include/palacios/vmm_host_events.h b/palacios/include/palacios/vmm_host_events.h index 7459501..dfe4775 100644 --- a/palacios/include/palacios/vmm_host_events.h +++ b/palacios/include/palacios/vmm_host_events.h @@ -30,9 +30,8 @@ struct v3_mouse_event { unsigned char data[3]; }; - struct v3_timer_event { - + unsigned int period_us; }; #ifdef __V3VEE__ @@ -70,7 +69,7 @@ struct v3_host_events { 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, @@ -79,6 +78,8 @@ int v3_hook_host_event(struct guest_info * info, #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); diff --git a/palacios/src/devices/keyboard.c b/palacios/src/devices/keyboard.c index ed00282..3d52f4e 100644 --- a/palacios/src/devices/keyboard.c +++ b/palacios/src/devices/keyboard.c @@ -98,8 +98,6 @@ #define MOUSE 1 -// The currently targetted keyboard -static struct vm_device * thekeyboard = NULL; //#define QUEUE_SIZE 32 @@ -325,57 +323,52 @@ static int PullFromInputQueue(struct vm_device *dev, uchar_t *value) #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; @@ -385,13 +378,15 @@ void deliver_mouse_to_vmm(uchar_t data[3]) 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; } @@ -1167,6 +1162,10 @@ int keyboard_init_device(struct vm_device * dev) 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 @@ -1208,16 +1207,12 @@ static struct vm_device_ops dev_ops = { 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; } diff --git a/palacios/src/devices/nvram.c b/palacios/src/devices/nvram.c index 6326487..d4a30fa 100644 --- a/palacios/src/devices/nvram.c +++ b/palacios/src/devices/nvram.c @@ -132,23 +132,14 @@ struct rtc_statd { -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) { @@ -175,12 +166,10 @@ static uchar_t add_to(uchar_t * left, uchar_t * right, uchar_t 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) { @@ -238,8 +227,7 @@ static uchar_t days_in_month(struct vm_device *dev, uchar_t month, uchar_t 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])); @@ -425,25 +413,23 @@ static void update_time(struct vm_device *dev, uint_t period_us) } } -*/ -/* 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 // @@ -527,16 +513,13 @@ static int set_nvram_defaults(struct vm_device * dev) 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; @@ -548,15 +531,13 @@ int nvram_reset_device(struct vm_device * dev) -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; } @@ -567,8 +548,7 @@ int nvram_stop_device(struct vm_device *dev) 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); @@ -581,11 +561,8 @@ int nvram_write_reg_port(ushort_t port, 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); @@ -603,8 +580,7 @@ int nvram_read_data_port(ushort_t port, 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); @@ -618,7 +594,7 @@ int nvram_write_data_port(ushort_t port, 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"); @@ -633,13 +609,12 @@ int nvram_init_device(struct vm_device * dev) { 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); @@ -663,17 +638,13 @@ static struct vm_device_ops dev_ops = { 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; } diff --git a/palacios/src/palacios/vmm_config.c b/palacios/src/palacios/vmm_config.c index ba2529a..3a4cbaf 100644 --- a/palacios/src/palacios/vmm_config.c +++ b/palacios/src/palacios/vmm_config.c @@ -32,6 +32,8 @@ #include +#include + #define USE_GENERIC 1 #define MAGIC_CODE 0xf1e2d3c4 @@ -92,6 +94,9 @@ static int passthrough_mem_write(addr_t guest_addr, void * src, uint_t length, v } */ + + + 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; @@ -124,6 +129,8 @@ int config_guest(struct guest_info * info, struct v3_vm_config * config_ptr) { init_emulator(info); + v3_init_host_events(info); + // SerialPrint("Guest Mem Dump at 0x%x\n", 0x100000); //PrintDebugMemDump((unsigned char *)(0x100000), 261 * 1024); @@ -195,7 +202,6 @@ int config_guest(struct guest_info * info, struct v3_vm_config * config_ptr) { print_shadow_map(&(info->mem_map)); - { struct vm_device * ramdisk = NULL;