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.


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