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