5e9a76736b1f8d356d3100fae5e1b27c375af3a7
[akaros.git] / kern / arch / i686 / init.c
1 /* See COPYRIGHT for copyright information. */
2
3 #ifdef __SHARC__
4 #pragma nosharc
5 #endif
6
7 #include <smp.h>
8
9 #include <arch/rl8168.h>
10 #include <arch/ne2k.h>
11 #include <arch/e1000.h>
12 #include <arch/mptables.h>
13 #include <arch/pci.h>
14 #include <arch/ioapic.h>
15 #include <arch/console.h>
16 #include <arch/perfmon.h>
17 #include <console.h>
18
19 /* irq handler for the console (kb, serial, etc) */
20 static void irq_console(struct trapframe *tf, void *data)
21 {
22         int c = cons_get_any_char();
23         if (!c)
24                 return;
25         /* Do our work in an RKM, instead of interrupt context */
26         if (c == 'G')
27                 send_kernel_message(core_id(), __run_mon, 0, 0, 0, KMSG_ROUTINE);
28         else
29                 send_kernel_message(core_id(), __cons_add_char, (long)&cons_buf,
30                                     (long)c, 0, KMSG_ROUTINE);
31 }
32
33 static void cons_irq_init(void)
34 {
35         register_interrupt_handler(interrupt_handlers, 1 + PIC1_OFFSET, irq_console,
36                                    0);
37         register_interrupt_handler(interrupt_handlers, 3 + PIC1_OFFSET, irq_console,
38                                    0);
39         register_interrupt_handler(interrupt_handlers, 4 + PIC1_OFFSET, irq_console,
40                                    0);
41         /* route kb and both serial interrupts to core 0 */
42 #ifdef __CONFIG_ENABLE_MPTABLES__
43         ioapic_route_irq(1, 0);
44         ioapic_route_irq(3, 0);
45         ioapic_route_irq(4, 0);
46 #else 
47         pic_unmask_irq(1);      /* keyboard */
48         pic_unmask_irq(3);      /* serial 2 or 4 */
49         pic_unmask_irq(4);      /* serial 1 or 3 */
50         unmask_lapic_lvt(LAPIC_LVT_LINT0);
51 #endif /* __CONFIG_ENABLE_MPTABLES__ */
52 }
53
54 void arch_init()
55 {
56         pci_init();
57 #ifdef __CONFIG_ENABLE_MPTABLES__
58         mptables_parse();
59         ioapic_init(); // MUST BE AFTER PCI/ISA INIT!
60         // TODO: move these back to regular init.  requires fixing the 
61         // __CONFIG_NETWORKING__ inits to not need multiple cores running.
62 #endif
63         // this returns when all other cores are done and ready to receive IPIs
64         #ifdef __CONFIG_SINGLE_CORE__
65                 smp_percpu_init();
66         #else
67                 smp_boot();
68         #endif
69         proc_init();
70
71         /* EXPERIMENTAL NETWORK FUNCTIONALITY
72          * To enable, define __CONFIG_NETWORKING__ in your Makelocal
73          * If enabled, will load the rl8168 driver (if device exists)
74          * and will a boot into userland matrix, so remote syscalls can be performed.
75          * If in simulation, will do some debugging information with the ne2k device
76          *
77          * Note: If you use this, you should also define the mac address of the 
78          * teathered machine via USER_MAC_ADDRESS in Makelocal.
79          *
80          * Additionally, you should have a look at the syscall server in the tools directory
81          */
82         #ifdef __CONFIG_NETWORKING__
83         #ifdef __CONFIG_SINGLE_CORE__
84                 warn("You currently can't have networking if you boot into single core mode!!\n");
85         #else
86                 rl8168_init();          
87                 ne2k_init();
88                 e1000_init();
89         #endif // __CONFIG_SINGLE_CORE__
90         #endif // __CONFIG_NETWORKING__
91
92         perfmon_init();
93         cons_irq_init();
94 }