Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merge branch 'devel'
[palacios.git] / kitten / palacios-glue / vmm_stubs.c
diff --git a/kitten/palacios-glue/vmm_stubs.c b/kitten/palacios-glue/vmm_stubs.c
new file mode 100644 (file)
index 0000000..aa5f54a
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National 
+ * Science Foundation and the Department of Energy.  
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico.  You can find out more at 
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.northwestern.edu>
+ *
+ * This is free software.  You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#include <lwk/palacios.h>
+#include <lwk/types.h>
+#include <lwk/pmem.h>
+#include <lwk/string.h>
+#include <lwk/cpuinfo.h>
+#include <lwk/kernel.h>
+#include <arch/page.h>
+#include <arch/ptrace.h>
+#include <arch/apic.h>
+
+struct guest_info * g_vm_guest = NULL;
+struct guest_info * irq_to_guest_map[256];
+
+
+
+void
+v3vee_init_stubs( void )
+{
+       memset(irq_to_guest_map, 0, sizeof(irq_to_guest_map) );
+}
+
+
+static void *
+kitten_pa_to_va(void *ptr)
+{
+       return (void*) __va(ptr);
+}
+
+
+static void *
+kitten_va_to_pa(
+       void *                  ptr
+)
+{
+       return (void*) __pa(ptr);
+}
+
+
+static void *
+Allocate_VMM_Pages(
+       int                     num_pages
+) 
+{
+       struct pmem_region result;
+  
+       int rc = pmem_alloc_umem( num_pages*PAGE_SIZE,PAGE_SIZE, &result );
+       if( rc )
+               return 0;
+
+       return (void*) result.start;
+}
+
+static void
+Free_VMM_Page(
+       void *                  page
+) 
+{
+       struct pmem_region      query;
+       struct pmem_region      result;
+
+       pmem_region_unset_all(&query);
+
+       query.start     = (uintptr_t)( page );
+       query.end       = (uintptr_t)( page + PAGE_SIZE );
+
+       int rc = pmem_query(&query,&result);
+
+       if( rc )
+       {
+               panic( "Asked to free non-allocated page %p! rc=%d",
+                       page,
+                       rc
+               );
+               return;
+       }
+
+       result.allocated = 0;
+       pmem_update(&result);
+}
+
+
+
+void
+send_key_to_vmm(
+       unsigned char           status,
+       unsigned char           scancode
+)
+{
+       if( !g_vm_guest )
+               return;
+
+       struct v3_keyboard_event evt = {
+               .status         = status,
+               .scan_code      = scancode,
+       };
+
+       v3_deliver_keyboard_event( g_vm_guest, &evt );
+}
+
+
+void
+send_mouse_to_vmm(
+       unsigned char           packet[3]
+)
+{
+       if( !g_vm_guest )
+               return;
+
+       struct v3_mouse_event evt;
+       memcpy(evt.data, packet, 3);
+
+       v3_deliver_mouse_event(g_vm_guest, &evt);
+}
+
+
+void
+send_tick_to_vmm(
+       unsigned int            period_us
+)
+{
+       if( !g_vm_guest )
+               return;
+
+       struct v3_timer_event evt = {
+               .period_us      = period_us,
+       };
+
+       v3_deliver_timer_event( g_vm_guest, &evt );
+}
+
+
+void
+translate_intr_handler(
+       struct pt_regs *        regs,
+       unsigned int            vector
+) 
+{
+       struct v3_interrupt intr = {
+               .irq            = vector-32,
+               .error          = regs->orig_rax,
+               .should_ack     = 0,
+       };
+
+       //  PrintBoth("translate_intr_handler: opaque=0x%x\n",mystate.opaque);
+       printk( "%s: irq %d\n", __func__, vector );
+       v3_deliver_irq( irq_to_guest_map[intr.irq], &intr );
+}
+
+
+int
+kitten_hook_interrupt(
+       struct guest_info *     vm,
+       unsigned int            irq
+)
+{
+       if( irq_to_guest_map[irq] ) {
+               //PrintBoth("Attempt to hook interrupt that is already hooked\n");
+               return -1;
+       }
+
+       //PrintBoth("Hooked interrupt 0x%x with opaque 0x%x\n", irq, vm);
+       printk( "%s: hook irq %d to %p\n", __func__, irq, vm );
+       irq_to_guest_map[irq] = vm;
+
+       set_idtvec_handler( irq, translate_intr_handler );
+       return 0;
+}
+
+
+static int
+ack_irq(
+       int                     irq
+) 
+{
+       lapic_ack_interrupt();
+       return 0;
+}
+
+  
+static unsigned int
+get_cpu_khz( void ) 
+{
+       return cpu_info[0].arch.cur_cpu_khz;
+}
+
+static void *
+v3vee_alloc(
+       unsigned int size
+)
+{
+       return kmem_alloc( size );
+}
+
+
+static void
+v3vee_free(
+       void * addr
+)
+{
+       return kmem_free( addr );
+}
+
+
+static void
+v3vee_printk(
+       const char *            fmt,
+       ...
+)
+{
+       va_list ap;
+       va_start( ap, fmt );
+       vprintk( fmt, ap );
+       va_end( ap );
+}
+
+
+struct v3_os_hooks v3vee_os_hooks = {
+       .print_debug            = v3vee_printk,  // serial print ideally
+       .print_info             = v3vee_printk,   // serial print ideally
+       .print_trace            = v3vee_printk,  // serial print ideally
+       .allocate_pages         = Allocate_VMM_Pages, // defined in vmm_stubs
+       .free_page              = Free_VMM_Page, // defined in vmm_stubs
+       .malloc                 = v3vee_alloc,
+       .free                   = v3vee_free,
+       .vaddr_to_paddr         = kitten_va_to_pa,
+       .paddr_to_vaddr         = kitten_pa_to_va,
+       .hook_interrupt         = kitten_hook_interrupt,
+       .ack_irq                = ack_irq,
+       .get_cpu_khz            = get_cpu_khz,
+};
+