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.


got the bios setup ok, now we have to handle the exits
[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
6
7 #define SPEAKER_PORT 0x61
8
9
10
11
12 inline void VM_Out_Byte(ushort_t port, uchar_t value)
13 {
14     __asm__ __volatile__ (
15         "outb %b0, %w1"
16         :
17         : "a" (value), "Nd" (port)
18     );
19 }
20
21 /*
22  * Read a byte from an I/O port.
23  */
24 inline uchar_t VM_In_Byte(ushort_t port)
25 {
26     uchar_t value;
27
28     __asm__ __volatile__ (
29         "inb %w1, %b0"
30         : "=a" (value)
31         : "Nd" (port)
32     );
33
34     return value;
35 }
36
37
38
39 int IO_Read(ushort_t port, void * dst, uint_t length) {
40   uchar_t * iter = dst;
41   uint_t i;
42
43   for (i = 0; i < length; i++) {
44     *iter = VM_In_Byte(port);    
45     iter++;
46   }
47   
48   return 0;
49 }
50
51
52
53 int IO_Write(ushort_t port, void * src, uint_t length) {
54   uchar_t * iter = src;
55   uint_t i;
56
57
58   for (i = 0; i < length; i++) {
59     VM_Out_Byte(port, *iter);    
60     iter++;
61   }
62
63   return 0;
64 }
65
66
67 int IO_Read_to_Serial(ushort_t port, void * dst, uint_t length) {
68   PrintBoth("Input from Guest on port %d (0x%x) Length=%d\n", port, port, length);
69   
70   return 0;
71 }
72
73
74
75 int IO_Write_to_Serial(ushort_t port, void * src, uint_t length) {
76   PrintBoth("Output from Guest on port %d (0x%x) Length=%d\n", port, port, length);
77   switch (length) {
78
79   case 1:
80     PrintBoth(">0x%.2x\n", *(char*)src);
81     break;
82   case 2:
83     PrintBoth(">0x%.4x\n", *(ushort_t*)src);
84     break;
85   case 4:
86     PrintBoth(">0x%.8x\n", *(uint_t*)src);
87     break;
88   default:
89     break;
90   }
91
92   //  SerialMemDump(src, length);
93   return length;
94 }
95
96
97
98 void BuzzVM()
99 {
100   int x;
101   int j;
102   unsigned char init;
103
104 #if 0  
105   __asm__ __volatile__ (
106     "popf"
107     );
108     
109 #endif
110     
111   PrintBoth("Starting To Buzz\n");
112
113   init=VM_In_Byte(SPEAKER_PORT);
114
115   while (1) {
116     VM_Out_Byte(SPEAKER_PORT, init|0x2);
117     for (j=0;j<1000000;j++) { 
118       x+=j;
119     }
120     VM_Out_Byte(SPEAKER_PORT, init);
121     for (j=0;j<1000000;j++) { 
122       x+=j;
123     }
124   }
125 }
126
127
128
129
130
131
132 int RunVMM(struct Boot_Info * bootInfo) {
133
134     struct vmm_os_hooks os_hooks;
135     struct vmm_ctrl_ops vmm_ops;
136     struct guest_info vm_info;
137     addr_t rsp;
138     addr_t rip;
139
140     memset(&os_hooks, 0, sizeof(struct vmm_os_hooks));
141     memset(&vmm_ops, 0, sizeof(struct vmm_ctrl_ops));
142     memset(&vm_info, 0, sizeof(struct guest_info));
143
144     os_hooks.print_debug = &PrintBoth;
145     os_hooks.print_info = &Print;
146     os_hooks.print_trace = &SerialPrint;
147     os_hooks.allocate_pages = &Allocate_VMM_Pages;
148     os_hooks.free_page = &Free_VMM_Page;
149     os_hooks.malloc = &VMM_Malloc;
150     os_hooks.free = &VMM_Free;
151     os_hooks.vaddr_to_paddr = &Identity;
152     os_hooks.paddr_to_vaddr = &Identity;
153
154
155     //   DumpGDT();
156     Init_VMM(&os_hooks, &vmm_ops);
157   
158     init_shadow_map(&(vm_info.mem_map));
159     init_shadow_page_state(&(vm_info.shdw_pg_state));
160     vm_info.page_mode = SHADOW_PAGING;
161
162     vm_info.cpu_mode = REAL;
163
164     init_vmm_io_map(&(vm_info.io_map));
165
166     
167     if (0) {
168       
169       //    add_shared_mem_range(&(vm_info.mem_layout), 0, 0x800000, 0x10000);    
170       //    add_shared_mem_range(&(vm_info.mem_layout), 0, 0x1000000, 0);
171       
172       rip = (ulong_t)(void*)&BuzzVM;
173       //  rip -= 0x10000;
174       //    rip = (addr_t)(void*)&exit_test;
175       //  rip -= 0x2000;
176       vm_info.rip = rip;
177       rsp = (addr_t)Alloc_Page();
178       
179       vm_info.vm_regs.rsp = (rsp +4092 );// - 0x2000;
180       
181             
182     } else if (0) {
183       //add_shared_mem_range(&(vm_info.mem_layout), 0x0, 0x1000, 0x100000);
184       //      add_shared_mem_range(&(vm_info.mem_layout), 0x0, 0x100000, 0x0);
185       
186       shadow_region_t *ent = Malloc(sizeof(shadow_region_t));;
187       init_shadow_region_physical(ent,0,0x100000,GUEST_REGION_PHYSICAL_MEMORY,
188                                   0x100000, HOST_REGION_PHYSICAL_MEMORY);
189       add_shadow_region(&(vm_info.mem_map),ent);
190
191       hook_io_port(&(vm_info.io_map), 0x61, &IO_Read, &IO_Write);
192       hook_io_port(&(vm_info.io_map), 0x05, &IO_Read, &IO_Write_to_Serial);
193       
194       /*
195       vm_info.cr0 = 0;
196       vm_info.cs.base=0xf000;
197       vm_info.cs.limit=0xffff;
198       */
199       //vm_info.rip = 0xfff0;
200
201       vm_info.rip = 0;
202       vm_info.vm_regs.rsp = 0x0;
203     } else {
204       shadow_region_t *ent = Malloc(sizeof(shadow_region_t));
205       /*
206         init_shadow_region_physical(ent,0xf0000,0x100000,GUEST_REGION_PHYSICAL_MEMORY,
207         0x100000, HOST_REGION_PHYSICAL_MEMORY);
208         add_shadow_region(&(vm_info.mem_map),ent);
209         ent = Malloc(sizeof(shadow_region_t));
210       */
211       void * guest_mem = Allocate_VMM_Pages(256);
212
213       PrintDebug("Guest Size: %lu\n", bootInfo->guest_size);
214
215       memcpy((void *)(guest_mem + 0xf0000), (void *)0x100000, bootInfo->guest_size);
216
217
218       SerialMemDump((unsigned char *)(guest_mem + 0xffff0), 16);
219
220       init_shadow_region_physical(ent, 0x0, 0x100000, GUEST_REGION_PHYSICAL_MEMORY, 
221                                   (addr_t)guest_mem, HOST_REGION_PHYSICAL_MEMORY);
222       add_shadow_region(&(vm_info.mem_map),ent);
223
224       hook_io_port(&(vm_info.io_map), 0x61, &IO_Read, &IO_Write);
225       hook_io_port(&(vm_info.io_map), 0x05, &IO_Read, &IO_Write_to_Serial);
226
227       hook_io_port(&(vm_info.io_map), 0x20, &IO_Read, &IO_Write_to_Serial);
228       hook_io_port(&(vm_info.io_map), 0x21, &IO_Read, &IO_Write_to_Serial);
229       hook_io_port(&(vm_info.io_map), 0xa0, &IO_Read, &IO_Write_to_Serial);
230       hook_io_port(&(vm_info.io_map), 0xa1, &IO_Read, &IO_Write_to_Serial);
231
232       vm_info.rip = 0xfff0;
233       vm_info.vm_regs.rsp = 0x0;
234     }
235
236     PrintBoth("Initializing Guest (eip=0x%.8x) (esp=0x%.8x)\n", (uint_t)vm_info.rip,(uint_t)vm_info.vm_regs.rsp);
237     (vmm_ops).init_guest(&vm_info);
238     PrintBoth("Starting Guest\n");
239     (vmm_ops).start_guest(&vm_info);
240
241     return 0;
242
243 }