mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-22 08:06:17 +04:00
Initial irq manager and add device tree registry
This commit is contained in:
parent
d7def80d82
commit
5006ef952f
@ -19,9 +19,3 @@ pub unsafe fn init_external_interrupt() {
|
||||
|
||||
sie::set_sext();
|
||||
}
|
||||
|
||||
pub unsafe fn enable_serial_interrupt() {
|
||||
const UART16550: *mut u8 = phys_to_virt(0x10000000) as *mut u8;
|
||||
UART16550.add(4).write_volatile(0x0B);
|
||||
UART16550.add(1).write_volatile(0x01);
|
||||
}
|
||||
|
@ -61,7 +61,6 @@ pub extern "C" fn rust_main(hartid: usize, device_tree_paddr: usize) -> ! {
|
||||
crate::drivers::init(device_tree_vaddr);
|
||||
#[cfg(not(feature = "board_k210"))]
|
||||
unsafe {
|
||||
board::enable_serial_interrupt();
|
||||
board::init_external_interrupt();
|
||||
}
|
||||
crate::process::init();
|
||||
|
@ -1,15 +1,15 @@
|
||||
use super::super::block::virtio_blk;
|
||||
use super::super::gpu::virtio_gpu;
|
||||
use super::super::input::virtio_input;
|
||||
use super::super::net::virtio_net;
|
||||
use crate::drivers::device_tree::DEVICE_TREE_REGISTRY;
|
||||
use crate::memory::phys_to_virt;
|
||||
use device_tree::util::SliceRead;
|
||||
use device_tree::Node;
|
||||
use log::*;
|
||||
use rcore_memory::PAGE_SIZE;
|
||||
use virtio_drivers::{DeviceType, VirtIOHeader};
|
||||
|
||||
use super::super::block::virtio_blk;
|
||||
use super::super::gpu::virtio_gpu;
|
||||
use super::super::input::virtio_input;
|
||||
use super::super::net::virtio_net;
|
||||
use crate::memory::phys_to_virt;
|
||||
|
||||
pub fn virtio_probe(node: &Node) {
|
||||
let reg = match node.prop_raw("reg") {
|
||||
Some(reg) => reg,
|
||||
@ -38,3 +38,9 @@ pub fn virtio_probe(node: &Node) {
|
||||
t => warn!("Unrecognized virtio device: {:?}", t),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn driver_init() {
|
||||
DEVICE_TREE_REGISTRY
|
||||
.write()
|
||||
.insert("virtio,mmio", virtio_probe);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use alloc::string::String;
|
||||
use alloc::{collections::BTreeMap, string::String};
|
||||
use core::slice;
|
||||
|
||||
use device_tree::{DeviceTree, Node};
|
||||
@ -7,20 +7,21 @@ use super::bus::virtio_mmio::virtio_probe;
|
||||
use super::serial::uart16550;
|
||||
use super::CMDLINE;
|
||||
use crate::memory::phys_to_virt;
|
||||
use spin::RwLock;
|
||||
|
||||
const DEVICE_TREE_MAGIC: u32 = 0xd00dfeed;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref DEVICE_TREE_REGISTRY: RwLock<BTreeMap<&'static str, fn(&Node)>> =
|
||||
RwLock::new(BTreeMap::new());
|
||||
}
|
||||
|
||||
fn walk_dt_node(dt: &Node) {
|
||||
if let Ok(compatible) = dt.prop_str("compatible") {
|
||||
// TODO: query this from table
|
||||
if compatible == "virtio,mmio" {
|
||||
virtio_probe(dt);
|
||||
let registry = DEVICE_TREE_REGISTRY.read();
|
||||
if let Some(f) = registry.get(compatible) {
|
||||
f(dt);
|
||||
}
|
||||
if compatible == "ns16550a" {
|
||||
let addr = dt.prop_u64("reg").unwrap() as usize;
|
||||
uart16550::init(None, phys_to_virt(addr));
|
||||
}
|
||||
// TODO: init other devices
|
||||
}
|
||||
if let Ok(bootargs) = dt.prop_str("bootargs") {
|
||||
if bootargs.len() > 0 {
|
||||
|
@ -5,6 +5,9 @@ use alloc::collections::BTreeMap;
|
||||
use alloc::sync::Arc;
|
||||
use alloc::vec::Vec;
|
||||
|
||||
pub mod plic;
|
||||
|
||||
// Root Irq manager
|
||||
pub struct IrqManager {
|
||||
// drivers that only respond to specific irq
|
||||
mapping: BTreeMap<usize, Vec<Arc<dyn Driver>>>,
|
||||
@ -75,3 +78,9 @@ impl IrqManager {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
// interrupt controller
|
||||
pub trait IntcDriver: Driver {
|
||||
/// Register interrupt controller local irq
|
||||
fn register_local_irq(&mut self, irq: usize, driver: Arc<dyn Driver>);
|
||||
}
|
1
kernel/src/drivers/irq/plic.rs
Normal file
1
kernel/src/drivers/irq/plic.rs
Normal file
@ -0,0 +1 @@
|
||||
|
@ -112,6 +112,8 @@ lazy_static! {
|
||||
|
||||
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64", target_arch = "mips"))]
|
||||
pub fn init(dtb: usize) {
|
||||
serial::uart16550::driver_init();
|
||||
bus::virtio_mmio::driver_init();
|
||||
device_tree::init(dtb);
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,18 @@
|
||||
//! 16550 serial adapter driver for malta board
|
||||
|
||||
use super::SerialDriver;
|
||||
use crate::drivers::device_tree::DEVICE_TREE_REGISTRY;
|
||||
use crate::drivers::IRQ_MANAGER;
|
||||
use crate::drivers::SERIAL_DRIVERS;
|
||||
use crate::drivers::{DeviceType, Driver, DRIVERS};
|
||||
use crate::sync::SpinLock as Mutex;
|
||||
use crate::util::{read, write};
|
||||
use crate::{
|
||||
memory::phys_to_virt,
|
||||
util::{read, write},
|
||||
};
|
||||
use alloc::{string::String, sync::Arc};
|
||||
use core::fmt::{Arguments, Result, Write};
|
||||
use device_tree::Node;
|
||||
|
||||
pub struct SerialPort {
|
||||
base: usize,
|
||||
@ -124,3 +129,12 @@ pub fn init(irq: Option<usize>, base: usize) {
|
||||
SERIAL_DRIVERS.write().push(com.clone());
|
||||
IRQ_MANAGER.write().register_opt(irq, com);
|
||||
}
|
||||
|
||||
pub fn init_dt(dt: &Node) {
|
||||
let addr = dt.prop_u64("reg").unwrap() as usize;
|
||||
init(None, phys_to_virt(addr));
|
||||
}
|
||||
|
||||
pub fn driver_init() {
|
||||
DEVICE_TREE_REGISTRY.write().insert("ns16550a", init_dt);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user