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.


updated devices to use new host event interface
[palacios.git] / geekos / src / geekos / vm.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
21
22 #include <geekos/vmm_stubs.h>
23
24 #include <geekos/debug.h>
25 #include <geekos/serial.h>
26 #include <geekos/vm.h>
27 #include <geekos/screen.h>
28
29 #include <palacios/vmm.h>
30 #include <palacios/vmm_io.h>
31
32
33 extern void * g_ramdiskImage;
34 extern ulong_t s_ramdiskSize;
35
36
37 #define SPEAKER_PORT 0x61
38
39 static inline void VM_Out_Byte(ushort_t port, uchar_t value)
40 {
41     __asm__ __volatile__ (
42         "outb %b0, %w1"
43         :
44         : "a" (value), "Nd" (port)
45     );
46 }
47
48 /*
49  * Read a byte from an I/O port.
50  */
51 static inline uchar_t VM_In_Byte(ushort_t port)
52 {
53     uchar_t value;
54
55     __asm__ __volatile__ (
56         "inb %w1, %b0"
57         : "=a" (value)
58         : "Nd" (port)
59     );
60
61     return value;
62 }
63
64
65
66
67 int IO_Read(ushort_t port, void * dst, uint_t length, void * priv_data) {
68
69   if (length != 1) {
70     return 0;
71   }
72
73   *(uchar_t*)dst = VM_In_Byte(port);    
74   return 1;
75 }
76
77
78
79 int IO_Write(ushort_t port, void * src, uint_t length, void * priv_data) {
80
81   if (length != 1) {
82     return 0;
83   }
84
85   VM_Out_Byte(port, *(uchar_t *)src);    
86
87   return 1;
88 }
89
90
91 int IO_Read_to_Serial(ushort_t port, void * dst, uint_t length, void * priv_data) {
92   PrintBoth("Input from Guest on port %d (0x%x) Length=%d\n", port, port, length);
93   
94   return 0;
95 }
96
97
98 char * bochs_debug_buf = NULL;
99 int bochs_debug_offset = 0;
100
101 char * bochs_info_buf = NULL;
102 int bochs_info_offset = 0;
103
104
105 int IO_BOCHS_debug(ushort_t port, void * src, uint_t length, void * priv_data) {
106   if (!bochs_debug_buf) {
107     bochs_debug_buf = (char*)Malloc(1024);
108   }
109
110   bochs_debug_buf[bochs_debug_offset++] = *(char*)src;
111
112   if ((*(char*)src == 0xa) ||  (bochs_debug_offset == 1023)) {
113     SerialPrint("BOCHSDEBUG>%s", bochs_debug_buf);
114     memset(bochs_debug_buf, 0, 1024);
115     bochs_debug_offset = 0;
116   }
117
118   return length;
119 }
120
121 int IO_BOCHS_info(ushort_t port, void * src, uint_t length, void * priv_data) {
122   if (!bochs_info_buf) {
123     bochs_info_buf = (char*)Malloc(1024);
124   }
125
126   bochs_info_buf[bochs_info_offset++] = *(char*)src;
127
128   if ((*(char*)src == 0xa) ||  (bochs_info_offset == 1023)) {
129     SerialPrint("BOCHSINFO>%s", bochs_info_buf);
130     memset(bochs_info_buf, 0, 1024);
131     bochs_info_offset = 0;
132   }
133
134   return length;
135 }
136
137
138 int IO_Write_to_Serial(ushort_t port, void * src, uint_t length, void * priv_data) {
139  SerialPrint("Output from Guest on port %d (0x%x) Length=%d\n", port, port, length);
140   switch (length) {
141
142   case 1:
143     SerialPrint(">0x%.2x\n", *(char*)src);
144     break;
145   case 2:
146     SerialPrint(">0x%.4x\n", *(ushort_t*)src);
147     break;
148   case 4:
149     SerialPrint(">0x%.8x\n", *(uint_t*)src);
150     break;
151   default:
152     break;
153   }
154
155   //  SerialMemDump(src, length);
156   return length;
157 }
158
159
160
161 void BuzzVM()
162 {
163   int x;
164   int j;
165   unsigned char init;
166
167 #if 0  
168   __asm__ __volatile__ (
169     "popf"
170     );
171     
172 #endif
173     
174   PrintBoth("Starting To Buzz\n");
175
176   init=VM_In_Byte(SPEAKER_PORT);
177
178   while (1) {
179     VM_Out_Byte(SPEAKER_PORT, init|0x2);
180     for (j=0;j<1000000;j++) { 
181       x+=j;
182     }
183     VM_Out_Byte(SPEAKER_PORT, init);
184     for (j=0;j<1000000;j++) { 
185       x+=j;
186     }
187   }
188 }
189
190
191 /*
192 int passthrough_mem_read(void * guest_addr, void * dst, uint_t length, void * priv_data) {
193   memcpy(dst, (void*)guest_addr, length);
194   return length;
195 }
196
197 int passthrough_mem_write(void * guest_addr, void * src, uint_t length, void * priv_data) {
198   memcpy((void*)guest_addr, src, length);
199   return length;
200 }
201 */
202
203
204 /* We need a configuration mechanism, so we can wrap this completely inside the VMM code, 
205  * with no pollution into the HOST OS
206  */
207
208 int RunVMM(struct Boot_Info * bootInfo) {
209   struct vmm_os_hooks os_hooks;
210   struct vmm_ctrl_ops vmm_ops;
211   struct guest_info * vm_info = 0;
212   struct v3_vm_config vm_config;
213
214
215
216   memset(&os_hooks, 0, sizeof(struct vmm_os_hooks));
217   memset(&vmm_ops, 0, sizeof(struct vmm_ctrl_ops));
218   memset(&vm_config, 0, sizeof(struct v3_vm_config));
219
220   
221   os_hooks.print_debug = &SerialPrint;
222   os_hooks.print_info = &Print;
223   os_hooks.print_trace = &SerialPrint;
224   os_hooks.allocate_pages = &Allocate_VMM_Pages;
225   os_hooks.free_page = &Free_VMM_Page;
226   os_hooks.malloc = &VMM_Malloc;
227   os_hooks.free = &VMM_Free;
228   os_hooks.vaddr_to_paddr = &Identity;
229   os_hooks.paddr_to_vaddr = &Identity;
230   os_hooks.hook_interrupt = &geekos_hook_interrupt;
231   os_hooks.ack_irq = &ack_irq;
232   os_hooks.get_cpu_khz = &get_cpu_khz;
233
234
235   
236   Init_V3(&os_hooks, &vmm_ops);
237
238
239   extern char _binary___palacios_vm_kernel_start;
240   PrintBoth(" Guest Load Addr: 0x%x\n", &_binary___palacios_vm_kernel_start);
241   
242   vm_config.vm_kernel = &_binary___palacios_vm_kernel_start;
243   
244   
245   if (g_ramdiskImage != NULL) {
246     vm_config.use_ramdisk = 1;
247     vm_config.ramdisk = g_ramdiskImage;
248     vm_config.ramdisk_size = s_ramdiskSize;
249   }
250
251
252
253
254   vm_info = (vmm_ops).allocate_guest();
255
256   Init_Stubs(vm_info);
257
258   PrintBoth("Allocated Guest\n");
259
260   (vmm_ops).config_guest(vm_info, &vm_config);
261
262   PrintBoth("Configured guest\n");
263
264
265   //v3_hook_io_port(&vm_info, 0x05, &IO_Read, &IO_Write_to_Serial, NULL);
266   
267   //v3_hook_io_port(vm_info, 0x61, &IO_Read, &IO_Write, NULL);
268   //v3_hook_io_port(vm_info, 0x400, &IO_Read, &IO_Write_to_Serial, NULL);
269   //v3_hook_io_port(vm_info, 0x401, &IO_Read, &IO_Write_to_Serial, NULL);
270   //v3_hook_io_port(vm_info, 0x402, &IO_Read, &IO_BOCHS_info, NULL);
271   //v3_hook_io_port(vm_info, 0x403, &IO_Read, &IO_BOCHS_debug, NULL);
272   
273
274   (vmm_ops).init_guest(vm_info);
275   PrintBoth("Starting Guest\n");
276   //Clear_Screen();
277
278   (vmm_ops).start_guest(vm_info);
279   
280     return 0;
281 }