aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Cunningham <cc@localhost>2022-08-19 21:22:18 -0700
committerChristian Cunningham <cc@localhost>2022-08-19 21:22:18 -0700
commit26ab71043d97c1b06bdd252378b64171cb95b1a9 (patch)
tree9bea25574fc20e77a4faae6811add97e0a248175 /src
parent0d061dac9e31831e4fe426a0df777463043868d7 (diff)
Updated docs
Diffstat (limited to 'src')
-rw-r--r--src/_arch/arm/asm.rs16
-rw-r--r--src/_arch/arm/cpu.rs12
-rw-r--r--src/_arch/arm/cpu/boot.rs16
-rw-r--r--src/alloc.rs12
-rw-r--r--src/console.rs37
-rw-r--r--src/cpu.rs9
-rw-r--r--src/cpu/boot.rs7
-rw-r--r--src/panic_wait.rs4
-rw-r--r--src/print.rs13
-rw-r--r--src/sync.rs33
-rw-r--r--src/uart.rs47
11 files changed, 173 insertions, 33 deletions
diff --git a/src/_arch/arm/asm.rs b/src/_arch/arm/asm.rs
index c1af5b4..5d53aa0 100644
--- a/src/_arch/arm/asm.rs
+++ b/src/_arch/arm/asm.rs
@@ -1,6 +1,10 @@
-//! Wrapping ARMv7-A Instructions
+//! # Wrapping ARMv7-A Instructions
+//!
+//! This provides bindings for assembly instructions
+//! to be used in other rust functions without `unsafe`
+//! markers everywhere.
-/// WFE
+/// # Wait for event
#[inline(always)]
pub fn wfe() {
unsafe {
@@ -8,7 +12,7 @@ pub fn wfe() {
}
}
-/// NOP
+/// # No Operation
#[inline(always)]
pub fn nop() {
unsafe {
@@ -16,7 +20,7 @@ pub fn nop() {
}
}
-/// Store u32 to address
+/// # Store u32 to memory address
#[inline]
pub fn store32(addr: u32, value: u32) {
unsafe {
@@ -24,7 +28,7 @@ pub fn store32(addr: u32, value: u32) {
}
}
-/// Read u32 value from address
+/// # Read u32 from memory address
#[inline]
pub fn load32(addr: u32) -> u32 {
unsafe {
@@ -32,7 +36,7 @@ pub fn load32(addr: u32) -> u32 {
}
}
-/// Wait for n cycles
+/// # Spin CPU for `n` cycles
#[inline]
pub fn spin_for_n_cycles(n: u32) {
unsafe {
diff --git a/src/_arch/arm/cpu.rs b/src/_arch/arm/cpu.rs
index 1ca6fab..cd80151 100644
--- a/src/_arch/arm/cpu.rs
+++ b/src/_arch/arm/cpu.rs
@@ -1,8 +1,16 @@
-//! Architectural processor code.
+//! # Architectural processor code.
+//!
+//! This module provides the assembly instructions and higher level constructions
+//! for the rest of the kernel.
+
mod asm;
+
+/// # Bare Assembly Instructions
+///
+/// Re-export bare ASM bindings.
pub use asm::*;
-/// Pause execution
+/// # Halt until event
pub fn wait_forever() -> ! {
loop {
asm::wfe()
diff --git a/src/_arch/arm/cpu/boot.rs b/src/_arch/arm/cpu/boot.rs
index 9ea2330..b81a16a 100644
--- a/src/_arch/arm/cpu/boot.rs
+++ b/src/_arch/arm/cpu/boot.rs
@@ -1,11 +1,19 @@
-//! Architectural boot code
-//! # Boot code for ARM
-//! crate::cpu::boot::arch_boot
+//! # Architectural boot code
+//!
+//! crate::cpu::boot::arch_boot
+//!
+//! ## Boot code for ARM
+//!
+//! Provides the initial handoff
+//! function from Assembly to Rust.
use core::arch::global_asm;
global_asm!(include_str!("boot.s"));
-/// The Rust entry of the `kernel` binary.
+/// # Rust entry of the `kernel` binary.
+///
+/// This function is unmangled so that the
+/// ASM boot code can switch to Rust safely.
#[no_mangle]
pub unsafe fn _start_rust() -> ! {
crate::kernel_init()
diff --git a/src/alloc.rs b/src/alloc.rs
index 9b77f13..0c0df56 100644
--- a/src/alloc.rs
+++ b/src/alloc.rs
@@ -6,10 +6,14 @@
/// - Default: Default value
/// - Type: Data Type
macro_rules! init_queue {
- ($name:tt,$size:tt,$default:tt,$type:ty) => {
- #[link_section = ".data.alloc"]
- pub static $name: QueueAllocator<'static, $type, {$size+2}> = QueueAllocator::<$type, {$size+2}>{inner: NullLock::new([QueueItem{data: $default, next: None}; {$size+2}])};
- }
+ ($name:tt,$size:tt,$default:tt,$type:ty) => {
+ init_queue!{@gen [$name,$size,$default,$type,concat!("# ", stringify!($type), " Queue Allocator")]}
+ };
+ (@gen [$name:tt,$size:tt,$default:tt,$type:ty,$doc:expr]) => {
+ #[doc = $doc]
+ #[link_section = ".data.alloc"]
+ pub static $name: QueueAllocator<'static, $type, {$size+2}> = QueueAllocator::<$type, {$size+2}>{inner: NullLock::new([QueueItem{data: $default, next: None}; {$size+2}])};
+ };
}
use crate::sync::NullLock;
diff --git a/src/console.rs b/src/console.rs
index bcde05a..1a732a7 100644
--- a/src/console.rs
+++ b/src/console.rs
@@ -1,18 +1,55 @@
+//! # UART Console module
+//!
+//! ## Encapsulates base trait for any console.
+//! ## Wraps the UART console.
+
+/// # Interface module
+///
+/// ## Provides trait for consoles.
pub mod interface {
use core::fmt;
+ /// # Write Trait
+ ///
+ /// Structure must provide ways to:
+ /// - Write individual characters
+ /// - Write formatted strings
+ /// - Flush write queue
pub trait Write {
+ /// # Write Character
+ ///
+ /// Writes an individual character to a console
fn write_char(&self, c: char);
+ /// # Write Format
+ ///
+ /// Writes a formatted string to a console
fn write_fmt(&self, args: fmt::Arguments) -> fmt::Result;
+ /// # Flush
+ ///
+ /// Flush console write queue
fn flush(&self);
}
+ /// # Statistics Trait
+ ///
+ /// Structure must provide a way to:
+ /// - Get how many characters have been written
pub trait Statistics {
+ /// # Get Written Chars
+ ///
+ /// Gets the statistic associated with how many
+ /// characters have been written to a console.
fn chars_written(&self) -> usize { 0 }
}
+ /// # All Trait
+ ///
+ /// Structure must provide both Write + Statistics
pub trait All: Write + Statistics {}
}
+/// # UART console
+///
+/// Returns a borrow for the UART writer
pub fn console() -> &'static crate::uart::Uart {
&crate::uart::UART_WRITER
}
diff --git a/src/cpu.rs b/src/cpu.rs
index 9f003f8..26efd52 100644
--- a/src/cpu.rs
+++ b/src/cpu.rs
@@ -1,7 +1,10 @@
-//! Processor code.
+//! # Processor code.
#[cfg(target_arch = "arm")]
#[path = "_arch/arm/cpu.rs"]
mod arch_cpu;
-pub use arch_cpu::{nop,wait_forever,spin_for_n_cycles,load32,store32};
-
mod boot;
+
+/// # Low-level bindings
+///
+/// Re-export low-level bindings
+pub use arch_cpu::{nop,wait_forever,spin_for_n_cycles,load32,store32};
diff --git a/src/cpu/boot.rs b/src/cpu/boot.rs
index 9ef25bd..43d8934 100644
--- a/src/cpu/boot.rs
+++ b/src/cpu/boot.rs
@@ -1,3 +1,8 @@
-//! Boot code
+//! # Boot code
+//!
+//! ## Architectural Boot code.
+//!
+//! Provides the initial handoff function from Assembly to Rust.
+
#[path = "../_arch/arm/cpu/boot.rs"]
mod arch_boot;
diff --git a/src/panic_wait.rs b/src/panic_wait.rs
index 33097d8..1136e54 100644
--- a/src/panic_wait.rs
+++ b/src/panic_wait.rs
@@ -1,8 +1,10 @@
+//! # Panic module
+//!
//! A panic handler that infinitely waits
use core::panic::PanicInfo;
-/// Panic handler
+/// # Panic handler
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
unimplemented!()
diff --git a/src/print.rs b/src/print.rs
index 932c655..88f39da 100644
--- a/src/print.rs
+++ b/src/print.rs
@@ -1,6 +1,7 @@
-//! Printing
+//! # Printing to UART
+//!
+//! This module contains the macros to print formatted strings to UART.
use core::fmt;
-
use crate::uart::UART_WRITER;
use crate::console::interface::Write;
@@ -9,13 +10,17 @@ pub fn _print(args: fmt::Arguments) {
UART_WRITER.write_fmt(args).unwrap();
}
-/// Print without newline
+/// # Print without newline
+///
+/// Print formatted arguments without a newline
#[macro_export]
macro_rules! print {
($($arg:tt)*) => ($crate::print::_print(format_args!($($arg)*)));
}
-/// Print with newline
+/// # Print with newline
+///
+/// Print formatted arguments with a newline
#[macro_export]
macro_rules! println {
() => ($crate::print!("\n"));
diff --git a/src/sync.rs b/src/sync.rs
index 2b7e1ff..cd626fa 100644
--- a/src/sync.rs
+++ b/src/sync.rs
@@ -1,20 +1,44 @@
+//! # Synchronization module
+//!
+//! Provides synchronization objects for thread-safe memory sharing.
+use core::cell::UnsafeCell;
+
+/// # Synchronization interfaces
+///
+/// Provides Synchronization traits.
pub mod interface {
+ /// # Mutex Trait
+ ///
+ /// Basic Locking primitive to allow single-process access to data
pub trait Mutex {
+ /// # The data
+ ///
+ /// Each mutex protects some internal data from modification across
+ /// processes when it is in use. This is important if the process
+ /// is preempted while the function is using it.
type Data;
+ /// # Locking mechanism
+ ///
+ /// Locks the mutex to access the data in a closure.
+ /// The data can be read and modified in this closure without worry
+ /// of poisoning the data across processes.
fn lock<'a, R>(&'a self, f: impl FnOnce(&'a mut Self::Data) -> R) -> R;
}
}
-use core::cell::UnsafeCell;
-
+/// # Basic Lock Structure
pub struct NullLock<T> where T: ?Sized {
+ /// The internal data to safely share
data: UnsafeCell<T>,
}
+/// # Allow thread sharing
unsafe impl<T> Send for NullLock<T> where T: ?Sized + Send {}
+/// # Allow thread sharing
unsafe impl<T> Sync for NullLock<T> where T: ?Sized + Send {}
impl<T> NullLock<T> {
+ /// # Create a new instance of the lock
pub const fn new(data: T) -> Self {
Self {
data: UnsafeCell::new(data),
@@ -23,8 +47,13 @@ impl<T> NullLock<T> {
}
impl<T> interface::Mutex for NullLock<T> {
+ /// # Underlying data of the lock
type Data = T;
+ /// # Locking mechanism
+ ///
+ /// Locks the Mutex, and passes a mutable reference
+ /// to the encapsulated data to a closure.
fn lock<'a, R>(&'a self, f: impl FnOnce(&'a mut T) -> R) -> R {
let data = unsafe { &mut *self.data.get() };
diff --git a/src/uart.rs b/src/uart.rs
index ffd9204..0f66116 100644
--- a/src/uart.rs
+++ b/src/uart.rs
@@ -1,32 +1,58 @@
+//! # UART Console Definition
use crate::cpu::*;
+use crate::sync::NullLock;
+use core::fmt;
+use crate::sync::interface::Mutex;
+/// # Data Register
const UART0_DR: u32 = 0x3F201000;
+/// # Flag Register
const UART0_FR: u32 = 0x3F201018;
-const UART0_CR: u32 = 0x3F201030;
-const UART0_ICR: u32 = 0x3F201044;
-const UART0_IBRD: u32 = 0x3F201024;
+/// # Fractional Baud Rate Register
const UART0_FBRD: u32 = 0x3F201028;
+/// # Line Control Register
const UART0_LCRH: u32 = 0x3F20102C;
+/// # Control Register
+const UART0_CR: u32 = 0x3F201030;
+/// # Interrupt Mask Set/ Clear Register
const UART0_IMSC: u32 = 0x3F201038;
+/// # Interrupt Control Register
+const UART0_ICR: u32 = 0x3F201044;
+/// # Integer Baud Rate Register
+const UART0_IBRD: u32 = 0x3F201024;
+
+/// GPIO Register
const GPPUD: u32 = 0x3F200094;
+/// GPIO Clock 0 Register
const GPPUDCLK0: u32 = 0x3F200098;
+/// # UART Inner Structure
+///
+/// Keeps record of the console statistics.
struct UartInner {
chars_written: usize,
}
-use crate::sync::NullLock;
+/// # UART Structure
+///
+/// Wraps the UART writer in a sharable lock.
pub struct Uart {
inner: NullLock<UartInner>,
}
impl UartInner {
+ /// # Clear statistics
+ ///
+ /// Create the writer with cleared statistics
pub const fn new() -> Self {
Self {
chars_written: 0,
}
}
+ /// # Initialize the UART setup
+ ///
+ /// Set baud rate and timings
pub fn init(&mut self) {
store32(UART0_CR, 0);
store32(GPPUD, 0);
@@ -42,6 +68,7 @@ impl UartInner {
store32(UART0_CR, (1<<0) | (1<<8) | (1<<9));
}
+ /// # Write `char` to UART
fn write_char(&mut self, ch: char) {
while load32(UART0_FR) & 0x20 != 0 {
nop();
@@ -50,6 +77,7 @@ impl UartInner {
self.chars_written += 1;
}
+ /// # Flush UART
fn flush(&self) {
while load32(UART0_FR) & 0x08 != 0 {
nop();
@@ -57,8 +85,8 @@ impl UartInner {
}
}
-use core::fmt;
impl fmt::Write for UartInner {
+ /// # Write string to UART console
fn write_str(&mut self, s: &str) -> fmt::Result {
for c in s.chars() {
self.write_char(c);
@@ -67,15 +95,16 @@ impl fmt::Write for UartInner {
}
}
-use crate::sync::interface::Mutex;
impl Uart {
+ /// # Create sharable UART wrapper
pub const fn new() -> Self {
Self {
inner: NullLock::new(UartInner::new()),
}
}
+ /// # Call UART initialization
pub fn init(&self) -> Result<(), &'static str> {
self.inner.lock(|inner| inner.init());
Ok(())
@@ -83,25 +112,31 @@ impl Uart {
}
impl super::console::interface::Write for Uart {
+ /// # Write `char` to UART
fn write_char(&self, c: char) {
self.inner.lock(|inner| inner.write_char(c));
}
+ /// # Write formatted string to UART
fn write_fmt(&self, args: core::fmt::Arguments) -> fmt::Result {
self.inner.lock(|inner| fmt::Write::write_fmt(inner, args))
}
+ /// # Flush UART
fn flush(&self) {
self.inner.lock(|inner| inner.flush());
}
}
impl super::console::interface::Statistics for Uart {
+ /// # Get `char` written stats
fn chars_written(&self) -> usize {
self.inner.lock(|inner| inner.chars_written)
}
}
+/// # UART Writer + Stats
impl super::console::interface::All for Uart {}
+/// # Public reference to console.
pub static UART_WRITER: Uart = Uart::new();