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.


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