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.


eab0aa045219cbd9ffaea996aced0f57a3d2e1c4
[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.45 $
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
33
34 #include <geekos/vm.h>
35 #include <geekos/gdt.h>
36
37 #include <geekos/vmm_stubs.h>
38
39 #include <geekos/pci.h>
40
41 #if 0
42 #include <geekos/ne2k.h>
43 #include <uip/uip.h>
44 #include <uip/uip_arp.h>
45 #endif
46
47 #include <geekos/socket.h>
48 //#include <geekos/ring_buffer.h>
49
50 #define SPEAKER_PORT 0x61
51 #define TEST_NE2K 0
52 #define BUF ((struct uip_eth_hdr *)&uip_buf[0])
53
54 #if TEST_NE2K
55 u8_t uip_buf[UIP_BUFSIZE+2];
56 u16_t uip_len;
57
58 int Packet_Received(struct NE2K_Packet_Info* info, uchar_t *pkt) {
59   uip_len = info->size;  
60   int i;
61   for(i = 0; i < info->size; i++) {
62     PrintBoth("%x ", *(pkt+i));
63     uip_buf[i] = *(pkt+i);
64     if(i % 10 == 0)
65       PrintBoth("\n");
66   }
67   Free(pkt);
68   if(BUF->type == htons(UIP_ETHTYPE_ARP)) {
69     uip_arp_arpin();
70   } else {
71     uip_arp_ipin();
72     uip_input();
73   }
74   return 0;
75 }
76 #endif
77
78 void Spin()
79 {
80   // hack - competing thread
81   while (1) {};
82
83 }
84
85
86 void Buzz(unsigned delay, unsigned num)
87 {
88   volatile int x;
89   int i,j;
90   unsigned char init;
91   
92   init=In_Byte(SPEAKER_PORT);
93
94   for (i=0;i<num;i++) { 
95     Out_Byte(SPEAKER_PORT, init|0x2);
96     for (j=0;j<delay;j++) { 
97       x+=j;
98     }
99     Out_Byte(SPEAKER_PORT, init);
100     for (j=0;j<delay;j++) { 
101       x+=j;
102     }
103   }
104 }
105
106 inline void MyOut_Byte(ushort_t port, uchar_t value)
107 {
108     __asm__ __volatile__ (
109         "outb %b0, %w1"
110         :
111         : "a" (value), "Nd" (port)
112     );
113 }
114
115 /*
116  * Read a byte from an I/O port.
117  */
118 inline uchar_t MyIn_Byte(ushort_t port)
119 {
120     uchar_t value;
121
122     __asm__ __volatile__ (
123         "inb %w1, %b0"
124         : "=a" (value)
125         : "Nd" (port)
126     );
127
128     return value;
129 }
130
131
132
133
134
135
136
137 void Buzzer(ulong_t arg) {
138   ulong_t *doIBuzz = (ulong_t*)arg;
139   while (1) {
140     // Quick and dirty hack to save my hearing...
141     // I'm not too worried about timing, so I'll deal with concurrency later...
142     if (*doIBuzz == 1) {
143       Buzz(1000000, 10);
144     }
145   }
146
147 }
148
149
150
151
152
153 void Keyboard_Listener(ulong_t arg) {
154   ulong_t * doIBuzz = (ulong_t*)arg;
155   Keycode key_press;
156
157   Print("Press F4 to turn on/off the speaker\n");
158
159   while ((key_press = Wait_For_Key())) {    
160     if (key_press == KEY_F4) {
161       Print("\nToggling Speaker Port\n");
162       SerialPrintLevel(100,"\nToggling Speaker Port\n");
163       *doIBuzz = (*doIBuzz + 1) % 2;
164     } else if (key_press == KEY_F5) {
165       Print("\nMachine Restart\n");
166       SerialPrintLevel(100,"\nMachine Restart\n");
167       machine_real_restart();
168     }
169   }
170   return;
171 }
172
173
174
175 extern char BSS_START, BSS_END;
176
177 extern char end;
178
179
180 /* This is an ugly hack to get at the VM  memory */
181 ulong_t vm_range_start;
182 ulong_t vm_range_end;
183 ulong_t guest_kernel_start;
184 ulong_t guest_kernel_end;
185 /* ** */
186
187
188 int AllocateAndMapPagesForRange(uint_t start, uint_t length, pte_t template_pte)
189 {
190   uint_t address;
191
192   for (address=start;address<start+length;address+=PAGE_SIZE) { 
193     void *page;
194     pte_t pte = template_pte;
195     
196     page=Alloc_Page();
197     KASSERT(page);
198     
199     pte.pageBaseAddr=PAGE_ALLIGNED_ADDR(page);
200
201     KASSERT(MapPage((void*)address,&pte,1));
202   }
203   
204   return 0;
205 }
206     
207
208
209 /*
210  * Kernel C code entry point.
211  * Initializes kernel subsystems, mounts filesystems,
212  * and spawns init process.
213  */
214 void Main(struct Boot_Info* bootInfo)
215 {
216
217
218   //Out_Byte(0x1234,5);
219   //Out_Byte(0x1234,5);
220
221   Init_BSS();
222   Init_Screen();
223
224   Init_Serial();
225
226   /*  {
227     extern char BSS_START, BSS_END;
228
229     SerialPrint("BSS 0x%x->0x%x\n", &BSS_START, &BSS_END);
230
231     }*/
232
233
234   // SerialPrint("Guest Mem Dump at 0x%x\n", 0x100000);
235   //SerialMemDump((unsigned char *)(0x100000), 261 * 1024);
236
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_PCI();
249
250   Init_Stubs();
251
252
253 #ifdef TEST_NE2K
254   {
255     init_network();
256     uchar_t local_addr[4];
257     uchar_t remote_addr[4];
258
259     local_addr[0] = 10;
260     local_addr[1] = 0;
261     local_addr[2] = 2;
262     local_addr[3] = 20;
263
264     set_ip_addr(local_addr);
265
266     remote_addr[0] = 10;
267     remote_addr[1] = 0;
268     remote_addr[2] = 2;
269     remote_addr[3] = 21;
270
271
272     connect(remote_addr, 4301);
273   }
274 #elif 0
275   Init_Ne2k(&Packet_Received);
276   uip_init();
277   uip_arp_init();
278
279   uip_ipaddr_t ipaddr;
280   uip_ipaddr(ipaddr, 10,0,2,21);  /* Local IP address */
281   uip_sethostaddr(ipaddr);
282
283   uip_ipaddr_t ripaddr;
284   uip_ipaddr(ripaddr, 10,0,2,20);  /* Remote IP address */
285   
286   /* Attempt a connection to port 8080 at address 10.0.2.20 */
287   struct uip_conn *conn;
288   conn = uip_connect(&ripaddr, HTONS(8080));
289
290   while(uip_len <= 0) {
291     uip_periodic_conn(conn);
292   }
293   NE2K_Transmit(uip_len+UIP_LLH_LEN);  /* This will transmit an ARP packet */
294
295   int l = 0;
296   while(l++ < 5000); /* When this is done, a response to the ARP should have been received. */
297   conn = uip_connect(&ripaddr, HTONS(8080));
298
299   while(uip_len <= 0) {
300     uip_periodic_conn(conn);
301   }
302   NE2K_Transmit(uip_len+UIP_LLH_LEN); /* This *should* transmit a SYN packet */
303
304 #endif /* TEST_NE2K */
305
306   //  Init_IDE();
307
308   // Print("Done; stalling\n");
309
310
311   
312 #if 0
313   SerialPrint("Dumping VM kernel Code (first 128 bytes @ 0x%x)\n", 0x100000);
314   SerialMemDump((unsigned char *)0x100000, 256);
315   /*
316     SerialPrint("Dumping kernel Code (first 512 bytes @ 0x%x)\n",KERNEL_START);
317     SerialMemDump((unsigned char *)VM_KERNEL_START, 512);
318   */
319 #endif
320
321
322 #if 1
323   struct Kernel_Thread *spin_thread;
324
325   spin_thread=Start_Kernel_Thread(Spin,0,PRIORITY_NORMAL,false);
326
327 #endif
328
329 #if 0
330   {
331
332   struct Kernel_Thread * key_thread;
333   struct Kernel_Thread * spkr_thread;
334
335   ulong_t doIBuzz = 0;
336
337   SerialPrint("Dumping BIOS code ffff0-fffff\n\n");
338   SerialMemDump((unsigned char *)0x10fff0, 16);
339   /*
340     SerialPrint("Dumping kernel Code (first 512 bytes @ 0x%x)\n",KERNEL_START);
341     SerialMemDump((unsigned char *)VM_KERNEL_START, 512);
342   */
343
344   SerialPrint("Noisemaker and keyboard listener threads\n");
345   key_thread = Start_Kernel_Thread(Keyboard_Listener, (ulong_t)&doIBuzz, PRIORITY_NORMAL, false);
346   spkr_thread = Start_Kernel_Thread(Buzzer, (ulong_t)&doIBuzz, PRIORITY_NORMAL, false);
347   }
348 #endif
349
350 #if !TEST_NE2K
351   {
352     RunVMM(bootInfo);
353   }
354 #endif
355
356
357   SerialPrint("RunVMM returned, spinning\n");
358   while (1) {} 
359
360
361   TODO("Write a Virtual Machine Monitor");
362   
363
364   Exit(0);
365 }