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.


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