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.
* 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 {
crate::endless_sleep,
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.
#[macro_export]
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+).
*/
/// Number of entries in a 4KiB mmu table.
pub const NUM_ENTRIES_4KIB: u64 = 512;
/// 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
pub enum PageTable {}
/// Shared trait for specific table levels.
pub trait TableLevel {}
/// Shared trait for hierarchical table levels.
///
/// Specifies what is the next level of page table hierarchy.
pub trait HierarchicalLevel: TableLevel {
/// Level of the next translation table below this one.
type NextLevel: TableLevel;
}
@ -434,7 +440,8 @@ impl HierarchicalLevel for PageDirectory {
}
// 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(align(4096))]
pub struct Table<L: TableLevel> {
@ -447,6 +454,7 @@ impl<L> Table<L>
where
L: TableLevel,
{
/// Zero out entire table.
pub fn zero(&mut self) {
for entry in self.entries.iter_mut() {
*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.
/// 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> {
// Prepare the memory attribute indirection register.
mair::set_up();

View File

@ -1,6 +1,9 @@
/*
* SPDX-License-Identifier: BlueOak-1.0.0
*/
//! Memory management functions for aarch64.
use {
crate::println,
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.
#[rustfmt::skip]
pub mod map {
/// Beginning of memory.
pub const START: usize = 0x0000_0000;
/// End of memory.
pub const END: usize = 0x3FFF_FFFF;
/// Physical RAM addresses.
pub mod phys {
/// Base address of video (VC) memory.
pub const VIDEOMEM_BASE: usize = 0x3e00_0000;
/// Base address of MMIO register range.
pub const MMIO_BASE: usize = 0x3F00_0000;
/// Base address of ARM<->VC mailbox area.
pub const VIDEOCORE_MBOX_BASE: usize = MMIO_BASE + 0x0000_B880;
/// Base address of GPIO registers.
pub const GPIO_BASE: usize = MMIO_BASE + 0x0020_0000;
/// Base address of regular UART.
pub const PL011_UART_BASE: usize = MMIO_BASE + 0x0020_1000;
/// Base address of MiniUART.
pub const MINI_UART_BASE: usize = MMIO_BASE + 0x0021_5000;
/// End of MMIO memory.
pub const MMIO_END: usize = super::END;
}
/// Virtual (mapped) addresses.
pub mod virt {
/// Start (top) of kernel stack.
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;
// 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;
/// End of DMA-able memory region.
pub const DMA_HEAP_END: usize = 0x005F_FFFF;
}
}
/// Types used for compiling the virtual memory layout of the kernel using
/// address ranges.
/// Types used for compiling the virtual memory layout of the kernel using address ranges.
pub mod kernel_mem_range {
use core::ops::RangeInclusive;
/// Memory region attributes.
#[derive(Copy, Clone)]
pub enum MemAttributes {
/// Regular memory
CacheableDRAM,
/// Memory without caching
NonCacheableDRAM,
/// Device memory
Device,
}
/// Memory region access permissions.
#[derive(Copy, Clone)]
pub enum AccessPermissions {
/// Read-only access
ReadOnly,
/// Read-write access
ReadWrite,
}
/// Memory region translation.
#[allow(dead_code)]
#[derive(Copy, Clone)]
pub enum Translation {
/// One-to-one address mapping
Identity,
/// Mapping with a specified offset
Offset(usize),
}
/// Summary structure of memory region properties.
#[derive(Copy, Clone)]
pub struct AttributeFields {
/// Attributes
pub mem_attributes: MemAttributes,
/// Permissions
pub acc_perms: AccessPermissions,
/// Disable executable code in this region
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 {
/// Name of the region
pub name: &'static str,
/// Virtual memory range
pub virtual_range: fn() -> RangeInclusive<usize>,
/// Mapping translation
pub translation: Translation,
/// Attributes
pub attribute_fields: AttributeFields,
}
}

View File

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

View File

@ -2,13 +2,15 @@
* 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_rules! print {
($($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_rules! println {
() => (print!("\n"));

View File

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

View File

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