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.


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