Process interrupt redirections
This commit is contained in:
parent
8d859654f4
commit
ae90171977
2 changed files with 36 additions and 6 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue