Enable serial interrupts on aarch64 ACPI
This commit is contained in:
+4
-3
@@ -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
@@ -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?}",
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
Reference in New Issue
Block a user