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
1 /*
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
11  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Jack Lange <jarusl@cs.northwestern.edu>
15  *
16  * This is free software.  You are permitted to use,
17  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
18  */
19
20 #include <lwk/palacios.h>
21 #include <lwk/types.h>
22 #include <lwk/pmem.h>
23 #include <lwk/string.h>
24 #include <lwk/cpuinfo.h>
25 #include <lwk/kernel.h>
26 #include <arch/page.h>
27 #include <arch/ptrace.h>
28 #include <arch/apic.h>
29
30 struct guest_info * g_vm_guest = NULL;
31 struct guest_info * irq_to_guest_map[256];
32
33
34
35 void
36 v3vee_init_stubs( void )
37 {
38         memset(irq_to_guest_map, 0, sizeof(irq_to_guest_map) );
39 }
40
41
42 static void *
43 kitten_pa_to_va(void *ptr)
44 {
45         return (void*) __va(ptr);
46 }
47
48
49 static void *
50 kitten_va_to_pa(
51         void *                  ptr
52 )
53 {
54         return (void*) __pa(ptr);
55 }
56
57
58 static void *
59 Allocate_VMM_Pages(
60         int                     num_pages
61
62 {
63         struct pmem_region result;
64   
65         int rc = pmem_alloc_umem( num_pages*PAGE_SIZE,PAGE_SIZE, &result );
66         if( rc )
67                 return 0;
68
69         return (void*) result.start;
70 }
71
72 static void
73 Free_VMM_Page(
74         void *                  page
75
76 {
77         struct pmem_region      query;
78         struct pmem_region      result;
79
80         pmem_region_unset_all(&query);
81
82         query.start     = (uintptr_t)( page );
83         query.end       = (uintptr_t)( page + PAGE_SIZE );
84
85         int rc = pmem_query(&query,&result);
86
87         if( rc )
88         {
89                 panic( "Asked to free non-allocated page %p! rc=%d",
90                         page,
91                         rc
92                 );
93                 return;
94         }
95
96         result.allocated = 0;
97         pmem_update(&result);
98 }
99
100
101
102 void
103 send_key_to_vmm(
104         unsigned char           status,
105         unsigned char           scancode
106 )
107 {
108         if( !g_vm_guest )
109                 return;
110
111         struct v3_keyboard_event evt = {
112                 .status         = status,
113                 .scan_code      = scancode,
114         };
115
116         v3_deliver_keyboard_event( g_vm_guest, &evt );
117 }
118
119
120 void
121 send_mouse_to_vmm(
122         unsigned char           packet[3]
123 )
124 {
125         if( !g_vm_guest )
126                 return;
127
128         struct v3_mouse_event evt;
129         memcpy(evt.data, packet, 3);
130
131         v3_deliver_mouse_event(g_vm_guest, &evt);
132 }
133
134
135 void
136 send_tick_to_vmm(
137         unsigned int            period_us
138 )
139 {
140         if( !g_vm_guest )
141                 return;
142
143         struct v3_timer_event evt = {
144                 .period_us      = period_us,
145         };
146
147         v3_deliver_timer_event( g_vm_guest, &evt );
148 }
149
150
151 void
152 translate_intr_handler(
153         struct pt_regs *        regs,
154         unsigned int            vector
155
156 {
157         struct v3_interrupt intr = {
158                 .irq            = vector-32,
159                 .error          = regs->orig_rax,
160                 .should_ack     = 0,
161         };
162
163         //  PrintBoth("translate_intr_handler: opaque=0x%x\n",mystate.opaque);
164         printk( "%s: irq %d\n", __func__, vector );
165         v3_deliver_irq( irq_to_guest_map[intr.irq], &intr );
166 }
167
168
169 int
170 kitten_hook_interrupt(
171         struct guest_info *     vm,
172         unsigned int            irq
173 )
174 {
175         if( irq_to_guest_map[irq] ) {
176                 //PrintBoth("Attempt to hook interrupt that is already hooked\n");
177                 return -1;
178         }
179
180         //PrintBoth("Hooked interrupt 0x%x with opaque 0x%x\n", irq, vm);
181         printk( "%s: hook irq %d to %p\n", __func__, irq, vm );
182         irq_to_guest_map[irq] = vm;
183
184         set_idtvec_handler( irq, translate_intr_handler );
185         return 0;
186 }
187
188
189 static int
190 ack_irq(
191         int                     irq
192
193 {
194         lapic_ack_interrupt();
195         return 0;
196 }
197
198   
199 static unsigned int
200 get_cpu_khz( void ) 
201 {
202         return cpu_info[0].arch.cur_cpu_khz;
203 }
204
205 static void *
206 v3vee_alloc(
207         unsigned int size
208 )
209 {
210         return kmem_alloc( size );
211 }
212
213
214 static void
215 v3vee_free(
216         void * addr
217 )
218 {
219         return kmem_free( addr );
220 }
221
222
223 static void
224 v3vee_printk(
225         const char *            fmt,
226         ...
227 )
228 {
229         va_list ap;
230         va_start( ap, fmt );
231         vprintk( fmt, ap );
232         va_end( ap );
233 }
234
235
236 struct v3_os_hooks v3vee_os_hooks = {
237         .print_debug            = v3vee_printk,  // serial print ideally
238         .print_info             = v3vee_printk,   // serial print ideally
239         .print_trace            = v3vee_printk,  // serial print ideally
240         .allocate_pages         = Allocate_VMM_Pages, // defined in vmm_stubs
241         .free_page              = Free_VMM_Page, // defined in vmm_stubs
242         .malloc                 = v3vee_alloc,
243         .free                   = v3vee_free,
244         .vaddr_to_paddr         = kitten_va_to_pa,
245         .paddr_to_vaddr         = kitten_pa_to_va,
246         .hook_interrupt         = kitten_hook_interrupt,
247         .ack_irq                = ack_irq,
248         .get_cpu_khz            = get_cpu_khz,
249 };
250