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.


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