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.


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