Add documentation

This commit is contained in:
Berkus Decker 2020-10-12 22:08:51 +03:00
parent 4898ad3139
commit 408857fcb6
7 changed files with 76 additions and 14 deletions

View File

@ -4,14 +4,15 @@
* Based on ideas from Jorge Aparicio, Andre Richter, Phil Oppenheimer. * Based on ideas from Jorge Aparicio, Andre Richter, Phil Oppenheimer.
* Copyright (c) 2019 Berkus Decker <berkus+vesper@metta.systems> * Copyright (c) 2019 Berkus Decker <berkus+vesper@metta.systems>
*/ */
//! Low-level boot of the Raspberry's processor
//! http://infocenter.arm.com/help/topic/com.arm.doc.dai0527a/DAI0527A_baremetal_boot_code_for_ARMv8_A_processors.pdf
use { use {
crate::endless_sleep, crate::endless_sleep,
cortex_a::{asm, regs::*}, cortex_a::{asm, regs::*},
}; };
/// Low-level boot of the Raspberry's processor
/// http://infocenter.arm.com/help/topic/com.arm.doc.dai0527a/DAI0527A_baremetal_boot_code_for_ARMv8_A_processors.pdf
/// Type check the user-supplied entry function. /// Type check the user-supplied entry function.
#[macro_export] #[macro_export]
macro_rules! entry { macro_rules! entry {

View File

@ -354,6 +354,7 @@ fn into_mmu_attributes(
* 48-bit virtual address space; different mappings in VBAR0 (EL0) and VBAR1 (EL1+). * 48-bit virtual address space; different mappings in VBAR0 (EL0) and VBAR1 (EL1+).
*/ */
/// Number of entries in a 4KiB mmu table.
pub const NUM_ENTRIES_4KIB: u64 = 512; pub const NUM_ENTRIES_4KIB: u64 = 512;
/// Trait for abstracting over the possible page sizes, 4KiB, 16KiB, 2MiB, 1GiB. /// Trait for abstracting over the possible page sizes, 4KiB, 16KiB, 2MiB, 1GiB.
@ -412,9 +413,14 @@ pub enum PageDirectory {}
/// L3 tables -- only pointers to 4/16KiB pages /// L3 tables -- only pointers to 4/16KiB pages
pub enum PageTable {} pub enum PageTable {}
/// Shared trait for specific table levels.
pub trait TableLevel {} pub trait TableLevel {}
/// Shared trait for hierarchical table levels.
///
/// Specifies what is the next level of page table hierarchy.
pub trait HierarchicalLevel: TableLevel { pub trait HierarchicalLevel: TableLevel {
/// Level of the next translation table below this one.
type NextLevel: TableLevel; type NextLevel: TableLevel;
} }
@ -434,7 +440,8 @@ impl HierarchicalLevel for PageDirectory {
} }
// PageTables do not have next level, therefore they are not HierarchicalLevel // PageTables do not have next level, therefore they are not HierarchicalLevel
// Contains just u64 internally, provides enum interface on top /// MMU address translation table.
/// Contains just u64 internally, provides enum interface on top
#[repr(C)] #[repr(C)]
#[repr(align(4096))] #[repr(align(4096))]
pub struct Table<L: TableLevel> { pub struct Table<L: TableLevel> {
@ -447,6 +454,7 @@ impl<L> Table<L>
where where
L: TableLevel, L: TableLevel,
{ {
/// Zero out entire table.
pub fn zero(&mut self) { pub fn zero(&mut self) {
for entry in self.entries.iter_mut() { for entry in self.entries.iter_mut() {
*entry = 0; *entry = 0;
@ -613,6 +621,11 @@ impl BaseAddr for [u64; 512] {
/// Set up identity mapped page tables for the first 1 gigabyte of address space. /// Set up identity mapped page tables for the first 1 gigabyte of address space.
/// default: 880 MB ARM ram, 128MB VC /// default: 880 MB ARM ram, 128MB VC
///
/// # Safety
///
/// Completely unsafe, we're in the hardware land! Incorrectly initialised tables will just
/// restart the CPU.
pub unsafe fn init() -> Result<(), &'static str> { pub unsafe fn init() -> Result<(), &'static str> {
// Prepare the memory attribute indirection register. // Prepare the memory attribute indirection register.
mair::set_up(); mair::set_up();

View File

@ -1,6 +1,9 @@
/* /*
* SPDX-License-Identifier: BlueOak-1.0.0 * SPDX-License-Identifier: BlueOak-1.0.0
*/ */
//! Memory management functions for aarch64.
use { use {
crate::println, crate::println,
core::{fmt, ops::RangeInclusive}, core::{fmt, ops::RangeInclusive},
@ -23,58 +26,85 @@ pub const PAGE_SIZE: usize = 4096;
/// @todo we need to infer the memory map from the provided DTB. /// @todo we need to infer the memory map from the provided DTB.
#[rustfmt::skip] #[rustfmt::skip]
pub mod map { pub mod map {
/// Beginning of memory.
pub const START: usize = 0x0000_0000; pub const START: usize = 0x0000_0000;
/// End of memory.
pub const END: usize = 0x3FFF_FFFF; pub const END: usize = 0x3FFF_FFFF;
/// Physical RAM addresses.
pub mod phys { pub mod phys {
/// Base address of video (VC) memory.
pub const VIDEOMEM_BASE: usize = 0x3e00_0000; pub const VIDEOMEM_BASE: usize = 0x3e00_0000;
/// Base address of MMIO register range.
pub const MMIO_BASE: usize = 0x3F00_0000; pub const MMIO_BASE: usize = 0x3F00_0000;
/// Base address of ARM<->VC mailbox area.
pub const VIDEOCORE_MBOX_BASE: usize = MMIO_BASE + 0x0000_B880; pub const VIDEOCORE_MBOX_BASE: usize = MMIO_BASE + 0x0000_B880;
/// Base address of GPIO registers.
pub const GPIO_BASE: usize = MMIO_BASE + 0x0020_0000; pub const GPIO_BASE: usize = MMIO_BASE + 0x0020_0000;
/// Base address of regular UART.
pub const PL011_UART_BASE: usize = MMIO_BASE + 0x0020_1000; pub const PL011_UART_BASE: usize = MMIO_BASE + 0x0020_1000;
/// Base address of MiniUART.
pub const MINI_UART_BASE: usize = MMIO_BASE + 0x0021_5000; pub const MINI_UART_BASE: usize = MMIO_BASE + 0x0021_5000;
/// End of MMIO memory.
pub const MMIO_END: usize = super::END; pub const MMIO_END: usize = super::END;
} }
/// Virtual (mapped) addresses.
pub mod virt { pub mod virt {
/// Start (top) of kernel stack.
pub const KERN_STACK_START: usize = super::START; pub const KERN_STACK_START: usize = super::START;
/// End (bottom) of kernel stack. SP starts at KERN_STACK_END + 1.
pub const KERN_STACK_END: usize = 0x0007_FFFF; pub const KERN_STACK_END: usize = 0x0007_FFFF;
// The second 2 MiB block. /// Location of DMA-able memory region (in the second 2 MiB block).
pub const DMA_HEAP_START: usize = 0x0020_0000; pub const DMA_HEAP_START: usize = 0x0020_0000;
/// End of DMA-able memory region.
pub const DMA_HEAP_END: usize = 0x005F_FFFF; pub const DMA_HEAP_END: usize = 0x005F_FFFF;
} }
} }
/// Types used for compiling the virtual memory layout of the kernel using /// Types used for compiling the virtual memory layout of the kernel using address ranges.
/// address ranges.
pub mod kernel_mem_range { pub mod kernel_mem_range {
use core::ops::RangeInclusive; use core::ops::RangeInclusive;
/// Memory region attributes.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub enum MemAttributes { pub enum MemAttributes {
/// Regular memory
CacheableDRAM, CacheableDRAM,
/// Memory without caching
NonCacheableDRAM, NonCacheableDRAM,
/// Device memory
Device, Device,
} }
/// Memory region access permissions.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub enum AccessPermissions { pub enum AccessPermissions {
/// Read-only access
ReadOnly, ReadOnly,
/// Read-write access
ReadWrite, ReadWrite,
} }
/// Memory region translation.
#[allow(dead_code)] #[allow(dead_code)]
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub enum Translation { pub enum Translation {
/// One-to-one address mapping
Identity, Identity,
/// Mapping with a specified offset
Offset(usize), Offset(usize),
} }
/// Summary structure of memory region properties.
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct AttributeFields { pub struct AttributeFields {
/// Attributes
pub mem_attributes: MemAttributes, pub mem_attributes: MemAttributes,
/// Permissions
pub acc_perms: AccessPermissions, pub acc_perms: AccessPermissions,
/// Disable executable code in this region
pub execute_never: bool, pub execute_never: bool,
} }
@ -88,10 +118,17 @@ pub mod kernel_mem_range {
} }
} }
/// Memory region descriptor.
///
/// Used to construct iterable kernel memory ranges.
pub struct Descriptor { pub struct Descriptor {
/// Name of the region
pub name: &'static str, pub name: &'static str,
/// Virtual memory range
pub virtual_range: fn() -> RangeInclusive<usize>, pub virtual_range: fn() -> RangeInclusive<usize>,
/// Mapping translation
pub translation: Translation, pub translation: Translation,
/// Attributes
pub attribute_fields: AttributeFields, pub attribute_fields: AttributeFields,
} }
} }

View File

@ -1,9 +1,13 @@
/* /*
* SPDX-License-Identifier: BlueOak-1.0.0 * SPDX-License-Identifier: BlueOak-1.0.0
*/ */
//! Implementation of aarch64 kernel functions.
mod boot; mod boot;
pub mod memory; pub mod memory;
/// Loop forever in sleep mode.
#[inline] #[inline]
pub fn endless_sleep() -> ! { pub fn endless_sleep() -> ! {
loop { loop {

View File

@ -2,13 +2,15 @@
* SPDX-License-Identifier: BlueOak-1.0.0 * SPDX-License-Identifier: BlueOak-1.0.0
*/ */
// https://doc.rust-lang.org/src/std/macros.rs.html /// Macro similar to [std](https://doc.rust-lang.org/src/std/macros.rs.html)
/// but for writing into kernel-specific output (UART or QEMU console).
#[macro_export] #[macro_export]
macro_rules! print { macro_rules! print {
($($arg:tt)*) => ($crate::macros::_print(format_args!($($arg)*))); ($($arg:tt)*) => ($crate::macros::_print(format_args!($($arg)*)));
} }
// https://doc.rust-lang.org/src/std/macros.rs.html /// Macro similar to [std](https://doc.rust-lang.org/src/std/macros.rs.html)
/// but for writing into kernel-specific output (UART or QEMU console).
#[macro_export] #[macro_export]
macro_rules! println { macro_rules! println {
() => (print!("\n")); () => (print!("\n"));

View File

@ -1,6 +1,11 @@
/* /*
* SPDX-License-Identifier: BlueOak-1.0.0 * SPDX-License-Identifier: BlueOak-1.0.0
*/ */
//! Vesper single-address-space exokernel.
//!
//! This crate implements the kernel binary proper.
#![no_std] #![no_std]
#![no_main] #![no_main]
#![feature(asm)] #![feature(asm)]
@ -17,6 +22,7 @@ use architecture_not_supported_sorry;
extern crate rlibc; // To enable linking memory intrinsics. extern crate rlibc; // To enable linking memory intrinsics.
/// Architecture-specific code.
#[macro_use] #[macro_use]
pub mod arch; pub mod arch;
pub use arch::*; pub use arch::*;
@ -41,8 +47,8 @@ fn init_mmu() {
println!("MMU initialised"); println!("MMU initialised");
} }
// Kernel entry point /// Kernel entry point.
// arch crate is responsible for calling this /// `arch` crate is responsible for calling it.
#[inline] #[inline]
pub fn kmain() -> ! { pub fn kmain() -> ! {
init_mmu(); init_mmu();

View File

@ -1,10 +1,9 @@
/* /*
* SPDX-License-Identifier: BlueOak-1.0.0 * SPDX-License-Identifier: BlueOak-1.0.0
*/ */
// No-alloc write!() implementation from https://stackoverflow.com/a/50201632/145434 /// No-alloc write!() implementation from https://stackoverflow.com/a/50201632/145434
// Requires you to allocate a buffer somewhere manually. /// Requires you to allocate a buffer somewhere manually.
// @todo Try to use arrayvec::ArrayString here instead? // @todo Try to use arrayvec::ArrayString here instead?
use core::{cmp::min, fmt}; use core::{cmp::min, fmt};
pub struct WriteTo<'a> { pub struct WriteTo<'a> {