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.


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