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.


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