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.


added profiling support
[palacios.git] / palacios / include / palacios / vmm.h
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 #ifndef __VMM_H__
21 #define __VMM_H__
22
23
24 #include <palacios/vm_guest.h>
25 #include <palacios/vmm_mem.h>
26
27
28 #ifdef __V3VEE__
29
30 //#include <palacios/vmm_types.h>
31 #include <palacios/vmm_string.h>
32
33
34 //#include <palacios/vmm_paging.h>
35
36 /* utility definitions */
37
38
39 #define PrintDebug(fmt, args...)                        \
40   do {                                                  \
41     extern struct v3_os_hooks * os_hooks;               \
42     if ((os_hooks) && (os_hooks)->print_debug) {        \
43       (os_hooks)->print_debug((fmt), ##args);           \
44     }                                                   \
45   } while (0)                                           
46
47 #if 1
48 #else
49 #define PrintDebug(fmt,args ...)
50 #endif
51
52
53
54 #define PrintError(fmt, args...)                                        \
55   do {                                                                  \
56     extern struct v3_os_hooks * os_hooks;                               \
57     if ((os_hooks) && (os_hooks)->print_debug) {                        \
58       (os_hooks)->print_debug("%s(%d): " fmt, __FILE__, __LINE__, ##args); \
59     }                                                                   \
60   } while (0)                                           
61
62
63
64 #ifdef VMM_INFO
65 #define PrintInfo(fmt, args...)                         \
66   do {                                                  \
67     extern struct v3_os_hooks * os_hooks;               \
68     if ((os_hooks) && (os_hooks)->print_info) {         \
69       (os_hooks)->print_info((fmt), ##args);            \
70     }                                                   \
71   } while (0)                                           
72 #else
73 #define PrintInfo(fmt, args...)
74 #endif
75
76
77 #ifdef VMM_TRACE
78 #define PrintTrace(fmt, args...)                                        \
79   do {                                                                  \
80     extern struct v3_os_hooks * os_hooks;                               \
81     if ((os_hooks) && (os_hooks)->print_trace) {                        \
82       (os_hooks)->print_trace(fmt, ##args);                             \
83     }                                                                   \
84   } while (0)                                           
85 #else
86 #define PrintTrace(fmt, args...)
87 #endif
88
89
90 #define V3_AllocPages(num_pages)                        \
91   ({                                                    \
92     extern struct v3_os_hooks * os_hooks;               \
93     void * ptr = 0;                                     \
94     if ((os_hooks) && (os_hooks)->allocate_pages) {     \
95       ptr = (os_hooks)->allocate_pages(num_pages);      \
96     }                                                   \
97     ptr;                                                \
98   })                                                    \
99
100
101 #define V3_FreePage(page)                       \
102   do {                                          \
103     extern struct v3_os_hooks * os_hooks;       \
104     if ((os_hooks) && (os_hooks)->free_page) {  \
105       (os_hooks)->free_page(page);              \
106     }                                           \
107   } while(0)                                    \
108
109
110 #define V3_VAddr(addr) ({                               \
111       extern struct v3_os_hooks * os_hooks;             \
112       void * var = 0;                                   \
113       if ((os_hooks) && (os_hooks)->paddr_to_vaddr) {   \
114         var = (os_hooks)->paddr_to_vaddr(addr);         \
115       }                                                 \
116       var;                                              \
117     })
118
119
120 #define V3_PAddr(addr) ({                               \
121       extern struct v3_os_hooks * os_hooks;             \
122       void * var = 0;                                   \
123       if ((os_hooks) && (os_hooks)->vaddr_to_paddr) {   \
124         var = (os_hooks)->vaddr_to_paddr(addr);         \
125       }                                                 \
126       var;                                              \
127     })
128
129
130
131 #define V3_Malloc(size) ({                      \
132       extern struct v3_os_hooks * os_hooks;     \
133       void * var = 0;                           \
134       if ((os_hooks) && (os_hooks)->malloc) {   \
135         var = (os_hooks)->malloc(size);         \
136       }                                         \
137       var;                                      \
138     })
139
140 // We need to check the hook structure at runtime to ensure its SAFE
141 #define V3_Free(addr)                                   \
142   do {                                                  \
143     extern struct v3_os_hooks * os_hooks;               \
144     if ((os_hooks) && (os_hooks)->free) {               \
145       (os_hooks)->free(addr);                           \
146     }                                                   \
147   } while (0)                                           \
148
149
150 // uint_t V3_CPU_KHZ();
151 #define V3_CPU_KHZ()                                    \
152   ({                                                    \
153     unsigned int khz = 0;                               \
154     extern struct v3_os_hooks * os_hooks;               \
155     if ((os_hooks) && (os_hooks)->get_cpu_khz) {        \
156       khz = (os_hooks)->get_cpu_khz();                  \
157     }                                                   \
158     khz;                                                \
159   })                                                    \
160     
161
162
163 #define V3_Hook_Interrupt(irq, opaque)                          \
164   ({                                                            \
165     int ret = 0;                                                \
166     extern struct v3_os_hooks * os_hooks;                       \
167     if ((os_hooks) && (os_hooks)->hook_interrupt) {             \
168       ret = (os_hooks)->hook_interrupt(irq, opaque);            \
169     }                                                           \
170     ret;                                                        \
171   })                                                            \
172
173 #define V3_Yield(addr)                                  \
174   do {                                                  \
175     extern struct v3_os_hooks * os_hooks;               \
176     if ((os_hooks) && (os_hooks)->yield_cpu) {          \
177       (os_hooks)->yield_cpu();                          \
178     }                                                   \
179   } while (0)                                           \
180
181
182
183
184
185 /* ** */
186
187 #define V3_ASSERT(x)                                                    \
188   do {                                                                  \
189     if (!(x)) {                                                         \
190       PrintDebug("Failed assertion in %s: %s at %s, line %d, RA=%lx\n", \
191                  __func__, #x, __FILE__, __LINE__,                      \
192                  (ulong_t) __builtin_return_address(0));                \
193       while(1);                                                         \
194     }                                                                   \
195   } while(0)                                                            \
196     
197
198
199
200 #define VMM_INVALID_CPU 0
201 #define VMM_VMX_CPU 1
202 #define VMM_SVM_CPU 2
203
204
205 // Maybe make this a define....
206 typedef enum v3_cpu_arch {V3_INVALID_CPU, V3_SVM_CPU, V3_SVM_REV3_CPU, V3_VMX_CPU} v3_cpu_arch_t;
207
208
209 #endif //!__V3VEE__
210
211
212
213 struct guest_info;
214
215 /* This will contain function pointers that provide OS services */
216 struct v3_os_hooks {
217   void (*print_info)(const char * format, ...)
218         __attribute__ ((format (printf, 1, 2)));
219   void (*print_debug)(const char * format, ...)
220         __attribute__ ((format (printf, 1, 2)));
221   void (*print_trace)(const char * format, ...)
222         __attribute__ ((format (printf, 1, 2)));
223   
224   void *(*allocate_pages)(int numPages);
225   void (*free_page)(void * page);
226
227   void *(*malloc)(unsigned int size);
228   void (*free)(void * addr);
229
230   void *(*paddr_to_vaddr)(void *addr);
231   void *(*vaddr_to_paddr)(void *addr);
232
233   //  int (*hook_interrupt)(struct guest_info *s, int irq);
234
235   int (*hook_interrupt)(struct guest_info * vm, unsigned int irq);
236
237   int (*ack_irq)(int irq);
238
239
240   unsigned int (*get_cpu_khz)(void);
241
242
243   void (*start_kernel_thread)(void); // include pointer to function
244
245   void (*yield_cpu)(void);
246
247 };
248
249
250 struct v3_vm_config {
251   void * rombios;
252   int rombios_size;
253
254   void * vgabios;
255   int vgabios_size;
256
257   unsigned long mem_size; // in bytes, var should be natural size of cpu
258                           // so we can specify maximum physical address size
259                           // (We're screwed if we want to do 32 bit host/64 bit guest)
260
261
262   int enable_profiling;
263
264   int use_ramdisk;
265   void * ramdisk;
266   int ramdisk_size;
267 };
268
269
270
271 /* This will contain Function pointers that control the VMs */
272 struct v3_ctrl_ops {
273   struct guest_info *(*allocate_guest)(void);
274
275   int (*config_guest)(struct guest_info * info, struct v3_vm_config * config_ptr);
276   int (*init_guest)(struct guest_info * info);
277   int (*start_guest)(struct guest_info * info);
278   //  int (*stop_vm)(uint_t vm_id);
279
280   int (*has_nested_paging)(void);
281
282   //  v3_cpu_arch_t (*get_cpu_arch)();
283 };
284
285
286
287
288 //
289 //
290 // This is the interrupt state that the VMM's interrupt handlers need to see
291 //
292 struct v3_interrupt {
293   unsigned int irq;
294   unsigned int error;
295
296   unsigned int should_ack;  // Should the vmm ack this interrupt, or will
297                       // the host OS do it?
298 };
299
300
301
302
303 void Init_V3(struct v3_os_hooks * hooks, struct v3_ctrl_ops * vmm_ops);
304
305 int v3_deliver_irq(struct guest_info * vm, struct v3_interrupt * intr);
306 int v3_deliver_keyboard_evt(struct guest_info * vm);
307
308
309 #endif