Skip to content

Commit d91ff9d

Browse files
n1tram1Martin Schmidt
authored and
Martin Schmidt
committed
refactor: reuse driver_manager code for drivers initialization from dt
1 parent 4380043 commit d91ff9d

File tree

7 files changed

+55
-91
lines changed

7 files changed

+55
-91
lines changed

kernel/src/driver_manager.rs

Lines changed: 40 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,50 @@
1-
use alloc::{boxed::Box, collections::LinkedList, sync::Arc};
1+
use alloc::boxed::Box;
22

33
use super::device_tree::DeviceTree;
44
use super::drivers::{self, Matcher};
55
use super::error::Error;
66
use super::kernel_console;
7-
use drivers::{Console, Driver};
8-
use fdt::node::FdtNode;
7+
use drivers::Console;
8+
use fdt::{
9+
node::FdtNode,
10+
standard_nodes::MemoryRegion,
11+
};
912

10-
use crate::hal;
11-
use crate::mm::alloc_pages_for_hal;
12-
use hal_core::mm::{PageMap, Permissions};
13+
use crate::HAL;
14+
use crate::globals;
15+
use hal_core::mm::{PageMap, Permissions, NullPageAllocator};
1316

14-
pub struct DriverManager {
15-
drivers: LinkedList<Arc<dyn Driver>>,
16-
}
17+
pub struct DriverManager;
1718

