new 64b kernel memory map (not userspace yet)
[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
18 #include <monitor.h>
19
20 void arch_init()
21 {
22         pci_init();
23 #ifdef __CONFIG_ENABLE_MPTABLES__
24         mptables_parse();
25         ioapic_init(); // MUST BE AFTER PCI/ISA INIT!
26         // TODO: move these back to regular init.  requires fixing the 
27         // __CONFIG_NETWORKING__ inits to not need multiple cores running.
28 #endif
29         // this returns when all other cores are done and ready to receive IPIs
30         #ifdef __CONFIG_SINGLE_CORE__
31                 smp_percpu_init();
32         #else
33                 smp_boot();
34         #endif
35         proc_init();
36
37         /* EXPERIMENTAL NETWORK FUNCTIONALITY
38          * To enable, define __CONFIG_NETWORKING__ in your Makelocal
39          * If enabled, will load the rl8168 driver (if device exists)
40          * and will a boot into userland matrix, so remote syscalls can be performed.
41          * If in simulation, will do some debugging information with the ne2k device
42          *
43          * Note: If you use this, you should also define the mac address of the 
44          * teathered machine via USER_MAC_ADDRESS in Makelocal.
45          *
46          * Additionally, you should have a look at the syscall server in the tools directory
47          */
48         #ifdef __CONFIG_NETWORKING__
49         #ifdef __CONFIG_SINGLE_CORE__
50                 warn("You currently can't have networking if you boot into single core mode!!\n");
51         #else
52                 rl8168_init();          
53                 ne2k_init();
54                 e1000_init();
55         #endif // __CONFIG_SINGLE_CORE__
56         #endif // __CONFIG_NETWORKING__
57
58         perfmon_init();
59                 
60 #ifdef __CONFIG_MONITOR_ON_INT__
61         /* Handler to read a char from the interrupt source and call the monitor.
62          * Need to read the character so the device will send another interrupt.
63          * Note this will read from both the serial and the keyboard, and throw away
64          * the result.  We condition, since we don't want to trigger on a keyboard
65          * up interrupt */
66         void mon_int(struct trapframe *tf, void *data)
67         {
68                 // Enable interrupts here so that we can receive 
69                 // other interrupts (e.g. from the NIC)
70                 enable_irq();
71                 if (cons_getc())
72                         monitor(0);
73         }
74         register_interrupt_handler(interrupt_handlers, 1 + PIC1_OFFSET, mon_int, 0);
75         register_interrupt_handler(interrupt_handlers, 3 + PIC1_OFFSET, mon_int, 0);
76         register_interrupt_handler(interrupt_handlers, 4 + PIC1_OFFSET, mon_int, 0);
77 # ifdef __CONFIG_ENABLE_MPTABLES__
78         ioapic_route_irq(1, 0);
79         ioapic_route_irq(3, 0);
80         ioapic_route_irq(4, 0);
81 # else 
82         pic_unmask_irq(1);      /* keyboard */
83         pic_unmask_irq(3);      /* serial 2 or 4 */
84         pic_unmask_irq(4);      /* serial 1 or 3 */
85         unmask_lapic_lvt(LAPIC_LVT_LINT0);
86 # endif /* __CONFIG_ENABLE_MPTABLES__ */
87         enable_irq(); /* we want these interrupts to work in the kernel. */
88 #endif /* __CONFIG_MONITOR_ON_INT__ */
89 }