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.


0721a1ee2c1fdb9f6bcc5967bac409503d2c4705
[palacios-OLD.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                 panic( "BAD" );
89
90         result.allocated = 0;
91         pmem_update(&result);
92 }
93
94
95
96 void
97 send_key_to_vmm(
98         unsigned char           status,
99         unsigned char           scancode
100 )
101 {
102         if( !g_vm_guest )
103                 return;
104
105         struct v3_keyboard_event evt = {
106                 .status         = status,
107                 .scan_code      = scancode,
108         };
109
110         v3_deliver_keyboard_event( g_vm_guest, &evt );
111 }
112
113
114 void
115 send_mouse_to_vmm(
116         unsigned char           packet[3]
117 )
118 {
119         if( !g_vm_guest )
120                 return;
121
122         struct v3_mouse_event evt;
123         memcpy(evt.data, packet, 3);
124
125         v3_deliver_mouse_event(g_vm_guest, &evt);
126 }
127
128
129 void
130 send_tick_to_vmm(
131         unsigned int            period_us
132 )
133 {
134         if( !g_vm_guest )
135                 return;
136
137         struct v3_timer_event evt = {
138                 .period_us      = period_us,
139         };
140
141         v3_deliver_timer_event( g_vm_guest, &evt );
142 }
143
144
145 void
146 translate_intr_handler(
147         struct pt_regs *        regs,
148         unsigned int            vector
149
150 {
151         struct v3_interrupt intr = {
152                 .irq            = vector-32,
153                 .error          = regs->orig_rax,
154                 .should_ack     = 0,
155         };
156
157         //  PrintBoth("translate_intr_handler: opaque=0x%x\n",mystate.opaque);
158         printk( "%s: irq %d\n", __func__, vector );
159         v3_deliver_irq( irq_to_guest_map[intr.irq], &intr );
160 }
161
162
163 int
164 kitten_hook_interrupt(
165         struct guest_info *     vm,
166         unsigned int            irq
167 )
168 {
169         if( irq_to_guest_map[irq] ) {
170                 //PrintBoth("Attempt to hook interrupt that is already hooked\n");
171                 return -1;
172         }
173
174         //PrintBoth("Hooked interrupt 0x%x with opaque 0x%x\n", irq, vm);
175         printk( "%s: hook irq %d to %p\n", __func__, irq, vm );
176         irq_to_guest_map[irq] = vm;
177
178         set_idtvec_handler( irq, translate_intr_handler );
179         return 0;
180 }
181
182
183 static int
184 ack_irq(
185         int                     irq
186
187 {
188         lapic_ack_interrupt();
189         return 0;
190 }
191
192   
193 static unsigned int
194 get_cpu_khz( void ) 
195 {
196         return cpu_info[0].arch.cur_cpu_khz;
197 }
198
199 static void *
200 v3vee_alloc(
201         unsigned int size
202 )
203 {
204         return kmem_alloc( size );
205 }
206
207
208 static void
209 v3vee_free(
210         void * addr
211 )
212 {
213         return kmem_free( addr );
214 }
215
216
217 static void
218 v3vee_printk(
219         const char *            fmt,
220         ...
221 )
222 {
223         va_list ap;
224         va_start( ap, fmt );
225         vprintk( fmt, ap );
226         va_end( ap );
227 }
228
229
230 struct v3_os_hooks v3vee_os_hooks = {
231         .print_debug            = 0, // printk,  // serial print ideally
232         .print_info             = v3vee_printk,   // serial print ideally
233         .print_trace            = v3vee_printk,  // serial print ideally
234         .allocate_pages         = Allocate_VMM_Pages, // defined in vmm_stubs
235         .free_page              = Free_VMM_Page, // defined in vmm_stubs
236         .malloc                 = v3vee_alloc,
237         .free                   = v3vee_free,
238         .vaddr_to_paddr         = kitten_va_to_pa,
239         .paddr_to_vaddr         = kitten_pa_to_va,
240         .hook_interrupt         = kitten_hook_interrupt,
241         .ack_irq                = ack_irq,
242         .get_cpu_khz            = get_cpu_khz,
243 };
244