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 configuration fixes
[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 #include <palacios/vmm_msr.h>
24 #include <palacios/vmm_decoder.h>
25 #include <palacios/vmm_profiler.h>
26 #include <palacios/vmm_mem.h>
27 #include <palacios/vmm_hypercall.h>
28 #include <palacios/vmm_dev_mgr.h>
29
30
31 #include <devices/generic.h>
32 #include <devices/ide.h>
33 #include <devices/ram_cd.h>
34 #include <devices/net_cd.h>
35 #include <devices/ram_hd.h>
36 #include <devices/net_hd.h>
37
38
39 #include <palacios/vmm_host_events.h>
40
41 #define USE_GENERIC 1
42
43
44 #include <palacios/vmm_socket.h>
45
46
47 static int setup_memory_map(struct guest_info * info, struct v3_vm_config * config_ptr);
48 static int setup_devices(struct guest_info * info, struct v3_vm_config * config_ptr);
49 static int configure_generic(struct guest_info * info, struct v3_vm_config * config_ptr);
50
51
52
53
54 static int passthrough_mem_write(addr_t guest_addr, void * src, uint_t length, void * priv_data) {
55
56     return length;
57     //  memcpy((void*)guest_addr, src, length);
58     PrintDebug("Write of %d bytes to %p\n", length, (void *)guest_addr);
59     PrintDebug("Write Value = %p\n", (void *)*(addr_t *)src);
60     
61     return length;
62 }
63
64
65 int v3_pre_config_guest(struct guest_info * info, struct v3_vm_config * config_ptr) {
66    extern v3_cpu_arch_t v3_cpu_type;
67
68     // Amount of ram the Guest will have, rounded to a 4K page boundary
69     info->mem_size = config_ptr->mem_size & ~(addr_t)0xfff;
70
71
72     // Initialize the subsystem data strutures
73     v3_init_time(info);
74     v3_init_io_map(info);
75     v3_init_msr_map(info);
76     v3_init_interrupt_state(info);
77     v3_init_exception_state(info);
78     v3_init_dev_mgr(info);
79     v3_init_host_events(info);
80
81
82     v3_init_decoder(info);
83     
84     v3_init_hypercall_map(info);
85
86
87     // Initialize the memory map
88     v3_init_shadow_map(info);
89     
90     if ((v3_cpu_type == V3_SVM_REV3_CPU) && 
91         (config_ptr->enable_nested_paging == 1)) {
92         PrintDebug("Guest Page Mode: NESTED_PAGING\n");
93         info->shdw_pg_mode = NESTED_PAGING;
94     } else {
95         PrintDebug("Guest Page Mode: SHADOW_PAGING\n");
96         v3_init_shadow_page_state(info);
97         info->shdw_pg_mode = SHADOW_PAGING;
98     }
99
100 #ifdef CONFIG_PROFILE_VMM
101     if (config_ptr->enable_profiling) {
102         info->enable_profiler = 1;
103         v3_init_profiler(info);
104     } else {
105         info->enable_profiler = 0;
106     }
107 #endif
108
109     if (config_ptr->schedule_freq == 0) {
110         // set the schedule frequency to 100 HZ
111         config_ptr->schedule_freq = 100;
112     }
113
114     PrintDebug("CPU_KHZ = %d, schedule_freq=%p\n", V3_CPU_KHZ(), (void *)config_ptr->schedule_freq);
115
116     info->yield_cycle_period = (V3_CPU_KHZ() * 1000) / config_ptr->schedule_freq;
117     
118     // Initial CPU operating mode
119     info->cpu_mode = REAL;
120     info->mem_mode = PHYSICAL_MEM;
121
122     return 0;
123 }
124
125
126 int v3_post_config_guest(struct guest_info * info, struct v3_vm_config * config_ptr) {
127
128     // Configure the memory map for the guest
129     if (setup_memory_map(info, config_ptr) == -1) {
130         PrintError("Setting up guest memory map failed...\n");
131         return -1;
132     }
133     
134     //v3_hook_io_port(info, 1234, &IO_Read, NULL, info);
135   
136     if (setup_devices(info, config_ptr) == -1) {
137         PrintError("Failed to setup devices\n");
138         return -1;
139     }
140
141     info->run_state = VM_STOPPED;
142
143     info->vm_regs.rdi = 0;
144     info->vm_regs.rsi = 0;
145     info->vm_regs.rbp = 0;
146     info->vm_regs.rsp = 0;
147     info->vm_regs.rbx = 0;
148     info->vm_regs.rdx = 0;
149     info->vm_regs.rcx = 0;
150     info->vm_regs.rax = 0;
151
152     return 0;
153 }
154
155
156
157
158
159 /* TODO:
160  * The amount of guest memory is stored in info->mem_size
161  * We need to make sure the memory map extends to cover it
162  */
163 static int setup_memory_map(struct guest_info * info, struct v3_vm_config * config_ptr) {
164     PrintDebug("Setting up memory map (memory size=%dMB)\n", (uint_t)(info->mem_size / (1024 * 1024)));
165     
166     // VGA frame buffer
167     if (1) {
168         if (v3_add_shadow_mem(info, 0xa0000, 0xc0000, 0xa0000) == -1) {
169             PrintError("Could not map VGA framebuffer\n");
170             return -1;
171         }
172     } else {
173         v3_hook_write_mem(info, 0xa0000, 0xc0000, 0xa0000,  passthrough_mem_write, NULL);
174     }
175
176 #define VGABIOS_START 0x000c0000
177 #define ROMBIOS_START 0x000f0000
178
179     /* layout vgabios */
180     {
181         extern uint8_t v3_vgabios_start[];
182         extern uint8_t v3_vgabios_end[];
183
184         addr_t vgabios_dst = v3_get_shadow_addr(&(info->mem_map.base_region), VGABIOS_START);
185         memcpy(V3_VAddr((void *)vgabios_dst), v3_vgabios_start, v3_vgabios_end - v3_vgabios_start);     
186     }
187     
188     /* layout rombios */
189     {
190         extern uint8_t v3_rombios_start[];
191         extern uint8_t v3_rombios_end[];
192
193         addr_t rombios_dst = v3_get_shadow_addr(&(info->mem_map.base_region), ROMBIOS_START);
194         memcpy(V3_VAddr((void *)rombios_dst), v3_rombios_start, v3_rombios_end - v3_rombios_start);
195     }
196
197 #ifdef CONFIG_CRAY_XT
198     {
199 #define SEASTAR_START 0xffe00000 
200 #define SEASTAR_END 0xffffffff 
201         // Map the Seastar straight through
202         if (v3_add_shadow_mem(info, SEASTAR_START, SEASTAR_END, SEASTAR_START) == -1) {
203             PrintError("Could not map through the seastar\n");
204             return -1;
205         }
206     }
207 #endif
208
209     print_shadow_map(info);
210
211     return 0;
212 }
213
214
215
216 static int setup_devices(struct guest_info * info, struct v3_vm_config * config_ptr) {
217
218     v3_create_device(info, "8259A", NULL);
219     v3_create_device(info, "KEYBOARD", NULL);
220     v3_create_device(info, "8254_PIT", NULL); 
221     v3_create_device(info, "BOCHS_DEBUG", NULL);
222     v3_create_device(info, "OS_DEBUG", NULL);
223     v3_create_device(info, "LAPIC", NULL);
224     v3_create_device(info, "IOAPIC", "LAPIC");
225     v3_create_device(info, "VMNET", NULL);
226     
227     int use_generic = USE_GENERIC;
228
229     if (config_ptr->enable_pci == 1) {
230         struct ide_cfg ide_config = {"PCI", "PIIX3"};
231         
232         v3_create_device(info, "PCI", NULL);
233         v3_create_device(info, "i440FX", "PCI");
234         v3_create_device(info, "PIIX3", "PCI");
235         
236
237         v3_create_device(info, "LNX_VIRTIO_SYM", "PCI");
238         v3_create_device(info, "LNX_VIRTIO_BLK", "PCI");
239         v3_create_device(info, "LNX_VIRTIO_BALLOON", "PCI");
240         v3_create_device(info, "SYM_SWAP", "LNX_VIRTIO_BLK");
241
242
243         v3_create_device(info, "IDE", &ide_config);
244     } else {
245         v3_create_device(info, "IDE", NULL);
246     }
247
248
249     if (config_ptr->pri_disk_type != NONE) {
250         if (config_ptr->pri_disk_type == CDROM) {
251             if (config_ptr->pri_disk_con == RAM) {
252                 struct ram_cd_cfg cfg = {"IDE", 0, 0, 
253                                          (addr_t)(config_ptr->pri_disk_info.ram.data_ptr), 
254                                          config_ptr->pri_disk_info.ram.size};
255
256                 PrintDebug("Creating RAM CD\n");
257
258                 v3_create_device(info, "RAM-CD", &cfg);
259             } else if (config_ptr->pri_disk_con == NETWORK) {
260                 struct net_cd_cfg cfg = {"IDE", 0, 0, 
261                                          config_ptr->pri_disk_info.net.ip_str,
262                                          config_ptr->pri_disk_info.net.port, 
263                                          config_ptr->pri_disk_info.net.disk_name};
264                 PrintDebug("Creating NET CD\n");
265
266                 v3_create_device(info, "NET-CD", &cfg);
267             }
268         } else if (config_ptr->pri_disk_type == HARDDRIVE) {
269             if (config_ptr->pri_disk_con == RAM) {
270                 struct ram_hd_cfg cfg = {"IDE", 0, 0, 
271                                          (addr_t)(config_ptr->pri_disk_info.ram.data_ptr), 
272                                          config_ptr->pri_disk_info.ram.size};
273
274                 PrintDebug("Creating RAM HD\n");
275
276                 v3_create_device(info, "RAM-HD", &cfg);
277             } else if (config_ptr->pri_disk_con == NETWORK) {
278                 struct net_hd_cfg cfg  = {"IDE", 0, 0, 
279                                           config_ptr->pri_disk_info.net.ip_str,
280                                           config_ptr->pri_disk_info.net.port, 
281                                           config_ptr->pri_disk_info.net.disk_name};
282                 PrintDebug("Creating NET HD\n");
283                 v3_create_device(info, "NET-HD", &cfg);
284             }
285         }
286     }
287
288
289
290     if (config_ptr->sec_disk_type != NONE) {
291         if (config_ptr->sec_disk_type == CDROM) {
292             if (config_ptr->sec_disk_con == RAM) {
293                 struct ram_cd_cfg cfg = {"IDE", 0, 1, 
294                                          (addr_t)(config_ptr->sec_disk_info.ram.data_ptr), 
295                                          config_ptr->sec_disk_info.ram.size};
296
297                 PrintDebug("Creating RAM CD\n");
298                 v3_create_device(info, "RAM-CD", &cfg);
299             } else if (config_ptr->sec_disk_con == NETWORK) {
300                 struct net_cd_cfg cfg = {"IDE", 0, 1, 
301                                          config_ptr->sec_disk_info.net.ip_str,
302                                          config_ptr->sec_disk_info.net.port, 
303                                          config_ptr->sec_disk_info.net.disk_name};
304
305                 PrintDebug("Creating NET CD\n");
306                 v3_create_device(info, "NET-CD", &cfg);    
307             }
308         } else if (config_ptr->sec_disk_type == HARDDRIVE) {
309             if (config_ptr->sec_disk_con == RAM) {
310                 struct ram_hd_cfg cfg = {"IDE", 0, 1, 
311                                          (addr_t)(config_ptr->sec_disk_info.ram.data_ptr), 
312                                          config_ptr->sec_disk_info.ram.size};
313                 PrintDebug("Creating RAM HD\n");
314                 v3_create_device(info, "RAM-HD", &cfg);
315             } else if (config_ptr->sec_disk_con == NETWORK) {
316                 struct net_hd_cfg cfg = {"IDE", 0, 1, 
317                                          config_ptr->sec_disk_info.net.ip_str,
318                                          config_ptr->sec_disk_info.net.port, 
319                                          config_ptr->sec_disk_info.net.disk_name};
320                 PrintDebug("Creating NET HD\n");
321                 v3_create_device(info, "NET-HD", &cfg);
322             }
323         }
324     }
325
326
327
328     if (use_generic) {
329         configure_generic(info, config_ptr);
330     }
331
332     // This should go last because it requires information about the Harddrives
333     v3_create_device(info, "NVRAM", "IDE");
334     
335     PrintDebugDevMgr(info);
336
337     return 0;
338 }
339
340
341
342
343 static int configure_generic(struct guest_info * info, struct v3_vm_config * config_ptr) {
344     PrintDebug("Creating Generic Device\n");
345     v3_create_device(info, "GENERIC", NULL);
346     
347
348     struct vm_device * generic = v3_find_dev(info, "GENERIC");
349
350     if (!generic) {
351         PrintError("Could not find generic device\n");
352         return -1;
353     }
354
355     // port 0x92: A20 enable/disable (bit 2) (This causes an MMU flush)
356
357
358     // Make the DMA controller invisible
359     v3_generic_add_port_range(generic, 0x00, 0x07, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channels 0,1,2,3 (address, counter)
360     v3_generic_add_port_range(generic, 0xc0, 0xc7, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channels 4,5,6,7 (address, counter)
361     v3_generic_add_port_range(generic, 0x87, 0x87, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 0 page register
362     v3_generic_add_port_range(generic, 0x83, 0x83, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 1 page register
363     v3_generic_add_port_range(generic, 0x81, 0x81, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 2 page register
364     v3_generic_add_port_range(generic, 0x82, 0x82, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 3 page register
365     v3_generic_add_port_range(generic, 0x8f, 0x8f, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 4 page register
366     v3_generic_add_port_range(generic, 0x8b, 0x8b, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 5 page register
367     v3_generic_add_port_range(generic, 0x89, 0x89, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 6 page register
368     v3_generic_add_port_range(generic, 0x8a, 0x8a, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 7 page register
369     v3_generic_add_port_range(generic, 0x08, 0x0f, GENERIC_PRINT_AND_IGNORE);   // DMA 1 misc registers (csr, req, smask,mode,clearff,reset,enable,mmask)
370     v3_generic_add_port_range(generic, 0xd0, 0xde, GENERIC_PRINT_AND_IGNORE);   // DMA 2 misc registers
371     
372     
373     
374     
375     // Make the Serial ports invisible 
376     
377     v3_generic_add_port_range(generic, 0x3f8, 0x3f8+7, GENERIC_PRINT_AND_IGNORE);      // COM 1
378     v3_generic_add_port_range(generic, 0x2f8, 0x2f8+7, GENERIC_PRINT_AND_IGNORE);      // COM 2
379     
380
381       
382
383     v3_generic_add_port_range(generic, 0x3e8, 0x3e8+7, GENERIC_PRINT_AND_IGNORE);      // COM 3
384     v3_generic_add_port_range(generic, 0x2e8, 0x2e8+7, GENERIC_PRINT_AND_IGNORE);      // COM 4
385
386       
387       
388
389     // Make the PCI bus invisible (at least it's configuration)
390     
391     //v3_generic_add_port_range(generic, 0xcf8, 0xcf8, GENERIC_PRINT_AND_IGNORE); // PCI Config Address
392     //v3_generic_add_port_range(generic, 0xcfc, 0xcfc, GENERIC_PRINT_AND_IGNORE); // PCI Config Data
393     
394     
395     
396 #if 0
397     if (!use_ramdisk) {
398         // Monitor the IDE controllers (very slow)
399         v3_generic_add_port_range(generic, 0x170, 0x178, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 1
400         v3_generic_add_port_range(generic, 0x376, 0x377, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 1
401     }
402       
403
404     v3_generic_add_port_range(generic, 0x1f0, 0x1f8, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 0
405     v3_generic_add_port_range(generic, 0x3f6, 0x3f7, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 0
406 #endif
407       
408       
409 #if 0
410     
411     // Make the floppy controllers invisible
412     
413     v3_generic_add_port_range(generic, 0x3f0, 0x3f2, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (base,statusa/statusb,DOR)
414     v3_generic_add_port_range(generic, 0x3f4, 0x3f5, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (mainstat/datarate,data)
415     v3_generic_add_port_range(generic, 0x3f7, 0x3f7, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (DIR)
416     v3_generic_add_port_range(generic, 0x370, 0x372, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (base,statusa/statusb,DOR)
417     v3_generic_add_port_range(generic, 0x374, 0x375, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (mainstat/datarate,data)
418     v3_generic_add_port_range(generic, 0x377, 0x377, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (DIR)
419     
420 #endif
421
422 #if 1
423
424     // Make the parallel port invisible
425       
426     v3_generic_add_port_range(generic, 0x378, 0x37f, GENERIC_PRINT_AND_IGNORE);
427
428 #endif
429
430 #if 1
431
432     // Monitor graphics card operations
433     
434     v3_generic_add_port_range(generic, 0x3b0, 0x3bb, GENERIC_PRINT_AND_PASSTHROUGH);
435     v3_generic_add_port_range(generic, 0x3c0, 0x3df, GENERIC_PRINT_AND_PASSTHROUGH);
436       
437 #endif
438
439
440 #if 1
441     // Make the ISA PNP features invisible
442     
443     v3_generic_add_port_range(generic, 0x274, 0x277, GENERIC_PRINT_AND_IGNORE);
444     v3_generic_add_port_range(generic, 0x279, 0x279, GENERIC_PRINT_AND_IGNORE);
445     v3_generic_add_port_range(generic, 0xa79, 0xa79, GENERIC_PRINT_AND_IGNORE);
446 #endif
447
448
449 #if 1
450     // Monitor any network card (realtek ne2000) operations 
451     v3_generic_add_port_range(generic, 0xc100, 0xc1ff, GENERIC_PRINT_AND_PASSTHROUGH);
452 #endif
453
454     //  v3_generic_add_port_range(generic, 0x378, 0x400, GENERIC_PRINT_AND_IGNORE);
455     
456     return 0;
457 }