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 irq initial setup
[palacios.git] / palacios / src / geekos / vm.c
1 #include <geekos/vmm_stubs.h>
2 #include <palacios/vmm.h>
3 #include <geekos/debug.h>
4 #include <geekos/serial.h>
5 #include <geekos/vm.h>
6 #include <geekos/screen.h>
7 #include <palacios/vmm_dev_mgr.h>
8 #include <devices/nvram.h>
9 #include <devices/timer.h>
10 #include <devices/simple_pic.h>
11 #include <palacios/vmm_intr.h>
12
13
14 #define SPEAKER_PORT 0x61
15
16
17
18
19 inline void VM_Out_Byte(ushort_t port, uchar_t value)
20 {
21     __asm__ __volatile__ (
22         "outb %b0, %w1"
23         :
24         : "a" (value), "Nd" (port)
25     );
26 }
27
28 /*
29  * Read a byte from an I/O port.
30  */
31 inline uchar_t VM_In_Byte(ushort_t port)
32 {
33     uchar_t value;
34
35     __asm__ __volatile__ (
36         "inb %w1, %b0"
37         : "=a" (value)
38         : "Nd" (port)
39     );
40
41     return value;
42 }
43
44
45
46 int IO_Read(ushort_t port, void * dst, uint_t length, void * priv_data) {
47
48   if (length != 1) {
49     return 0;
50   }
51
52   *(uchar_t*)dst = VM_In_Byte(port);    
53   return 1;
54 }
55
56
57
58 int IO_Write(ushort_t port, void * src, uint_t length, void * priv_data) {
59
60   if (length != 1) {
61     return 0;
62   }
63
64   VM_Out_Byte(port, *(uchar_t *)src);    
65
66   return 1;
67 }
68
69
70 int IO_Read_to_Serial(ushort_t port, void * dst, uint_t length, void * priv_data) {
71   PrintBoth("Input from Guest on port %d (0x%x) Length=%d\n", port, port, length);
72   
73   return 0;
74 }
75
76
77 char * bochs_debug_buf = NULL;
78 int bochs_debug_offset = 0;
79
80
81 int IO_BOCHS_debug(ushort_t port, void * src, uint_t length, void * priv_data) {
82   if (!bochs_debug_buf) {
83     bochs_debug_buf = (char*)Malloc(1024);
84   }
85
86   bochs_debug_buf[bochs_debug_offset++] = *(char*)src;
87
88   if ((*(char*)src == 0xa) ||  (bochs_debug_offset == 1023)) {
89     SerialPrint("BOCHS>%s", bochs_debug_buf);
90     memset(bochs_debug_buf, 0, 1024);
91     bochs_debug_offset = 0;
92   }
93
94   return length;
95 }
96
97
98 int IO_Write_to_Serial(ushort_t port, void * src, uint_t length, void * priv_data) {
99  SerialPrint("Output from Guest on port %d (0x%x) Length=%d\n", port, port, length);
100   switch (length) {
101
102   case 1:
103     SerialPrint(">0x%.2x\n", *(char*)src);
104     break;
105   case 2:
106     SerialPrint(">0x%.4x\n", *(ushort_t*)src);
107     break;
108   case 4:
109     SerialPrint(">0x%.8x\n", *(uint_t*)src);
110     break;
111   default:
112     break;
113   }
114
115   //  SerialMemDump(src, length);
116   return length;
117 }
118
119
120
121 void BuzzVM()
122 {
123   int x;
124   int j;
125   unsigned char init;
126
127 #if 0  
128   __asm__ __volatile__ (
129     "popf"
130     );
131     
132 #endif
133     
134   PrintBoth("Starting To Buzz\n");
135
136   init=VM_In_Byte(SPEAKER_PORT);
137
138   while (1) {
139     VM_Out_Byte(SPEAKER_PORT, init|0x2);
140     for (j=0;j<1000000;j++) { 
141       x+=j;
142     }
143     VM_Out_Byte(SPEAKER_PORT, init);
144     for (j=0;j<1000000;j++) { 
145       x+=j;
146     }
147   }
148 }
149
150
151
152
153
154
155 int RunVMM(struct Boot_Info * bootInfo) {
156
157     struct vmm_os_hooks os_hooks;
158     struct vmm_ctrl_ops vmm_ops;
159     struct guest_info vm_info;
160     addr_t rsp;
161     addr_t rip;
162
163
164
165     memset(&os_hooks, 0, sizeof(struct vmm_os_hooks));
166     memset(&vmm_ops, 0, sizeof(struct vmm_ctrl_ops));
167     memset(&vm_info, 0, sizeof(struct guest_info));
168
169     os_hooks.print_debug = &SerialPrint;
170     os_hooks.print_info = &Print;
171     os_hooks.print_trace = &SerialPrint;
172     os_hooks.allocate_pages = &Allocate_VMM_Pages;
173     os_hooks.free_page = &Free_VMM_Page;
174     os_hooks.malloc = &VMM_Malloc;
175     os_hooks.free = &VMM_Free;
176     os_hooks.vaddr_to_paddr = &Identity;
177     os_hooks.paddr_to_vaddr = &Identity;
178
179  
180     //   DumpGDT();
181     Init_VMM(&os_hooks, &vmm_ops);
182   
183     init_shadow_map(&(vm_info.mem_map));
184     init_shadow_page_state(&(vm_info.shdw_pg_state));
185     vm_info.page_mode = SHADOW_PAGING;
186
187     vm_info.cpu_mode = REAL;
188
189     //init_irq_map(&(vm_info.irq_map));
190     init_vmm_io_map(&(vm_info.io_map));
191     init_interrupt_state(&vm_info);
192
193     dev_mgr_init(&(vm_info.dev_mgr));
194     
195     if (0) {
196       
197       //    add_shared_mem_range(&(vm_info.mem_layout), 0, 0x800000, 0x10000);    
198       //    add_shared_mem_range(&(vm_info.mem_layout), 0, 0x1000000, 0);
199       
200       rip = (ulong_t)(void*)&BuzzVM;
201       //  rip -= 0x10000;
202       //    rip = (addr_t)(void*)&exit_test;
203       //  rip -= 0x2000;
204       vm_info.rip = rip;
205       rsp = (addr_t)Alloc_Page();
206       
207       vm_info.vm_regs.rsp = (rsp +4092 );// - 0x2000;
208       
209             
210     } else if (0) {
211       //add_shared_mem_range(&(vm_info.mem_layout), 0x0, 0x1000, 0x100000);
212       //      add_shared_mem_range(&(vm_info.mem_layout), 0x0, 0x100000, 0x0);
213       
214       /*
215         shadow_region_t *ent = Malloc(sizeof(shadow_region_t));;
216         init_shadow_region_physical(ent,0,0x100000,GUEST_REGION_PHYSICAL_MEMORY,
217         0x100000, HOST_REGION_PHYSICAL_MEMORY);
218         add_shadow_region(&(vm_info.mem_map),ent);
219       */
220
221       add_shadow_region_passthrough(&vm_info, 0x0, 0x100000, 0x100000);
222
223       hook_io_port(&(vm_info.io_map), 0x61, &IO_Read, &IO_Write, NULL);
224       hook_io_port(&(vm_info.io_map), 0x05, &IO_Read, &IO_Write_to_Serial, NULL);
225       
226       /*
227         vm_info.cr0 = 0;
228         vm_info.cs.base=0xf000;
229         vm_info.cs.limit=0xffff;
230       */
231       //vm_info.rip = 0xfff0;
232
233       vm_info.rip = 0;
234       vm_info.vm_regs.rsp = 0x0;
235     } else {
236       int i;
237       void * region_start;
238
239  
240       PrintDebug("Guest Size: %lu\n", bootInfo->guest_size);
241
242       struct guest_mem_layout * layout = (struct guest_mem_layout *)0x100000;
243
244       if (layout->magic != MAGIC_CODE) {
245         PrintDebug("Layout Magic Mismatch (0x%x)\n", layout->magic);
246       }
247
248       PrintDebug("%d layout regions\n", layout->num_regions);
249
250       region_start = (void *)&(layout->regions[layout->num_regions]);
251
252       PrintDebug("region start = 0x%x\n", region_start);
253
254       for (i = 0; i < layout->num_regions; i++) {
255         struct layout_region * reg = &(layout->regions[i]);
256         uint_t num_pages = (reg->length / PAGE_SIZE) + ((reg->length % PAGE_SIZE) ? 1 : 0);
257         void * guest_mem = Allocate_VMM_Pages(num_pages);
258
259         PrintDebug("Layout Region %d bytes\n", reg->length);
260         memcpy(guest_mem, region_start, reg->length);
261         
262         SerialMemDump((unsigned char *)(guest_mem), 16);
263
264         add_shadow_region_passthrough(&vm_info, reg->final_addr, reg->final_addr + (num_pages * PAGE_SIZE), (addr_t)guest_mem);
265
266         PrintDebug("Adding Shadow Region (0x%x-0x%x) -> 0x%x\n", reg->final_addr, reg->final_addr + (num_pages * PAGE_SIZE), guest_mem);
267
268         region_start += reg->length;
269       }
270       
271       add_shadow_region_passthrough(&vm_info, 0xc0000, 0xc8000, 0xc0000);
272       add_shadow_region_passthrough(&vm_info, 0x0, 0xa0000, (addr_t)Allocate_VMM_Pages(160));
273       add_shadow_region_passthrough(&vm_info, 0xa0000, 0xc0000, 0xa0000); 
274       if (add_shadow_region_passthrough(&vm_info, 0xc8000, 0xf0000, (addr_t)Allocate_VMM_Pages(40)) == -1) {
275         PrintDebug("Error adding shadow region\n");
276       }
277
278
279       print_shadow_map(&(vm_info.mem_map));
280
281       hook_io_port(&(vm_info.io_map), 0x61, &IO_Read, &IO_Write, NULL);
282       hook_io_port(&(vm_info.io_map), 0x05, &IO_Read, &IO_Write_to_Serial, NULL);
283
284       hook_io_port(&(vm_info.io_map), 0x20, &IO_Read, &IO_Write_to_Serial, NULL);
285       hook_io_port(&(vm_info.io_map), 0x21, &IO_Read, &IO_Write_to_Serial, NULL);
286       hook_io_port(&(vm_info.io_map), 0xa0, &IO_Read, &IO_Write_to_Serial, NULL);
287       hook_io_port(&(vm_info.io_map), 0xa1, &IO_Read, &IO_Write_to_Serial, NULL);
288
289       hook_io_port(&(vm_info.io_map), 0x400, &IO_Read, &IO_Write_to_Serial, NULL);
290       hook_io_port(&(vm_info.io_map), 0x401, &IO_Read, &IO_Write_to_Serial, NULL);
291       hook_io_port(&(vm_info.io_map), 0x402, &IO_Read, &IO_BOCHS_debug, NULL);
292       hook_io_port(&(vm_info.io_map), 0x403, &IO_Read, &IO_Write_to_Serial, NULL);
293
294       {
295         //struct vm_device * nvram = create_nvram();
296         //struct vm_device * timer = create_timer();
297         struct vm_device * pic = create_pic();
298
299         //attach_device(&(vm_info), nvram);
300         //attach_device(&(vm_info), timer);
301         attach_device(&(vm_info), pic);
302
303         PrintDebugDevMgr(&(vm_info.dev_mgr));
304         
305
306
307       }
308
309
310       hook_irq(&vm_info, 6);
311
312       vm_info.rip = 0xfff0;
313       vm_info.vm_regs.rsp = 0x0;
314     }
315
316     PrintBoth("Initializing Guest (eip=0x%.8x) (esp=0x%.8x)\n", (uint_t)vm_info.rip,(uint_t)vm_info.vm_regs.rsp);
317     (vmm_ops).init_guest(&vm_info);
318     PrintBoth("Starting Guest\n");
319     //Clear_Screen();
320     (vmm_ops).start_guest(&vm_info);
321
322     return 0;
323 }