Program LAPIC deadline
This commit is contained in:
+11
-5
@@ -7,6 +7,7 @@
|
||||
#include <zinnia/utils.h>
|
||||
#include <zinnia/vma.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <arch/timer.h>
|
||||
#include <stdint.h>
|
||||
#include <x86_64/apic.h>
|
||||
#include <x86_64/asm.h>
|
||||
@@ -95,17 +96,22 @@ void lapic_init(struct local_apic* lapic) {
|
||||
clock_spin_ns(10'000'000);
|
||||
|
||||
lapic->ticks_per_10ms = 0xFFFF'FFFF - lapic_read_reg(lapic, APIC_REG_CCR);
|
||||
lapic_write_reg(lapic, APIC_REG_LVT_TR, IDT_IPI_RESCHED | 0x20000);
|
||||
lapic_write_reg(lapic, APIC_REG_ICR_TIMER, lapic->ticks_per_10ms);
|
||||
lapic_write_reg(lapic, APIC_REG_LVT_TR, mmio_field(APIC_LVT_TR_VECTOR, IDT_TIMER));
|
||||
lapic_write_reg(lapic, APIC_REG_ICR_TIMER, 0);
|
||||
}
|
||||
|
||||
void arch_timer_program(uint64_t deadline_ns) {
|
||||
struct local_apic* lapic = &percpu_ref(arch_data)->lapic;
|
||||
const uint64_t now = clock_get_elapsed_ns();
|
||||
const uint64_t delta = MIN(deadline_ns > now ? deadline_ns - now : 0, 1'000'000'000);
|
||||
const uint64_t ticks = delta * lapic->ticks_per_10ms / 10'000'000;
|
||||
lapic_write_reg(lapic, APIC_REG_ICR_TIMER, MIN(MAX(ticks, 1), 0xFFFF'FFFF));
|
||||
}
|
||||
|
||||
void lapic_eoi(struct local_apic* lapic) {
|
||||
lapic_write_reg(lapic, APIC_REG_EOI, 0);
|
||||
}
|
||||
|
||||
constexpr uint64_t the_icr =
|
||||
mmio_field(APIC_ICR_VECTOR, 128) | mmio_field(APIC_ICR_DELIVERY_MODE, APIC_DELIVERY_STARTUP);
|
||||
|
||||
void lapic_send_ipi(
|
||||
struct local_apic* lapic,
|
||||
uint32_t target,
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void arch_timer_program(uint64_t deadline_ns);
|
||||
Reference in New Issue
Block a user