diff options
| author | Richard Qin <richard.qin.x@gmail.com> | 2026-11-08 05:56:48 +0800 |
|---|---|---|
| committer | Richard Qin <richard.qin.x@gmail.com> | 2026-11-08 05:56:48 +0800 |
| commit | 85ce9edd4ab33c9694ee5d4486a2a50a6442240b (patch) | |
| tree | ea11457cd09a45b58948d8e1ff1270d768a1e9f2 | |
| parent | 33e4bf49511154ac126e36f0490a574d0e01275f (diff) | |
| download | rcc-project-85ce9edd4ab33c9694ee5d4486a2a50a6442240b.tar.gz rcc-project-85ce9edd4ab33c9694ee5d4486a2a50a6442240b.tar.xz | |
[mubios] Enable IRQ0
Signed-off-by: Richard Qin <richard.qin.x@gmail.com>
| -rw-r--r-- | mubios/arch/mode_switch.S | 6 | ||||
| -rw-r--r-- | mubios/arch/reset.S | 5 | ||||
| -rw-r--r-- | mubios/core/post.c | 3 | ||||
| -rw-r--r-- | mubios/drivers/ioapic.c | 87 | ||||
| -rw-r--r-- | mubios/drivers/pic.c | 18 | ||||
| -rw-r--r-- | mubios/drivers/pit.c | 11 | ||||
| -rw-r--r-- | mubios/include/bios.h | 1 |
7 files changed, 112 insertions, 19 deletions
diff --git a/mubios/arch/mode_switch.S b/mubios/arch/mode_switch.S index 575c78d..9b2643a 100644 --- a/mubios/arch/mode_switch.S +++ b/mubios/arch/mode_switch.S @@ -109,7 +109,7 @@ protected_mode_entry: mov fs, ax mov gs, ax - mov esp, 0x00008000 + mov esp, 0x00007000 call post_main @@ -165,7 +165,7 @@ protected16_return: # Leave protected mode while already using a 16-bit code segment. mov eax, cr0 - and eax 0xFFFFFFFE + and eax, 0xFFFFFFFE mov cr0, eax # Jump to the prepared real-mode CS:IP pointer. @@ -179,6 +179,8 @@ real_mode_return: mov ds, ax mov es, ax mov ss, ax + mov fs, ax + mov gs, ax mov sp, 0x7FFE ret diff --git a/mubios/arch/reset.S b/mubios/arch/reset.S index 92dad17..0be8a05 100644 --- a/mubios/arch/reset.S +++ b/mubios/arch/reset.S @@ -40,8 +40,11 @@ reset_entry: call enter_protected_mode reset_halt: + sti + +reset_halt_loop: hlt - jmp reset_halt + jmp reset_halt_loop .section .reset, "ax" diff --git a/mubios/core/post.c b/mubios/core/post.c index 34ee715..a37f192 100644 --- a/mubios/core/post.c +++ b/mubios/core/post.c @@ -30,10 +30,11 @@ post_main (void) memory_init (); bda_init (); - ivt_init(); + ivt_init (); pic_init (); pit_init (); + ioapic_init (); serial_write ("mubios: IVT/PIC/PIT initialized\r\n"); } 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); } diff --git a/mubios/include/bios.h b/mubios/include/bios.h index e524682..eee22e8 100644 --- a/mubios/include/bios.h +++ b/mubios/include/bios.h @@ -46,6 +46,7 @@ void serial_write (const char *text); void pic_init (void); void pit_init (void); +void ioapic_init (void); void ivt_init (void); |
