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.


dce6c85b4c6c4cbc503422480827389056f05337
[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.24 $
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
35 #include <geekos/gdt.h>
36
37
38 #include <geekos/vmm_stubs.h>
39
40
41 #define SPEAKER_PORT 0x61
42
43
44 void Buzz(unsigned delay, unsigned num)
45 {
46   volatile int x;
47   int i,j;
48   unsigned char init;
49   
50   init=In_Byte(SPEAKER_PORT);
51
52   for (i=0;i<num;i++) { 
53     Out_Byte(SPEAKER_PORT, init|0x2);
54     for (j=0;j<delay;j++) { 
55       x+=j;
56     }
57     Out_Byte(SPEAKER_PORT, init);
58     for (j=0;j<delay;j++) { 
59       x+=j;
60     }
61   }
62 }
63
64 inline void MyOut_Byte(ushort_t port, uchar_t value)
65 {
66     __asm__ __volatile__ (
67         "outb %b0, %w1"
68         :
69         : "a" (value), "Nd" (port)
70     );
71 }
72
73 /*
74  * Read a byte from an I/O port.
75  */
76 inline uchar_t MyIn_Byte(ushort_t port)
77 {
78     uchar_t value;
79
80     __asm__ __volatile__ (
81         "inb %w1, %b0"
82         : "=a" (value)
83         : "Nd" (port)
84     );
85
86     return value;
87 }
88
89
90
91 int IO_Read(ushort_t port, void * dst, uint_t length) {
92   uchar_t * iter = dst;
93   uint_t i;
94
95   for (i = 0; i < length; i++) {
96     *iter = MyIn_Byte(port);    
97     iter++;
98   }
99   
100   return 0;
101 }
102
103
104
105 int IO_Write(ushort_t port, void * src, uint_t length) {
106   uchar_t * iter = src;
107   uint_t i;
108
109
110   for (i = 0; i < length; i++) {
111     MyOut_Byte(port, *iter);    
112     iter++;
113   }
114
115   return 0;
116 }
117
118
119 void BuzzVM()
120 {
121   int x;
122   int j;
123   unsigned char init;
124
125 #if 0  
126   __asm__ __volatile__ (
127     "popf"
128     );
129     
130 #endif
131     
132   PrintBoth("Starting To Buzz\n");
133
134   init=MyIn_Byte(SPEAKER_PORT);
135
136   while (1) {
137     MyOut_Byte(SPEAKER_PORT, init|0x2);
138     for (j=0;j<1000000;j++) { 
139       x+=j;
140     }
141     MyOut_Byte(SPEAKER_PORT, init);
142     for (j=0;j<1000000;j++) { 
143       x+=j;
144     }
145   }
146 }
147
148
149
150
151
152
153
154
155 void Buzzer(ulong_t arg) {
156   ulong_t *doIBuzz = (ulong_t*)arg;
157   while (1) {
158     // Quick and dirty hack to save my hearing...
159     // I'm not too worried about timing, so I'll deal with concurrency later...
160     if (*doIBuzz == 1) {
161       Buzz(1000000, 10);
162     }
163   }
164
165 }
166
167
168
169
170
171 void Keyboard_Listener(ulong_t arg) {
172   ulong_t * doIBuzz = (ulong_t*)arg;
173   Keycode key_press;
174
175   Print("Press F4 to turn on/off the speaker\n");
176
177   while ((key_press = Wait_For_Key())) {    
178     if (key_press == KEY_F4) {
179       Print("\nToggling Speaker Port\n");
180       SerialPrintLevel(100,"\nToggling Speaker Port\n");
181       *doIBuzz = (*doIBuzz + 1) % 2;
182     } else if (key_press == KEY_F5) {
183       Print("\nMachine Restart\n");
184       SerialPrintLevel(100,"\nMachine Restart\n");
185       machine_real_restart();
186     }
187   }
188   return;
189 }
190
191
192
193 extern char BSS_START, BSS_END;
194
195 extern char end;
196
197
198 /* This is an ugly hack to get at the VM  memory */
199 ulong_t vm_range_start;
200 ulong_t vm_range_end;
201 ulong_t guest_kernel_start;
202 ulong_t guest_kernel_end;
203 /* ** */
204
205
206 int AllocateAndMapPagesForRange(uint_t start, uint_t length, pte_t template_pte)
207 {
208   uint_t address;
209
210   for (address=start;address<start+length;address+=PAGE_SIZE) { 
211     void *page;
212     pte_t pte = template_pte;
213     
214     page=Alloc_Page();
215     KASSERT(page);
216     
217     pte.pageBaseAddr=PAGE_ALLIGNED_ADDR(page);
218
219     KASSERT(MapPage((void*)address,&pte,1));
220   }
221   
222   return 0;
223 }
224     
225
226
227 /*
228  * Kernel C code entry point.
229  * Initializes kernel subsystems, mounts filesystems,
230  * and spawns init process.
231  */
232 void Main(struct Boot_Info* bootInfo)
233 {
234   struct Kernel_Thread * key_thread;
235   struct Kernel_Thread * spkr_thread;
236
237   ulong_t doIBuzz = 0;
238
239   Init_BSS();
240   Init_Screen();
241
242
243   Init_Serial();
244   Init_Mem(bootInfo);
245   Init_CRC32();
246   Init_TSS();
247   Init_Interrupts();
248   Init_Scheduler();
249   Init_Traps();
250   Init_Timer();
251   Init_Keyboard();
252   Init_VM(bootInfo);
253   Init_Paging();
254
255   //  Init_IDE();
256
257   // Print("Done; stalling\n");
258
259
260   
261 #if 0
262   SerialPrint("Dumping VM kernel Code (first 128 bytes @ 0x%x)\n", 0x100000);
263   SerialMemDump((unsigned char *)0xfe000, 4096);
264   /*
265     SerialPrint("Dumping kernel Code (first 512 bytes @ 0x%x)\n",KERNEL_START);
266     SerialMemDump((unsigned char *)VM_KERNEL_START, 512);
267   */
268 #endif
269
270 #if 0
271   SerialPrint("Dumping BIOS code f0000-fffff\n\n");
272   SerialMemDump((unsigned char *)0xf0000, 65536);
273   /*
274     SerialPrint("Dumping kernel Code (first 512 bytes @ 0x%x)\n",KERNEL_START);
275     SerialMemDump((unsigned char *)VM_KERNEL_START, 512);
276   */
277 #endif
278
279 #if 1
280   SerialPrintLevel(1000,"Launching Noisemaker and keyboard listener threads\n");
281   key_thread = Start_Kernel_Thread(Keyboard_Listener, (ulong_t)&doIBuzz, PRIORITY_NORMAL, false);
282   spkr_thread = Start_Kernel_Thread(Buzzer, (ulong_t)&doIBuzz, PRIORITY_NORMAL, false);
283
284 #endif
285
286   {
287     struct vmm_os_hooks os_hooks;
288     struct vmm_ctrl_ops vmm_ops;
289     guest_info_t vm_info;
290     addr_t rsp;
291     addr_t rip;
292
293     memset(&os_hooks, 0, sizeof(struct vmm_os_hooks));
294     memset(&vmm_ops, 0, sizeof(struct vmm_ctrl_ops));
295     memset(&vm_info, 0, sizeof(guest_info_t));
296
297     os_hooks.print_debug = &PrintBoth;
298     os_hooks.print_info = &Print;
299     os_hooks.print_trace = &SerialPrint;
300     os_hooks.allocate_pages = &Allocate_VMM_Pages;
301     os_hooks.free_page = &Free_VMM_Page;
302     os_hooks.malloc = &VMM_Malloc;
303     os_hooks.free = &VMM_Free;
304     os_hooks.vaddr_to_paddr = &Identity;
305     os_hooks.paddr_to_vaddr = &Identity;
306
307
308     //   DumpGDT();
309     Init_VMM(&os_hooks, &vmm_ops);
310   
311     init_shadow_map(&(vm_info.mem_map));
312     init_shadow_page_state(&(vm_info.shadow_page_state));
313     vm_info.page_mode = SHADOW_PAGING;
314
315     vm_info.cpu_mode = REAL;
316
317     init_vmm_io_map(&(vm_info.io_map));
318
319     
320     if (0) {
321       
322       //    add_shared_mem_range(&(vm_info.mem_layout), 0, 0x800000, 0x10000);    
323       //    add_shared_mem_range(&(vm_info.mem_layout), 0, 0x1000000, 0);
324       
325       rip = (ulong_t)(void*)&BuzzVM;
326       //  rip -= 0x10000;
327       //    rip = (addr_t)(void*)&exit_test;
328       //  rip -= 0x2000;
329       vm_info.rip = rip;
330       rsp = (addr_t)Alloc_Page();
331       
332       vm_info.rsp = (rsp +4092 );// - 0x2000;
333       
334             
335     } else {
336       //add_shared_mem_range(&(vm_info.mem_layout), 0x0, 0x1000, 0x100000);
337       //      add_shared_mem_range(&(vm_info.mem_layout), 0x0, 0x100000, 0x0);
338       
339       shadow_region_t *ent = Malloc(sizeof(shadow_region_t));;
340       init_shadow_region_physical(ent,0,0x100000,GUEST_REGION_PHYSICAL_MEMORY,
341                                   0x100000, HOST_REGION_PHYSICAL_MEMORY);
342       add_shadow_region(&(vm_info.mem_map),ent);
343
344       hook_io_port(&(vm_info.io_map), 0x61, &IO_Read, &IO_Write);
345       /*
346       vm_info.cr0 = 0;
347       vm_info.cs.base=0xf000;
348       vm_info.cs.limit=0xffff;
349       */
350       vm_info.rip = 0xfff0;
351       vm_info.rsp = 0x0;
352     }
353
354     PrintBoth("Initializing Guest (eip=0x%.8x) (esp=0x%.8x)\n", (uint_t)vm_info.rip,(uint_t)vm_info.rsp);
355     (vmm_ops).init_guest(&vm_info);
356     PrintBoth("Starting Guest\n");
357     (vmm_ops).start_guest(&vm_info);
358   }
359
360
361   
362
363
364   TODO("Write a Virtual Machine Monitor");
365   
366
367   Exit(0);
368 }