Process interrupt redirections

This commit is contained in:
Mathieu Strypsteen 2024-10-09 19:19:55 +02:00
parent 8d859654f4
commit ae90171977
2 changed files with 36 additions and 6 deletions

View file

@ -54,15 +54,24 @@ fn get_apic_for_gsi(gsi: usize) -> usize {
}
panic!("Invalid GSI");
}
fn read_redirection(mut gsi: usize) -> RedirectionEntry {
let apic_i = get_apic_for_gsi(gsi);
gsi -= IOAPICS[apic_i].start_gsi.load(Ordering::Relaxed) as usize;
let mut redirection_int = read_register(apic_i, REGISTER_REDIRECTION + gsi as u8 * 2) as u64;
redirection_int |= (read_register(apic_i, REGISTER_REDIRECTION + gsi as u8 * 2 + 1) as u64) << 32;
return RedirectionEntry(redirection_int);
}
fn write_redirection(mut gsi: usize, redirection: RedirectionEntry) {
let apic_i = get_apic_for_gsi(gsi);
gsi -= IOAPICS[apic_i].start_gsi.load(Ordering::Relaxed) as usize;
write_register(apic_i, REGISTER_REDIRECTION + gsi as u8 * 2, redirection.0 as u32);
write_register(apic_i, REGISTER_REDIRECTION + gsi as u8 * 2 + 1, (redirection.0 >> 32) as u32);
}
fn mask_gsi(gsi: usize) {
let mut redirection = RedirectionEntry(0);
redirection.set_mask(1);
pub fn set_irq_override(gsi: usize, vector: usize, polarity: u8, trigger: u8) {
let mut redirection = read_redirection(gsi);
redirection.set_vector(48 + vector as u64);
redirection.set_pin_polarity(polarity as u64);
redirection.set_trigger_mode(trigger as u64);
write_redirection(gsi, redirection);
}
pub fn setup_ioapic(apic_i: u8, phys: u64, gsi_base: u32) {
@ -75,7 +84,11 @@ pub fn setup_ioapic(apic_i: u8, phys: u64, gsi_base: u32) {
IOAPICS[apic_i].start_gsi.store(gsi_base, Ordering::Relaxed);
let max_ints = (read_register(apic_i, REGISTER_VERSION) >> 16) & 0xff;
IOAPICS[apic_i].end_gsi.store(gsi_base + max_ints, Ordering::Relaxed);
assert!(gsi_base + max_ints < 128);
for i in gsi_base..gsi_base + max_ints {
mask_gsi(i as usize);
let mut redirection = RedirectionEntry(0);
redirection.set_mask(1);
redirection.set_vector(48 + i as u64);
write_redirection(i as usize, redirection);
}
}

View file

@ -3,8 +3,8 @@ use core::mem::size_of;
use crate::sys::acpica_osl::AE_OK;
use super::{
acpica::{acpi_madt_io_apic, acpi_madt_local_apic_override, acpi_subtable_header, acpi_table_header, acpi_table_madt, AcpiGetTable},
ioapic::setup_ioapic,
acpica::{acpi_madt_interrupt_override, acpi_madt_io_apic, acpi_madt_local_apic_override, acpi_subtable_header, acpi_table_header, acpi_table_madt, AcpiGetTable},
ioapic::{set_irq_override, setup_ioapic},
lapic::setup_lapic,
};
@ -45,4 +45,21 @@ pub fn parse_madt() {
subtable_address += subtable_header.Length as u64;
}
setup_lapic(lapic_address);
while subtable_address < end_address {
let subtable_header;
unsafe {
subtable_header = &*(subtable_address 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);
}
_ => {}
}
subtable_address += subtable_header.Length as u64;
}
}