summaryrefslogtreecommitdiff
path: root/arch/x86/machine/lapic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/machine/lapic.c')
-rw-r--r--arch/x86/machine/lapic.c111
1 files changed, 59 insertions, 52 deletions
diff --git a/arch/x86/machine/lapic.c b/arch/x86/machine/lapic.c
index a15bd5f1..ed5bba3f 100644
--- a/arch/x86/machine/lapic.c
+++ b/arch/x86/machine/lapic.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2017 Richard Braun.
+ * Copyright (c) 2011-2018 Richard Braun.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,7 +29,6 @@
#include <machine/cpu.h>
#include <machine/lapic.h>
#include <machine/pmap.h>
-#include <machine/trap.h>
#include <vm/vm_kmem.h>
/*
@@ -201,7 +200,7 @@ lapic_compute_freq(void)
{
uint32_t c1, c2;
- lapic_write(&lapic_map->svr, LAPIC_SVR_SOFT_EN | TRAP_LAPIC_SPURIOUS);
+ lapic_write(&lapic_map->svr, LAPIC_SVR_SOFT_EN | CPU_EXC_LAPIC_SPURIOUS);
lapic_write(&lapic_map->timer_dcr, LAPIC_TIMER_DCR_DIV1);
/* The APIC timer counter should never wrap around here */
@@ -222,6 +221,52 @@ lapic_eoi(void)
lapic_write(&lapic_map->eoi, 0);
}
+#ifdef CONFIG_PERFMON
+static void
+lapic_pmc_overflow_intr(unsigned int vector)
+{
+ (void)vector;
+
+ lapic_eoi();
+
+ /* Reset the LVT entry as it is automatically cleared when triggered */
+ lapic_write(&lapic_map->lvt_pmc, CPU_EXC_LAPIC_PMC_OF);
+
+ perfmon_overflow_intr();
+}
+#endif /* CONFIG_PERFMON */
+
+static void
+lapic_timer_intr(unsigned int vector)
+{
+ (void)vector;
+
+ lapic_eoi();
+ clock_tick_intr();
+}
+
+static void
+lapic_error_intr(unsigned int vector)
+{
+ uint32_t esr;
+
+ (void)vector;
+
+ esr = lapic_read(&lapic_map->esr);
+ log_err("lapic: error on cpu%u: esr:%08x", cpu_id(), esr);
+ lapic_write(&lapic_map->esr, 0);
+ lapic_eoi();
+}
+
+static void
+lapic_spurious_intr(unsigned int vector)
+{
+ (void)vector;
+ log_warning("lapic: spurious interrupt");
+
+ /* No EOI for this interrupt */
+}
+
static void __init
lapic_setup_registers(void)
{
@@ -229,18 +274,18 @@ lapic_setup_registers(void)
* LVT mask bits can only be cleared when the local APIC is enabled.
* They are kept disabled while the local APIC is disabled.
*/
- lapic_write(&lapic_map->svr, LAPIC_SVR_SOFT_EN | TRAP_LAPIC_SPURIOUS);
+ lapic_write(&lapic_map->svr, LAPIC_SVR_SOFT_EN | CPU_EXC_LAPIC_SPURIOUS);
lapic_write(&lapic_map->tpr, 0);
lapic_write(&lapic_map->eoi, 0);
lapic_write(&lapic_map->esr, 0);
lapic_write(&lapic_map->lvt_timer, LAPIC_LVT_TIMER_PERIODIC
- | TRAP_LAPIC_TIMER);
+ | CPU_EXC_LAPIC_TIMER);
lapic_write(&lapic_map->lvt_lint0, LAPIC_LVT_MASK_INTR);
lapic_write(&lapic_map->lvt_lint1, LAPIC_LVT_MASK_INTR);
- lapic_write(&lapic_map->lvt_error, TRAP_LAPIC_ERROR);
+ lapic_write(&lapic_map->lvt_error, CPU_EXC_LAPIC_ERROR);
lapic_write(&lapic_map->timer_dcr, LAPIC_TIMER_DCR_DIV1);
lapic_write(&lapic_map->timer_icr, lapic_bus_freq / CLOCK_FREQ);
- lapic_write(&lapic_map->lvt_pmc, TRAP_LAPIC_PMC_OF);
+ lapic_write(&lapic_map->lvt_pmc, CPU_EXC_LAPIC_PMC_OF);
}
void __init
@@ -248,6 +293,13 @@ lapic_setup(uint32_t map_addr)
{
uint32_t value;
+#ifdef CONFIG_PERFMON
+ cpu_register_intr(CPU_EXC_LAPIC_PMC_OF, lapic_pmc_overflow_intr);
+#endif
+ cpu_register_intr(CPU_EXC_LAPIC_TIMER, lapic_timer_intr);
+ cpu_register_intr(CPU_EXC_LAPIC_ERROR, lapic_error_intr);
+ cpu_register_intr(CPU_EXC_LAPIC_SPURIOUS, lapic_spurious_intr);
+
lapic_map = vm_kmem_map_pa(map_addr, sizeof(*lapic_map), NULL, NULL);
if (lapic_map == NULL) {
@@ -334,48 +386,3 @@ lapic_ipi_broadcast(uint32_t vector)
lapic_ipi(0, LAPIC_ICR_DEST_ALL_EXCEPT_SELF
| (vector & LAPIC_ICR_VECTOR_MASK));
}
-
-#ifdef CONFIG_PERFMON
-void
-lapic_pmc_overflow_intr(struct trap_frame *frame)
-{
- (void)frame;
-
- lapic_eoi();
-
- /* Reset the LVT entry as it is automatically cleared when triggered */
- lapic_write(&lapic_map->lvt_pmc, TRAP_LAPIC_PMC_OF);
-
- perfmon_overflow_intr();
-}
-#endif /* CONFIG_PERFMON */
-
-void
-lapic_timer_intr(struct trap_frame *frame)
-{
- (void)frame;
-
- lapic_eoi();
- clock_tick_intr();
-}
-
-void
-lapic_error_intr(struct trap_frame *frame)
-{
- uint32_t esr;
-
- (void)frame;
- esr = lapic_read(&lapic_map->esr);
- log_err("lapic: error on cpu%u: esr:%08x", cpu_id(), esr);
- lapic_write(&lapic_map->esr, 0);
- lapic_eoi();
-}
-
-void
-lapic_spurious_intr(struct trap_frame *frame)
-{
- (void)frame;
- log_warning("lapic: spurious interrupt");
-
- /* No EOI for this interrupt */
-}