From 85ce9edd4ab33c9694ee5d4486a2a50a6442240b Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Sun, 8 Nov 2026 05:56:48 +0800 Subject: [mubios] Enable IRQ0 Signed-off-by: Richard Qin --- mubios/drivers/ioapic.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 mubios/drivers/ioapic.c (limited to 'mubios/drivers/ioapic.c') 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 + . + */ + +#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); +} -- cgit v1.2.3