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.


Update to the device framework.
[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
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     if (config_ptr->enable_profiling) {
101         info->enable_profiler = 1;
102         v3_init_profiler(info);
103     } else {
104         info->enable_profiler = 0;
105     }
106
107     
108     // Initial CPU operating mode
109     info->cpu_mode = REAL;
110     info->mem_mode = PHYSICAL_MEM;
111
112     return 0;
113 }
114
115
116 int v3_post_config_guest(struct guest_info * info, struct v3_vm_config * config_ptr) {
117
118     // Configure the memory map for the guest
119     if (setup_memory_map(info, config_ptr) == -1) {
120         PrintError("Setting up guest memory map failed...\n");
121         return -1;
122     }
123     
124     //v3_hook_io_port(info, 1234, &IO_Read, NULL, info);
125   
126     if (setup_devices(info, config_ptr) == -1) {
127         PrintError("Failed to setup devices\n");
128         return -1;
129     }
130
131     info->run_state = VM_STOPPED;
132
133     info->vm_regs.rdi = 0;
134     info->vm_regs.rsi = 0;
135     info->vm_regs.rbp = 0;
136     info->vm_regs.rsp = 0;
137     info->vm_regs.rbx = 0;
138     info->vm_regs.rdx = 0;
139     info->vm_regs.rcx = 0;
140     info->vm_regs.rax = 0;
141
142     return 0;
143 }
144
145
146
147
148
149 /* TODO:
150  * The amount of guest memory is stored in info->mem_size
151  * We need to make sure the memory map extends to cover it
152  */
153 static int setup_memory_map(struct guest_info * info, struct v3_vm_config * config_ptr) {
154     PrintDebug("Setting up memory map (memory size=%dMB)\n", (uint_t)(info->mem_size / (1024 * 1024)));
155     
156     // VGA frame buffer
157     if (1) {
158         if (v3_add_shadow_mem(info, 0xa0000, 0xc0000, 0xa0000) == -1) {
159             PrintError("Could not map VGA framebuffer\n");
160             return -1;
161         }
162     } else {
163         v3_hook_write_mem(info, 0xa0000, 0xc0000, 0xa0000,  passthrough_mem_write, NULL);
164     }  
165
166 #define VGABIOS_START 0x000c0000
167 #define ROMBIOS_START 0x000f0000
168
169     /* layout vgabios */
170     {
171         addr_t vgabios_dst = v3_get_shadow_addr(&(info->mem_map.base_region), VGABIOS_START);
172         memcpy(V3_VAddr((void *)vgabios_dst), config_ptr->vgabios, config_ptr->vgabios_size);   
173     }
174     
175     /* layout rombios */
176     {
177         addr_t rombios_dst = v3_get_shadow_addr(&(info->mem_map.base_region), ROMBIOS_START);
178         memcpy(V3_VAddr((void *)rombios_dst), config_ptr->rombios, config_ptr->rombios_size);
179     }
180
181 #ifdef CRAY_XT
182     {
183 #define SEASTAR_START 0xffe00000 
184 #define SEASTAR_END 0xffffffff 
185         // Map the Seastar straight through
186         if (v3_add_shadow_mem(info, SEASTAR_START, SEASTAR_END, SEASTAR_START) == -1) {
187             PrintError("Could not map through the seastar\n");
188             return -1;
189         }
190     }
191 #endif    
192
193     print_shadow_map(info);
194
195     return 0;
196 }
197
198
199
200 static int setup_devices(struct guest_info * info, struct v3_vm_config * config_ptr) {
201
202
203     v3_create_device(info, "8259A", NULL);
204     v3_create_device(info, "KEYBOARD", NULL);
205     v3_create_device(info, "8254_PIT", NULL); 
206     v3_create_device(info, "BOCHS_DEBUG", NULL);
207     v3_create_device(info, "OS_DEBUG", NULL);
208     v3_create_device(info, "LAPIC", NULL);
209     v3_create_device(info, "IOAPIC", "LAPIC");
210     v3_create_device(info, "PARANET", NULL);
211     
212     int use_generic = USE_GENERIC;
213
214
215     if (config_ptr->enable_pci == 1) {
216         struct ide_cfg ide_config = {"PCI", "PIIX3"};   
217         
218         v3_create_device(info, "PCI", NULL);
219         v3_create_device(info, "i440FX", "PCI");
220         v3_create_device(info, "PIIX3", "PCI");
221         
222         v3_create_device(info, "IDE", &ide_config);
223     } else {
224         v3_create_device(info, "IDE", NULL);
225
226     }
227
228
229
230
231
232     if (config_ptr->pri_disk_type != NONE) {
233         if (config_ptr->pri_disk_type == CDROM) {
234             if (config_ptr->pri_disk_con == RAM) {
235                 struct ram_cd_cfg cfg = {"IDE", 0, 0, 
236                                          (addr_t)(config_ptr->pri_disk_info.ram.data_ptr), 
237                                          config_ptr->pri_disk_info.ram.size};
238
239                 PrintDebug("Creating RAM CD\n");
240
241                 v3_create_device(info, "RAM-CD", &cfg);
242             } else if (config_ptr->pri_disk_con == NETWORK) {
243                 struct net_cd_cfg cfg = {"IDE", 0, 0, 
244                                          config_ptr->pri_disk_info.net.ip_str,
245                                          config_ptr->pri_disk_info.net.port, 
246                                          config_ptr->pri_disk_info.net.disk_name};
247                 PrintDebug("Creating NET CD\n");
248
249                 v3_create_device(info, "NET-CD", &cfg);    
250             }
251         } else if (config_ptr->pri_disk_type == HARDDRIVE) {
252             if (config_ptr->pri_disk_con == RAM) {
253                 struct ram_hd_cfg cfg = {"IDE", 0, 0, 
254                                          (addr_t)(config_ptr->pri_disk_info.ram.data_ptr), 
255                                          config_ptr->pri_disk_info.ram.size};
256
257                 PrintDebug("Creating RAM HD\n");
258
259                 v3_create_device(info, "RAM-HD", &cfg);
260             } else if (config_ptr->pri_disk_con == NETWORK) {
261                 struct net_hd_cfg cfg  = {"IDE", 0, 0, 
262                                           config_ptr->pri_disk_info.net.ip_str,
263                                           config_ptr->pri_disk_info.net.port, 
264                                           config_ptr->pri_disk_info.net.disk_name};
265                 PrintDebug("Creating NET HD\n");
266                 v3_create_device(info, "NET-HD", &cfg);
267             }
268         }
269     }
270
271
272
273     if (config_ptr->sec_disk_type != NONE) {
274         if (config_ptr->sec_disk_type == CDROM) {
275             if (config_ptr->sec_disk_con == RAM) {
276                 struct ram_cd_cfg cfg = {"IDE", 0, 1, 
277                                          (addr_t)(config_ptr->sec_disk_info.ram.data_ptr), 
278                                          config_ptr->sec_disk_info.ram.size};
279
280                 PrintDebug("Creating RAM CD\n");
281                 v3_create_device(info, "RAM-CD", &cfg);
282             } else if (config_ptr->sec_disk_con == NETWORK) {
283                 struct net_cd_cfg cfg = {"IDE", 0, 1, 
284                                          config_ptr->sec_disk_info.net.ip_str,
285                                          config_ptr->sec_disk_info.net.port, 
286                                          config_ptr->sec_disk_info.net.disk_name};
287
288                 PrintDebug("Creating NET CD\n");
289                 v3_create_device(info, "NET-CD", &cfg);    
290             }
291         } else if (config_ptr->sec_disk_type == HARDDRIVE) {
292             if (config_ptr->sec_disk_con == RAM) {
293                 struct ram_hd_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                 PrintDebug("Creating RAM HD\n");
297                 v3_create_device(info, "RAM-HD", &cfg);
298             } else if (config_ptr->sec_disk_con == NETWORK) {
299                 struct net_hd_cfg cfg = {"IDE", 0, 1, 
300                                          config_ptr->sec_disk_info.net.ip_str,
301                                          config_ptr->sec_disk_info.net.port, 
302                                          config_ptr->sec_disk_info.net.disk_name};
303                 PrintDebug("Creating NET HD\n");
304                 v3_create_device(info, "NET-HD", &cfg);
305             }
306         }
307     }
308
309
310
311     if (use_generic) {
312         configure_generic(info, config_ptr);
313     }
314
315     // This should go last because it requires information about the Harddrives
316     v3_create_device(info, "NVRAM", "IDE");
317     
318     PrintDebugDevMgr(info);
319
320     return 0;
321 }
322
323
324
325
326 static int configure_generic(struct guest_info * info, struct v3_vm_config * config_ptr) {
327     PrintDebug("Creating Generic Device\n");
328     v3_create_device(info, "GENERIC", NULL);
329     
330
331     struct vm_device * generic = v3_find_dev(info, "GENERIC");
332
333     if (!generic) {
334         PrintError("Could not find generic device\n");
335         return -1;
336     }
337
338     // port 0x92: A20 enable/disable (bit 2) (This causes an MMU flush)
339
340
341     // Make the DMA controller invisible
342     v3_generic_add_port_range(generic, 0x00, 0x07, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channels 0,1,2,3 (address, counter)
343     v3_generic_add_port_range(generic, 0xc0, 0xc7, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channels 4,5,6,7 (address, counter)
344     v3_generic_add_port_range(generic, 0x87, 0x87, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 0 page register
345     v3_generic_add_port_range(generic, 0x83, 0x83, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 1 page register
346     v3_generic_add_port_range(generic, 0x81, 0x81, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 2 page register
347     v3_generic_add_port_range(generic, 0x82, 0x82, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 3 page register
348     v3_generic_add_port_range(generic, 0x8f, 0x8f, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 4 page register
349     v3_generic_add_port_range(generic, 0x8b, 0x8b, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 5 page register
350     v3_generic_add_port_range(generic, 0x89, 0x89, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 6 page register
351     v3_generic_add_port_range(generic, 0x8a, 0x8a, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 7 page register
352     v3_generic_add_port_range(generic, 0x08, 0x0f, GENERIC_PRINT_AND_IGNORE);   // DMA 1 misc registers (csr, req, smask,mode,clearff,reset,enable,mmask)
353     v3_generic_add_port_range(generic, 0xd0, 0xde, GENERIC_PRINT_AND_IGNORE);   // DMA 2 misc registers
354     
355     
356     
357     
358     // Make the Serial ports invisible 
359     
360     v3_generic_add_port_range(generic, 0x3f8, 0x3f8+7, GENERIC_PRINT_AND_IGNORE);      // COM 1
361     v3_generic_add_port_range(generic, 0x2f8, 0x2f8+7, GENERIC_PRINT_AND_IGNORE);      // COM 2
362     
363
364       
365
366     v3_generic_add_port_range(generic, 0x3e8, 0x3e8+7, GENERIC_PRINT_AND_IGNORE);      // COM 3
367     v3_generic_add_port_range(generic, 0x2e8, 0x2e8+7, GENERIC_PRINT_AND_IGNORE);      // COM 4
368
369       
370       
371
372     // Make the PCI bus invisible (at least it's configuration)
373     
374     //v3_generic_add_port_range(generic, 0xcf8, 0xcf8, GENERIC_PRINT_AND_IGNORE); // PCI Config Address
375     //v3_generic_add_port_range(generic, 0xcfc, 0xcfc, GENERIC_PRINT_AND_IGNORE); // PCI Config Data
376     
377     
378     
379 #if 0
380     if (!use_ramdisk) {
381         // Monitor the IDE controllers (very slow)
382         v3_generic_add_port_range(generic, 0x170, 0x178, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 1
383         v3_generic_add_port_range(generic, 0x376, 0x377, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 1
384     }
385       
386
387     v3_generic_add_port_range(generic, 0x1f0, 0x1f8, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 0
388     v3_generic_add_port_range(generic, 0x3f6, 0x3f7, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 0
389 #endif
390       
391       
392 #if 0
393     
394     // Make the floppy controllers invisible
395     
396     v3_generic_add_port_range(generic, 0x3f0, 0x3f2, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (base,statusa/statusb,DOR)
397     v3_generic_add_port_range(generic, 0x3f4, 0x3f5, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (mainstat/datarate,data)
398     v3_generic_add_port_range(generic, 0x3f7, 0x3f7, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (DIR)
399     v3_generic_add_port_range(generic, 0x370, 0x372, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (base,statusa/statusb,DOR)
400     v3_generic_add_port_range(generic, 0x374, 0x375, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (mainstat/datarate,data)
401     v3_generic_add_port_range(generic, 0x377, 0x377, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (DIR)
402     
403 #endif
404
405 #if 1
406
407     // Make the parallel port invisible
408       
409     v3_generic_add_port_range(generic, 0x378, 0x37f, GENERIC_PRINT_AND_IGNORE);
410
411 #endif
412
413 #if 1
414
415     // Monitor graphics card operations
416     
417     v3_generic_add_port_range(generic, 0x3b0, 0x3bb, GENERIC_PRINT_AND_PASSTHROUGH);
418     v3_generic_add_port_range(generic, 0x3c0, 0x3df, GENERIC_PRINT_AND_PASSTHROUGH);
419       
420 #endif
421
422
423 #if 1
424     // Make the ISA PNP features invisible
425     
426     v3_generic_add_port_range(generic, 0x274, 0x277, GENERIC_PRINT_AND_IGNORE);
427     v3_generic_add_port_range(generic, 0x279, 0x279, GENERIC_PRINT_AND_IGNORE);
428     v3_generic_add_port_range(generic, 0xa79, 0xa79, GENERIC_PRINT_AND_IGNORE);
429 #endif
430
431
432 #if 1
433     // Monitor any network card (realtek ne2000) operations 
434     v3_generic_add_port_range(generic, 0xc100, 0xc1ff, GENERIC_PRINT_AND_PASSTHROUGH);
435 #endif
436
437
438
439     //  v3_generic_add_port_range(generic, 0x378, 0x400, GENERIC_PRINT_AND_IGNORE);
440     
441
442     return 0;
443 }