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.


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