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.


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