summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorsigsegv7 <ian@vegaa.systems>2023-10-18 18:22:48 -0400
committersigsegv7 <ian@vegaa.systems>2023-10-18 18:24:15 -0400
commitb184afe98009836e31f2daa7dcb5fba211c453e1 (patch)
tree445d1fbf417a4c68f15d080d196b6d31cce4e6d2 /sys
parentd42c2061e1b8abb7ddaf628b6016e7a1ad8eedb0 (diff)
kernel/amd64: lapic: Add ESR reading logic
Signed-off-by: sigsegv7 <ian@vegaa.systems>
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/amd64/lapic.c21
-rw-r--r--sys/include/arch/amd64/lapicvar.h6
2 files changed, 27 insertions, 0 deletions
diff --git a/sys/arch/amd64/lapic.c b/sys/arch/amd64/lapic.c
index af219d2..6f2f6c1 100644
--- a/sys/arch/amd64/lapic.c
+++ b/sys/arch/amd64/lapic.c
@@ -208,6 +208,27 @@ lapic_set_ldr(void)
lapic_writel(LAPIC_LDR, LAPIC_STARTUP_LID);
}
+/*
+ * Reads the Local APIC error status
+ * register. Returns the value read.
+ *
+ * XXX: It is a good idea to save the value returned as
+ * each read will clear the register.
+ */
+static inline uint32_t
+lapic_read_esr(void)
+{
+ /*
+ * We'll need to write 0 to clear the ESR and reload
+ * it with any new errors that happened... In xAPIC mode
+ * we can write anything to do this; however, in x2APIC
+ * mode, writes of 0 are enforced. We'll only write 0 to
+ * work both with x2APIC and xAPIC mode...
+ */
+ lapic_writel(LAPIC_ERR, 0);
+ return lapic_readl(LAPIC_ERR);
+}
+
void
lapic_timer_init(size_t *freq_out)
{
diff --git a/sys/include/arch/amd64/lapicvar.h b/sys/include/arch/amd64/lapicvar.h
index 6c2c37f..2ad1a09 100644
--- a/sys/include/arch/amd64/lapicvar.h
+++ b/sys/include/arch/amd64/lapicvar.h
@@ -91,4 +91,10 @@
/* LVT bits */
#define LAPIC_LVT_MASK __BIT(16)
+/* Possible error bits within ESR */
+#define ESR_REDIR_IPI __BIT(4) /* Redirectible IPI */
+#define ESR_SIV __BIT(5) /* Send Illegal Vector */
+#define ESR_RIV __BIT(6) /* Received Illegal Vector */
+#define ESR_IRA __BIT(7) /* Illegal Register Address */
+
#endif /* !_AMD64_LAPICVAR_H_ */