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.


changed memory map to be layered on top of a single contiguous allocation
[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 #include <devices/serial.h>
31 #include <devices/keyboard.h>
32 #include <devices/8259a.h>
33 #include <devices/8254.h>
34 #include <devices/nvram.h>
35 #include <devices/generic.h>
36 #include <devices/ide.h>
37 #include <devices/ram_cd.h>
38 #include <devices/ram_hd.h>
39 #include <devices/bochs_debug.h>
40 #include <devices/os_debug.h>
41 #include <devices/apic.h>
42 #include <devices/io_apic.h>
43 #include <devices/para_net.h>
44 #include <devices/pci.h>
45 #include <devices/i440fx.h>
46 #include <devices/piix3.h>
47
48
49 #include <palacios/vmm_host_events.h>
50
51 #define USE_GENERIC 1
52
53
54
55
56
57 static int setup_memory_map(struct guest_info * info, struct v3_vm_config * config_ptr);
58 static int setup_devices(struct guest_info * info, struct v3_vm_config * config_ptr);
59 static struct vm_device *  configure_generic(struct guest_info * info, struct v3_vm_config * config_ptr);
60
61
62
63
64 static int passthrough_mem_write(addr_t guest_addr, void * src, uint_t length, void * priv_data) {
65
66     return length;
67     //  memcpy((void*)guest_addr, src, length);
68     PrintDebug("Write of %d bytes to %p\n", length, (void *)guest_addr);
69     PrintDebug("Write Value = %p\n", (void *)*(addr_t *)src);
70     
71     return length;
72 }
73
74
75
76 int v3_config_guest(struct guest_info * info, struct v3_vm_config * config_ptr) {
77     extern v3_cpu_arch_t v3_cpu_type;
78
79     // Amount of ram the Guest will have, rounded to a 4K page boundary
80     info->mem_size = config_ptr->mem_size & ~(addr_t)0xfff;
81
82     // Initialize the subsystem data strutures
83     v3_init_time(info);
84     v3_init_io_map(info);
85     v3_init_msr_map(info);
86     v3_init_interrupt_state(info);
87     v3_init_dev_mgr(info);
88     v3_init_host_events(info);
89     
90     v3_init_decoder(info);
91     
92     v3_init_hypercall_map(info);
93
94     
95     // Initialize the memory map
96     v3_init_shadow_map(info);
97     
98     
99     if ((v3_cpu_type == V3_SVM_REV3_CPU) && 
100         (config_ptr->enable_nested_paging == 1)) {
101         PrintDebug("Guest Page Mode: NESTED_PAGING\n");
102         info->shdw_pg_mode = NESTED_PAGING;
103     } else {
104         PrintDebug("Guest Page Mode: SHADOW_PAGING\n");
105         v3_init_shadow_page_state(info);
106         info->shdw_pg_mode = SHADOW_PAGING;
107     }
108     
109     // Initial CPU operating mode
110     info->cpu_mode = REAL;
111     info->mem_mode = PHYSICAL_MEM;
112     
113     // Configure the memory map for the guest
114     if (setup_memory_map(info, config_ptr) == -1) {
115         PrintError("Setting up guest memory map failed...\n");
116         return -1;
117     }
118     
119     // Configure the devices for the guest
120     setup_devices(info, config_ptr);
121     
122     if (config_ptr->enable_profiling) {
123         info->enable_profiler = 1;
124         v3_init_profiler(info);
125     } else {
126         info->enable_profiler = 0;
127     }
128
129     //v3_hook_io_port(info, 1234, &IO_Read, NULL, info);
130     
131     // Setup initial cpu register state
132     info->rip = 0xfff0;
133     info->vm_regs.rsp = 0x0;
134   
135     
136     return 0;
137 }
138
139
140 /* TODO:
141  * The amount of guest memory is stored in info->mem_size
142  * We need to make sure the memory map extends to cover it
143  */
144 static int setup_memory_map(struct guest_info * info, struct v3_vm_config * config_ptr) {
145     PrintDebug("Setting up memory map (memory size=%dMB)\n", (uint_t)(info->mem_size / (1024 * 1024)));
146     
147     // VGA frame buffer
148     if (1) {
149         if (v3_add_shadow_mem(info, 0xa0000, 0xc0000, 0xa0000) == -1) {
150             PrintError("Could not map VGA framebuffer\n");
151             return -1;
152         }
153     } else {
154         v3_hook_write_mem(info, 0xa0000, 0xc0000, 0xa0000,  passthrough_mem_write, NULL);
155     }  
156
157 #define VGABIOS_START 0x000c0000
158 #define ROMBIOS_START 0x000f0000
159
160     /* layout vgabios */
161     {
162         addr_t vgabios_dst = v3_get_shadow_addr(&(info->mem_map.base_region), VGABIOS_START);
163         memcpy(V3_VAddr((void *)vgabios_dst), config_ptr->vgabios, config_ptr->vgabios_size);   
164     }
165     
166     /* layout rombios */
167     {
168         addr_t rombios_dst = v3_get_shadow_addr(&(info->mem_map.base_region), ROMBIOS_START);
169         memcpy(V3_VAddr((void *)rombios_dst), config_ptr->rombios, config_ptr->rombios_size);
170     }
171
172 #ifdef CRAY_XT
173     {
174 #define SEASTAR_START 0xffe00000 
175 #define SEASTAR_END 0xffffffff 
176         // Map the Seastar straight through
177         if (v3_add_shadow_mem(info, SEASTAR_START, SEASTAR_END, SEASTAR_START) == -1) {
178             PrintError("Could not map through the seastar\n");
179             return -1;
180         }
181     }
182 #endif    
183
184     print_shadow_map(info);
185
186     return 0;
187 }
188
189
190
191 static int setup_devices(struct guest_info * info, struct v3_vm_config * config_ptr) {
192
193     struct vm_device * ide = NULL;
194     struct vm_device * ramdisk = NULL;
195     
196     struct vm_device * pci = NULL;
197     struct vm_device * northbridge = NULL;
198     struct vm_device * southbridge = NULL;
199
200     struct vm_device * nvram = NULL;
201     struct vm_device * pic = v3_create_pic();
202     struct vm_device * keyboard = v3_create_keyboard();
203     struct vm_device * pit = v3_create_pit(); 
204     struct vm_device * bochs_debug = v3_create_bochs_debug();
205     struct vm_device * os_debug = v3_create_os_debug();
206     struct vm_device * apic = v3_create_apic();
207     struct vm_device * ioapic = v3_create_io_apic(apic);
208     struct vm_device * para_net = v3_create_para_net();
209
210
211     //struct vm_device * serial = v3_create_serial();
212     struct vm_device * generic = NULL;
213
214
215     int use_generic = USE_GENERIC;
216
217     if (config_ptr->enable_pci == 1) {
218         pci = v3_create_pci();
219         northbridge = v3_create_i440fx(pci);
220         southbridge = v3_create_piix3(pci);
221         ide = v3_create_ide(pci, southbridge);
222     } else {
223         ide = v3_create_ide(NULL, NULL);
224     }
225
226
227
228     nvram = v3_create_nvram(ide);
229
230     if (config_ptr->use_ram_cd == 1) {
231         PrintDebug("Creating Ram CD\n");
232         ramdisk = v3_create_ram_cd(ide, 0, 0, 
233                                    (addr_t)(config_ptr->ramdisk), 
234                                    config_ptr->ramdisk_size);
235     } else if (config_ptr->use_ram_hd == 1) {
236         PrintDebug("Creating Ram HD\n");
237         ramdisk = v3_create_ram_hd(ide, 0, 0, 
238                                    (addr_t)(config_ptr->ramdisk), 
239                                    config_ptr->ramdisk_size);
240     }
241     
242     
243     if (use_generic) {
244         generic = configure_generic(info, config_ptr);
245     }
246
247
248
249
250
251     v3_attach_device(info, pic);
252     v3_attach_device(info, pit);
253     v3_attach_device(info, keyboard);
254     // v3_attach_device(info, serial);
255     v3_attach_device(info, bochs_debug);
256     v3_attach_device(info, os_debug);
257
258     v3_attach_device(info, apic);
259     v3_attach_device(info, ioapic);
260
261     v3_attach_device(info, para_net);
262
263     if (config_ptr->enable_pci == 1) {
264         PrintDebug("Attaching PCI\n");
265         v3_attach_device(info, pci);
266         PrintDebug("Attaching Northbridge\n");
267         v3_attach_device(info, northbridge);
268         PrintDebug("Attaching Southbridge\n");
269         v3_attach_device(info, southbridge);
270     }
271
272     PrintDebug("Attaching IDE\n");
273     v3_attach_device(info, ide);
274
275     if (ramdisk != NULL) {
276         v3_attach_device(info, ramdisk);
277     }
278
279     if (use_generic) {
280         // Important that this be attached last!
281         v3_attach_device(info, generic);
282     }
283
284     // This should go last because it contains the hardware state
285     v3_attach_device(info, nvram);
286     
287     PrintDebugDevMgr(info);
288
289     return 0;
290 }
291
292
293
294 static struct vm_device *  configure_generic(struct guest_info * info, struct v3_vm_config * config_ptr) {
295     PrintDebug("Creating Generic Device\n");
296     struct vm_device * generic = v3_create_generic();
297     
298     // Make the DMA controller invisible
299     v3_generic_add_port_range(generic, 0x00, 0x07, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channels 0,1,2,3 (address, counter)
300     v3_generic_add_port_range(generic, 0xc0, 0xc7, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channels 4,5,6,7 (address, counter)
301     v3_generic_add_port_range(generic, 0x87, 0x87, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 0 page register
302     v3_generic_add_port_range(generic, 0x83, 0x83, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 1 page register
303     v3_generic_add_port_range(generic, 0x81, 0x81, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 2 page register
304     v3_generic_add_port_range(generic, 0x82, 0x82, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 3 page register
305     v3_generic_add_port_range(generic, 0x8f, 0x8f, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 4 page register
306     v3_generic_add_port_range(generic, 0x8b, 0x8b, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 5 page register
307     v3_generic_add_port_range(generic, 0x89, 0x89, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 6 page register
308     v3_generic_add_port_range(generic, 0x8a, 0x8a, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 7 page register
309     v3_generic_add_port_range(generic, 0x08, 0x0f, GENERIC_PRINT_AND_IGNORE);   // DMA 1 misc registers (csr, req, smask,mode,clearff,reset,enable,mmask)
310     v3_generic_add_port_range(generic, 0xd0, 0xde, GENERIC_PRINT_AND_IGNORE);   // DMA 2 misc registers
311     
312     
313     
314     
315     // Make the Serial ports invisible 
316     
317     v3_generic_add_port_range(generic, 0x3f8, 0x3f8+7, GENERIC_PRINT_AND_IGNORE);      // COM 1
318     v3_generic_add_port_range(generic, 0x2f8, 0x2f8+7, GENERIC_PRINT_AND_IGNORE);      // COM 2
319     
320
321       
322
323     v3_generic_add_port_range(generic, 0x3e8, 0x3e8+7, GENERIC_PRINT_AND_IGNORE);      // COM 3
324     v3_generic_add_port_range(generic, 0x2e8, 0x2e8+7, GENERIC_PRINT_AND_IGNORE);      // COM 4
325
326       
327       
328
329     // Make the PCI bus invisible (at least it's configuration)
330     
331     //v3_generic_add_port_range(generic, 0xcf8, 0xcf8, GENERIC_PRINT_AND_IGNORE); // PCI Config Address
332     //v3_generic_add_port_range(generic, 0xcfc, 0xcfc, GENERIC_PRINT_AND_IGNORE); // PCI Config Data
333     
334     
335     
336 #if 0
337     if (!use_ramdisk) {
338         // Monitor the IDE controllers (very slow)
339         v3_generic_add_port_range(generic, 0x170, 0x178, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 1
340         v3_generic_add_port_range(generic, 0x376, 0x377, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 1
341     }
342       
343
344     v3_generic_add_port_range(generic, 0x1f0, 0x1f8, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 0
345     v3_generic_add_port_range(generic, 0x3f6, 0x3f7, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 0
346 #endif
347       
348       
349 #if 0
350     
351     // Make the floppy controllers invisible
352     
353     v3_generic_add_port_range(generic, 0x3f0, 0x3f2, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (base,statusa/statusb,DOR)
354     v3_generic_add_port_range(generic, 0x3f4, 0x3f5, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (mainstat/datarate,data)
355     v3_generic_add_port_range(generic, 0x3f7, 0x3f7, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (DIR)
356     v3_generic_add_port_range(generic, 0x370, 0x372, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (base,statusa/statusb,DOR)
357     v3_generic_add_port_range(generic, 0x374, 0x375, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (mainstat/datarate,data)
358     v3_generic_add_port_range(generic, 0x377, 0x377, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (DIR)
359     
360 #endif
361
362 #if 1
363
364     // Make the parallel port invisible
365       
366     v3_generic_add_port_range(generic, 0x378, 0x37f, GENERIC_PRINT_AND_IGNORE);
367
368 #endif
369
370 #if 1
371
372     // Monitor graphics card operations
373     
374     v3_generic_add_port_range(generic, 0x3b0, 0x3bb, GENERIC_PRINT_AND_PASSTHROUGH);
375     v3_generic_add_port_range(generic, 0x3c0, 0x3df, GENERIC_PRINT_AND_PASSTHROUGH);
376       
377 #endif
378
379
380 #if 1
381     // Make the ISA PNP features invisible
382     
383     v3_generic_add_port_range(generic, 0x274, 0x277, GENERIC_PRINT_AND_IGNORE);
384     v3_generic_add_port_range(generic, 0x279, 0x279, GENERIC_PRINT_AND_IGNORE);
385     v3_generic_add_port_range(generic, 0xa79, 0xa79, GENERIC_PRINT_AND_IGNORE);
386 #endif
387
388
389 #if 1
390     // Monitor any network card (realtek ne2000) operations 
391     v3_generic_add_port_range(generic, 0xc100, 0xc1ff, GENERIC_PRINT_AND_PASSTHROUGH);
392 #endif
393
394
395 #if 1
396     // Make any Bus master ide controller invisible
397     
398     v3_generic_add_port_range(generic, 0xc000, 0xc00f, GENERIC_PRINT_AND_IGNORE);
399 #endif
400     //  v3_generic_add_port_range(generic, 0x378, 0x400, GENERIC_PRINT_AND_IGNORE);
401     
402
403     return generic;
404 }