Skip to content

Commit dec07da

Browse files
author
Jiajie Chen
committed
Add irq manager for drivers
1 parent ffe4fae commit dec07da

File tree

3 files changed

+70
-4
lines changed

3 files changed

+70
-4
lines changed

kernel/src/drivers/irq.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
use super::Driver;
2+
use alloc::collections::btree_map::Entry;
3+
use alloc::collections::BTreeMap;
4+
use alloc::sync::Arc;
5+
use alloc::vec::Vec;
6+
7+
struct IrqManager {
8+
// drivers that only respond to specific irq
9+
mapping: BTreeMap<u32, Vec<Arc<Driver>>>,
10+
// drivers that respond to all irqs
11+
all: Vec<Arc<Driver>>,
12+
}
13+
14+
impl IrqManager {
15+
pub fn new() -> IrqManager {
16+
IrqManager {
17+
mapping: BTreeMap::new(),
18+
all: Vec::new(),
19+
}
20+
}
21+
22+
pub fn register_irq(&mut self, irq: u32, driver: Arc<Driver>) {
23+
match self.mapping.entry(irq) {
24+
Entry::Occupied(mut e) => {
25+
e.get_mut().push(driver);
26+
}
27+
Entry::Vacant(e) => {
28+
let mut v = Vec::new();
29+
v.push(driver);
30+
e.insert(v);
31+
}
32+
}
33+
}
34+
35+
pub fn register_all(&mut self, driver: Arc<Driver>) {
36+
self.all.push(driver);
37+
}
38+
39+
pub fn deregister_irq(&mut self, irq: u32, driver: Arc<Driver>) {
40+
if let Some(e) = self.mapping.get_mut(&irq) {
41+
e.retain(|d| !Arc::ptr_eq(&d, &driver));
42+
}
43+
}
44+
45+
pub fn deregister_all(&mut self, driver: Arc<Driver>) {
46+
self.all.retain(|d| !Arc::ptr_eq(&d, &driver));
47+
}
48+
49+
pub fn handle_interrupt(&self, irq: u32) -> bool {
50+
if let Some(e) = self.mapping.get(&irq) {
51+
for dri in e.iter() {
52+
if dri.try_handle_interrupt(Some(irq)) {
53+
return true;
54+
}
55+
}
56+
}
57+
58+
for dri in self.all.iter() {
59+
if dri.try_handle_interrupt(Some(irq)) {
60+
return true;
61+
}
62+
}
63+
false
64+
}
65+
}

kernel/src/drivers/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ mod device_tree;
1818
mod gpu;
1919
#[allow(dead_code)]
2020
mod input;
21+
pub mod irq;
2122
#[allow(dead_code)]
2223
pub mod net;
2324
mod provider;

kernel/src/syscall/fs.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ impl Syscall<'_> {
338338
) -> SysResult {
339339
// TODO: check permissions based on uid/gid
340340
let proc = self.process();
341-
let path = unsafe { check_and_clone_cstr(path)? };
341+
let path = check_and_clone_cstr(path)?;
342342
let flags = AtFlags::from_bits_truncate(flags);
343343
if !proc.pid.is_init() {
344344
// we trust pid 0 process
@@ -419,7 +419,7 @@ impl Syscall<'_> {
419419
len: usize,
420420
) -> SysResult {
421421
let proc = self.process();
422-
let path = unsafe { check_and_clone_cstr(path)? };
422+
let path = check_and_clone_cstr(path)?;
423423
let slice = unsafe { self.vm().check_write_array(base, len)? };
424424
info!(
425425
"readlinkat: dirfd: {}, path: {:?}, base: {:?}, len: {}",
@@ -465,7 +465,7 @@ impl Syscall<'_> {
465465

466466
pub fn sys_truncate(&mut self, path: *const u8, len: usize) -> SysResult {
467467
let proc = self.process();
468-
let path = unsafe { check_and_clone_cstr(path)? };
468+
let path = check_and_clone_cstr(path)?;
469469
info!("truncate: path: {:?}, len: {}", path, len);
470470
proc.lookup_inode(&path)?.resize(len)?;
471471
Ok(0)
@@ -678,7 +678,7 @@ impl Syscall<'_> {
678678

679679
pub fn sys_unlinkat(&mut self, dirfd: usize, path: *const u8, flags: usize) -> SysResult {
680680
let proc = self.process();
681-
let path = unsafe { check_and_clone_cstr(path)? };
681+
let path = check_and_clone_cstr(path)?;
682682
let flags = AtFlags::from_bits_truncate(flags);
683683
info!(
684684
"unlinkat: dirfd: {}, path: {:?}, flags: {:?}",

0 commit comments

Comments
 (0)