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 new copyright and license
[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
21 #include <palacios/vmm_config.h>
22 #include <palacios/vmm.h>
23 #include <palacios/vmm_debug.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
33
34
35 static int mem_test_read(addr_t guest_addr, void * dst, uint_t length, void * priv_data) {
36   int foo = 20;
37
38
39   memcpy(dst, &foo, length);
40
41   PrintDebug("Passthrough mem read returning: %d (length=%d)\n", foo + (guest_addr & 0xfff), length);
42   return length;
43 }
44
45 static int passthrough_mem_read(addr_t guest_addr, void * dst, uint_t length, void * priv_data) {
46     memcpy(dst, (void*)guest_addr, length);
47     return length;
48 }
49
50 static int passthrough_mem_write(addr_t guest_addr, void * src, uint_t length, void * priv_data) {
51   memcpy((void*)guest_addr, src, length);
52   return length;
53 }
54
55
56 /*static int IO_Read(ushort_t port, void * dst, uint_t length, void * priv_data) {
57
58   struct guest_info * info = priv_data;
59   ulong_t tsc_spread = 0;
60   ullong_t exit_tsc = 0;
61
62   
63   *(ulong_t *)(&exit_tsc) = info->vm_regs.rbx;
64   *(ulong_t *)((&exit_tsc) + 4) = info->vm_regs.rcx; 
65   tsc_spread = info->exit_tsc - exit_tsc;
66   
67   PrintError("IOREAD tsc diff = %lu\n",tsc_spread); 
68   info->rip += 3;
69
70
71   return 1;
72 }
73 */
74
75 int config_guest(struct guest_info * info, void * config_ptr) {
76
77   struct guest_mem_layout * layout = (struct guest_mem_layout *)config_ptr;
78   extern v3_cpu_arch_t v3_cpu_type;
79   void * region_start;
80   int i;
81
82   
83   v3_init_time(info);
84   init_shadow_map(info);
85   
86   if (v3_cpu_type == V3_SVM_REV3_CPU) {
87     info->shdw_pg_mode = NESTED_PAGING;
88   } else {
89     init_shadow_page_state(info);
90     info->shdw_pg_mode = SHADOW_PAGING;
91   }
92   
93   info->cpu_mode = REAL;
94   info->mem_mode = PHYSICAL_MEM;
95   
96  
97   init_vmm_io_map(info);
98   init_interrupt_state(info);
99   
100   dev_mgr_init(info);
101
102   init_emulator(info);
103   
104  
105   //     SerialPrint("Guest Mem Dump at 0x%x\n", 0x100000);
106   //PrintDebugMemDump((unsigned char *)(0x100000), 261 * 1024);
107   if (layout->magic != MAGIC_CODE) {
108     
109     PrintDebug("Layout Magic Mismatch (0x%x)\n", layout->magic);
110     return -1;
111   }
112   
113   PrintDebug("%d layout regions\n", layout->num_regions);
114   
115   region_start = (void *)&(layout->regions[layout->num_regions]);
116   
117   PrintDebug("region start = 0x%x\n", region_start);
118   
119   for (i = 0; i < layout->num_regions; i++) {
120     struct layout_region * reg = &(layout->regions[i]);
121     uint_t num_pages = (reg->length / PAGE_SIZE) + ((reg->length % PAGE_SIZE) ? 1 : 0);
122     void * guest_mem = V3_AllocPages(num_pages);
123     
124     PrintDebug("Layout Region %d bytes\n", reg->length);
125     memcpy(guest_mem, region_start, reg->length);
126     
127     PrintDebugMemDump((unsigned char *)(guest_mem), 16);
128     
129     add_shadow_region_passthrough(info, reg->final_addr, reg->final_addr + (num_pages * PAGE_SIZE), (addr_t)guest_mem);
130     
131     PrintDebug("Adding Shadow Region (0x%x-0x%x) -> 0x%x\n", reg->final_addr, reg->final_addr + (num_pages * PAGE_SIZE), guest_mem);
132     
133     region_start += reg->length;
134   }
135   
136       //     
137   add_shadow_region_passthrough(info, 0x0, 0xa0000, (addr_t)V3_AllocPages(160));
138   
139   if (1) {
140     add_shadow_region_passthrough(info, 0xa0000, 0xc0000, 0xa0000); 
141   } else {
142     hook_guest_mem(info, 0xa0000, 0xc0000, passthrough_mem_read, passthrough_mem_write, NULL);
143   }  
144   
145   // TEMP
146   //add_shadow_region_passthrough(info, 0xc0000, 0xc8000, 0xc0000);
147   
148   if (1) {
149     add_shadow_region_passthrough(info, 0xc7000, 0xc8000, (addr_t)V3_AllocPages(1));
150     if (add_shadow_region_passthrough(info, 0xc8000, 0xf0000, (addr_t)V3_AllocPages(40)) == -1) {
151       PrintDebug("Error adding shadow region\n");
152     }
153   } else {
154     add_shadow_region_passthrough(info, 0xc0000, 0xc8000, 0xc0000);
155     add_shadow_region_passthrough(info, 0xc8000, 0xf0000, 0xc8000);
156   }
157   
158   
159   if (1) {
160   add_shadow_region_passthrough(info, 0x100000, 0x1000000, (addr_t)V3_AllocPages(4096));
161   } else {
162     /* MEMORY HOOK TEST */
163     add_shadow_region_passthrough(info, 0x100000, 0xa00000, (addr_t)V3_AllocPages(2304));
164     hook_guest_mem(info, 0xa00000, 0xa01000, mem_test_read, passthrough_mem_write, NULL); 
165     add_shadow_region_passthrough(info, 0xa01000, 0x1000000, (addr_t)V3_AllocPages(1791));
166   }
167
168     add_shadow_region_passthrough(info, 0x1000000, 0x8000000, (addr_t)V3_AllocPages(32768));
169  
170   // test - give linux accesss to PCI space - PAD
171   add_shadow_region_passthrough(info, 0xc0000000,0xffffffff,0xc0000000);
172   
173   
174   print_shadow_map(&(info->mem_map));
175
176   
177   {
178     
179     struct vm_device * nvram = create_nvram();
180     //struct vm_device * timer = create_timer();
181     struct vm_device * pic = create_pic();
182     struct vm_device * keyboard = create_keyboard();
183     struct vm_device * pit = create_pit(); 
184     //struct vm_device * serial = create_serial();
185     
186     
187 #define GENERIC 1
188     
189 #if GENERIC
190     generic_port_range_type range[] = {
191 #if 1
192       // Make the DMA controller invisible
193
194       {0x00, 0x07, GENERIC_PRINT_AND_IGNORE},   // DMA 1 channels 0,1,2,3 (address, counter)
195       {0xc0, 0xc7, GENERIC_PRINT_AND_IGNORE},   // DMA 2 channels 4,5,6,7 (address, counter)
196       {0x87, 0x87, GENERIC_PRINT_AND_IGNORE},   // DMA 1 channel 0 page register
197       {0x83, 0x83, GENERIC_PRINT_AND_IGNORE},   // DMA 1 channel 1 page register
198       {0x81, 0x81, GENERIC_PRINT_AND_IGNORE},   // DMA 1 channel 2 page register
199       {0x82, 0x82, GENERIC_PRINT_AND_IGNORE},   // DMA 1 channel 3 page register
200       {0x8f, 0x8f, GENERIC_PRINT_AND_IGNORE},   // DMA 2 channel 4 page register
201       {0x8b, 0x8b, GENERIC_PRINT_AND_IGNORE},   // DMA 2 channel 5 page register
202       {0x89, 0x89, GENERIC_PRINT_AND_IGNORE},   // DMA 2 channel 6 page register
203       {0x8a, 0x8a, GENERIC_PRINT_AND_IGNORE},   // DMA 2 channel 7 page register
204       {0x08, 0x0f, GENERIC_PRINT_AND_IGNORE},   // DMA 1 misc registers (csr, req, smask,mode,clearff,reset,enable,mmask)
205       {0xd0, 0xde, GENERIC_PRINT_AND_IGNORE},   // DMA 2 misc registers
206 #endif
207       
208
209 #if 1      
210       // Make the Serial ports invisible 
211
212       {0x3f8, 0x3f8+7, GENERIC_PRINT_AND_IGNORE},      // COM 1
213       {0x2f8, 0x2f8+7, GENERIC_PRINT_AND_IGNORE},      // COM 2
214       {0x3e8, 0x3e8+7, GENERIC_PRINT_AND_IGNORE},      // COM 3
215       {0x2e8, 0x2e8+7, GENERIC_PRINT_AND_IGNORE},      // COM 4
216 #endif
217
218
219 #if 1
220       // Make the PCI bus invisible (at least it's configuration)
221
222       {0xcf8, 0xcf8, GENERIC_PRINT_AND_IGNORE}, // PCI Config Address
223       {0xcfc, 0xcfc, GENERIC_PRINT_AND_IGNORE}, // PCI Config Data
224 #endif
225  
226 #if 1
227
228       // Monitor the IDE controllers (very slow)
229
230       {0x170, 0x178, GENERIC_PRINT_AND_PASSTHROUGH}, // IDE 1
231       {0x376, 0x377, GENERIC_PRINT_AND_PASSTHROUGH}, // IDE 1
232       {0x1f0, 0x1f8, GENERIC_PRINT_AND_PASSTHROUGH}, // IDE 0
233       {0x3f6, 0x3f7, GENERIC_PRINT_AND_PASSTHROUGH}, // IDE 0
234 #endif
235       
236
237 #if 0
238
239       // Make the floppy controllers invisible
240
241       {0x3f0, 0x3f2, GENERIC_PRINT_AND_IGNORE}, // Primary floppy controller (base,statusa/statusb,DOR)
242       {0x3f4, 0x3f5, GENERIC_PRINT_AND_IGNORE}, // Primary floppy controller (mainstat/datarate,data)
243       {0x3f7, 0x3f7, GENERIC_PRINT_AND_IGNORE}, // Primary floppy controller (DIR)
244       {0x370, 0x372, GENERIC_PRINT_AND_IGNORE}, // Secondary floppy controller (base,statusa/statusb,DOR)
245       {0x374, 0x375, GENERIC_PRINT_AND_IGNORE}, // Secondary floppy controller (mainstat/datarate,data)
246       {0x377, 0x377, GENERIC_PRINT_AND_IGNORE}, // Secondary floppy controller (DIR)
247       
248 #endif
249
250 #if 1
251
252       // Make the parallel port invisible
253       
254       {0x378, 0x37f, GENERIC_PRINT_AND_IGNORE},
255
256 #endif
257
258 #if 1
259
260       // Monitor graphics card operations
261
262       {0x3b0, 0x3bb, GENERIC_PRINT_AND_PASSTHROUGH},
263       {0x3c0, 0x3df, GENERIC_PRINT_AND_PASSTHROUGH},
264       
265 #endif
266
267
268 #if 1
269       // Make the ISA PNP features invisible
270
271       {0x274, 0x277, GENERIC_PRINT_AND_IGNORE},
272       {0x279, 0x279, GENERIC_PRINT_AND_IGNORE},
273       {0xa79, 0xa79, GENERIC_PRINT_AND_IGNORE},
274 #endif
275
276
277 #if 1
278       // Monitor any network card (realtek ne2000) operations 
279       {0xc100, 0xc1ff, GENERIC_PRINT_AND_PASSTHROUGH},
280 #endif
281
282
283 #if 1
284       // Make any Bus master ide controller invisible
285       
286       {0xc000, 0xc00f, GENERIC_PRINT_AND_IGNORE},
287 #endif
288
289
290       //          {0x378, 0x400, GENERIC_PRINT_AND_IGNORE}
291       
292       {0,0,0},  // sentinal - must be last
293       
294     };
295     
296
297     struct vm_device * generic = create_generic(range, NULL, NULL);
298     
299 #endif
300     
301     v3_attach_device(info, nvram);
302     //v3_attach_device(info, timer);
303     v3_attach_device(info, pic);
304     v3_attach_device(info, pit);
305     v3_attach_device(info, keyboard);
306     // v3_attach_device(info, serial);
307
308
309 #if GENERIC
310     // Important that this be attached last!
311     v3_attach_device(info, generic);
312     
313 #endif
314     
315     PrintDebugDevMgr(info);
316   }
317   
318   // give keyboard interrupts to vm
319   // no longer needed since we have a keyboard device
320   //hook_irq(&vm_info, 1);
321   
322 #if 1
323   // give floppy controller to vm
324   v3_hook_irq_for_guest_injection(info, 6);
325 #endif
326   
327 #if 1
328   //primary ide
329   v3_hook_irq_for_guest_injection(info, 14);
330   
331   // secondary ide
332   v3_hook_irq_for_guest_injection(info, 15);
333 #endif
334   
335
336   //v3_hook_io_port(info, 1234, &IO_Read, NULL, info);
337
338   info->rip = 0xfff0;
339   info->vm_regs.rsp = 0x0;
340   
341
342   return 0;
343 }
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366 #if 0
367
368     
369     if (0) {
370       
371       //    add_shared_mem_range(&(vm_info.mem_layout), 0, 0x800000, 0x10000);    
372       //    add_shared_mem_range(&(vm_info.mem_layout), 0, 0x1000000, 0);
373       
374       rip = (ulong_t)(void*)&BuzzVM;
375       //  rip -= 0x10000;
376       //    rip = (addr_t)(void*)&exit_test;
377       //  rip -= 0x2000;
378       vm_info.rip = rip;
379       rsp = (addr_t)Alloc_Page();
380       
381       vm_info.vm_regs.rsp = (rsp +4092 );// - 0x2000;
382       
383             
384     } else if (0) {
385       //add_shared_mem_range(&(vm_info.mem_layout), 0x0, 0x1000, 0x100000);
386       //      add_shared_mem_range(&(vm_info.mem_layout), 0x0, 0x100000, 0x0);
387       
388       /*
389         shadow_region_t *ent = Malloc(sizeof(shadow_region_t));;
390         init_shadow_region_physical(ent,0,0x100000,GUEST_REGION_PHYSICAL_MEMORY,
391         0x100000, HOST_REGION_PHYSICAL_MEMORY);
392         add_shadow_region(&(vm_info.mem_map),ent);
393       */
394
395       add_shadow_region_passthrough(&vm_info, 0x0, 0x100000, 0x100000);
396
397       v3_hook_io_port(&vm_info, 0x61, &IO_Read, &IO_Write, NULL);
398       v3_hook_io_port(&vm_info, 0x05, &IO_Read, &IO_Write_to_Serial, NULL);
399       
400
401
402       /*
403         vm_info.cr0 = 0;
404         vm_info.cs.base=0xf000;
405         vm_info.cs.limit=0xffff;
406       */
407       //vm_info.rip = 0xfff0;
408
409       vm_info.rip = 0;
410       vm_info.vm_regs.rsp = 0x0;
411     } else {
412    
413     }
414
415 #endif