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