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.


modified copyright tags
[palacios.git] / palacios / src / geekos / vm.c
1 /* (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> */
2 /* (c) 2008, The V3VEE Project <http://www.v3vee.org> */
3
4 #include <geekos/vmm_stubs.h>
5
6 #include <geekos/debug.h>
7 #include <geekos/serial.h>
8 #include <geekos/vm.h>
9 #include <geekos/screen.h>
10
11 #include <palacios/vmm.h>
12 #include <palacios/vmm_io.h>
13
14
15
16 #define SPEAKER_PORT 0x61
17
18 static inline void VM_Out_Byte(ushort_t port, uchar_t value)
19 {
20     __asm__ __volatile__ (
21         "outb %b0, %w1"
22         :
23         : "a" (value), "Nd" (port)
24     );
25 }
26
27 /*
28  * Read a byte from an I/O port.
29  */
30 static inline uchar_t VM_In_Byte(ushort_t port)
31 {
32     uchar_t value;
33
34     __asm__ __volatile__ (
35         "inb %w1, %b0"
36         : "=a" (value)
37         : "Nd" (port)
38     );
39
40     return value;
41 }
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 char * bochs_info_buf = NULL;
81 int bochs_info_offset = 0;
82
83
84 int IO_BOCHS_debug(ushort_t port, void * src, uint_t length, void * priv_data) {
85   if (!bochs_debug_buf) {
86     bochs_debug_buf = (char*)Malloc(1024);
87   }
88
89   bochs_debug_buf[bochs_debug_offset++] = *(char*)src;
90
91   if ((*(char*)src == 0xa) ||  (bochs_debug_offset == 1023)) {
92     SerialPrint("BOCHSDEBUG>%s", bochs_debug_buf);
93     memset(bochs_debug_buf, 0, 1024);
94     bochs_debug_offset = 0;
95   }
96
97   return length;
98 }
99
100 int IO_BOCHS_info(ushort_t port, void * src, uint_t length, void * priv_data) {
101   if (!bochs_info_buf) {
102     bochs_info_buf = (char*)Malloc(1024);
103   }
104
105   bochs_info_buf[bochs_info_offset++] = *(char*)src;
106
107   if ((*(char*)src == 0xa) ||  (bochs_info_offset == 1023)) {
108     SerialPrint("BOCHSINFO>%s", bochs_info_buf);
109     memset(bochs_info_buf, 0, 1024);
110     bochs_info_offset = 0;
111   }
112
113   return length;
114 }
115
116
117 int IO_Write_to_Serial(ushort_t port, void * src, uint_t length, void * priv_data) {
118  SerialPrint("Output from Guest on port %d (0x%x) Length=%d\n", port, port, length);
119   switch (length) {
120
121   case 1:
122     SerialPrint(">0x%.2x\n", *(char*)src);
123     break;
124   case 2:
125     SerialPrint(">0x%.4x\n", *(ushort_t*)src);
126     break;
127   case 4:
128     SerialPrint(">0x%.8x\n", *(uint_t*)src);
129     break;
130   default:
131     break;
132   }
133
134   //  SerialMemDump(src, length);
135   return length;
136 }
137
138
139
140 void BuzzVM()
141 {
142   int x;
143   int j;
144   unsigned char init;
145
146 #if 0  
147   __asm__ __volatile__ (
148     "popf"
149     );
150     
151 #endif
152     
153   PrintBoth("Starting To Buzz\n");
154
155   init=VM_In_Byte(SPEAKER_PORT);
156
157   while (1) {
158     VM_Out_Byte(SPEAKER_PORT, init|0x2);
159     for (j=0;j<1000000;j++) { 
160       x+=j;
161     }
162     VM_Out_Byte(SPEAKER_PORT, init);
163     for (j=0;j<1000000;j++) { 
164       x+=j;
165     }
166   }
167 }
168
169
170 /*
171 int passthrough_mem_read(void * guest_addr, void * dst, uint_t length, void * priv_data) {
172   memcpy(dst, (void*)guest_addr, length);
173   return length;
174 }
175
176 int passthrough_mem_write(void * guest_addr, void * src, uint_t length, void * priv_data) {
177   memcpy((void*)guest_addr, src, length);
178   return length;
179 }
180 */
181
182
183 /* We need a configuration mechanism, so we can wrap this completely inside the VMM code, 
184  * with no pollution into the HOST OS
185  */
186
187 int RunVMM(struct Boot_Info * bootInfo) {
188   void * config_data;
189
190   struct vmm_os_hooks os_hooks;
191   struct vmm_ctrl_ops vmm_ops;
192   struct guest_info * vm_info = 0;
193   
194
195
196   
197   memset(&os_hooks, 0, sizeof(struct vmm_os_hooks));
198   memset(&vmm_ops, 0, sizeof(struct vmm_ctrl_ops));
199
200   
201   os_hooks.print_debug = &SerialPrint;
202   os_hooks.print_info = &Print;
203   os_hooks.print_trace = &SerialPrint;
204   os_hooks.allocate_pages = &Allocate_VMM_Pages;
205   os_hooks.free_page = &Free_VMM_Page;
206   os_hooks.malloc = &VMM_Malloc;
207   os_hooks.free = &VMM_Free;
208   os_hooks.vaddr_to_paddr = &Identity;
209   os_hooks.paddr_to_vaddr = &Identity;
210   os_hooks.hook_interrupt = &geekos_hook_interrupt_new;
211   os_hooks.ack_irq = &ack_irq;
212   os_hooks.get_cpu_khz = &get_cpu_khz;
213
214
215   
216   Init_V3(&os_hooks, &vmm_ops);
217
218   extern char _binary_vm_kernel_start;
219   PrintBoth(" Guest Load Addr: 0x%x\n", &_binary_vm_kernel_start);
220   
221   config_data = &_binary_vm_kernel_start;
222
223   vm_info = (vmm_ops).allocate_guest();
224
225   PrintBoth("Allocated Guest\n");
226
227   (vmm_ops).config_guest(vm_info, config_data);
228
229   PrintBoth("Configured guest\n");
230   
231   v3_hook_io_port(vm_info, 0x61, &IO_Read, &IO_Write, NULL);
232   //v3_hook_io_port(&vm_info, 0x05, &IO_Read, &IO_Write_to_Serial, NULL);
233   
234   
235   v3_hook_io_port(vm_info, 0x400, &IO_Read, &IO_Write_to_Serial, NULL);
236   v3_hook_io_port(vm_info, 0x401, &IO_Read, &IO_Write_to_Serial, NULL);
237   v3_hook_io_port(vm_info, 0x402, &IO_Read, &IO_BOCHS_info, NULL);
238   v3_hook_io_port(vm_info, 0x403, &IO_Read, &IO_BOCHS_debug, NULL);
239   
240
241   (vmm_ops).init_guest(vm_info);
242   PrintBoth("Starting Guest\n");
243   //Clear_Screen();
244   (vmm_ops).start_guest(vm_info);
245   
246     return 0;
247 }