1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
// SPDX-License-Identifier: MPL-2.0
//! Definitions of page mapping properties.
use core::fmt::Debug;
use bitflags::bitflags;
/// The property of a mapped virtual memory page.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct PageProperty {
/// The flags associated with the page,
pub flags: PageFlags,
/// The cache policy for the page.
pub cache: CachePolicy,
pub(crate) priv_flags: PrivilegedPageFlags,
}
impl PageProperty {
/// Creates a new `PageProperty` with the given flags and cache policy for the user.
pub fn new(flags: PageFlags, cache: CachePolicy) -> Self {
Self {
flags,
cache,
priv_flags: PrivilegedPageFlags::USER,
}
}
/// Creates a page property that implies an invalid page without mappings.
pub fn new_absent() -> Self {
Self {
flags: PageFlags::empty(),
cache: CachePolicy::Writeback,
priv_flags: PrivilegedPageFlags::empty(),
}
}
}
// TODO: Make it more abstract when supporting other architectures.
/// A type to control the cacheability of the main memory.
///
/// The type currently follows the definition as defined by the AMD64 manual.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum CachePolicy {
/// Uncacheable (UC).
///
/// Reads from, and writes to, UC memory are not cacheable.
/// Reads from UC memory cannot be speculative.
/// Write-combining to UC memory is not allowed.
/// Reads from or writes to UC memory cause the write buffers to be written to memory
/// and be invalidated prior to the access to UC memory.
///
/// The UC memory type is useful for memory-mapped I/O devices
/// where strict ordering of reads and writes is important.
Uncacheable,
/// Write-Combining (WC).
///
/// Reads from, and writes to, WC memory are not cacheable.
/// Reads from WC memory can be speculative.
///
/// Writes to this memory type can be combined internally by the processor
/// and written to memory as a single write operation to reduce memory accesses.
///
/// The WC memory type is useful for graphics-display memory buffers
/// where the order of writes is not important.
WriteCombining,
/// Write-Protect (WP).
///
/// Reads from WP memory are cacheable and allocate cache lines on a read miss.
/// Reads from WP memory can be speculative.
///
/// Writes to WP memory that hit in the cache do not update the cache.
/// Instead, all writes update memory (write to memory),
/// and writes that hit in the cache invalidate the cache line.
/// Write buffering of WP memory is allowed.
///
/// The WP memory type is useful for shadowed-ROM memory
/// where updates must be immediately visible to all devices that read the shadow locations.
WriteProtected,
/// Writethrough (WT).
///
/// Reads from WT memory are cacheable and allocate cache lines on a read miss.
/// Reads from WT memory can be speculative.
///
/// All writes to WT memory update main memory,
/// and writes that hit in the cache update the cache line.
/// Writes that miss the cache do not allocate a cache line.
/// Write buffering of WT memory is allowed.
Writethrough,
/// Writeback (WB).
///
/// The WB memory is the "normal" memory. See detailed descriptions in the manual.
///
/// This type of memory provides the highest-possible performance
/// and is useful for most software and data stored in system memory (DRAM).
Writeback,
}
bitflags! {
/// Page protection permissions and access status.
pub struct PageFlags: u8 {
/// Readable.
const R = 0b00000001;
/// Writable.
const W = 0b00000010;
/// Executable.
const X = 0b00000100;
/// Readable + writable.
const RW = Self::R.bits | Self::W.bits;
/// Readable + execuable.
const RX = Self::R.bits | Self::X.bits;
/// Readable + writable + executable.
const RWX = Self::R.bits | Self::W.bits | Self::X.bits;
/// Has the memory page been read or written.
const ACCESSED = 0b00001000;
/// Has the memory page been written.
const DIRTY = 0b00010000;
}
}
bitflags! {
/// Page property that are only accessible in OSTD.
pub(crate) struct PrivilegedPageFlags: u8 {
/// Accessible from user mode.
const USER = 0b00000001;
/// Global page that won't be evicted from TLB with normal TLB flush.
const GLOBAL = 0b00000010;
/// (TEE only) If the page is shared with the host.
/// Otherwise the page is ensured confidential and not visible outside the guest.
#[cfg(feature = "intel_tdx")]
const SHARED = 0b10000000;
}
}