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.


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