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