asterinas/kernel/comps/uart/src/arch/x86/mod.rs

51 lines
1.2 KiB
Rust

// SPDX-License-Identifier: MPL-2.0
use alloc::string::ToString;
use ostd::{
arch::{
irq::{IRQ_CHIP, MappedIrqLine},
serial::SERIAL_PORT,
},
irq::IrqLine,
};
use spin::Once;
use crate::{
CONSOLE_NAME,
console::{Uart, UartConsole},
};
/// ISA interrupt number for UART serial.
// FIXME: The interrupt number should be retrieved from the ACPI table instead of being hard-coded.
const ISA_INTR_NUM: u8 = 4;
/// IRQ line for UART serial.
static IRQ_LINE: Once<MappedIrqLine> = Once::new();
pub(super) fn init() {
let Some(uart) = SERIAL_PORT.get() else {
return;
};
let Ok(mut irq_line) = IrqLine::alloc().and_then(|irq_line| {
IRQ_CHIP
.get()
.unwrap()
.map_isa_pin_to(irq_line, ISA_INTR_NUM)
}) else {
log::info!("[UART]: IRQ line is not available");
return;
};
let uart_console = UartConsole::new(uart);
aster_console::register_device(CONSOLE_NAME.to_string(), uart_console.clone());
irq_line.on_active(move |_| uart_console.trigger_input_callbacks());
IRQ_LINE.call_once(move || irq_line);
uart.flush();
log::info!("[UART]: Registered NS16550A as a console");
}