RustForge

rust-kernel

Rustbelt: a hobby x86_64 kernel written in Rust

rust-kernel / src / arch / aarch64 / board / mod.rs
1984 bytes ยท raw
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
//! What differs from board to board, behind three small traits. The rest of
//! the arm64 code only talks to `board::current()`.
//!
//! - `virt`: QEMU's generic Arm board. Implemented and tested; addresses
//!   come from its device tree, with the usual values as a fallback.
//! - `raspi3`: the Raspberry Pi 3 (BCM2837). A skeleton: the addresses are
//!   written down, the drivers are TODO (see the README's Pi roadmap).

pub mod pl011;
pub mod raspi3;
pub mod virt;

/// A serial port: one byte out.
pub trait Uart: Sync {
    fn putc(&self, byte: u8);
}

/// An interrupt controller.
pub trait IrqController: Sync {
    /// Reset it and switch it on (all interrupts still disabled).
    fn init(&self);
    /// Let interrupt number `irq` through.
    fn enable(&self, irq: u32);
    /// Which interrupt is this? (`None`: a spurious one, nothing to do.)
    fn ack(&self) -> Option<u32>;
    /// Done with `irq`.
    fn eoi(&self, irq: u32);
}

/// What kind of memory a 1 GiB block of physical addresses holds.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Kind {
    /// RAM: cached, can hold code.
    Normal,
    /// Device registers: uncached, in order, never executed.
    Device,
}

/// A board.
pub trait Board: Sync {
    fn name(&self) -> &'static str;
    fn uart(&self) -> &dyn Uart;
    fn irq(&self) -> &dyn IrqController;
    /// The interrupt number of the EL1 virtual timer at this controller.
    fn timer_irq(&self) -> u32;
    /// The physical memory map, in 1 GiB blocks: (first address, kind).
    fn memory_map(&self) -> &'static [(u64, Kind)];
    /// Read the device tree at `dtb` (if any) and use what it says.
    /// Returns lines for the boot log.
    fn configure(&self, dtb: Option<&super::dtb::Fdt>) -> alloc::vec::Vec<alloc::string::String>;
}

/// The board this kernel was built for. (Only `virt` for now; picking the
/// Pi 3 will be a cargo feature once its drivers exist.)
pub fn current() -> &'static dyn Board {
    &virt::VIRT
}