Changes rdtsc serialization methods
[akaros.git] / kern / arch / i686 / init.c
index 851361f..ff72649 100644 (file)
 #include <arch/pci.h>
 #include <arch/ioapic.h>
 #include <arch/console.h>
-#include <monitor.h>
+#include <arch/perfmon.h>
+#include <arch/init.h>
+#include <console.h>
+
+/* irq handler for the console (kb, serial, etc) */
+static void irq_console(struct trapframe *tf, void *data)
+{
+       uint8_t c;
+       struct cons_dev *cdev = (struct cons_dev*)data;
+       assert(cdev);
+       if (cons_get_char(cdev, &c))
+               return;
+       /* Do our work in an RKM, instead of interrupt context.  Note the RKM will
+        * cast 'c' to a char. */
+       if (c == 'G')
+               send_kernel_message(core_id(), __run_mon, 0, 0, 0, KMSG_ROUTINE);
+       else
+               send_kernel_message(core_id(), __cons_add_char, (long)&cons_buf,
+                                   (long)c, 0, KMSG_ROUTINE);
+}
+
+static void cons_irq_init(void)
+{
+       struct cons_dev *i;
+       /* Register interrupt handlers for all console devices */
+       SLIST_FOREACH(i, &cdev_list, next) {
+               register_interrupt_handler(interrupt_handlers, i->irq + PIC1_OFFSET,
+                                          irq_console, i);
+               /* Route any console IRQs to core 0 */
+       #ifdef __CONFIG_ENABLE_MPTABLES__
+               ioapic_route_irq(i->irq, 0);
+       #else
+               pic_unmask_irq(i->irq);
+               unmask_lapic_lvt(LAPIC_LVT_LINT0);
+       #endif /* __CONFIG_ENABLE_MPTABLES__ */
+               printd("Registered handler for IRQ %d (ISR %d)\n", i->irq,
+                      i->irq + PIC1_OFFSET);
+       }
+}
 
 void arch_init()
 {
        pci_init();
-#ifndef __CONFIG_DISABLE_MPTABLES__
+#ifdef __CONFIG_ENABLE_MPTABLES__
        mptables_parse();
        ioapic_init(); // MUST BE AFTER PCI/ISA INIT!
        // TODO: move these back to regular init.  requires fixing the 
@@ -53,30 +91,7 @@ void arch_init()
        #endif // __CONFIG_SINGLE_CORE__
        #endif // __CONFIG_NETWORKING__
 
-#ifdef __CONFIG_MONITOR_ON_INT__
-       /* Handler to read a char from the interrupt source and call the monitor.
-        * Need to read the character so the device will send another interrupt.
-        * Note this will read from both the serial and the keyboard, and throw away
-        * the result.  We condition, since we don't want to trigger on a keyboard
-        * up interrupt */
-       void mon_int(struct trapframe *tf, void *data)
-       {
-               if (cons_getc())
-                       monitor(0);
-       }
-       register_interrupt_handler(interrupt_handlers, 1 + PIC1_OFFSET, mon_int, 0);
-       register_interrupt_handler(interrupt_handlers, 3 + PIC1_OFFSET, mon_int, 0);
-       register_interrupt_handler(interrupt_handlers, 4 + PIC1_OFFSET, mon_int, 0);
-# ifdef __CONFIG_DISABLE_MPTABLES__
-       pic_unmask_irq(1);      /* keyboard */
-       pic_unmask_irq(3);      /* serial 2 or 4 */
-       pic_unmask_irq(4);      /* serial 1 or 3 */
-       unmask_lapic_lvt(LAPIC_LVT_LINT0);
-# else 
-       ioapic_route_irq(1, 0);
-       ioapic_route_irq(3, 0);
-       ioapic_route_irq(4, 0);
-# endif /* __CONFIG_DISABLE_MPTABLES__ */
-       enable_irq(); /* we want these interrupts to work in the kernel. */
-#endif /* __CONFIG_MONITOR_ON_INT__ */
+       perfmon_init();
+       cons_irq_init();
+       check_timing_stability();
 }