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.


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