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.


.....
[palacios.git] / palacios / src / palacios / vmm_config.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 <palacios/vmm_config.h>
21 #include <palacios/vmm.h>
22 #include <palacios/vmm_debug.h>
23 #include <palacios/vmm_msr.h>
24 #include <palacios/vmm_decoder.h>
25 #include <palacios/vmm_profiler.h>
26 #include <palacios/vmm_mem.h>
27
28
29 #include <devices/serial.h>
30 #include <devices/keyboard.h>
31 #include <devices/8259a.h>
32 #include <devices/8254.h>
33 #include <devices/nvram.h>
34 #include <devices/generic.h>
35 #include <devices/ramdisk.h>
36 #include <devices/cdrom.h>
37 #include <devices/bochs_debug.h>
38 #include <devices/os_debug.h>
39 #include <devices/apic.h>
40
41
42
43 #include <palacios/vmm_host_events.h>
44
45 #define USE_GENERIC 1
46
47
48 #define ROMBIOS_START 0x000f0000
49 #define VGABIOS_START 0x000c0000
50
51
52
53 static int setup_memory_map(struct guest_info * info, struct v3_vm_config * config_ptr);
54 static int setup_devices(struct guest_info * info, struct v3_vm_config * config_ptr);
55 static struct vm_device *  configure_generic(struct guest_info * info, struct v3_vm_config * config_ptr);
56
57
58
59
60 static int passthrough_mem_write(addr_t guest_addr, void * src, uint_t length, void * priv_data) {
61
62   return length;
63   //  memcpy((void*)guest_addr, src, length);
64   PrintDebug("Write of %d bytes to %p\n", length, (void *)guest_addr);
65   PrintDebug("Write Value = %p\n", (void *)*(addr_t *)src);
66
67   return length;
68 }
69
70
71
72 int v3_config_guest(struct guest_info * info, struct v3_vm_config * config_ptr) {
73   extern v3_cpu_arch_t v3_cpu_type;
74
75   // Initialize the subsystem data strutures
76   v3_init_time(info);
77   v3_init_io_map(info);
78   v3_init_msr_map(info);
79   v3_init_interrupt_state(info);
80   v3_init_dev_mgr(info);
81   v3_init_host_events(info);
82
83   v3_init_decoder(info);
84   
85   v3_init_shadow_map(info);
86   
87   if (v3_cpu_type == V3_SVM_REV3_CPU) {
88     info->shdw_pg_mode = NESTED_PAGING;
89   } else {
90     v3_init_shadow_page_state(info);
91     info->shdw_pg_mode = SHADOW_PAGING;
92   }
93   
94   // Initial CPU operating mode
95   info->cpu_mode = REAL;
96   info->mem_mode = PHYSICAL_MEM;
97
98   // Amount of ram the Guest will have
99   info->mem_size = config_ptr->mem_size;
100
101   // Configure the memory map for the guest
102   setup_memory_map(info, config_ptr);
103
104   // Configure the devices for the guest
105   setup_devices(info, config_ptr);
106  
107
108
109   if (config_ptr->enable_profiling) {
110     info->enable_profiler = 1;
111     v3_init_profiler(info);
112   } else {
113     info->enable_profiler = 0;
114   }
115
116   //v3_hook_io_port(info, 1234, &IO_Read, NULL, info);
117
118   // Setup initial cpu register state
119   info->rip = 0xfff0;
120   info->vm_regs.rsp = 0x0;
121   
122
123   return 0;
124 }
125
126
127 /* TODO:
128  * The amount of guest memory is stored in info->mem_size
129  * We need to make sure the memory map extends to cover it
130  */
131 static int setup_memory_map(struct guest_info * info, struct v3_vm_config * config_ptr) {
132
133   /* layout rombios */
134   {
135     uint_t num_pages = (config_ptr->rombios_size + PAGE_SIZE - 1) / PAGE_SIZE;
136     void * guest_mem =  V3_AllocPages(num_pages);
137
138     PrintDebug("Layout Region %d bytes\n", config_ptr->rombios_size);
139     memcpy(V3_VAddr(guest_mem), config_ptr->rombios, config_ptr->rombios_size);
140
141     v3_add_shadow_mem(info, ROMBIOS_START, ROMBIOS_START + (num_pages * PAGE_SIZE) - 1, (addr_t)guest_mem);
142     
143     PrintDebug("Adding Shadow Region (0x%p-0x%p) -> 0x%p\n", 
144                (void *)ROMBIOS_START, 
145                (void *)ROMBIOS_START + (num_pages * PAGE_SIZE), 
146                (void *)guest_mem);
147   }
148
149
150   /* layout vgabios */
151   {
152     uint_t num_pages = (config_ptr->vgabios_size + PAGE_SIZE - 1) / PAGE_SIZE;
153     void * guest_mem =  V3_AllocPages(num_pages);
154
155     PrintDebug("Layout Region %d bytes\n", config_ptr->vgabios_size);
156     memcpy(V3_VAddr(guest_mem), config_ptr->vgabios, config_ptr->vgabios_size);
157
158     v3_add_shadow_mem(info, VGABIOS_START, VGABIOS_START + (num_pages * PAGE_SIZE) - 1, (addr_t)guest_mem);
159     
160     PrintDebug("Adding Shadow Region (0x%p-0x%p) -> 0x%p\n", 
161                (void *)VGABIOS_START, 
162                (void *)VGABIOS_START + (num_pages * PAGE_SIZE), 
163                (void *)guest_mem);
164   }
165
166       //     
167   v3_add_shadow_mem(info, 0x0, 0x9ffff, (addr_t)V3_AllocPages(160));
168   
169   if (1) {
170     v3_add_shadow_mem(info, 0xa0000, 0xbffff, 0xa0000); 
171   } else {
172     v3_hook_write_mem(info, 0xa0000, 0xbffff, 0xa0000,  passthrough_mem_write, NULL);
173   }  
174   
175   // TEMP
176   //add_shadow_region_passthrough(info, 0xc0000, 0xc8000, 0xc0000);
177   
178   if (1) {
179     v3_add_shadow_mem(info, 0xc7000, 0xc8000, (addr_t)V3_AllocPages(1));
180     if (v3_add_shadow_mem(info, 0xc8000, 0xf0000, (addr_t)V3_AllocPages(40)) == -1) {
181       PrintDebug("Error adding shadow region\n");
182     }
183   } else {
184     v3_add_shadow_mem(info, 0xc0000, 0xc8000, 0xc0000);
185     v3_add_shadow_mem(info, 0xc8000, 0xf0000, 0xc8000);
186   }
187   
188   
189   if (1) {
190     v3_add_shadow_mem(info, 0x100000, 0x1000000, (addr_t)V3_AllocPages(4096));
191   } else {
192     /* MEMORY HOOK TEST */
193     v3_add_shadow_mem(info, 0x100000, 0xa00000, (addr_t)V3_AllocPages(2304));
194     v3_hook_write_mem(info, 0xa00000, 0xa01000, (addr_t)V3_AllocPages(1), passthrough_mem_write, NULL); 
195     v3_add_shadow_mem(info, 0xa01000, 0x1000000, (addr_t)V3_AllocPages(1791));
196   }
197
198   v3_add_shadow_mem(info, 0x1000000, 0x8000000, (addr_t)V3_AllocPages(32768));
199  
200   // test - give linux accesss to PCI space - PAD
201   //v3_add_shadow_mem(info, 0xc0000000,0xffffffff,0xc0000000);
202   
203   
204   print_shadow_map(info);
205
206   return 0;
207 }
208
209
210
211 static int setup_devices(struct guest_info * info, struct v3_vm_config * config_ptr) {
212     struct vm_device * ramdisk = NULL;
213     struct vm_device * cdrom = NULL;
214     struct vm_device * nvram = v3_create_nvram();
215     //struct vm_device * timer = v3_create_timer();
216     struct vm_device * pic = v3_create_pic();
217     struct vm_device * keyboard = v3_create_keyboard();
218     struct vm_device * pit = v3_create_pit(); 
219     struct vm_device * bochs_debug = v3_create_bochs_debug();
220     struct vm_device * os_debug = v3_create_os_debug();
221     // struct vm_device * apic = v3_create_apic();
222
223     //struct vm_device * serial = v3_create_serial();
224     struct vm_device * generic = NULL;
225
226     int use_ramdisk = config_ptr->use_ramdisk;
227     int use_generic = USE_GENERIC;
228
229
230     if (use_ramdisk) {
231       PrintDebug("Creating Ramdisk\n");
232       ramdisk = v3_create_ramdisk();
233       cdrom = v3_create_cdrom(ramdisk, config_ptr->ramdisk, config_ptr->ramdisk_size); 
234     }
235     
236     
237     if (use_generic) {
238       generic = configure_generic(info, config_ptr);
239     }
240
241
242     v3_attach_device(info, nvram);
243     //v3_attach_device(info, timer);
244     v3_attach_device(info, pic);
245     v3_attach_device(info, pit);
246     v3_attach_device(info, keyboard);
247     // v3_attach_device(info, serial);
248     v3_attach_device(info, bochs_debug);
249     v3_attach_device(info, os_debug);
250
251     // v3_attach_device(info, apic);
252
253     if (use_ramdisk) {
254       v3_attach_device(info, ramdisk);
255       v3_attach_device(info, cdrom);
256     }
257
258     if (use_generic) {
259       // Important that this be attached last!
260       v3_attach_device(info, generic);
261     }
262     
263     PrintDebugDevMgr(info);
264
265
266     // give keyboard interrupts to vm
267     // no longer needed since we have a keyboard device
268     //hook_irq(&vm_info, 1);
269     
270 #if 0
271     // give floppy controller to vm
272     v3_hook_passthrough_irq(info, 6);
273 #endif
274     
275     
276     if (!use_ramdisk) {
277       PrintDebug("Hooking IDE IRQs\n");
278       
279       //primary ide
280       v3_hook_passthrough_irq(info, 14);
281       
282       // secondary ide
283       v3_hook_passthrough_irq(info, 15);    
284     }  
285     
286
287   return 0;
288 }
289
290
291
292 static struct vm_device *  configure_generic(struct guest_info * info, struct v3_vm_config * config_ptr) {
293       PrintDebug("Creating Generic Device\n");
294       struct vm_device * generic = v3_create_generic();
295       
296       // Make the DMA controller invisible
297       v3_generic_add_port_range(generic, 0x00, 0x07, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channels 0,1,2,3 (address, counter)
298       v3_generic_add_port_range(generic, 0xc0, 0xc7, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channels 4,5,6,7 (address, counter)
299       v3_generic_add_port_range(generic, 0x87, 0x87, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 0 page register
300       v3_generic_add_port_range(generic, 0x83, 0x83, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 1 page register
301       v3_generic_add_port_range(generic, 0x81, 0x81, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 2 page register
302       v3_generic_add_port_range(generic, 0x82, 0x82, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 3 page register
303       v3_generic_add_port_range(generic, 0x8f, 0x8f, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 4 page register
304       v3_generic_add_port_range(generic, 0x8b, 0x8b, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 5 page register
305       v3_generic_add_port_range(generic, 0x89, 0x89, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 6 page register
306       v3_generic_add_port_range(generic, 0x8a, 0x8a, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 7 page register
307       v3_generic_add_port_range(generic, 0x08, 0x0f, GENERIC_PRINT_AND_IGNORE);   // DMA 1 misc registers (csr, req, smask,mode,clearff,reset,enable,mmask)
308       v3_generic_add_port_range(generic, 0xd0, 0xde, GENERIC_PRINT_AND_IGNORE);   // DMA 2 misc registers
309       
310       
311       
312       
313       // Make the Serial ports invisible 
314       
315       v3_generic_add_port_range(generic, 0x3f8, 0x3f8+7, GENERIC_PRINT_AND_IGNORE);      // COM 1
316       v3_generic_add_port_range(generic, 0x2f8, 0x2f8+7, GENERIC_PRINT_AND_IGNORE);      // COM 2
317       
318
319       
320
321       v3_generic_add_port_range(generic, 0x3e8, 0x3e8+7, GENERIC_PRINT_AND_IGNORE);      // COM 3
322       v3_generic_add_port_range(generic, 0x2e8, 0x2e8+7, GENERIC_PRINT_AND_IGNORE);      // COM 4
323
324       
325       
326
327       // Make the PCI bus invisible (at least it's configuration)
328       
329       v3_generic_add_port_range(generic, 0xcf8, 0xcf8, GENERIC_PRINT_AND_IGNORE); // PCI Config Address
330       v3_generic_add_port_range(generic, 0xcfc, 0xcfc, GENERIC_PRINT_AND_IGNORE); // PCI Config Data
331
332       
333       
334 #if 0
335       if (!use_ramdisk) {
336         // Monitor the IDE controllers (very slow)
337         v3_generic_add_port_range(generic, 0x170, 0x178, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 1
338         v3_generic_add_port_range(generic, 0x376, 0x377, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 1
339       }
340       
341
342       v3_generic_add_port_range(generic, 0x1f0, 0x1f8, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 0
343       v3_generic_add_port_range(generic, 0x3f6, 0x3f7, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 0
344 #endif
345       
346       
347 #if 0
348       
349       // Make the floppy controllers invisible
350       
351       v3_generic_add_port_range(generic, 0x3f0, 0x3f2, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (base,statusa/statusb,DOR)
352       v3_generic_add_port_range(generic, 0x3f4, 0x3f5, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (mainstat/datarate,data)
353       v3_generic_add_port_range(generic, 0x3f7, 0x3f7, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (DIR)
354       v3_generic_add_port_range(generic, 0x370, 0x372, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (base,statusa/statusb,DOR)
355       v3_generic_add_port_range(generic, 0x374, 0x375, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (mainstat/datarate,data)
356       v3_generic_add_port_range(generic, 0x377, 0x377, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (DIR)
357       
358 #endif
359
360 #if 1
361
362       // Make the parallel port invisible
363       
364       v3_generic_add_port_range(generic, 0x378, 0x37f, GENERIC_PRINT_AND_IGNORE);
365
366 #endif
367
368 #if 1
369
370       // Monitor graphics card operations
371
372       v3_generic_add_port_range(generic, 0x3b0, 0x3bb, GENERIC_PRINT_AND_PASSTHROUGH);
373       v3_generic_add_port_range(generic, 0x3c0, 0x3df, GENERIC_PRINT_AND_PASSTHROUGH);
374       
375 #endif
376
377
378 #if 1
379       // Make the ISA PNP features invisible
380
381       v3_generic_add_port_range(generic, 0x274, 0x277, GENERIC_PRINT_AND_IGNORE);
382       v3_generic_add_port_range(generic, 0x279, 0x279, GENERIC_PRINT_AND_IGNORE);
383       v3_generic_add_port_range(generic, 0xa79, 0xa79, GENERIC_PRINT_AND_IGNORE);
384 #endif
385
386
387 #if 1
388       // Monitor any network card (realtek ne2000) operations 
389       v3_generic_add_port_range(generic, 0xc100, 0xc1ff, GENERIC_PRINT_AND_PASSTHROUGH);
390 #endif
391
392
393 #if 1
394       // Make any Bus master ide controller invisible
395       
396       v3_generic_add_port_range(generic, 0xc000, 0xc00f, GENERIC_PRINT_AND_IGNORE);
397 #endif
398       //  v3_generic_add_port_range(generic, 0x378, 0x400, GENERIC_PRINT_AND_IGNORE);
399       
400
401       return generic;
402
403 }