VMMCP: initialization
[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 #include <arch/usb.h>
16
17 struct ancillary_state x86_default_fpu;
18 uint32_t kerndate;
19
20 #define capchar2ctl(x) ((x) - '@')
21
22 /* irq handler for the console (kb, serial, etc) */
23 static void irq_console(struct hw_trapframe *hw_tf, void *data)
24 {
25         uint8_t c;
26         struct cons_dev *cdev = (struct cons_dev*)data;
27         assert(cdev);
28         if (cons_get_char(cdev, &c))
29                 return;
30         /* Control code intercepts */
31         switch (c) {
32                 case capchar2ctl('G'):
33                         /* traditional 'ctrl-g', will put you in the monitor gracefully */
34                         send_kernel_message(core_id(), __run_mon, 0, 0, 0, KMSG_ROUTINE);
35                         return;
36                 case capchar2ctl('Q'):
37                         /* force you into the monitor.  you might deadlock. */
38                         printk("\nForcing entry to the monitor\n");
39                         monitor(hw_tf);
40                         return;
41                 case capchar2ctl('B'):
42                         /* backtrace / debugging for the core receiving the irq */
43                         printk("\nForced trapframe and backtrace for core %d\n", core_id());
44                         if (!hw_tf) {
45                                 printk("(no hw_tf, we probably polled the console)\n");
46                                 return;
47                         }
48                         print_trapframe(hw_tf);
49                         backtrace_kframe(hw_tf);
50                         return;
51         }
52         /* Do our work in an RKM, instead of interrupt context.  Note the RKM will
53          * cast 'c' to a char. */
54         send_kernel_message(core_id(), __cons_add_char, (long)&cons_buf, (long)c,
55                             0, KMSG_ROUTINE);
56 }
57
58 static void cons_poller(void *arg)
59 {
60         while (1) {
61                 udelay_sched(10000);
62                 irq_console(0, arg);
63         }
64 }
65
66 static void cons_irq_init(void)
67 {
68         struct cons_dev *i;
69         /* Register interrupt handlers for all console devices */
70         SLIST_FOREACH(i, &cdev_list, next) {
71                 register_irq(i->irq, irq_console, i, MKBUS(BusISA, 0, 0, 0));
72 #ifdef CONFIG_POLL_CONSOLE
73                 ktask("cons_poller", cons_poller, i);
74 #endif /* CONFIG_POLL_CONSOLE */
75         }
76 }
77
78 void arch_init()
79 {
80         /* need to reinit before saving, in case boot agents used the FPU or it is
81          * o/w dirty.  had this happen on c89, which had a full FP stack after
82          * booting. */
83         asm volatile ("fninit");
84         save_fp_state(&x86_default_fpu); /* used in arch/trap.h for fpu init */
85         pci_init();
86         vmm_init();
87         // this returns when all other cores are done and ready to receive IPIs
88         #ifdef CONFIG_SINGLE_CORE
89                 smp_percpu_init();
90         #else
91                 smp_boot();
92         #endif
93         proc_init();
94
95         perfmon_init();
96         cons_irq_init();
97         intel_lpc_init();
98         usb_disable_legacy();
99         check_timing_stability();
100 }