acpi: calibrate local APIC timer on BSP
This commit is contained in:
@@ -119,6 +119,28 @@ static void ioapic_init(uintptr_t base, unsigned int int_base)
|
||||
queue_push_back(&io_apics, &apic->io_entry);
|
||||
}
|
||||
|
||||
void local_apic_config_timer(void)
|
||||
{
|
||||
local_apic lapic(lapic_base);
|
||||
lapic.write(local_apic::TIMER_DIV, 0x3);
|
||||
lapic.write(local_apic::TIMER_INITCOUNT, (uint32_t)-1);
|
||||
pit_wait(100);
|
||||
lapic.write(local_apic::LVT_TIMER, APIC_LVT_INT_MASKED);
|
||||
|
||||
/* mask IRQ0 to block interrupts from the PIT. */
|
||||
io_apic *irq0_apic = get_ioapic_for_irq(0);
|
||||
irq0_apic->mask_irq(0);
|
||||
|
||||
uint32_t total_ticks = 0xFFFFFFFF - lapic.read(local_apic::TIMER_CURCOUNT);
|
||||
|
||||
total_ticks /= 100;
|
||||
printk("total_ticks=%u", total_ticks);
|
||||
|
||||
lapic.write(local_apic::LVT_TIMER, IRQ0 | APIC_LVT_TIMER_MODE_PERIODIC);
|
||||
lapic.write(local_apic::TIMER_DIV, 0x3);
|
||||
lapic.write(local_apic::TIMER_INITCOUNT, total_ticks);
|
||||
}
|
||||
|
||||
static void parse_legacy_irq_override(struct acpi_madt *madt)
|
||||
{
|
||||
unsigned char *p = (unsigned char *)madt + sizeof *madt;
|
||||
@@ -193,8 +215,11 @@ kern_status_t apic_init(void)
|
||||
disable_8259();
|
||||
|
||||
apic_enabled = 1;
|
||||
irq_enable();
|
||||
|
||||
pit_start(1000);
|
||||
local_apic_config_timer();
|
||||
|
||||
pit_start(10);
|
||||
printk("acpi: all APIC online");
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user