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.


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