pvh 0.1.0

Xen's x86/HVM direct boot ABI (PVH).
Documentation
//! PVH start info.
//!
//! This module contains the raw structs and constants from
//! [xen/include/public/arch-x86/hvm/start_info.h]. The [`reader`] module
//! provides corresponding readers for reading from physical addresses.
//!
//! After implementing the PVH entry point in assembly
//! ([`xen_elfnote_phys32_entry!`]), you can jump into Rust code. Using the
//! physical address of [`StartInfo`] provided at the entry point in `ebx`, we
//! can read the start info as well as any referenced data using a
//! [`StartInfoReader`].
//!
//! # Examples
//!
//! ```
//! use pvh::start_info::reader::StartInfoReader;
//!
//! /// The Rust entry point.
//! unsafe extern "C" fn rust_start(start_info_paddr: u32) -> ! {
//!     // SAFETY: The caller upholds that `start_info_paddr` is valid.
//!     // We have configured the machine to use identity-mapping.
//!     let start_info = unsafe { StartInfoReader::from_paddr_identity(start_info_paddr).unwrap() };
//!
//!     println!("Start info:");
//!     println!("{start_info:#?}");
//!
//!     # unimplemented!()
//!     // ...
//! }
//! ```
//!
//! [xen/include/public/arch-x86/hvm/start_info.h]: https://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=xen/include/public/arch-x86/hvm/start_info.h;h=e33557c0b4e98c6db3d3521710daa3838586733c;hb=06af9ef22996cecc2024a2e6523cec77a655581e
//! [`xen_elfnote_phys32_entry!`]: crate::xen_elfnote_phys32_entry
//! [`StartInfoReader`]: reader::StartInfoReader

mod header;
#[cfg(feature = "reader")]
pub mod reader;
mod sif;

pub use self::header::{MemmapTableEntry, MemmapType, ModlistEntry, START_MAGIC_VALUE, StartInfo};
pub use self::sif::Sif;

impl StartInfo {
    /// Creates a start info reference from a raw pointer.
    ///
    /// If the `reader` feature is enabled, use [`StartInfoReader::from_paddr`]
    /// instead.
    ///
    /// # Safety
    ///
    /// - `start_info` must be valid for `u32` reads.
    /// - If `start_info` points to the correct [`START_MAGIC_VALUE`], it must
    ///   be valid for `StartInfo` reads.
    ///
    /// [`StartInfoReader::from_paddr`]: reader::StartInfoReader::from_paddr
    #[inline]
    #[must_use]
    pub unsafe fn from_ptr<'a>(start_info: *const Self) -> Option<&'a Self> {
        // SAFETY: The caller upholds the pointer being valid for `u32` reads.
        let magic = unsafe { start_info.cast::<u32>().read() };

        if magic != START_MAGIC_VALUE {
            return None;
        }

        // SAFETY: The magic value is correct. Thus, the caller upholds that the pointer
        // is valid for `StartInfo`.
        let start_info = unsafe { &*start_info };
        Some(start_info)
    }
}

impl MemmapTableEntry {
    /// Returns the memory map type as an enum.
    ///
    /// This returns [`field@Self::ty`], but as a [`MemmapType`] instead of an
    /// `u32`.
    #[inline]
    #[must_use]
    pub fn ty(&self) -> MemmapType {
        MemmapType::from(self.ty)
    }
}