1819
impl DriverManager {
19-
fn new() -> Self {
20-
Self {
21-
drivers: LinkedList::new(),
22-
}
23-
}
24-
25-
pub fn with_devices(dt: &DeviceTree) -> Result<Self, Error> {
26-
let mut mgr = Self::new();
27-
28-
mgr.do_console(dt)?;
29-
30-
Ok(mgr)
31-
}
32-
33-
fn do_console(&mut self, dt: &DeviceTree) -> Result<(), Error> {
20+
pub fn do_console(dt: &DeviceTree) -> Result<(), Error> {
3421
let cons_node = dt.console_node().ok_or(Error::DeviceNotFound(
3522
"dtb doesn't contain a console node...",
3623
))?;
3724

3825
map_dt_regions(&cons_node)?;
3926

4027
if let Some(cons_driver) =
41-
self.find_driver::<dyn Console + Sync + Send>(&cons_node, drivers::CONSOLE_MATCHERS)
28+
Self::find_driver::<dyn Console + Sync + Send>(&cons_node, drivers::CONSOLE_MATCHERS)
4229
{
43-
self.register_console(cons_driver)?;
30+
kernel_console::set_console(cons_driver)?;
4431
Ok(())
4532
} else {
4633
unmap_dt_regions(&cons_node)?;
4734
Err(Error::NoMatchingDriver("console"))
4835
}
4936
}
5037

38+
pub fn map_irq_chip(dt: &DeviceTree) -> Result<(), Error> {
39+
let intc = dt
40+
.interrupt_controller()
41+
.expect("device tree has no interrupt-controller node...");
42+
43+
map_dt_regions(&intc)?;
44+
45+
Ok(())
46+
}
47+
5148
fn extract_compatibles<'a>(node: &'a FdtNode) -> impl Iterator<Item = &'a str> {
5249
let compatible = node
5350
.properties()
@@ -58,7 +55,6 @@ impl DriverManager {
5855
}
5956

6057
pub fn find_driver<T: ?Sized>(
61-
&self,
6258
node: &FdtNode,
6359
matchers: &[&Matcher<T>],
6460
) -> Option<Box<T>> {
@@ -76,32 +72,31 @@ impl DriverManager {
7672

7773
None
7874
}
75+
}
7976

80-
fn register_console(&mut self, cons: Box<dyn Console + Sync + Send>) -> Result<(), Error> {
81-
let cons: Arc<dyn Console + Sync + Send> = Arc::from(cons);
82-
self.register_driver(cons.clone());
83-
kernel_console::set_console(cons.clone())?;
77+
fn num_pages(memory_region: &MemoryRegion) -> Result<usize, Error> {
78+
let size = memory_region.size.ok_or(Error::InvalidFdtNode)?;
8479

85-
Ok(())
86-
}
87-
88-
fn register_driver(&mut self, drv: Arc<dyn Driver>) {
89-
self.drivers.push_back(drv);
80+
if size < HAL.page_size() {
81+
Ok(1)
82+
} else {
83+
Ok(size / HAL.page_size())
9084
}
9185
}
9286

9387
fn map_dt_regions(node: &FdtNode) -> Result<(), Error> {
9488
if let Some(reg) = node.reg() {
89+
let mut kpt = HAL.kpt().lock();
9590
for memory_region in reg {
9691
let start = memory_region.starting_address as usize;
97-
let size = memory_region.size.ok_or(Error::InvalidFdtNode)?;
92+
let num_pages = num_pages(&memory_region)?;
93+
log::debug!("node: {:X} (#pages {})", start, num_pages);
9894

99-
assert!(size % hal::mm::PAGE_SIZE == 0);
100-
hal::mm::current().identity_map_range(
95+
kpt.identity_map_range(
10196
start.into(),
102-
size / hal::mm::PAGE_SIZE,
97+
num_pages,
10398
Permissions::READ | Permissions::WRITE,
104-
alloc_pages_for_hal,
99+
&globals::PHYSICAL_MEMORY_MANAGER
105100
)?;
106101
}
107102
}
@@ -110,18 +105,16 @@ fn map_dt_regions(node: &FdtNode) -> Result<(), Error> {
110105
}
111106

112107
fn unmap_dt_regions(node: &FdtNode) -> Result<(), Error> {
113-
let pagesize = hal::mm::PAGE_SIZE;
114-
115108
if let Some(reg) = node.reg() {
116109
for memory_region in reg {
117110
let start = memory_region.starting_address as usize;
118111
let size = memory_region.size.ok_or(Error::InvalidFdtNode)?;
119-
assert!(size % hal::mm::PAGE_SIZE == 0);
112+
assert!(size % HAL.page_size() == 0);
120113

121-
let kernel_pt = hal::mm::current();
122-
for page in (start..start + size).step_by(pagesize) {
114+
let mut kernel_pt = HAL.kpt().lock();
115+
for page in (start..start + size).step_by(HAL.page_size()) {
123116
kernel_pt
124-
.add_invalid_entry(page.into(), |_| unreachable!())
117+
.add_invalid_entry(page.into(), &NullPageAllocator)
125118
.unwrap();
126119
}
127120
}

kernel/src/drivers/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,4 @@ impl<T: ?Sized> Matcher<T> {
3131
}
3232
type ConsoleMatcher = Matcher<dyn Console + Send + Sync>;
3333

34-
pub const CONSOLE_MATCHERS: &[&ConsoleMatcher] = &[&pl011::MATCHER, &ns16550::MATCHER];
34+
pub static CONSOLE_MATCHERS: &[&ConsoleMatcher] = &[&pl011::MATCHER, &ns16550::MATCHER];

kernel/src/drivers/ns16550.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ impl Console for Ns16550 {
8181
}
8282
}
8383

84-
pub(super) const MATCHER: ConsoleMatcher = ConsoleMatcher {
84+
pub(super) static MATCHER: ConsoleMatcher = ConsoleMatcher {
8585
compatibles: &["ns16550a"],
8686
constructor: |reg| {
8787
Ok(Box::new(Ns16550::new(

kernel/src/drivers/pl011.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ impl Pl011 {
6262
}
6363
}
6464

65-
pub(super) const MATCHER: ConsoleMatcher = ConsoleMatcher {
65+
pub(super) static MATCHER: ConsoleMatcher = ConsoleMatcher {
6666
compatibles: &["arm,pl011"],
6767
constructor: |reg| {
6868
Ok(Box::new(Pl011::new(

kernel/src/generic_main.rs

Lines changed: 7 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
use super::device_tree::DeviceTree;
2-
use super::drivers::qemuexit::QemuExit;
2+
use super::drivers::qemuexit::QemuExit;
33
use super::drivers::Driver;
44
use super::globals;
5+
use super::driver_manager::DriverManager;
56

6-
use crate::HAL;
77
use crate::mm;
8-
8+
use crate::HAL;
99

1010
use crate::tests::{self, TestResult};
1111

1212
use log::info;
1313

14-
use hal_core::mm::{PageMap, Permissions, VAddr};
1514

1615
pub fn generic_main<const LAUNCH_TESTS: bool>(dt: DeviceTree, hacky_devices: &[&dyn Driver]) -> ! {
1716
info!("Entered generic_main");
@@ -24,43 +23,14 @@ pub fn generic_main<const LAUNCH_TESTS: bool>(dt: DeviceTree, hacky_devices: &[&
2423
globals::PHYSICAL_MEMORY_MANAGER
2524
.init_from_device_tree(&dt)
2625
.unwrap();
26+
// Below this comment, using alloc is possible.
2727
mm::map_address_space(&dt, devices).expect("failed to map the addres space");
2828

29-
// Driver stuff
30-
// let _drvmgr = DriverManager::with_devices(&dt).unwrap();
31-
32-
cfg_if::cfg_if! {
33-
if #[cfg(target_arch = "aarch64")] {
34-
// XXX: Ideally we'd read the device tree but we're not doing for now...
35-
log::trace!("mapping gic pages");
36-
let (gicd_base, gicc_base) = (0x800_0000, 0x801_0000);
37-
HAL.kpt().lock().identity_map_range(
38-
VAddr::new(gicd_base),
39-
0x0001_0000 / HAL.page_size(),
40-
Permissions::READ | Permissions::WRITE,
41-
&globals::PHYSICAL_MEMORY_MANAGER
42-
).unwrap();
43-
HAL.kpt().lock().identity_map_range(
44-
VAddr::new(gicc_base),
45-
0x0001_0000 / HAL.page_size(),
46-
Permissions::READ | Permissions::WRITE,
47-
&globals::PHYSICAL_MEMORY_MANAGER
48-
).unwrap();
49-
} else if #[cfg(target_arch = "riscv64")] {
50-
let base = 0xc000000;
51-
let max_offset = 0x3FFFFFC;
52-
HAL.kpt().lock().identity_map_range(
53-
VAddr::new(base),
54-
max_offset / HAL.page_size() + 1,
55-
Permissions::READ | Permissions::WRITE,
56-
&globals::PHYSICAL_MEMORY_MANAGER,
57-
).unwrap();
58-
}
59-
}
29+
DriverManager::do_console(&dt).expect("couldn't initialize a console from the device tree");
30+
DriverManager::map_irq_chip(&dt).expect("failed to map irq chip from the device tree");
6031

6132
log::trace!("initializing irq chip");
62-
63-
crate::HAL
33+
HAL
6434
.init_irq_chip(&globals::PHYSICAL_MEMORY_MANAGER)
6535
.expect("initialization of irq chip failed");
6636

kernel/src/kernel_console.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ use core::fmt::{self, Write};
33
use crate::drivers::Console;
44
use crate::Error;
55

6-
use alloc::sync::Arc;
6+
use alloc::boxed::Box;
77

88
use log::{Level, LevelFilter, Metadata, Record};
99
use spin::Mutex;
1010

1111
struct KernelConsole {
1212
earlyinit_console: Option<&'static (dyn Console + Sync)>,
13-
console: Option<Arc<dyn Console + Sync + Send>>,
13+
console: Option<Box<dyn Console + Sync + Send>>,
1414
}
1515

1616
impl KernelConsole {
@@ -38,7 +38,7 @@ impl fmt::Write for KernelConsole {
3838
}
3939
}
4040

41-
fn print_fmt(args: fmt::Arguments) {
41+
pub fn print_fmt(args: fmt::Arguments) {
4242
KERNEL_CONSOLE.lock().write_fmt(args).unwrap();
4343
}
4444

@@ -72,7 +72,7 @@ pub fn set_earlyinit_console(new_console: &'static (dyn Console + Sync)) {
7272
KERNEL_CONSOLE.lock().earlyinit_console = Some(new_console);
7373
}
7474

75-
pub fn set_console(new_console: Arc<dyn Console + Sync + Send>) -> Result<(), Error> {
75+
pub fn set_console(new_console: Box<dyn Console + Sync + Send>) -> Result<(), Error> {
7676
KERNEL_CONSOLE.lock().console = Some(new_console);
7777

7878
// TODO: return an error if the error already was some (unless we consider it is ok)

kernel/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
pub extern crate alloc;
1414

1515
pub mod drivers;
16+
pub mod driver_manager;
1617
mod utils;
1718

1819
pub mod error;

0 commit comments

Comments
 (0)