Add FADT check for presence of i8042 controller.
[lunaix-os.git] / lunaix-os / hal / apic.c
index c74d3f91b38425033c494e5d931967ebf0edbd8a..0d427d1dcaa80691658ff3e7a38ddd6b12c066ea 100644 (file)
 
 LOG_MODULE("APIC")
 
-void
-apic_setup_timer();
-
 void
 apic_setup_lvts();
 
 void
-init_apic()
+apic_init()
 {
     // ensure that external interrupt is disabled
     cpu_disable_interrupt();
@@ -47,7 +44,7 @@ init_apic()
         "rdmsr\n"
         "orl %1, %%eax\n"
         "wrmsr\n"
-        ::"i"(IA32_APIC_BASE_MSR), "i"(IA32_APIC_ENABLE)
+        ::"i"(IA32_MSR_APIC_BASE), "i"(IA32_APIC_ENABLE)
         : "eax", "ecx", "edx"
     );
 
@@ -77,9 +74,6 @@ init_apic()
     // install our handler for spurious interrupt.
     spiv = (spiv & ~0xff) | APIC_SPIV_APIC_ENABLE  | APIC_SPIV_IV;
     apic_write_reg(APIC_SPIVR, spiv);
-
-    // setup timer and performing calibrations
-    apic_setup_timer();
 }
 
 #define LVT_ENTRY_LINT0(vector)           (LVT_DELIVERY_FIXED | vector)
@@ -89,7 +83,6 @@ init_apic()
 // LINT#1 *must* be edge trigged (Intel manual vol3. 10-14)
 #define LVT_ENTRY_LINT1                   (LVT_DELIVERY_NMI | LVT_MASKED | LVT_TRIGGER_EDGE)
 #define LVT_ENTRY_ERROR(vector)           (LVT_DELIVERY_FIXED | vector)
-#define LVT_ENTRY_TIMER(vector, mode)     (LVT_DELIVERY_FIXED | mode | vector)
 
 void
 apic_setup_lvts()
@@ -98,124 +91,3 @@ apic_setup_lvts()
     apic_write_reg(APIC_LVT_LINT1, LVT_ENTRY_LINT1);
     apic_write_reg(APIC_LVT_ERROR, LVT_ENTRY_ERROR(APIC_ERROR_IV));
 }
-
-void
-temp_intr_routine_rtc_tick(const isr_param* param);
-
-void
-temp_intr_routine_apic_timer(const isr_param* param);
-
-void
-test_timer(const isr_param* param);
-
-uint32_t apic_timer_base_freq = 0;
-
-// Don't optimize them! Took me an half hour to figure that out...
-
-volatile uint32_t rtc_counter = 0;
-volatile uint8_t apic_timer_done = 0;
-
-#define APIC_CALIBRATION_CONST  0x100000
-
-void
-apic_setup_timer()
-{
-    cpu_disable_interrupt();
-    
-    // Setup APIC timer
-
-    // Setup a one-shot timer, we will use this to measure the bus speed. So we can
-    //   then calibrate apic timer to work at *nearly* accurate hz
-    apic_write_reg(APIC_TIMER_LVT,  LVT_ENTRY_TIMER(APIC_TIMER_IV, LVT_TIMER_ONESHOT));
-    
-    // Set divider to 64
-    apic_write_reg(APIC_TIMER_DCR, APIC_TIMER_DIV64);
-
-    /*
-        Timer calibration process - measure the APIC timer base frequency
-
-         step 1: setup a temporary isr for RTC timer which trigger at each tick (1024Hz)
-         step 2: setup a temporary isr for #APIC_TIMER_IV
-         step 3: setup the divider, APIC_TIMER_DCR
-         step 4: Startup RTC timer
-         step 5: Write a large value, v, to APIC_TIMER_ICR to start APIC timer 
-                 (this must be followed immediately after step 4)
-         step 6: issue a write to EOI and clean up.
-
-        When the APIC ICR counting down to 0 #APIC_TIMER_IV triggered, save the rtc timer's 
-        counter, k, and disable RTC timer immediately (although the RTC interrupts should be 
-        blocked by local APIC as we are currently busy on handling #APIC_TIMER_IV)
-
-        So the apic timer frequency F_apic in Hz can be calculate as
-            v / F_apic = k / 1024
-            =>  F_apic = v / k * 1024
-
-    */
-
-    apic_timer_base_freq = 0;
-    rtc_counter = 0;
-    apic_timer_done = 0;
-
-    intr_subscribe(APIC_TIMER_IV, temp_intr_routine_apic_timer);
-    intr_subscribe(RTC_TIMER_IV, temp_intr_routine_rtc_tick);
-
-        
-    rtc_enable_timer();                                         // start RTC timer
-    apic_write_reg(APIC_TIMER_ICR, APIC_CALIBRATION_CONST);     // start APIC timer
-    
-    // enable interrupt, just for our RTC start ticking!
-    cpu_enable_interrupt();
-
-    wait_until(apic_timer_done);
-    
-    // cpu_disable_interrupt();
-
-    assert_msg(apic_timer_base_freq, "Fail to initialize timer");
-
-    kprintf(KINFO "Timer base frequency: %u Hz\n", apic_timer_base_freq);
-
-    // cleanup
-    intr_unsubscribe(APIC_TIMER_IV, temp_intr_routine_apic_timer);
-    intr_unsubscribe(RTC_TIMER_IV, temp_intr_routine_rtc_tick);
-
-    // TODO: now setup timer with our custom frequency which we can derived from the base frequency
-    //          we measured
-
-    apic_write_reg(APIC_TIMER_LVT,  LVT_ENTRY_TIMER(APIC_TIMER_IV, LVT_TIMER_PERIODIC));
-    intr_subscribe(APIC_TIMER_IV, test_timer);
-    
-    apic_write_reg(APIC_TIMER_ICR, apic_timer_base_freq);
-}
-
-volatile rtc_datetime datetime;
-
-void
-test_timer(const isr_param* param) {
-
-    rtc_get_datetime(&datetime);
-
-    kprintf(KWARN "%u/%02u/%02u %02u:%02u:%02u\r",
-           datetime.year,
-           datetime.month,
-           datetime.day,
-           datetime.hour,
-           datetime.minute,
-           datetime.second);
-}
-
-void
-temp_intr_routine_rtc_tick(const isr_param* param) {
-    rtc_counter++;
-
-    // dummy read on register C so RTC can send anther interrupt
-    //  This strange behaviour observed in virtual box & bochs 
-    (void) rtc_read_reg(RTC_REG_C);
-}
-
-void
-temp_intr_routine_apic_timer(const isr_param* param) {
-    apic_timer_base_freq = APIC_CALIBRATION_CONST / rtc_counter * RTC_TIMER_BASE_FREQUENCY;
-    apic_timer_done = 1;
-
-    rtc_disable_timer();
-}
\ No newline at end of file