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.


WTF??????
[palacios.git] / palacios / src / geekos / main.c
1 /*
2  * GeekOS C code entry point
3  * Copyright (c) 2001,2003,2004 David H. Hovemeyer <daveho@cs.umd.edu>
4  * Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
5  * Copyright (c) 2004, Iulian Neamtiu <neamtiu@cs.umd.edu>
6  * $Revision: 1.18 $
7  * 
8  * This is free software.  You are permitted to use,
9  * redistribute, and modify it as specified in the file "COPYING".
10  */
11
12 #include <geekos/bootinfo.h>
13 #include <geekos/string.h>
14 #include <geekos/screen.h>
15 #include <geekos/mem.h>
16 #include <geekos/crc32.h>
17 #include <geekos/tss.h>
18 #include <geekos/int.h>
19 #include <geekos/kthread.h>
20 #include <geekos/trap.h>
21 #include <geekos/timer.h>
22 #include <geekos/keyboard.h>
23 #include <geekos/io.h>
24 #include <geekos/serial.h>
25 #include <geekos/reboot.h>
26 #include <geekos/mem.h>
27 #include <geekos/paging.h>
28 #include <geekos/ide.h>
29 #include <geekos/malloc.h>
30
31 #include <geekos/debug.h>
32 #include <geekos/vmm.h>
33
34 #include <geekos/gdt.h>
35
36
37 #include <geekos/vmm_stubs.h>
38
39
40
41
42 extern void Get_MSR(ulong_t msr, unsigned int *val1, unsigned int *val2);
43 extern void Set_MSR(ulong_t msr, ulong_t val1, ulong_t val2);
44 extern uint_t Get_EIP();
45 extern uint_t Get_ESP();
46 extern uint_t Get_EBP();
47
48
49 int foo=42;
50
51 #define SPEAKER_PORT 0x61
52
53
54 void Buzz(unsigned delay, unsigned num)
55 {
56   volatile int x;
57   int i,j;
58   unsigned char init;
59   
60   init=In_Byte(SPEAKER_PORT);
61
62   for (i=0;i<num;i++) { 
63     Out_Byte(SPEAKER_PORT, init|0x2);
64     for (j=0;j<delay;j++) { 
65       x+=j;
66     }
67     Out_Byte(SPEAKER_PORT, init);
68     for (j=0;j<delay;j++) { 
69       x+=j;
70     }
71   }
72 }
73
74 inline void MyOut_Byte(ushort_t port, uchar_t value)
75 {
76     __asm__ __volatile__ (
77         "outb %b0, %w1"
78         :
79         : "a" (value), "Nd" (port)
80     );
81 }
82
83 /*
84  * Read a byte from an I/O port.
85  */
86 inline uchar_t MyIn_Byte(ushort_t port)
87 {
88     uchar_t value;
89
90     __asm__ __volatile__ (
91         "inb %w1, %b0"
92         : "=a" (value)
93         : "Nd" (port)
94     );
95
96     return value;
97 }
98
99
100 extern void MyBuzzVM();
101
102 #define MYBUZZVM_START MyBuzzVM
103 #define MYBUZZVM_LEN   0x3d
104
105 void BuzzVM()
106 {
107   int x;
108   int j;
109   unsigned char init;
110   
111     
112   SerialPrint("Starting To Buzz\n");
113
114   init=MyIn_Byte(SPEAKER_PORT);
115
116   while (1) {
117     MyOut_Byte(SPEAKER_PORT, init|0x2);
118     for (j=0;j<1000000;j++) { 
119       x+=j;
120     }
121     MyOut_Byte(SPEAKER_PORT, init);
122     for (j=0;j<1000000;j++) { 
123       x+=j;
124     }
125   }
126 }
127
128 extern void RunVM();
129
130 int vmRunning = 0;
131
132 void RunVM() {
133   vmRunning = 1;
134
135   while(1);
136 }
137
138
139
140
141
142
143 void Buzzer(ulong_t arg) {
144   ulong_t *doIBuzz = (ulong_t*)arg;
145   while (1) {
146     // Quick and dirty hack to save my hearing...
147     // I'm not too worried about timing, so I'll deal with concurrency later...
148     if (*doIBuzz == 1) {
149       Buzz(1000000, 10);
150     }
151   }
152
153 }
154
155
156
157
158
159 void Keyboard_Listener(ulong_t arg) {
160   ulong_t * doIBuzz = (ulong_t*)arg;
161   Keycode key_press;
162
163   Print("Press F4 to turn on/off the speaker\n");
164
165   while ((key_press = Wait_For_Key())) {    
166     if (key_press == KEY_F4) {
167       Print("\nToggling Speaker Port\n");
168       SerialPrintLevel(100,"\nToggling Speaker Port\n");
169       *doIBuzz = (*doIBuzz + 1) % 2;
170     } else if (key_press == KEY_F5) {
171       Print("\nMachine Restart\n");
172       SerialPrintLevel(100,"\nMachine Restart\n");
173       machine_real_restart();
174     }
175   }
176   return;
177 }
178
179
180
181 extern char BSS_START, BSS_END;
182
183 extern char end;
184
185
186 /* This is an ugly hack to get at the VM  memory */
187 ulong_t vm_range_start;
188 ulong_t vm_range_end;
189 ulong_t guest_kernel_start;
190 ulong_t guest_kernel_end;
191 /* ** */
192
193
194 int AllocateAndMapPagesForRange(uint_t start, uint_t length, pte_t template_pte)
195 {
196   uint_t address;
197
198   for (address=start;address<start+length;address+=PAGE_SIZE) { 
199     void *page;
200     pte_t pte = template_pte;
201     
202     page=Alloc_Page();
203     KASSERT(page);
204     
205     pte.pageBaseAddr=PAGE_ALLIGNED_ADDR(page);
206
207     KASSERT(MapPage((void*)address,&pte,1));
208   }
209   
210   return 0;
211 }
212     
213
214
215 /*
216  * Kernel C code entry point.
217  * Initializes kernel subsystems, mounts filesystems,
218  * and spawns init process.
219  */
220 void Main(struct Boot_Info* bootInfo)
221 {
222   struct Kernel_Thread * key_thread;
223   struct Kernel_Thread * spkr_thread;
224   // struct Kernel_Thread * vm_thread;
225   // struct VMDescriptor    vm;
226
227   ulong_t doIBuzz = 0;
228
229   Init_BSS();
230   Init_Screen();
231
232
233   Init_Serial();
234   Init_Mem(bootInfo);
235   Init_CRC32();
236   Init_TSS();
237   Init_Interrupts();
238   Init_Scheduler();
239   Init_Traps();
240   Init_Timer();
241   Init_Keyboard();
242   Init_VM(bootInfo);
243   Init_Paging();
244
245   //  Init_IDE();
246
247   Print("Done; stalling\n");
248
249
250   
251 #if 0
252   SerialPrint("Dumping VM kernel Code (first 512 bytes @ 0x%x)\n",VM_KERNEL_START);
253   SerialMemDump((unsigned char *)VM_KERNEL_START, 512);
254   /*
255     SerialPrint("Dumping kernel Code (first 512 bytes @ 0x%x)\n",KERNEL_START);
256     SerialMemDump((unsigned char *)VM_KERNEL_START, 512);
257   */
258 #endif
259
260 #if 0
261   SerialPrint("Dumping GUEST KERNEL CODE (first 512*2 bytes @ 0x100000)\n");
262   SerialMemDump((unsigned char *)0x100000, 512*2);
263 #endif
264
265   key_thread = Start_Kernel_Thread(Keyboard_Listener, (ulong_t)&doIBuzz, PRIORITY_NORMAL, false);
266   spkr_thread = Start_Kernel_Thread(Buzzer, (ulong_t)&doIBuzz, PRIORITY_NORMAL, false);
267
268
269   {
270     struct vmm_os_hooks os_hooks;
271     struct vmm_ctrl_ops vmm_ops;
272     guest_info_t vm_info;
273     addr_t rsp;
274     addr_t rip;
275
276     memset(&os_hooks, 0, sizeof(struct vmm_os_hooks));
277     memset(&vmm_ops, 0, sizeof(struct vmm_ctrl_ops));
278     memset(&vm_info, 0, sizeof(guest_info_t));
279
280     os_hooks.print_debug = &PrintBoth;
281     os_hooks.print_info = &Print;
282     os_hooks.print_trace = &SerialPrint;
283     os_hooks.allocate_pages = &Allocate_VMM_Pages;
284     os_hooks.free_page = &Free_VMM_Page;
285     os_hooks.malloc = &VMM_Malloc;
286     os_hooks.free = &VMM_Free;
287
288
289     Init_VMM(&os_hooks, &vmm_ops);
290   
291
292     init_mem_layout(&(vm_info.mem_layout));
293     init_mem_list(&(vm_info.mem_list));
294
295
296     add_mem_list_pages(&(vm_info.mem_list), vm_range_start, (vm_range_end - vm_range_start) / PAGE_SIZE);
297     //    add_unmapped_mem_range(&(vm_info.mem_layout), 0, 256);
298     //add_shared_mem_range(&(vm_info.mem_layout), guest_kernel_start, (guest_kernel_end - guest_kernel_start) / PAGE_SIZE, guest_kernel_start);
299     //add_guest_mem_range(&(vm_info.mem_layout), guest_kernel_end, 20);
300
301     add_shared_mem_range(&(vm_info.mem_layout), 0, 0x1000000, 0);
302
303     rip = (ulong_t)(void*)&BuzzVM;
304     vm_info.rip = rip;
305     rsp = (ulong_t)Alloc_Page();
306     vm_info.rsp = rsp;
307
308
309     SerialPrint("Initializing Guest (eip=0x%.8x) (esp=0x%.8x)\n", rip, rsp);
310     (vmm_ops).init_guest(&vm_info);
311     SerialPrint("Starting Guest\n");
312     (vmm_ops).start_guest(&vm_info);
313     
314   }
315
316
317   SerialPrintLevel(1000,"Launching Noisemaker and keyboard listener threads\n");
318   
319
320
321
322
323
324
325   /*
326   // jump into vmxassist
327   vm.entry_ip=(uint_t)0x00107fd0;
328   vm.exit_eip=0;
329   // Put the stack at 512K
330   vm.guest_esp=(uint_t)4096 + 8192 - 4;
331   *(unsigned int *)(vm.guest_esp) = 1024 * 1024;
332   vm.guest_esp -= 4;
333   *(unsigned int *)(vm.guest_esp) = 8;
334   vm.guest_esp -= 4;
335   *(unsigned int *)(vm.guest_esp) = vm.guest_esp + 4;;
336   vm.guest_esp -= 4;
337   *(unsigned int *)(vm.guest_esp) = vm.entry_ip;
338   //  vm.guest_esp -= 4;
339
340  
341   SerialMemDump((unsigned char *)vm.entry_ip, 512);
342   */
343  
344   // vm_thread = Start_Kernel_Thread(VM_Thread, (ulong_t)&vm,PRIORITY_NORMAL,false);
345
346   
347   SerialPrintLevel(1000,"Next: setup GDT\n");
348
349
350
351   TODO("Write a Virtual Machine Monitor");
352   
353   
354   /* Now this thread is done. */
355   Exit(0);
356 }