summaryrefslogtreecommitdiff
path: root/sys/arch/amd64
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/amd64')
-rw-r--r--sys/arch/amd64/cpu/idt.S9
-rw-r--r--sys/arch/amd64/cpu/lapic.c24
2 files changed, 33 insertions, 0 deletions
diff --git a/sys/arch/amd64/cpu/idt.S b/sys/arch/amd64/cpu/idt.S
index c430a44..729d958 100644
--- a/sys/arch/amd64/cpu/idt.S
+++ b/sys/arch/amd64/cpu/idt.S
@@ -306,6 +306,15 @@ page_fault:
jmp 1b
hlt
+ .globl lapic_tmr_isr
+lapic_tmr_isr:
+ KFENCE
+ push_frame 0x81
+ nop
+ pop_frame 0x81
+ KFENCE
+ iretq
+
.section .data
.align 8
IDT:
diff --git a/sys/arch/amd64/cpu/lapic.c b/sys/arch/amd64/cpu/lapic.c
index acf2573..076ddd3 100644
--- a/sys/arch/amd64/cpu/lapic.c
+++ b/sys/arch/amd64/cpu/lapic.c
@@ -43,6 +43,7 @@
#include <md/i8254.h>
#include <md/cpuid.h>
#include <md/msr.h>
+#include <md/idt.h>
#define dtrace(fmt, ...) trace("lapic: " fmt, ##__VA_ARGS__)
@@ -82,6 +83,7 @@
/* Accessed via RDMSR/WRMSR */
#define X2APIC_MSR_BASE 0x00000800
+extern void lapic_tmr_isr(void);
static struct acpi_madt *madt;
/*
@@ -337,6 +339,17 @@ lapic_enable(struct mcb *mcb)
lapic_write(mcb, LAPIC_REG_SVR, svr | 0xFF);
}
+static void
+lapic_timer_oneshot(struct mcb *mcb, size_t count)
+{
+ if (mcb == NULL) {
+ return;
+ }
+
+ lapic_tmr_enable(mcb, LAPIC_TMR_ONESHOT);
+ lapic_write(mcb, LAPIC_REG_TICR, count);
+}
+
uint32_t
lapic_read_id(struct mcb *mcb)
{
@@ -350,6 +363,16 @@ lapic_read_id(struct mcb *mcb)
}
void
+lapic_oneshot_usec(struct mcb *mcb, size_t usec)
+{
+ if (mcb == NULL) {
+ return;
+ }
+
+ lapic_timer_oneshot(mcb, mcb->lapic_tmr_freq / 1000000);
+}
+
+void
lapic_init(void)
{
struct cpu_info *ci;
@@ -375,4 +398,5 @@ lapic_init(void)
lapic_enable(mcb);
mcb->lapic_tmr_freq = lapic_tmr_clbr(mcb);
+ idt_set_gate(LAPIC_TMR_VEC, INT_GATE, (uintptr_t)lapic_tmr_isr, 0);
}