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.


working paged real mode
[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.19 $
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     
125   PrintBoth("Starting To Buzz\n");
126
127   init=MyIn_Byte(SPEAKER_PORT);
128
129   while (1) {
130     MyOut_Byte(SPEAKER_PORT, init|0x2);
131     for (j=0;j<1000000;j++) { 
132       x+=j;
133     }
134     MyOut_Byte(SPEAKER_PORT, init);
135     for (j=0;j<1000000;j++) { 
136       x+=j;
137     }
138   }
139 }
140
141
142
143
144
145
146
147
148 void Buzzer(ulong_t arg) {
149   ulong_t *doIBuzz = (ulong_t*)arg;
150   while (1) {
151     // Quick and dirty hack to save my hearing...
152     // I'm not too worried about timing, so I'll deal with concurrency later...
153     if (*doIBuzz == 1) {
154       Buzz(1000000, 10);
155     }
156   }
157
158 }
159
160
161
162
163
164 void Keyboard_Listener(ulong_t arg) {
165   ulong_t * doIBuzz = (ulong_t*)arg;
166   Keycode key_press;
167
168   Print("Press F4 to turn on/off the speaker\n");
169
170   while ((key_press = Wait_For_Key())) {    
171     if (key_press == KEY_F4) {
172       Print("\nToggling Speaker Port\n");
173       SerialPrintLevel(100,"\nToggling Speaker Port\n");
174       *doIBuzz = (*doIBuzz + 1) % 2;
175     } else if (key_press == KEY_F5) {
176       Print("\nMachine Restart\n");
177       SerialPrintLevel(100,"\nMachine Restart\n");
178       machine_real_restart();
179     }
180   }
181   return;
182 }
183
184
185
186 extern char BSS_START, BSS_END;
187
188 extern char end;
189
190
191 /* This is an ugly hack to get at the VM  memory */
192 ulong_t vm_range_start;
193 ulong_t vm_range_end;
194 ulong_t guest_kernel_start;
195 ulong_t guest_kernel_end;
196 /* ** */
197
198
199 int AllocateAndMapPagesForRange(uint_t start, uint_t length, pte_t template_pte)
200 {
201   uint_t address;
202
203   for (address=start;address<start+length;address+=PAGE_SIZE) { 
204     void *page;
205     pte_t pte = template_pte;
206     
207     page=Alloc_Page();
208     KASSERT(page);
209     
210     pte.pageBaseAddr=PAGE_ALLIGNED_ADDR(page);
211
212     KASSERT(MapPage((void*)address,&pte,1));
213   }
214   
215   return 0;
216 }
217     
218
219
220 /*
221  * Kernel C code entry point.
222  * Initializes kernel subsystems, mounts filesystems,
223  * and spawns init process.
224  */
225 void Main(struct Boot_Info* bootInfo)
226 {
227   struct Kernel_Thread * key_thread;
228   struct Kernel_Thread * spkr_thread;
229
230   ulong_t doIBuzz = 0;
231
232   Init_BSS();
233   Init_Screen();
234
235
236   Init_Serial();
237   Init_Mem(bootInfo);
238   Init_CRC32();
239   Init_TSS();
240   Init_Interrupts();
241   Init_Scheduler();
242   Init_Traps();
243   Init_Timer();
244   Init_Keyboard();
245   Init_VM(bootInfo);
246   Init_Paging();
247
248   //  Init_IDE();
249
250   Print("Done; stalling\n");
251
252
253   
254 #if 1
255   SerialPrint("Dumping VM kernel Code (first 128 bytes @ 0x%x)\n", 0x100000);
256   SerialMemDump((unsigned char *)0x100000, 128);
257   /*
258     SerialPrint("Dumping kernel Code (first 512 bytes @ 0x%x)\n",KERNEL_START);
259     SerialMemDump((unsigned char *)VM_KERNEL_START, 512);
260   */
261 #endif
262
263
264
265   SerialPrintLevel(1000,"Launching Noisemaker and keyboard listener threads\n");
266   key_thread = Start_Kernel_Thread(Keyboard_Listener, (ulong_t)&doIBuzz, PRIORITY_NORMAL, false);
267   spkr_thread = Start_Kernel_Thread(Buzzer, (ulong_t)&doIBuzz, PRIORITY_NORMAL, false);
268
269
270   {
271     struct vmm_os_hooks os_hooks;
272     struct vmm_ctrl_ops vmm_ops;
273     guest_info_t vm_info;
274     addr_t rsp;
275     addr_t rip;
276
277     memset(&os_hooks, 0, sizeof(struct vmm_os_hooks));
278     memset(&vmm_ops, 0, sizeof(struct vmm_ctrl_ops));
279     memset(&vm_info, 0, sizeof(guest_info_t));
280
281     os_hooks.print_debug = &PrintBoth;
282     os_hooks.print_info = &Print;
283     os_hooks.print_trace = &SerialPrint;
284     os_hooks.allocate_pages = &Allocate_VMM_Pages;
285     os_hooks.free_page = &Free_VMM_Page;
286     os_hooks.malloc = &VMM_Malloc;
287     os_hooks.free = &VMM_Free;
288
289
290     //   DumpGDT();
291     Init_VMM(&os_hooks, &vmm_ops);
292   
293
294     init_mem_layout(&(vm_info.mem_layout));
295     init_mem_list(&(vm_info.mem_list));
296     init_vmm_io_map(&(vm_info.io_map));
297
298     
299     add_mem_list_pages(&(vm_info.mem_list), vm_range_start, (vm_range_end - vm_range_start) / PAGE_SIZE);
300     //    add_unmapped_mem_range(&(vm_info.mem_layout), 0, 256);
301     //add_shared_mem_range(&(vm_info.mem_layout), guest_kernel_start, (guest_kernel_end - guest_kernel_start) / PAGE_SIZE, guest_kernel_start);
302     //add_guest_mem_range(&(vm_info.mem_layout), guest_kernel_end, 20);
303     
304     if (0) {
305       
306       //    add_shared_mem_range(&(vm_info.mem_layout), 0, 0x800000, 0x10000);    
307       add_shared_mem_range(&(vm_info.mem_layout), 0, 0x1000000, 0);
308       
309       rip = (ulong_t)(void*)&BuzzVM;
310       //  rip -= 0x10000;
311       //    rip = (addr_t)(void*)&exit_test;
312       //  rip -= 0x2000;
313       vm_info.rip = rip;
314       rsp = (addr_t)Alloc_Page();
315       
316       vm_info.rsp = (rsp +4092 );// - 0x2000;
317       
318             
319     } else {
320       add_shared_mem_range(&(vm_info.mem_layout), 0x0, 0x1000, 0x100000);
321
322       
323
324       hook_io_port(&(vm_info.io_map), 0x61, &IO_Read, &IO_Write);
325
326       vm_info.rip = 0x0;
327       vm_info.rsp = 0x0;
328     }
329
330     PrintBoth("Initializing Guest (eip=0x%.8x) (esp=0x%.8x)\n", (uint_t)vm_info.rip,(uint_t)vm_info.rsp);
331     (vmm_ops).init_guest(&vm_info);
332     PrintBoth("Starting Guest\n");
333     (vmm_ops).start_guest(&vm_info);
334   }
335
336
337   
338
339
340   TODO("Write a Virtual Machine Monitor");
341   
342
343   Exit(0);
344 }