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.


Merge branch 'devel'
[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 #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_interrupt_state(info);
94   
95   v3_init_dev_mgr(info);
96
97   v3_init_emulator(info);
98   
99   v3_init_host_events(info);
100
101  
102
103   /* layout rombios */
104   {
105     uint_t num_pages = (config_ptr->rombios_size + PAGE_SIZE - 1) / PAGE_SIZE;
106     void * guest_mem =  V3_AllocPages(num_pages);
107
108     PrintDebug("Layout Region %d bytes\n", config_ptr->rombios_size);
109     memcpy(V3_VAddr(guest_mem), config_ptr->rombios, config_ptr->rombios_size);
110
111     add_shadow_region_passthrough(info, ROMBIOS_START, ROMBIOS_START + (num_pages * PAGE_SIZE), (addr_t)guest_mem);
112     
113     PrintDebug("Adding Shadow Region (0x%p-0x%p) -> 0x%p\n", 
114                (void *)ROMBIOS_START, 
115                (void *)ROMBIOS_START + (num_pages * PAGE_SIZE), 
116                (void *)guest_mem);
117   }
118
119
120   /* layout vgabios */
121   {
122     uint_t num_pages = (config_ptr->vgabios_size + PAGE_SIZE - 1) / PAGE_SIZE;
123     void * guest_mem =  V3_AllocPages(num_pages);
124
125     PrintDebug("Layout Region %d bytes\n", config_ptr->vgabios_size);
126     memcpy(V3_VAddr(guest_mem), config_ptr->vgabios, config_ptr->vgabios_size);
127
128     add_shadow_region_passthrough(info, VGABIOS_START, VGABIOS_START + (num_pages * PAGE_SIZE), (addr_t)guest_mem);
129     
130     PrintDebug("Adding Shadow Region (0x%p-0x%p) -> 0x%p\n", 
131                (void *)VGABIOS_START, 
132                (void *)VGABIOS_START + (num_pages * PAGE_SIZE), 
133                (void *)guest_mem);
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     struct vm_device * ramdisk = NULL;
178     struct vm_device * cdrom = NULL;
179     struct vm_device * nvram = v3_create_nvram();
180     //struct vm_device * timer = v3_create_timer();
181     struct vm_device * pic = v3_create_pic();
182     struct vm_device * keyboard = v3_create_keyboard();
183     struct vm_device * pit = v3_create_pit(); 
184     struct vm_device * bochs_debug = v3_create_bochs_debug();
185
186     //struct vm_device * serial = v3_create_serial();
187     struct vm_device * generic = NULL;
188
189
190
191
192     if (use_ramdisk) {
193       PrintDebug("Creating Ramdisk\n");
194       ramdisk = v3_create_ramdisk();
195       cdrom = v3_create_cdrom(ramdisk, config_ptr->ramdisk, config_ptr->ramdisk_size); 
196     }
197     
198     
199     if (use_generic) {
200       PrintDebug("Creating Generic Device\n");
201       generic = v3_create_generic();
202       
203       // Make the DMA controller invisible
204       v3_generic_add_port_range(generic, 0x00, 0x07, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channels 0,1,2,3 (address, counter)
205       v3_generic_add_port_range(generic, 0xc0, 0xc7, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channels 4,5,6,7 (address, counter)
206       v3_generic_add_port_range(generic, 0x87, 0x87, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 0 page register
207       v3_generic_add_port_range(generic, 0x83, 0x83, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 1 page register
208       v3_generic_add_port_range(generic, 0x81, 0x81, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 2 page register
209       v3_generic_add_port_range(generic, 0x82, 0x82, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 3 page register
210       v3_generic_add_port_range(generic, 0x8f, 0x8f, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 4 page register
211       v3_generic_add_port_range(generic, 0x8b, 0x8b, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 5 page register
212       v3_generic_add_port_range(generic, 0x89, 0x89, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 6 page register
213       v3_generic_add_port_range(generic, 0x8a, 0x8a, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 7 page register
214       v3_generic_add_port_range(generic, 0x08, 0x0f, GENERIC_PRINT_AND_IGNORE);   // DMA 1 misc registers (csr, req, smask,mode,clearff,reset,enable,mmask)
215       v3_generic_add_port_range(generic, 0xd0, 0xde, GENERIC_PRINT_AND_IGNORE);   // DMA 2 misc registers
216       
217       
218       
219       
220       // Make the Serial ports invisible 
221       
222       v3_generic_add_port_range(generic, 0x3f8, 0x3f8+7, GENERIC_PRINT_AND_IGNORE);      // COM 1
223       v3_generic_add_port_range(generic, 0x2f8, 0x2f8+7, GENERIC_PRINT_AND_IGNORE);      // COM 2
224       
225
226       
227
228       v3_generic_add_port_range(generic, 0x3e8, 0x3e8+7, GENERIC_PRINT_AND_IGNORE);      // COM 3
229       v3_generic_add_port_range(generic, 0x2e8, 0x2e8+7, GENERIC_PRINT_AND_IGNORE);      // COM 4
230
231       
232       
233
234       // Make the PCI bus invisible (at least it's configuration)
235       
236       v3_generic_add_port_range(generic, 0xcf8, 0xcf8, GENERIC_PRINT_AND_IGNORE); // PCI Config Address
237       v3_generic_add_port_range(generic, 0xcfc, 0xcfc, GENERIC_PRINT_AND_IGNORE); // PCI Config Data
238
239       
240       
241 #if 0
242       if (!use_ramdisk) {
243         // Monitor the IDE controllers (very slow)
244         v3_generic_add_port_range(generic, 0x170, 0x178, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 1
245         v3_generic_add_port_range(generic, 0x376, 0x377, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 1
246       }
247       
248
249       v3_generic_add_port_range(generic, 0x1f0, 0x1f8, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 0
250       v3_generic_add_port_range(generic, 0x3f6, 0x3f7, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 0
251 #endif
252       
253       
254 #if 0
255       
256       // Make the floppy controllers invisible
257       
258       v3_generic_add_port_range(generic, 0x3f0, 0x3f2, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (base,statusa/statusb,DOR)
259       v3_generic_add_port_range(generic, 0x3f4, 0x3f5, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (mainstat/datarate,data)
260       v3_generic_add_port_range(generic, 0x3f7, 0x3f7, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (DIR)
261       v3_generic_add_port_range(generic, 0x370, 0x372, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (base,statusa/statusb,DOR)
262       v3_generic_add_port_range(generic, 0x374, 0x375, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (mainstat/datarate,data)
263       v3_generic_add_port_range(generic, 0x377, 0x377, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (DIR)
264       
265 #endif
266
267 #if 1
268
269       // Make the parallel port invisible
270       
271       v3_generic_add_port_range(generic, 0x378, 0x37f, GENERIC_PRINT_AND_IGNORE);
272
273 #endif
274
275 #if 1
276
277       // Monitor graphics card operations
278
279       v3_generic_add_port_range(generic, 0x3b0, 0x3bb, GENERIC_PRINT_AND_PASSTHROUGH);
280       v3_generic_add_port_range(generic, 0x3c0, 0x3df, GENERIC_PRINT_AND_PASSTHROUGH);
281       
282 #endif
283
284
285 #if 1
286       // Make the ISA PNP features invisible
287
288       v3_generic_add_port_range(generic, 0x274, 0x277, GENERIC_PRINT_AND_IGNORE);
289       v3_generic_add_port_range(generic, 0x279, 0x279, GENERIC_PRINT_AND_IGNORE);
290       v3_generic_add_port_range(generic, 0xa79, 0xa79, GENERIC_PRINT_AND_IGNORE);
291 #endif
292
293
294 #if 1
295       // Monitor any network card (realtek ne2000) operations 
296       v3_generic_add_port_range(generic, 0xc100, 0xc1ff, GENERIC_PRINT_AND_PASSTHROUGH);
297 #endif
298
299
300 #if 1
301       // Make any Bus master ide controller invisible
302       
303       v3_generic_add_port_range(generic, 0xc000, 0xc00f, GENERIC_PRINT_AND_IGNORE);
304 #endif
305       
306     }
307       //  v3_generic_add_port_range(generic, 0x378, 0x400, GENERIC_PRINT_AND_IGNORE);
308       
309
310
311     
312
313     v3_attach_device(info, nvram);
314     //v3_attach_device(info, timer);
315     v3_attach_device(info, pic);
316     v3_attach_device(info, pit);
317     v3_attach_device(info, keyboard);
318     // v3_attach_device(info, serial);
319     v3_attach_device(info, bochs_debug);
320
321     if (use_ramdisk) {
322       v3_attach_device(info, ramdisk);
323       v3_attach_device(info, cdrom);
324     }
325
326     if (use_generic) {
327       // Important that this be attached last!
328       v3_attach_device(info, generic);
329     }
330     
331     PrintDebugDevMgr(info);
332   }
333   
334   // give keyboard interrupts to vm
335   // no longer needed since we have a keyboard device
336   //hook_irq(&vm_info, 1);
337   
338 #if 0
339   // give floppy controller to vm
340   v3_hook_passthrough_irq(info, 6);
341 #endif
342   
343
344   if (!use_ramdisk) {
345     PrintDebug("Hooking IDE IRQs\n");
346
347     //primary ide
348     v3_hook_passthrough_irq(info, 14);
349   
350     // secondary ide
351     v3_hook_passthrough_irq(info, 15);    
352   }  
353
354   //v3_hook_io_port(info, 1234, &IO_Read, NULL, info);
355
356   info->rip = 0xfff0;
357   info->vm_regs.rsp = 0x0;
358   
359
360   return 0;
361 }