Add documentation
This commit is contained in:
parent
4898ad3139
commit
408857fcb6
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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> {
|
||||
|
|
Loading…
Reference in New Issue