diff --git a/Cargo.toml b/Cargo.toml index 4093c793d8..3b2f5247db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -105,7 +105,11 @@ static_assertions = "1.1.0" thiserror = "2" toml = "1" +[workspace.lints.rust] +missing_docs = "warn" #TODO: set to deny when all public functions are documented + [workspace.lints.clippy] +missing_safety_doc = "warn" #TODO: set to deny when all safety documentation is completed precedence = "deny" [patch."https://gitlab.redox-os.org/redox-os/relibc.git"] diff --git a/drivers/common/src/dma.rs b/drivers/common/src/dma.rs index 47ab51efb9..3d359f4b3b 100644 --- a/drivers/common/src/dma.rs +++ b/drivers/common/src/dma.rs @@ -11,8 +11,8 @@ use crate::{memory_root_fd, MemoryType, VirtaddrTranslationHandle}; /// Defines the platform-specific memory type for DMA operations /// -/// - On x86 systems, DMA uses Write-back memory ([MemoryType::Writeback]) -/// - On aarch64 systems, DMA uses uncacheable memory ([MemoryType::Uncacheable]) +/// - On x86 systems, DMA uses Write-back memory ([`MemoryType::Writeback`]) +/// - On aarch64 systems, DMA uses uncacheable memory ([`MemoryType::Uncacheable`]) const DMA_MEMTY: MemoryType = { if cfg!(any(target_arch = "x86", target_arch = "x86_64")) { // x86 ensures cache coherence with DMA memory @@ -52,7 +52,7 @@ pub(crate) fn phys_contiguous_fd() -> Result { /// Allocates a chunk of physical memory for DMA, and then maps it to virtual memory. /// /// # Arguments -/// 'length: [usize]' - The length of the memory region. Must be a multiple of [PAGE_SIZE] +/// 'length: [usize]' - The length of the memory region. Must be a multiple of [`PAGE_SIZE`] /// /// # Returns /// @@ -63,10 +63,10 @@ pub(crate) fn phys_contiguous_fd() -> Result { /// # Errors /// /// This function asserts if: -/// - length is not a multiple of [PAGE_SIZE] +/// - length is not a multiple of [`PAGE_SIZE`] /// /// This function returns an error if: -/// - A file descriptor to physically contiguous memory of type [DMA_MEMTY] could not be acquired +/// - A file descriptor to physically contiguous memory of type [`DMA_MEMTY`] could not be acquired /// - A virtual mapping for the physically contiguous memory could not be created /// - The virtual address returned by the memory manager was invalid. fn alloc_and_map(length: usize, handle: &VirtaddrTranslationHandle) -> Result<(usize, *mut ())> { @@ -97,7 +97,7 @@ fn alloc_and_map(length: usize, handle: &VirtaddrTranslationHandle) -> Result<(u pub struct Dma { /// The physical address of the memory phys: usize, - /// The page-aligned length of the memory. Will be a multiple of [PAGE_SIZE] + /// The page-aligned length of the memory. Will be a multiple of [`PAGE_SIZE`] aligned_len: usize, /// The pointer to the Dma memory in the virtual address space. virt: *mut T, @@ -148,11 +148,11 @@ impl Dma> { /// instance of an object of type `[Dma]`. /// /// # Returns - /// - `[Dma]` - The original structure without the [MaybeUninit] wrapper around its contents. + /// - `[Dma]` - The original structure without the [`MaybeUninit`] wrapper around its contents. /// /// # Notes /// - This is unsafe because it assumes that the memory stored within the `[Dma]` is a valid - /// instance of T. If it isn't (for example -- if it was initialized with [Dma::zeroed]), + /// instance of T. If it isn't (for example -- if it was initialized with [`Dma::zeroed`]), /// then the underlying memory may not contain the expected T structure. pub unsafe fn assume_init(self) -> Dma { let Dma { diff --git a/drivers/common/src/io.rs b/drivers/common/src/io.rs index 375949bacf..6c7ad20839 100644 --- a/drivers/common/src/io.rs +++ b/drivers/common/src/io.rs @@ -58,13 +58,13 @@ impl ReadOnly { } impl ReadOnly { - /// Calls [Io::read] + /// Calls [`Io::read`] #[inline(always)] pub fn read(&self) -> I::Value { self.inner.read() } - /// Calls [Io::readf] + /// Calls [`Io::readf`] #[inline(always)] pub fn readf(&self, flags: I::Value) -> bool { self.inner.readf(flags) @@ -85,7 +85,7 @@ impl WriteOnly { } impl WriteOnly { - /// Calls [Io::write] + /// Calls [`Io::write`] #[inline(always)] pub fn write(&mut self, value: I::Value) { self.inner.write(value) diff --git a/drivers/common/src/io/mmio_ptr.rs b/drivers/common/src/io/mmio_ptr.rs index eb3704fa9e..07c31fec64 100644 --- a/drivers/common/src/io/mmio_ptr.rs +++ b/drivers/common/src/io/mmio_ptr.rs @@ -7,14 +7,17 @@ pub struct MmioPtr { impl MmioPtr { //TODO: reads and writes are unsafe, not new. + /// Creates a `MmioPtr`. pub unsafe fn new(ptr: *mut T) -> Self { Self { ptr } } + /// Creates a const pointer from a `MmioPtr`. pub const fn as_ptr(&self) -> *const T { self.ptr } + /// Creates a mutable pointer from a `MmioPtr`. pub const fn as_mut_ptr(&mut self) -> *mut T { self.ptr } diff --git a/drivers/common/src/lib.rs b/drivers/common/src/lib.rs index ad1901ce7f..b6661e3aaa 100644 --- a/drivers/common/src/lib.rs +++ b/drivers/common/src/lib.rs @@ -2,11 +2,14 @@ //! //! This includes direct memory access via [dma], and Scatter-Gather List support via [sgl]. It also //! provides various memory management structures for use with drivers, and some logging support. -#![warn(missing_docs)] use libredox::call::MmapArgs; use libredox::flag::{self, O_CLOEXEC, O_RDONLY, O_RDWR, O_WRONLY}; -use libredox::{errno::EINVAL, error::*, Fd}; +use libredox::{ + errno::EINVAL, + error::{Error, Result}, + Fd, +}; use syscall::{ProcSchemeVerb, PAGE_SIZE}; /// The Direct Memory Access (DMA) API for drivers @@ -25,6 +28,13 @@ use std::sync::OnceLock; static MEMORY_ROOT_FD: OnceLock = OnceLock::new(); +/// Initializes a file descriptor to be used as the root memory for a driver. +/// +/// # Panics +/// +/// This function will panic if: +/// - `libredox` is unable to open a file descriptor. +/// - The memory root file descriptor has already been set (this function has already been called). pub fn init() { if MEMORY_ROOT_FD .set( @@ -37,6 +47,11 @@ pub fn init() { } } +/// Gets the memory root file descriptor. +/// +/// # Panics +/// +/// This function will panic if `init` has not already been called first. pub fn memory_root_fd() -> &'static libredox::Fd { MEMORY_ROOT_FD .get() @@ -82,8 +97,8 @@ impl Default for MemoryType { /// Represents the protection level of an area of memory. /// -/// This structure shouldn't be used directly -- instead, use the [Prot::RO] (Read-Only), -/// [Prot::WO] (Write-Only) and [Prot::RW] (Read-Write) constants to specify the memory's protection +/// This structure shouldn't be used directly -- instead, use the [`Prot::RO`] (Read-Only), +/// [`Prot::WO`] (Write-Only) and [`Prot::RW`] (Read-Write) constants to specify the memory's protection /// level. #[derive(Clone, Copy, Debug)] pub struct Prot { @@ -114,16 +129,14 @@ impl Prot { }; } -// TODO: Safe, as the kernel ensures it doesn't conflict with any other memory described in the -// memory map for regular RAM. /// Maps physical memory to virtual memory /// /// # Arguments /// -/// * 'base_phys: [usize]' - The base address of the physical memory to map. -/// * 'len: [usize]' - The length of the physical memory to map (Should be a multiple of [PAGE_SIZE] +/// * '`base_phys`: [usize]' - The base address of the physical memory to map. +/// * 'len: [usize]' - The length of the physical memory to map (Should be a multiple of [`PAGE_SIZE`] /// * '_: [Prot]' - The memory protection level of the mapping. -/// * 'type: [MemoryType]' - The caching behavior specification of the memory. +/// * 'type: [`MemoryType`]' - The caching behavior specification of the memory. /// /// # Returns /// @@ -135,14 +148,18 @@ impl Prot { /// /// This function will return an error if: /// - An invalid value is provided to 'read' or 'write' -/// - The system could not open a file descriptor to the memory scheme for the specified [MemoryType]. -/// - The system failed to map the physical address to a virtual address. See [libredox::call::mmap] +/// - The system could not open a file descriptor to the memory scheme for the specified [`MemoryType`]. +/// - The system failed to map the physical address to a virtual address. See [`libredox::call::mmap`] /// +/// # Safety +/// +/// Safe, as the kernel ensures it doesn't conflict with any other memory described in the memory +/// map for regular RAM. /// /// # Notes /// - This function is unsafe, and upon using it you will be responsible for freeing the memory with -/// [libredox::call::munmap]. If you want a safe accessor, use [PhysBorrowed] instead. -/// - The MemoryType specified is used to tell the function which memory scheme to access. (i.e +/// [`libredox::call::munmap`]. If you want a safe accessor, use [`PhysBorrowed`] instead. +/// - The `MemoryType` specified is used to tell the function which memory scheme to access. (i.e /// /scheme/memory/physical@wb, /scheme/memory/physical@uc, etc). pub unsafe fn physmap( base_phys: usize, @@ -216,14 +233,14 @@ pub struct PhysBorrowed { len: usize, } impl PhysBorrowed { - /// Constructs a PhysBorrowed instance. + /// Constructs a `PhysBorrowed` instance. /// /// # Arguments /// See [physmap] for a description of the parameters. /// /// # Returns /// A '[Result]' which contains the following: - /// - A '[PhysBorrowed]' which represents the newly mapped region. + /// - A '[`PhysBorrowed`]' which represents the newly mapped region. /// - An 'Err' if a memory mapping error occurs. /// /// # Errors @@ -242,7 +259,7 @@ impl PhysBorrowed { /// - self.mem - A pointer to the mapped region in virtual memory. /// /// # Notes - /// - The pointer may live beyond the lifetime of [PhysBorrowed], so dereferences to the pointer + /// - The pointer may live beyond the lifetime of [`PhysBorrowed`], so dereferences to the pointer /// must be treated as unsafe. /// pub fn as_ptr(&self) -> *mut () { @@ -252,7 +269,7 @@ impl PhysBorrowed { /// Gets the length of the mapped region. /// /// # Returns - /// - self.len - The length of the mapped region. It should be a multiple of [PAGE_SIZE] + /// - self.len - The length of the mapped region. It should be a multiple of [`PAGE_SIZE`] pub fn mapped_len(&self) -> usize { self.len } diff --git a/drivers/common/src/logger.rs b/drivers/common/src/logger.rs index 51e7620119..82ec2bd054 100644 --- a/drivers/common/src/logger.rs +++ b/drivers/common/src/logger.rs @@ -3,10 +3,12 @@ use std::str::FromStr; use libredox::{flag, Fd}; use redox_log::{OutputBuilder, RedoxLogger}; +/// Get the log verbosity for the output level. pub fn output_level() -> log::LevelFilter { log::LevelFilter::Info } +/// Get the log verbosity for the file level. pub fn file_level() -> log::LevelFilter { log::LevelFilter::Info } @@ -96,9 +98,7 @@ fn read_bootloader_log_level_env(category: &str, subcategory: &str) -> Option, @@ -42,7 +42,7 @@ impl Sgl { /// /// # Arguments /// - /// 'unaligned_length: [usize]' - The length of the SGL, not necessarily aligned to the nearest + /// '`unaligned_length`: [usize]' - The length of the SGL, not necessarily aligned to the nearest /// page. pub fn new(unaligned_length: usize) -> Result { let unaligned_length = NonZeroUsize::new(unaligned_length).ok_or(Error::new(EINVAL))?; diff --git a/drivers/common/src/timeout.rs b/drivers/common/src/timeout.rs index a87c067e11..4a2b19814c 100644 --- a/drivers/common/src/timeout.rs +++ b/drivers/common/src/timeout.rs @@ -1,11 +1,13 @@ use std::time::{Duration, Instant}; +/// Represents an amount of time for a driver to give up to the OS scheduler. pub struct Timeout { instant: Instant, duration: Duration, } impl Timeout { + /// Create a new `Timeout` from a `Duration`. #[inline] pub fn new(duration: Duration) -> Self { Self { @@ -14,21 +16,30 @@ impl Timeout { } } + /// Create a new `Timeout` by specifying the amount of microseconds. #[inline] pub fn from_micros(micros: u64) -> Self { Self::new(Duration::from_micros(micros)) } + /// Create a new `Timeout` by specifying the amount of milliseconds. #[inline] pub fn from_millis(millis: u64) -> Self { Self::new(Duration::from_millis(millis)) } + /// Create a new `Timeout` by specifying the amount of seconds. #[inline] pub fn from_secs(secs: u64) -> Self { Self::new(Duration::from_secs(secs)) } + /// Execute the `Timeout`. + /// + /// # Errors + /// + /// Returns an `Err` if the duration of the `Timeout` has already elapsed + /// between creating the `Timeout` and calling this function. #[inline] pub fn run(&self) -> Result<(), ()> { if self.instant.elapsed() < self.duration {