1
0
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:
Jiajie Chen 2020-06-21 08:04:49 +08:00
parent d7def80d82
commit 5006ef952f
8 changed files with 49 additions and 23 deletions

View File

@ -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);
}

View File

@ -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();

View File

@ -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);
}

View File

@ -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 {

View File

@ -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>);
}

View File

@ -0,0 +1 @@

View File

@ -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);
}

View File

@ -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);
}