Changes rdtsc serialization methods
[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 <arch/init.h>
18 #include <console.h>
19
20 /* irq handler for the console (kb, serial, etc) */
21 static void irq_console(struct trapframe *tf, void *data)
22 {
23         uint8_t c;
24         struct cons_dev *cdev = (struct cons_dev*)data;
25         assert(cdev);
26         if (cons_get_char(cdev, &c))
27                 return;
28         /* Do our work in an RKM, instead of interrupt context.  Note the RKM will
29          * cast 'c' to a char. */
30         if (c == 'G')
31                 send_kernel_message(core_id(), __run_mon, 0, 0, 0, KMSG_ROUTINE);
32         else
33                 send_kernel_message(core_id(), __cons_add_char, (long)&cons_buf,
34                                     (long)c, 0, KMSG_ROUTINE);
35 }
36
37 static void cons_irq_init(void)
38 {
39         struct cons_dev *i;
40         /* Register interrupt handlers for all console devices */
41         SLIST_FOREACH(i, &cdev_list, next) {
42                 register_interrupt_handler(interrupt_handlers, i->irq + PIC1_OFFSET,
43                                            irq_console, i);
44                 /* Route any console IRQs to core 0 */
45         #ifdef __CONFIG_ENABLE_MPTABLES__
46                 ioapic_route_irq(i->irq, 0);
47         #else
48                 pic_unmask_irq(i->irq);
49                 unmask_lapic_lvt(LAPIC_LVT_LINT0);
50         #endif /* __CONFIG_ENABLE_MPTABLES__ */
51                 printd("Registered handler for IRQ %d (ISR %d)\n", i->irq,
52                        i->irq + PIC1_OFFSET);
53         }
54 }
55
56 void arch_init()
57 {
58         pci_init();
59 #ifdef __CONFIG_ENABLE_MPTABLES__
60         mptables_parse();
61         ioapic_init(); // MUST BE AFTER PCI/ISA INIT!
62         // TODO: move these back to regular init.  requires fixing the 
63         // __CONFIG_NETWORKING__ inits to not need multiple cores running.
64 #endif
65         // this returns when all other cores are done and ready to receive IPIs
66         #ifdef __CONFIG_SINGLE_CORE__
67                 smp_percpu_init();
68         #else
69                 smp_boot();
70         #endif
71         proc_init();
72
73         /* EXPERIMENTAL NETWORK FUNCTIONALITY
74          * To enable, define __CONFIG_NETWORKING__ in your Makelocal
75          * If enabled, will load the rl8168 driver (if device exists)
76          * and will a boot into userland matrix, so remote syscalls can be performed.
77          * If in simulation, will do some debugging information with the ne2k device
78          *
79          * Note: If you use this, you should also define the mac address of the 
80          * teathered machine via USER_MAC_ADDRESS in Makelocal.
81          *
82          * Additionally, you should have a look at the syscall server in the tools directory
83          */
84         #ifdef __CONFIG_NETWORKING__
85         #ifdef __CONFIG_SINGLE_CORE__
86                 warn("You currently can't have networking if you boot into single core mode!!\n");
87         #else
88                 rl8168_init();          
89                 ne2k_init();
90                 e1000_init();
91         #endif // __CONFIG_SINGLE_CORE__
92         #endif // __CONFIG_NETWORKING__
93
94         perfmon_init();
95         cons_irq_init();
96         check_timing_stability();
97 }