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.


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