Bring a bit more apic infrastructure up.
[akaros.git] / kern / arch / x86 / 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/pci.h>
10 #include <arch/console.h>
11 #include <arch/perfmon.h>
12 #include <arch/init.h>
13 #include <console.h>
14 #include <monitor.h>
15
16 struct ancillary_state x86_default_fpu;
17 uint32_t kerndate;
18
19 #define capchar2ctl(x) ((x) - '@')
20
21 /* irq handler for the console (kb, serial, etc) */
22 static void irq_console(struct hw_trapframe *hw_tf, void *data)
23 {
24         uint8_t c;
25         struct cons_dev *cdev = (struct cons_dev*)data;
26         assert(cdev);
27         if (cons_get_char(cdev, &c))
28                 return;
29         /* Control code intercepts */
30         switch (c) {
31                 case capchar2ctl('G'):
32                         /* traditional 'shift-g', will put you in the monitor gracefully */
33                         send_kernel_message(core_id(), __run_mon, 0, 0, 0, KMSG_ROUTINE);
34                         return;
35                 case capchar2ctl('Q'):
36                         /* force you into the monitor.  you might deadlock. */
37                         printk("\nForcing entry to the monitor\n");
38                         monitor(hw_tf);
39                         return;
40                 case capchar2ctl('B'):
41                         /* backtrace / debugging for the core receiving the irq */
42                         printk("\nForced trapframe and backtrace for core %d\n", core_id());
43                         print_trapframe(hw_tf);
44                         backtrace_kframe(hw_tf);
45                         return;
46         }
47         /* Do our work in an RKM, instead of interrupt context.  Note the RKM will
48          * cast 'c' to a char. */
49         if (c == 'G')
50                 send_kernel_message(core_id(), __run_mon, 0, 0, 0, KMSG_ROUTINE);
51         else
52                 send_kernel_message(core_id(), __cons_add_char, (long)&cons_buf,
53                                     (long)c, 0, KMSG_ROUTINE);
54 }
55
56 static void cons_irq_init(void)
57 {
58         struct cons_dev *i;
59         /* Register interrupt handlers for all console devices */
60         SLIST_FOREACH(i, &cdev_list, next)
61                 register_dev_irq(i->irq, irq_console, i);
62 }
63
64 void arch_init()
65 {
66         /* need to reinit before saving, in case boot agents used the FPU or it is
67          * o/w dirty.  had this happen on c89, which had a full FP stack after
68          * booting. */
69         asm volatile ("fninit");
70         save_fp_state(&x86_default_fpu); /* used in arch/trap.h for fpu init */
71         pci_init();
72 #ifdef CONFIG_ENABLE_MPTABLES
73         int acpiinit(void);
74         /* this also does the mpacpi ... is that enough? */
75         acpiinit();
76         void ioapiconline(void);
77         ioapiconline();
78         void apiconline(void);
79         apiconline();
80 #endif
81         // this returns when all other cores are done and ready to receive IPIs
82         #ifdef CONFIG_SINGLE_CORE
83                 smp_percpu_init();
84         #else
85                 smp_boot();
86         #endif
87         proc_init();
88
89         /* EXPERIMENTAL NETWORK FUNCTIONALITY
90          * To enable, define CONFIG_NETWORKING in your Makelocal
91          * If enabled, will load the rl8168 driver (if device exists)
92          * and will a boot into userland matrix, so remote syscalls can be performed.
93          * If in simulation, will do some debugging information with the ne2k device
94          *
95          * Note: If you use this, you should also define the mac address of the 
96          * teathered machine via USER_MAC_ADDRESS in Makelocal.
97          *
98          * Additionally, you should have a look at the syscall server in the tools directory
99          */
100         #ifdef CONFIG_NETWORKING
101         #ifdef CONFIG_SINGLE_CORE
102                 warn("You currently can't have networking if you boot into single core mode!!\n");
103         #else
104                 /* TODO: use something like linux's device_init() to call these. */
105                 #ifdef CONFIG_RL8168
106                 extern void rl8168_init(void);          
107                 rl8168_init();          
108                 #endif
109                 #ifdef CONFIG_NE2K
110                 extern void ne2k_init(void);            
111                 ne2k_init();
112                 #endif
113                 #ifdef CONFIG_E1000
114                 extern void e1000_init(void);           
115                 e1000_init();
116                 #endif
117         #endif // CONFIG_SINGLE_CORE
118         #endif // CONFIG_NETWORKING
119
120         perfmon_init();
121         cons_irq_init();
122         check_timing_stability();
123 }