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