Enable serial interrupts on aarch64 ACPI

This commit is contained in:
Jeremy Soller
2025-11-21 08:39:38 -07:00
parent e3cafc975f
commit 7ffc046d46
3 changed files with 27 additions and 4 deletions
+4 -3
View File
@@ -153,12 +153,13 @@ pub unsafe fn init(already_supplied_rsdp: Option<*const u8>) {
}
}
//TODO: support this on any arch
#[cfg(target_arch = "aarch64")]
spcr::Spcr::init();
// TODO: Enumerate processors in userspace, and then provide an ACPI-independent interface
// to initialize enumerated processors to userspace?
Madt::init();
//TODO: support this on any arch
// SPCR must be initialized after MADT for interrupt controllers
#[cfg(target_arch = "aarch64")]
spcr::Spcr::init();
// TODO: Let userspace setup HPET, and then provide an interface to specify which timer to
// use?
Hpet::init();
+14 -1
View File
@@ -8,6 +8,12 @@ use crate::{
memory::{map_device_memory, PhysicalAddress, PAGE_SIZE},
};
const INTERRUPT_TYPE_8259: u8 = 1 << 0;
const INTERRUPT_TYPE_APIC: u8 = 1 << 1;
const INTERRUPT_TYPE_SAPIC: u8 = 1 << 2;
const INTERRUPT_TYPE_GIC: u8 = 1 << 3;
const INTERRUPT_TYPE_PLIC: u8 = 1 << 4;
#[derive(Clone, Copy, Debug)]
#[repr(C, packed)]
pub struct Spcr {
@@ -78,7 +84,14 @@ impl Spcr {
)
};
let serial_port = uart_pl011::SerialPort::new(virt.data(), false);
*COM1.lock() = SerialKind::Pl011(serial_port)
*COM1.lock() = SerialKind::Pl011(serial_port);
//TODO: enable IRQ on more platforms and interrupt types
if (spcr.interrupt_type & INTERRUPT_TYPE_GIC) == INTERRUPT_TYPE_GIC {
#[cfg(target_arch = "aarch64")]
unsafe {
crate::device::serial::init_acpi(spcr.gsiv);
}
}
} else {
warn!(
"SPCR unsuppoted address for PL011 {:#x?}",
+9
View File
@@ -88,3 +88,12 @@ pub unsafe fn init(fdt: &Fdt) {
COM1.lock().enable_irq();
}
}
pub unsafe fn init_acpi(irq: u32) {
//TODO: what should chip index be?
let virq = IRQ_CHIP.irq_chip_list.chips[0].ic.irq_to_virq(irq).unwrap();
info!("serial_port virq = {}", virq);
register_irq(virq as u32, Box::new(Com1Irq {}));
IRQ_CHIP.irq_enable(virq as u32);
COM1.lock().enable_irq();
}