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.


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