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.


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