blob: 840f3977bcde6601daf5d2ca3edbf4ad337c4ddf (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
#![no_std]
#[macro_use]
pub mod util;
pub mod allocators;
pub mod collections;
pub mod console;
pub mod device_tree;
pub mod drivers;
pub mod interrupts;
pub mod prelude;
#[cfg(not(test))]
mod panic;
use crate::prelude::*;
/// The entrypoint to the kernel. This should be executed by hart0 alone. It performs some early
/// boot tasks, then wakes up any other harts.
///
/// # Safety
///
/// - The `device_tree` pointer must be a valid pointer into physical memory. See
/// `device_tree::FlattenedDeviceTree::from_ptr` for the precise requirements.
/// - This must be called in supervisor mode with paging and traps disabled, but with all traps
/// delegated to supervisor mode.
#[no_mangle]
pub unsafe extern "C" fn hart0_boot(device_tree: *const u8) -> ! {
console::init();
info!("device_tree = {device_tree:?}");
let flattened_device_tree = unsafe { device_tree::FlattenedDeviceTree::from_ptr(device_tree) }
.expect("invalid DeviceTree");
for event in flattened_device_tree.struct_events() {
let event = event.expect("invalid DeviceTree");
dbg!(event);
}
// Set up the allocator and the timer subsystem.
//
// TODO: The timer really oughta be later...
flattened_device_tree
.for_each_property(|node, prop, value| {
if node == ["", "cpus"] && prop == "timebase-frequency" {
if value.len() == 4 {
let value = [value[0], value[1], value[2], value[3]];
let timebase_frequency = u32::from_be_bytes(value);
// SAFETY: Nobody is concurrently running, so they can't be concurrently
// modifying this.
unsafe {
drivers::riscv_timer::TIMEBASE_FREQUENCY = timebase_frequency;
}
dbg!(timebase_frequency);
} else {
warn!("/cpus/timebase-frequency was not a 4-byte quantity");
}
} else {
info!("{node}{prop} = {value:?}");
}
Ok(())
})
.map_err(|err| err.left_or_else(|void| void::unreachable(void)))
.expect("invalid DeviceTree");
interrupts::example_timer();
info!("sleeping forever...");
loop {
unsafe { core::arch::asm!("wfi") }
}
}
|