- 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);