acpi: calibrate local APIC timer on BSP

This commit is contained in:
2023-03-28 21:38:47 +01:00
parent 9828f35d36
commit e0e6f4a9ae
8 changed files with 133 additions and 9 deletions

View File

@@ -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;
}