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.


updated the block device interfaces to be more generic, and have the virtio block...
[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     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     v3_create_device(info, "8259A", NULL);
203     v3_create_device(info, "KEYBOARD", NULL);
204     v3_create_device(info, "8254_PIT", NULL); 
205     v3_create_device(info, "BOCHS_DEBUG", NULL);
206     v3_create_device(info, "OS_DEBUG", NULL);
207     v3_create_device(info, "LAPIC", NULL);
208     v3_create_device(info, "IOAPIC", "LAPIC");
209     v3_create_device(info, "VMNET", NULL);
210     
211     int use_generic = USE_GENERIC;
212
213     if (config_ptr->enable_pci == 1) {
214         struct ide_cfg ide_config = {"PCI", "PIIX3"};
215         
216         v3_create_device(info, "PCI", NULL);
217         v3_create_device(info, "i440FX", "PCI");
218         v3_create_device(info, "PIIX3", "PCI");
219         
220
221         v3_create_device(info, "LNX_VIRTIO_BLK", "PCI");
222         v3_create_device(info, "SYM_SWAP", "LNX_VIRTIO_BLK");
223
224         v3_create_device(info, "IDE", &ide_config);
225     } else {
226         v3_create_device(info, "IDE", NULL);
227     }
228
229
230     if (config_ptr->pri_disk_type != NONE) {
231         if (config_ptr->pri_disk_type == CDROM) {
232             if (config_ptr->pri_disk_con == RAM) {
233                 struct ram_cd_cfg cfg = {"IDE", 0, 0, 
234                                          (addr_t)(config_ptr->pri_disk_info.ram.data_ptr), 
235                                          config_ptr->pri_disk_info.ram.size};
236
237                 PrintDebug("Creating RAM CD\n");
238
239                 v3_create_device(info, "RAM-CD", &cfg);
240             } else if (config_ptr->pri_disk_con == NETWORK) {
241                 struct net_cd_cfg cfg = {"IDE", 0, 0, 
242                                          config_ptr->pri_disk_info.net.ip_str,
243                                          config_ptr->pri_disk_info.net.port, 
244                                          config_ptr->pri_disk_info.net.disk_name};
245                 PrintDebug("Creating NET CD\n");
246
247                 v3_create_device(info, "NET-CD", &cfg);
248             }
249         } else if (config_ptr->pri_disk_type == HARDDRIVE) {
250             if (config_ptr->pri_disk_con == RAM) {
251                 struct ram_hd_cfg cfg = {"IDE", 0, 0, 
252                                          (addr_t)(config_ptr->pri_disk_info.ram.data_ptr), 
253                                          config_ptr->pri_disk_info.ram.size};
254
255                 PrintDebug("Creating RAM HD\n");
256
257                 v3_create_device(info, "RAM-HD", &cfg);
258             } else if (config_ptr->pri_disk_con == NETWORK) {
259                 struct net_hd_cfg cfg  = {"IDE", 0, 0, 
260                                           config_ptr->pri_disk_info.net.ip_str,
261                                           config_ptr->pri_disk_info.net.port, 
262                                           config_ptr->pri_disk_info.net.disk_name};
263                 PrintDebug("Creating NET HD\n");
264                 v3_create_device(info, "NET-HD", &cfg);
265             }
266         }
267     }
268
269
270
271     if (config_ptr->sec_disk_type != NONE) {
272         if (config_ptr->sec_disk_type == CDROM) {
273             if (config_ptr->sec_disk_con == RAM) {
274                 struct ram_cd_cfg cfg = {"IDE", 0, 1, 
275                                          (addr_t)(config_ptr->sec_disk_info.ram.data_ptr), 
276                                          config_ptr->sec_disk_info.ram.size};
277
278                 PrintDebug("Creating RAM CD\n");
279                 v3_create_device(info, "RAM-CD", &cfg);
280             } else if (config_ptr->sec_disk_con == NETWORK) {
281                 struct net_cd_cfg cfg = {"IDE", 0, 1, 
282                                          config_ptr->sec_disk_info.net.ip_str,
283                                          config_ptr->sec_disk_info.net.port, 
284                                          config_ptr->sec_disk_info.net.disk_name};
285
286                 PrintDebug("Creating NET CD\n");
287                 v3_create_device(info, "NET-CD", &cfg);    
288             }
289         } else if (config_ptr->sec_disk_type == HARDDRIVE) {
290             if (config_ptr->sec_disk_con == RAM) {
291                 struct ram_hd_cfg cfg = {"IDE", 0, 1, 
292                                          (addr_t)(config_ptr->sec_disk_info.ram.data_ptr), 
293                                          config_ptr->sec_disk_info.ram.size};
294                 PrintDebug("Creating RAM HD\n");
295                 v3_create_device(info, "RAM-HD", &cfg);
296             } else if (config_ptr->sec_disk_con == NETWORK) {
297                 struct net_hd_cfg cfg = {"IDE", 0, 1, 
298                                          config_ptr->sec_disk_info.net.ip_str,
299                                          config_ptr->sec_disk_info.net.port, 
300                                          config_ptr->sec_disk_info.net.disk_name};
301                 PrintDebug("Creating NET HD\n");
302                 v3_create_device(info, "NET-HD", &cfg);
303             }
304         }
305     }
306
307
308
309     if (use_generic) {
310         configure_generic(info, config_ptr);
311     }
312
313     // This should go last because it requires information about the Harddrives
314     v3_create_device(info, "NVRAM", "IDE");
315     
316     PrintDebugDevMgr(info);
317
318     return 0;
319 }
320
321
322
323
324 static int configure_generic(struct guest_info * info, struct v3_vm_config * config_ptr) {
325     PrintDebug("Creating Generic Device\n");
326     v3_create_device(info, "GENERIC", NULL);
327     
328
329     struct vm_device * generic = v3_find_dev(info, "GENERIC");
330
331     if (!generic) {
332         PrintError("Could not find generic device\n");
333         return -1;
334     }
335
336     // port 0x92: A20 enable/disable (bit 2) (This causes an MMU flush)
337
338
339     // Make the DMA controller invisible
340     v3_generic_add_port_range(generic, 0x00, 0x07, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channels 0,1,2,3 (address, counter)
341     v3_generic_add_port_range(generic, 0xc0, 0xc7, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channels 4,5,6,7 (address, counter)
342     v3_generic_add_port_range(generic, 0x87, 0x87, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 0 page register
343     v3_generic_add_port_range(generic, 0x83, 0x83, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 1 page register
344     v3_generic_add_port_range(generic, 0x81, 0x81, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 2 page register
345     v3_generic_add_port_range(generic, 0x82, 0x82, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 3 page register
346     v3_generic_add_port_range(generic, 0x8f, 0x8f, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 4 page register
347     v3_generic_add_port_range(generic, 0x8b, 0x8b, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 5 page register
348     v3_generic_add_port_range(generic, 0x89, 0x89, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 6 page register
349     v3_generic_add_port_range(generic, 0x8a, 0x8a, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 7 page register
350     v3_generic_add_port_range(generic, 0x08, 0x0f, GENERIC_PRINT_AND_IGNORE);   // DMA 1 misc registers (csr, req, smask,mode,clearff,reset,enable,mmask)
351     v3_generic_add_port_range(generic, 0xd0, 0xde, GENERIC_PRINT_AND_IGNORE);   // DMA 2 misc registers
352     
353     
354     
355     
356     // Make the Serial ports invisible 
357     
358     v3_generic_add_port_range(generic, 0x3f8, 0x3f8+7, GENERIC_PRINT_AND_IGNORE);      // COM 1
359     v3_generic_add_port_range(generic, 0x2f8, 0x2f8+7, GENERIC_PRINT_AND_IGNORE);      // COM 2
360     
361
362       
363
364     v3_generic_add_port_range(generic, 0x3e8, 0x3e8+7, GENERIC_PRINT_AND_IGNORE);      // COM 3
365     v3_generic_add_port_range(generic, 0x2e8, 0x2e8+7, GENERIC_PRINT_AND_IGNORE);      // COM 4
366
367       
368       
369
370     // Make the PCI bus invisible (at least it's configuration)
371     
372     //v3_generic_add_port_range(generic, 0xcf8, 0xcf8, GENERIC_PRINT_AND_IGNORE); // PCI Config Address
373     //v3_generic_add_port_range(generic, 0xcfc, 0xcfc, GENERIC_PRINT_AND_IGNORE); // PCI Config Data
374     
375     
376     
377 #if 0
378     if (!use_ramdisk) {
379         // Monitor the IDE controllers (very slow)
380         v3_generic_add_port_range(generic, 0x170, 0x178, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 1
381         v3_generic_add_port_range(generic, 0x376, 0x377, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 1
382     }
383       
384
385     v3_generic_add_port_range(generic, 0x1f0, 0x1f8, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 0
386     v3_generic_add_port_range(generic, 0x3f6, 0x3f7, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 0
387 #endif
388       
389       
390 #if 0
391     
392     // Make the floppy controllers invisible
393     
394     v3_generic_add_port_range(generic, 0x3f0, 0x3f2, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (base,statusa/statusb,DOR)
395     v3_generic_add_port_range(generic, 0x3f4, 0x3f5, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (mainstat/datarate,data)
396     v3_generic_add_port_range(generic, 0x3f7, 0x3f7, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (DIR)
397     v3_generic_add_port_range(generic, 0x370, 0x372, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (base,statusa/statusb,DOR)
398     v3_generic_add_port_range(generic, 0x374, 0x375, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (mainstat/datarate,data)
399     v3_generic_add_port_range(generic, 0x377, 0x377, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (DIR)
400     
401 #endif
402
403 #if 1
404
405     // Make the parallel port invisible
406       
407     v3_generic_add_port_range(generic, 0x378, 0x37f, GENERIC_PRINT_AND_IGNORE);
408
409 #endif
410
411 #if 1
412
413     // Monitor graphics card operations
414     
415     v3_generic_add_port_range(generic, 0x3b0, 0x3bb, GENERIC_PRINT_AND_PASSTHROUGH);
416     v3_generic_add_port_range(generic, 0x3c0, 0x3df, GENERIC_PRINT_AND_PASSTHROUGH);
417       
418 #endif
419
420
421 #if 1
422     // Make the ISA PNP features invisible
423     
424     v3_generic_add_port_range(generic, 0x274, 0x277, GENERIC_PRINT_AND_IGNORE);
425     v3_generic_add_port_range(generic, 0x279, 0x279, GENERIC_PRINT_AND_IGNORE);
426     v3_generic_add_port_range(generic, 0xa79, 0xa79, GENERIC_PRINT_AND_IGNORE);
427 #endif
428
429
430 #if 1
431     // Monitor any network card (realtek ne2000) operations 
432     v3_generic_add_port_range(generic, 0xc100, 0xc1ff, GENERIC_PRINT_AND_PASSTHROUGH);
433 #endif
434
435     //  v3_generic_add_port_range(generic, 0x378, 0x400, GENERIC_PRINT_AND_IGNORE);
436     
437     return 0;
438 }