Send all interrupts to BSP

This commit is contained in:
Mathieu Strypsteen 2024-10-10 08:26:22 +02:00
parent ae90171977
commit b0d07b47aa
10 changed files with 68 additions and 42 deletions

View file

@ -13,3 +13,6 @@ spin = "0.9.8"
[build-dependencies]
bindgen = "0.70.1"
[profile.release]
lto = true

View file

@ -1,3 +1,5 @@
.text
rdrand:
rdrand %rax
jnc rdrand

View file

@ -2,6 +2,8 @@ use core::arch::global_asm;
use log::warn;
use crate::sys::lapic::send_eoi;
global_asm!(include_str!("isr.s"), options(att_syntax));
#[repr(C)]
@ -71,10 +73,13 @@ extern "C" fn isr_handler(state: ISRState) {
panic!("Exception: {}", EXCEPTIONS[state.isr as usize]);
}
if 32 <= state.isr && state.isr <= 47 {
return; // PIC interrupt
return; // Legacy PIC interrupt
}
if state.isr == 255 {
return; // Spurious interrupt
}
if 48 <= state.isr && state.isr <= 254 {
send_eoi(); // APIC interrupt
}
warn!("Unhandled interrupt: {}", state.isr);
}

View file

@ -1,3 +1,5 @@
.text
.macro isr i
.global isr\i
isr\i:

View file

@ -5,7 +5,7 @@ use core::{
use bitfield::bitfield;
use crate::cpu::paging::map_physical;
use crate::{cpu::paging::map_physical, sys::lapic::BSP_LAPIC_ID};
struct IOAPIC {
address: AtomicPtr<u32>,
@ -89,6 +89,7 @@ pub fn setup_ioapic(apic_i: u8, phys: u64, gsi_base: u32) {
let mut redirection = RedirectionEntry(0);
redirection.set_mask(1);
redirection.set_vector(48 + i as u64);
redirection.set_destination(BSP_LAPIC_ID.load(Ordering::Relaxed) as u64);
write_redirection(i as usize, redirection);
}
}

View file

@ -1,19 +1,21 @@
use core::{
ptr::{null_mut, write_volatile},
sync::atomic::{AtomicPtr, Ordering},
ptr::{null_mut, read_volatile, write_volatile},
sync::atomic::{AtomicPtr, AtomicU8, Ordering},
};
use crate::cpu::paging::map_physical;
const REGISTER_EOI: u64 = 0xb0;
const REGISTER_SPURIOUS_INT: u64 = 0xf0;
const REGISTER_ID: usize = 0x20;
const REGISTER_EOI: usize = 0xb0;
const REGISTER_SPURIOUS_INT: usize = 0xf0;
static ADDRESS: AtomicPtr<u32> = AtomicPtr::new(null_mut());
pub static BSP_LAPIC_ID: AtomicU8 = AtomicU8::new(0);
pub fn send_eoi() {
let address = ADDRESS.load(Ordering::Relaxed);
unsafe {
write_volatile(address.add(REGISTER_EOI as usize / 4), 0);
write_volatile(address.add(REGISTER_EOI / 4), 0);
}
}
pub fn setup_lapic(phys: u64) {
@ -23,7 +25,8 @@ pub fn setup_lapic(phys: u64) {
}
ADDRESS.store(address, Ordering::Relaxed);
unsafe {
write_volatile(address.add(REGISTER_SPURIOUS_INT as usize / 4), 0x1ff);
BSP_LAPIC_ID.store(read_volatile(address.add(REGISTER_ID / 4)) as u8, Ordering::Relaxed);
write_volatile(address.add(REGISTER_SPURIOUS_INT / 4), 0x1ff);
}
send_eoi();
}

View file

@ -1,4 +1,4 @@
use core::mem::size_of;
use core::{arch::asm, mem::size_of};
use crate::sys::acpica_osl::AE_OK;
@ -18,48 +18,55 @@ pub fn parse_madt() {
madt = &*(address as *const acpi_table_madt);
}
let mut lapic_address: u64 = madt.Address as u64;
let mut subtable_address = madt as *const acpi_table_madt as u64 + size_of::<acpi_table_madt>() as u64;
let subtable_address = madt as *const acpi_table_madt as u64 + size_of::<acpi_table_madt>() as u64;
let end_address = madt as *const acpi_table_madt as u64 + madt.Header.Length as u64;
while subtable_address < end_address {
let mut subtable_address_i = subtable_address;
while subtable_address_i < end_address {
let subtable_header;
unsafe {
subtable_header = &*(subtable_address as *const acpi_subtable_header);
subtable_header = &*(subtable_address_i as *const acpi_subtable_header);
}
match subtable_header.Type {
1 => {
let subtable;
unsafe {
subtable = &*(subtable_address as *const acpi_madt_io_apic);
}
setup_ioapic(subtable.Id, subtable.Address as u64, subtable.GlobalIrqBase);
if subtable_header.Type == 5 {
let subtable;
unsafe {
subtable = &*(subtable_address_i as *const acpi_madt_local_apic_override);
}
5 => {
let subtable;
unsafe {
subtable = &*(subtable_address as *const acpi_madt_local_apic_override);
}
lapic_address = subtable.Address;
}
_ => {}
lapic_address = subtable.Address;
}
subtable_address += subtable_header.Length as u64;
subtable_address_i += subtable_header.Length as u64;
}
setup_lapic(lapic_address);
while subtable_address < end_address {
subtable_address_i = subtable_address;
while subtable_address_i < end_address {
let subtable_header;
unsafe {
subtable_header = &*(subtable_address as *const acpi_subtable_header);
subtable_header = &*(subtable_address_i as *const acpi_subtable_header);
}
match subtable_header.Type {
2 => {
let subtable;
unsafe {
subtable = &*(subtable_address as *const acpi_madt_interrupt_override);
}
set_irq_override(subtable.GlobalIrq as usize, subtable.SourceIrq as usize, subtable.IntiFlags as u8 & 3, subtable.IntiFlags as u8 & 0xc);
if subtable_header.Type == 1 {
let subtable;
unsafe {
subtable = &*(subtable_address_i as *const acpi_madt_io_apic);
}
_ => {}
setup_ioapic(subtable.Id, subtable.Address as u64, subtable.GlobalIrqBase);
}
subtable_address += subtable_header.Length as u64;
subtable_address_i += subtable_header.Length as u64;
}
subtable_address_i = subtable_address;
while subtable_address_i < end_address {
let subtable_header;
unsafe {
subtable_header = &*(subtable_address_i as *const acpi_subtable_header);
}
if subtable_header.Type == 2 {
let subtable;
unsafe {
subtable = &*(subtable_address_i as *const acpi_madt_interrupt_override);
}
set_irq_override(subtable.GlobalIrq as usize, subtable.SourceIrq as usize, subtable.IntiFlags as u8 & 3, subtable.IntiFlags as u8 & 0xc);
}
subtable_address_i += subtable_header.Length as u64;
}
unsafe {
asm!("sti");
}
}

View file

@ -1,6 +1,6 @@
pub mod acpica;
pub mod acpica_osl;
mod ioapic;
mod lapic;
pub mod lapic;
pub mod madt;
pub mod pic;

4
loader/Cargo.lock generated
View file

@ -65,9 +65,9 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "proc-macro2"
version = "1.0.86"
version = "1.0.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a"
dependencies = [
"unicode-ident",
]

View file

@ -9,3 +9,6 @@ kernel-common = {path = "../lib/kernel-common"}
log = "0.4.22"
static-alloc = "0.2.5"
uefi = "0.32.0"
[profile.release]
lto = true