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.


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