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.


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