43 lines
1.0 KiB
C++
43 lines
1.0 KiB
C++
#include "interrupt/apic_timer.h"
|
|
|
|
#include "debug/debug.h"
|
|
#include "interrupt/apic.h"
|
|
#include "interrupt/timer.h"
|
|
|
|
const uint32_t kScheduleFrequency = 20;
|
|
ApicTimer* gApicTimer = nullptr;
|
|
|
|
void ApicTimer::Init() {
|
|
gApicTimer = new ApicTimer();
|
|
gApicTimer->StartCalibration();
|
|
asm("sti;");
|
|
gApicTimer->WaitCalibration();
|
|
asm("cli;");
|
|
}
|
|
|
|
void ApicTimer::StartCalibration() {
|
|
SetFrequency(100);
|
|
gApic->InitializeLocalTimer(0xFFFFFFFF, Apic::ONESHOT);
|
|
gApic->UnmaskPit();
|
|
}
|
|
|
|
void ApicTimer::Calibrate() {
|
|
if (calibration_.initial_measurement == 0) {
|
|
calibration_.initial_measurement = gApic->GetLocalTimerValue();
|
|
return;
|
|
}
|
|
calibration_.tick_count++;
|
|
|
|
if (calibration_.tick_count == 10) {
|
|
calculated_frequency_ =
|
|
10 * (calibration_.initial_measurement - gApic->GetLocalTimerValue());
|
|
FinishCalibration();
|
|
}
|
|
}
|
|
|
|
void ApicTimer::FinishCalibration() {
|
|
gApic->MaskPit();
|
|
gApic->InitializeLocalTimer(calculated_frequency_ / kScheduleFrequency,
|
|
Apic::PERIODIC);
|
|
}
|