Skip to content

Commit 3382a7c

Browse files
n1tram1Skallwar
authored andcommitted
refactor: reuse driver_manager code for drivers initialization from dt
1 parent afa941c commit 3382a7c

File tree

7 files changed

+50
-94
lines changed

7 files changed

+50
-94
lines changed

kernel/src/driver_manager.rs

Lines changed: 37 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,47 @@
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::{node::FdtNode, standard_nodes::MemoryRegion};
99

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

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

1816
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> {
17+
pub fn do_console(dt: &DeviceTree) -> Result<(), Error> {
3418
let cons_node = dt.console_node().ok_or(Error::DeviceNotFound(
3519
"dtb doesn't contain a console node...",
3620
))?;
3721

3822
map_dt_regions(&cons_node)?;
3923

4024
if let Some(cons_driver) =
41-
self.find_driver::<dyn Console + Sync + Send>(&cons_node, drivers::CONSOLE_MATCHERS)
25+
Self::find_driver::<dyn Console + Sync + Send>(&cons_node, drivers::CONSOLE_MATCHERS)
4226
{
43-
self.register_console(cons_driver)?;
27+
kernel_console::set_console(cons_driver)?;
4428
Ok(())
4529
} else {
4630
unmap_dt_regions(&cons_node)?;
4731
Err(Error::NoMatchingDriver("console"))
4832
}
4933
}
5034

35+
pub fn map_irq_chip(dt: &DeviceTree) -> Result<(), Error> {
36+
let intc = dt
37+
.interrupt_controller()
38+
.expect("device tree has no interrupt-controller node...");
39+
40+
map_dt_regions(&intc)?;
41+
42+
Ok(())
43+
}
44+
5145
fn extract_compatibles<'a>(node: &'a FdtNode) -> impl Iterator<Item = &'a str> {
5246
let compatible = node
5347
.properties()
@@ -57,11 +51,7 @@ impl DriverManager {
5751
compatible.split('\0')
5852
}
5953

60-
pub fn find_driver<T: ?Sized>(
61-
&self,
62-
node: &FdtNode,
63-
matchers: &[&Matcher<T>],
64-
) -> Option<Box<T>> {
54+
pub fn find_driver<T: ?Sized>(node: &FdtNode, matchers: &[&Matcher<T>]) -> Option<Box<T>> {
6555
for compat in Self::extract_compatibles(node) {
6656
let matching_constructor = matchers
6757
.iter()
@@ -76,32 +66,30 @@ impl DriverManager {
7666

7767
None
7868
}
69+
}
7970

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())?;
71+
fn num_pages(memory_region: &MemoryRegion) -> Result<usize, Error> {
72+
let size = memory_region.size.ok_or(Error::InvalidFdtNode)?;
8473

85-
Ok(())
86-
}
87-
88-
fn register_driver(&mut self, drv: Arc<dyn Driver>) {
89-
self.drivers.push_back(drv);
74+
if size < HAL.page_size() {
75+
Ok(1)
76+
} else {
77+
Ok(size / HAL.page_size())
9078
}
9179
}
9280

9381
fn map_dt_regions(node: &FdtNode) -> Result<(), Error> {
9482
if let Some(reg) = node.reg() {
83+
let mut kpt = HAL.kpt().lock();
9584
for memory_region in reg {
9685
let start = memory_region.starting_address as usize;
97-
let size = memory_region.size.ok_or(Error::InvalidFdtNode)?;
86+
let num_pages = num_pages(&memory_region)?;
9887

99-
assert!(size % hal::mm::PAGE_SIZE == 0);
100-
hal::mm::current().identity_map_range(
88+
kpt.identity_map_range(
10189
start.into(),
102-
size / hal::mm::PAGE_SIZE,
90+
num_pages,
10391
Permissions::READ | Permissions::WRITE,
104-
alloc_pages_for_hal,
92+
&globals::PHYSICAL_MEMORY_MANAGER,
10593
)?;
10694
}
10795
}
@@ -110,18 +98,16 @@ fn map_dt_regions(node: &FdtNode) -> Result<(), Error> {
11098
}
11199

112100
fn unmap_dt_regions(node: &FdtNode) -> Result<(), Error> {
113-
let pagesize = hal::mm::PAGE_SIZE;
114-
115101
if let Some(reg) = node.reg() {
116102
for memory_region in reg {
117103
let start = memory_region.starting_address as usize;
118104
let size = memory_region.size.ok_or(Error::InvalidFdtNode)?;
119-
assert!(size % hal::mm::PAGE_SIZE == 0);
105+
assert!(size % HAL.page_size() == 0);
120106

121-
let kernel_pt = hal::mm::current();
122-
for page in (start..start + size).step_by(pagesize) {
107+
let mut kernel_pt = HAL.kpt().lock();
108+
for page in (start..start + size).step_by(HAL.page_size()) {
123109
kernel_pt
124-
.add_invalid_entry(page.into(), |_| unreachable!())
110+
.add_invalid_entry(page.into(), &NullPageAllocator)
125111
.unwrap();
126112
}
127113
}

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: 5 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::device_tree::DeviceTree;
2+
use super::driver_manager::DriverManager;
23
use super::drivers::qemuexit::QemuExit;
34
use super::drivers::Driver;
45
use super::globals;
@@ -10,8 +11,6 @@ use crate::tests::{self, TestResult};
1011

1112
use log::info;
1213

13-
use hal_core::mm::{PageMap, Permissions, VAddr};
14-
1514
pub fn generic_main<const LAUNCH_TESTS: bool>(dt: DeviceTree, hacky_devices: &[&dyn Driver]) -> ! {
1615
info!("Entered generic_main");
1716
let qemu_exit = QemuExit::new();
@@ -23,44 +22,14 @@ pub fn generic_main<const LAUNCH_TESTS: bool>(dt: DeviceTree, hacky_devices: &[&
2322
globals::PHYSICAL_MEMORY_MANAGER
2423
.init_from_device_tree(&dt)
2524
.unwrap();
25+
// Below this comment, using alloc is possible.
2626
mm::map_address_space(&dt, devices).expect("failed to map the addres space");
2727

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

6031
log::trace!("initializing irq chip");
61-
62-
crate::HAL
63-
.init_irq_chip(&globals::PHYSICAL_MEMORY_MANAGER)
32+
HAL.init_irq_chip(&globals::PHYSICAL_MEMORY_MANAGER)
6433
.expect("initialization of irq chip failed");
6534

6635
HAL.unmask_interrupts();

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
@@ -12,6 +12,7 @@
1212

1313
pub extern crate alloc;
1414

15+
pub mod driver_manager;
1516
pub mod drivers;
1617
mod utils;
1718

0 commit comments

Comments
 (0)