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 mem_size config variable
[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
25
26 #include <devices/serial.h>
27 #include <devices/keyboard.h>
28 #include <devices/8259a.h>
29 #include <devices/8254.h>
30 #include <devices/nvram.h>
31 #include <devices/generic.h>
32 #include <devices/ramdisk.h>
33 #include <devices/cdrom.h>
34 #include <devices/bochs_debug.h>
35
36
37 #include <palacios/vmm_host_events.h>
38
39 #define USE_GENERIC 1
40
41
42 #define ROMBIOS_START 0x000f0000
43 #define VGABIOS_START 0x000c0000
44
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 struct vm_device *  configure_generic(struct guest_info * info, struct v3_vm_config * config_ptr);
50
51
52
53 static int mem_test_read(addr_t guest_addr, void * dst, uint_t length, void * priv_data) {
54   int foo = 20;
55
56
57   memcpy(dst, &foo, length);
58
59   PrintDebug("Passthrough mem read returning: %p (length=%d)\n", (void *)(foo + (guest_addr & 0xfff)), length);
60   return length;
61 }
62
63 static int passthrough_mem_read(addr_t guest_addr, void * dst, uint_t length, void * priv_data) {
64     memcpy(dst, (void*)guest_addr, length);
65     return length;
66 }
67
68 static int passthrough_mem_write(addr_t guest_addr, void * src, uint_t length, void * priv_data) {
69   memcpy((void*)guest_addr, src, length);
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   // Initialize the subsystem data strutures
79   v3_init_time(info);
80   v3_init_vmm_io_map(info);
81   v3_init_msr_map(info);
82   v3_init_interrupt_state(info);
83   v3_init_dev_mgr(info);
84   v3_init_emulator(info);
85   v3_init_host_events(info);
86
87   init_shadow_map(info);
88   
89   if (v3_cpu_type == V3_SVM_REV3_CPU) {
90     info->shdw_pg_mode = NESTED_PAGING;
91   } else {
92     v3_init_shadow_page_state(info);
93     info->shdw_pg_mode = SHADOW_PAGING;
94   }
95   
96   // Initial CPU operating mode
97   info->cpu_mode = REAL;
98   info->mem_mode = PHYSICAL_MEM;
99
100   // Amount of ram the Guest will have
101   info->mem_size = config_ptr->mem_size;
102
103   // Configure the memory map for the guest
104   setup_memory_map(info, config_ptr);
105
106   // Configure the devices for the guest
107   setup_devices(info, config_ptr);
108  
109
110   //v3_hook_io_port(info, 1234, &IO_Read, NULL, info);
111
112   // Setup initial cpu register state
113   info->rip = 0xfff0;
114   info->vm_regs.rsp = 0x0;
115   
116
117   return 0;
118 }
119
120
121 /* TODO:
122  * The amount of guest memory is stored in info->mem_size
123  * We need to make sure the memory map extends to cover it
124  */
125 static int setup_memory_map(struct guest_info * info, struct v3_vm_config * config_ptr) {
126
127   /* layout rombios */
128   {
129     uint_t num_pages = (config_ptr->rombios_size + PAGE_SIZE - 1) / PAGE_SIZE;
130     void * guest_mem =  V3_AllocPages(num_pages);
131
132     PrintDebug("Layout Region %d bytes\n", config_ptr->rombios_size);
133     memcpy(V3_VAddr(guest_mem), config_ptr->rombios, config_ptr->rombios_size);
134
135     add_shadow_region_passthrough(info, ROMBIOS_START, ROMBIOS_START + (num_pages * PAGE_SIZE), (addr_t)guest_mem);
136     
137     PrintDebug("Adding Shadow Region (0x%p-0x%p) -> 0x%p\n", 
138                (void *)ROMBIOS_START, 
139                (void *)ROMBIOS_START + (num_pages * PAGE_SIZE), 
140                (void *)guest_mem);
141   }
142
143
144   /* layout vgabios */
145   {
146     uint_t num_pages = (config_ptr->vgabios_size + PAGE_SIZE - 1) / PAGE_SIZE;
147     void * guest_mem =  V3_AllocPages(num_pages);
148
149     PrintDebug("Layout Region %d bytes\n", config_ptr->vgabios_size);
150     memcpy(V3_VAddr(guest_mem), config_ptr->vgabios, config_ptr->vgabios_size);
151
152     add_shadow_region_passthrough(info, VGABIOS_START, VGABIOS_START + (num_pages * PAGE_SIZE), (addr_t)guest_mem);
153     
154     PrintDebug("Adding Shadow Region (0x%p-0x%p) -> 0x%p\n", 
155                (void *)VGABIOS_START, 
156                (void *)VGABIOS_START + (num_pages * PAGE_SIZE), 
157                (void *)guest_mem);
158   }
159
160       //     
161   add_shadow_region_passthrough(info, 0x0, 0xa0000, (addr_t)V3_AllocPages(160));
162   
163   if (1) {
164     add_shadow_region_passthrough(info, 0xa0000, 0xc0000, 0xa0000); 
165   } else {
166     hook_guest_mem(info, 0xa0000, 0xc0000, passthrough_mem_read, passthrough_mem_write, NULL);
167   }  
168   
169   // TEMP
170   //add_shadow_region_passthrough(info, 0xc0000, 0xc8000, 0xc0000);
171   
172   if (1) {
173     add_shadow_region_passthrough(info, 0xc7000, 0xc8000, (addr_t)V3_AllocPages(1));
174     if (add_shadow_region_passthrough(info, 0xc8000, 0xf0000, (addr_t)V3_AllocPages(40)) == -1) {
175       PrintDebug("Error adding shadow region\n");
176     }
177   } else {
178     add_shadow_region_passthrough(info, 0xc0000, 0xc8000, 0xc0000);
179     add_shadow_region_passthrough(info, 0xc8000, 0xf0000, 0xc8000);
180   }
181   
182   
183   if (1) {
184   add_shadow_region_passthrough(info, 0x100000, 0x1000000, (addr_t)V3_AllocPages(4096));
185   } else {
186     /* MEMORY HOOK TEST */
187     add_shadow_region_passthrough(info, 0x100000, 0xa00000, (addr_t)V3_AllocPages(2304));
188     hook_guest_mem(info, 0xa00000, 0xa01000, mem_test_read, passthrough_mem_write, NULL); 
189     add_shadow_region_passthrough(info, 0xa01000, 0x1000000, (addr_t)V3_AllocPages(1791));
190   }
191
192     add_shadow_region_passthrough(info, 0x1000000, 0x8000000, (addr_t)V3_AllocPages(32768));
193  
194   // test - give linux accesss to PCI space - PAD
195   add_shadow_region_passthrough(info, 0xc0000000,0xffffffff,0xc0000000);
196   
197   
198   print_shadow_map(&(info->mem_map));
199
200   return 0;
201 }
202
203
204
205 static int setup_devices(struct guest_info * info, struct v3_vm_config * config_ptr) {
206     struct vm_device * ramdisk = NULL;
207     struct vm_device * cdrom = NULL;
208     struct vm_device * nvram = v3_create_nvram();
209     //struct vm_device * timer = v3_create_timer();
210     struct vm_device * pic = v3_create_pic();
211     struct vm_device * keyboard = v3_create_keyboard();
212     struct vm_device * pit = v3_create_pit(); 
213     struct vm_device * bochs_debug = v3_create_bochs_debug();
214
215     //struct vm_device * serial = v3_create_serial();
216     struct vm_device * generic = NULL;
217
218     int use_ramdisk = config_ptr->use_ramdisk;
219     int use_generic = USE_GENERIC;
220
221
222     if (use_ramdisk) {
223       PrintDebug("Creating Ramdisk\n");
224       ramdisk = v3_create_ramdisk();
225       cdrom = v3_create_cdrom(ramdisk, config_ptr->ramdisk, config_ptr->ramdisk_size); 
226     }
227     
228     
229     if (use_generic) {
230       generic = configure_generic(info, config_ptr);
231     }
232
233
234     v3_attach_device(info, nvram);
235     //v3_attach_device(info, timer);
236     v3_attach_device(info, pic);
237     v3_attach_device(info, pit);
238     v3_attach_device(info, keyboard);
239     // v3_attach_device(info, serial);
240     v3_attach_device(info, bochs_debug);
241
242     if (use_ramdisk) {
243       v3_attach_device(info, ramdisk);
244       v3_attach_device(info, cdrom);
245     }
246
247     if (use_generic) {
248       // Important that this be attached last!
249       v3_attach_device(info, generic);
250     }
251     
252     PrintDebugDevMgr(info);
253
254
255     // give keyboard interrupts to vm
256     // no longer needed since we have a keyboard device
257     //hook_irq(&vm_info, 1);
258     
259 #if 0
260     // give floppy controller to vm
261     v3_hook_passthrough_irq(info, 6);
262 #endif
263     
264     
265     if (!use_ramdisk) {
266       PrintDebug("Hooking IDE IRQs\n");
267       
268       //primary ide
269       v3_hook_passthrough_irq(info, 14);
270       
271       // secondary ide
272       v3_hook_passthrough_irq(info, 15);    
273     }  
274     
275
276   return 0;
277 }
278
279
280
281 static struct vm_device *  configure_generic(struct guest_info * info, struct v3_vm_config * config_ptr) {
282       PrintDebug("Creating Generic Device\n");
283       struct vm_device * generic = v3_create_generic();
284       
285       // Make the DMA controller invisible
286       v3_generic_add_port_range(generic, 0x00, 0x07, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channels 0,1,2,3 (address, counter)
287       v3_generic_add_port_range(generic, 0xc0, 0xc7, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channels 4,5,6,7 (address, counter)
288       v3_generic_add_port_range(generic, 0x87, 0x87, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 0 page register
289       v3_generic_add_port_range(generic, 0x83, 0x83, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 1 page register
290       v3_generic_add_port_range(generic, 0x81, 0x81, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 2 page register
291       v3_generic_add_port_range(generic, 0x82, 0x82, GENERIC_PRINT_AND_IGNORE);   // DMA 1 channel 3 page register
292       v3_generic_add_port_range(generic, 0x8f, 0x8f, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 4 page register
293       v3_generic_add_port_range(generic, 0x8b, 0x8b, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 5 page register
294       v3_generic_add_port_range(generic, 0x89, 0x89, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 6 page register
295       v3_generic_add_port_range(generic, 0x8a, 0x8a, GENERIC_PRINT_AND_IGNORE);   // DMA 2 channel 7 page register
296       v3_generic_add_port_range(generic, 0x08, 0x0f, GENERIC_PRINT_AND_IGNORE);   // DMA 1 misc registers (csr, req, smask,mode,clearff,reset,enable,mmask)
297       v3_generic_add_port_range(generic, 0xd0, 0xde, GENERIC_PRINT_AND_IGNORE);   // DMA 2 misc registers
298       
299       
300       
301       
302       // Make the Serial ports invisible 
303       
304       v3_generic_add_port_range(generic, 0x3f8, 0x3f8+7, GENERIC_PRINT_AND_IGNORE);      // COM 1
305       v3_generic_add_port_range(generic, 0x2f8, 0x2f8+7, GENERIC_PRINT_AND_IGNORE);      // COM 2
306       
307
308       
309
310       v3_generic_add_port_range(generic, 0x3e8, 0x3e8+7, GENERIC_PRINT_AND_IGNORE);      // COM 3
311       v3_generic_add_port_range(generic, 0x2e8, 0x2e8+7, GENERIC_PRINT_AND_IGNORE);      // COM 4
312
313       
314       
315
316       // Make the PCI bus invisible (at least it's configuration)
317       
318       v3_generic_add_port_range(generic, 0xcf8, 0xcf8, GENERIC_PRINT_AND_IGNORE); // PCI Config Address
319       v3_generic_add_port_range(generic, 0xcfc, 0xcfc, GENERIC_PRINT_AND_IGNORE); // PCI Config Data
320
321       
322       
323 #if 0
324       if (!use_ramdisk) {
325         // Monitor the IDE controllers (very slow)
326         v3_generic_add_port_range(generic, 0x170, 0x178, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 1
327         v3_generic_add_port_range(generic, 0x376, 0x377, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 1
328       }
329       
330
331       v3_generic_add_port_range(generic, 0x1f0, 0x1f8, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 0
332       v3_generic_add_port_range(generic, 0x3f6, 0x3f7, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 0
333 #endif
334       
335       
336 #if 0
337       
338       // Make the floppy controllers invisible
339       
340       v3_generic_add_port_range(generic, 0x3f0, 0x3f2, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (base,statusa/statusb,DOR)
341       v3_generic_add_port_range(generic, 0x3f4, 0x3f5, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (mainstat/datarate,data)
342       v3_generic_add_port_range(generic, 0x3f7, 0x3f7, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (DIR)
343       v3_generic_add_port_range(generic, 0x370, 0x372, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (base,statusa/statusb,DOR)
344       v3_generic_add_port_range(generic, 0x374, 0x375, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (mainstat/datarate,data)
345       v3_generic_add_port_range(generic, 0x377, 0x377, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (DIR)
346       
347 #endif
348
349 #if 1
350
351       // Make the parallel port invisible
352       
353       v3_generic_add_port_range(generic, 0x378, 0x37f, GENERIC_PRINT_AND_IGNORE);
354
355 #endif
356
357 #if 1
358
359       // Monitor graphics card operations
360
361       v3_generic_add_port_range(generic, 0x3b0, 0x3bb, GENERIC_PRINT_AND_PASSTHROUGH);
362       v3_generic_add_port_range(generic, 0x3c0, 0x3df, GENERIC_PRINT_AND_PASSTHROUGH);
363       
364 #endif
365
366
367 #if 1
368       // Make the ISA PNP features invisible
369
370       v3_generic_add_port_range(generic, 0x274, 0x277, GENERIC_PRINT_AND_IGNORE);
371       v3_generic_add_port_range(generic, 0x279, 0x279, GENERIC_PRINT_AND_IGNORE);
372       v3_generic_add_port_range(generic, 0xa79, 0xa79, GENERIC_PRINT_AND_IGNORE);
373 #endif
374
375
376 #if 1
377       // Monitor any network card (realtek ne2000) operations 
378       v3_generic_add_port_range(generic, 0xc100, 0xc1ff, GENERIC_PRINT_AND_PASSTHROUGH);
379 #endif
380
381
382 #if 1
383       // Make any Bus master ide controller invisible
384       
385       v3_generic_add_port_range(generic, 0xc000, 0xc00f, GENERIC_PRINT_AND_IGNORE);
386 #endif
387       //  v3_generic_add_port_range(generic, 0x378, 0x400, GENERIC_PRINT_AND_IGNORE);
388       
389
390       return generic;
391
392 }