Merge branch 'common-docs' into 'main'
add documentation to public functions in common See merge request redox-os/base!200
This commit is contained in:
@@ -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"]
|
||||
|
||||
@@ -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<Fd> {
|
||||
/// 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<Fd> {
|
||||
/// # 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<T: ?Sized> {
|
||||
/// 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<T> Dma<MaybeUninit<T>> {
|
||||
/// instance of an object of type `[Dma]<T>`.
|
||||
///
|
||||
/// # Returns
|
||||
/// - `[Dma]<T>` - The original structure without the [MaybeUninit] wrapper around its contents.
|
||||
/// - `[Dma]<T>` - The original structure without the [`MaybeUninit`] wrapper around its contents.
|
||||
///
|
||||
/// # Notes
|
||||
/// - This is unsafe because it assumes that the memory stored within the `[Dma]<T>` 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<T> {
|
||||
let Dma {
|
||||
|
||||
@@ -58,13 +58,13 @@ impl<I: Io> ReadOnly<I> {
|
||||
}
|
||||
|
||||
impl<I: Io> ReadOnly<I> {
|
||||
/// 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<I: Io> WriteOnly<I> {
|
||||
}
|
||||
|
||||
impl<I: Io> WriteOnly<I> {
|
||||
/// Calls [Io::write]
|
||||
/// Calls [`Io::write`]
|
||||
#[inline(always)]
|
||||
pub fn write(&mut self, value: I::Value) {
|
||||
self.inner.write(value)
|
||||
|
||||
@@ -7,14 +7,17 @@ pub struct MmioPtr<T> {
|
||||
|
||||
impl<T> MmioPtr<T> {
|
||||
//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
|
||||
}
|
||||
|
||||
+34
-17
@@ -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<libredox::Fd> = 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
|
||||
}
|
||||
|
||||
@@ -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<lo
|
||||
for log_env_key in log_env_keys {
|
||||
let log_env_key = log_env_key.as_bytes();
|
||||
if let Some(log_env) = envs.iter().find_map(|var| var.strip_prefix(log_env_key)) {
|
||||
if let Ok(Ok(log_level)) =
|
||||
str::from_utf8(&log_env).map(|s| log::LevelFilter::from_str(s))
|
||||
{
|
||||
if let Ok(Ok(log_level)) = str::from_utf8(&log_env).map(log::LevelFilter::from_str) {
|
||||
return Some(log_level);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@ use crate::VirtaddrTranslationHandle;
|
||||
pub struct Sgl {
|
||||
/// A raw pointer to the SGL in virtual memory
|
||||
virt: *mut u8,
|
||||
/// The length of the allocated memory, guaranteed to be a multiple of [PAGE_SIZE].
|
||||
/// The length of the allocated memory, guaranteed to be a multiple of [`PAGE_SIZE`].
|
||||
aligned_length: usize,
|
||||
/// The length of the allocated memory. This value is NOT guaranteed to be a multiple of [PAGE_SIZE]
|
||||
/// The length of the allocated memory. This value is NOT guaranteed to be a multiple of [`PAGE_SIZE`]
|
||||
unaligned_length: NonZeroUsize,
|
||||
/// The vector of chunks tracked by this [Sgl] object. This is the sparsely-populated vector in the SGL algorithm.
|
||||
chunks: Vec<Chunk>,
|
||||
@@ -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<Self> {
|
||||
let unaligned_length = NonZeroUsize::new(unaligned_length).ok_or(Error::new(EINVAL))?;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user