aboutsummaryrefslogtreecommitdiff
path: root/mubios/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'mubios/drivers')
-rw-r--r--mubios/drivers/ioapic.c87
-rw-r--r--mubios/drivers/pic.c18
-rw-r--r--mubios/drivers/pit.c11
3 files changed, 101 insertions, 15 deletions
diff --git a/mubios/drivers/ioapic.c b/mubios/drivers/ioapic.c
new file mode 100644
index 0000000..98f2210
--- /dev/null
+++ b/mubios/drivers/ioapic.c
@@ -0,0 +1,87 @@
+/*
+ RCC-Project
+
+ Copyright (C) 2026 Richard Qin
+
+ This file is part of RCC-Project.
+
+ RCC-Project is free software; you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your option) any
+ later version.
+
+ RCC-Project is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ RCC-Project; see the file COPYING. If not see
+ <http://www.gnu.org/licenses/>.
+ */
+
+#include "bios.h"
+#include "io.h"
+
+#define IOAPIC_INDEX 0xFEC00000u
+#define IOAPIC_DATA 0xFEC00010u
+
+#define IOAPIC_IRQ0_LOW 0x10u
+#define IOAPIC_IRQ0_HIGH 0x11u
+
+#define IOAPIC_IRQ0_EXTINT 0x00000700u
+
+#define IA32_APIC_BASE_MSR 0x0000001Bu
+#define APIC_BASE 0xFEE00000u
+#define APIC_SVR_OFFSET 0x000000F0u
+#define APIC_LVT0_OFFSET 0x00000350u
+
+static volatile u32 *const ioapic_index = (volatile u32 *)IOAPIC_INDEX;
+
+static volatile u32 *const ioapic_data = (volatile u32 *)IOAPIC_DATA;
+
+static inline void
+rdmsr (u32 msr, u32 *low, u32 *high)
+{
+ __asm__ volatile ("rdmsr" : "=a"(*low), "=d"(*high) : "c"(msr));
+}
+
+static inline void
+wrmsr (u32 msr, u32 low, u32 high)
+{
+ __asm__ volatile ("wrmsr" : : "a"(low), "d"(high), "c"(msr));
+}
+
+static void
+ioapic_write (u8 index, u32 value)
+{
+ *ioapic_index = index;
+ *ioapic_data = value;
+}
+
+void
+ioapic_init (void)
+{
+ u32 apic_base_low;
+ u32 apic_base_high;
+
+ rdmsr (IA32_APIC_BASE_MSR, &apic_base_low, &apic_base_high);
+
+ apic_base_low |= 0x00000800u;
+ wrmsr (IA32_APIC_BASE_MSR, apic_base_low, apic_base_high);
+
+ /*
+ * Enable the local APIC.
+ */
+ *(volatile u32 *)(APIC_BASE + APIC_SVR_OFFSET) = 0x000001FFu;
+
+ /*
+ * Route legacy PIC interrupts through LVT0.
+ */
+ *(volatile u32 *)(APIC_BASE + APIC_LVT0_OFFSET) = 0x00000700u;
+
+ /*
+ * Route IOAPIC pin 0 to the legacy PIC ExtINT path.
+ */
+ ioapic_write (IOAPIC_IRQ0_LOW, IOAPIC_IRQ0_EXTINT);
+ ioapic_write (IOAPIC_IRQ0_HIGH, 0x00000000u);
+}
diff --git a/mubios/drivers/pic.c b/mubios/drivers/pic.c
index 099cee8..2144b6b 100644
--- a/mubios/drivers/pic.c
+++ b/mubios/drivers/pic.c
@@ -23,9 +23,9 @@
#include "io.h"
#define PIC1_COMMAND 0x0020u
-#define PIC1_DATA 0x0021u
+#define PIC1_DATA 0x0021u
#define PIC2_COMMAND 0x00A0u
-#define PIC2_DATA 0x00A1u
+#define PIC2_DATA 0x00A1u
#define PIC_ICW1_INIT 0x11u
#define PIC_ICW4_8086 0x01u
@@ -36,30 +36,28 @@
#define PIC1_CASCADE_ID 0x04u
#define PIC2_CASCADE_ID 0x02u
-#define PIC1_MASK_DEFAULT 0xFBu
+#define PIC1_MASK_DEFAULT 0xFAu
#define PIC2_MASK_DEFAULT 0xFFu
void
pic_init (void)
{
io_out8 (PIC1_COMMAND, PIC_ICW1_INIT);
- io_out8(PIC2_COMMAND, PIC_ICW1_INIT);
+ io_out8 (PIC2_COMMAND, PIC_ICW1_INIT);
- io_out8(PIC1_DATA, PIC1_VECTOR_BASE);
+ io_out8 (PIC1_DATA, PIC1_VECTOR_BASE);
io_out8 (PIC2_DATA, PIC2_VECTOR_BASE);
- io_out8(PIC1_DATA, PIC1_CASCADE_ID);
+ io_out8 (PIC1_DATA, PIC1_CASCADE_ID);
io_out8 (PIC2_DATA, PIC2_CASCADE_ID);
- io_out8(PIC1_DATA, PIC_ICW4_8086);
+ io_out8 (PIC1_DATA, PIC_ICW4_8086);
io_out8 (PIC2_DATA, PIC_ICW4_8086);
/*
* Keep the cascade line enabled.
* All actual hardware IRQ lines remain masked.
*/
- io_out8(PIC1_DATA, PIC1_MASK_DEFAULT);
+ io_out8 (PIC1_DATA, PIC1_MASK_DEFAULT);
io_out8 (PIC2_DATA, PIC2_MASK_DEFAULT);
-
}
-
diff --git a/mubios/drivers/pit.c b/mubios/drivers/pit.c
index 4213940..69b3390 100644
--- a/mubios/drivers/pit.c
+++ b/mubios/drivers/pit.c
@@ -23,17 +23,18 @@
#include "io.h"
#define PIT_COUNTER0 0x0040u
-#define PIT_COMMAND 0x0043u
+#define PIT_COMMAND 0x0043u
#define PIT_SELECT_CHANNEL0 0x00u
-#define PIT_ACCESS_WORD 0x30u
-#define PIT_MODE_2 0x04u
+#define PIT_ACCESS_WORD 0x30u
+#define PIT_MODE_2 0x04u
#define PIT_BINARY 0x00u
#define PIT_COMMAND_CHANNEL0_MODE2 \
(PIT_SELECT_CHANNEL0 | PIT_ACCESS_WORD | PIT_MODE_2 | PIT_BINARY)
-void pit_init(void)
+void
+pit_init (void)
{
io_out8 (PIT_COMMAND, PIT_COMMAND_CHANNEL0_MODE2);
@@ -41,5 +42,5 @@ void pit_init(void)
* A divisor of zero represents 65536.
*/
io_out8 (PIT_COUNTER0, 0x00u);
- io_out8 (PIT_COUNTER0, 0x00u);
+ io_out8 (PIT_COUNTER0, 0x00u);
}