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");
|
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) {
|
fn write_redirection(mut gsi: usize, redirection: RedirectionEntry) {
|
||||||
let apic_i = get_apic_for_gsi(gsi);
|
let apic_i = get_apic_for_gsi(gsi);
|
||||||
gsi -= IOAPICS[apic_i].start_gsi.load(Ordering::Relaxed) as usize;
|
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, redirection.0 as u32);
|
||||||
write_register(apic_i, REGISTER_REDIRECTION + gsi as u8 * 2 + 1, (redirection.0 >> 32) as u32);
|
write_register(apic_i, REGISTER_REDIRECTION + gsi as u8 * 2 + 1, (redirection.0 >> 32) as u32);
|
||||||
}
|
}
|
||||||
fn mask_gsi(gsi: usize) {
|
pub fn set_irq_override(gsi: usize, vector: usize, polarity: u8, trigger: u8) {
|
||||||
let mut redirection = RedirectionEntry(0);
|
let mut redirection = read_redirection(gsi);
|
||||||
redirection.set_mask(1);
|
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);
|
write_redirection(gsi, redirection);
|
||||||
}
|
}
|
||||||
pub fn setup_ioapic(apic_i: u8, phys: u64, gsi_base: u32) {
|
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);
|
IOAPICS[apic_i].start_gsi.store(gsi_base, Ordering::Relaxed);
|
||||||
let max_ints = (read_register(apic_i, REGISTER_VERSION) >> 16) & 0xff;
|
let max_ints = (read_register(apic_i, REGISTER_VERSION) >> 16) & 0xff;
|
||||||
IOAPICS[apic_i].end_gsi.store(gsi_base + max_ints, Ordering::Relaxed);
|
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 {
|
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 crate::sys::acpica_osl::AE_OK;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
acpica::{acpi_madt_io_apic, acpi_madt_local_apic_override, acpi_subtable_header, acpi_table_header, acpi_table_madt, AcpiGetTable},
|
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::setup_ioapic,
|
ioapic::{set_irq_override, setup_ioapic},
|
||||||
lapic::setup_lapic,
|
lapic::setup_lapic,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -45,4 +45,21 @@ pub fn parse_madt() {
|
||||||
subtable_address += subtable_header.Length as u64;
|
subtable_address += subtable_header.Length as u64;
|
||||||
}
|
}
|
||||||
setup_lapic(lapic_address);
|
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