Skip to main content

strat9_kernel/memory/
block_meta.rs

1//! Compatibility layer for the block-oriented metadata API.
2//!
3//! This module exposes the new block-level entry points on top of the current
4//! frame metadata implementation. The dedicated head/sub-frame layout is
5//! introduced in a later migration step.
6
7use x86_64::PhysAddr;
8
9use crate::memory::{block::BlockHandle, frame, ownership_table};
10
11/// Current metadata backing a block head (see [`frame::MetaSlot`] / issue #38).
12pub type BlockMeta = frame::MetaSlot;
13
14/// Sentinel refcount for an unused block.
15pub const REFCOUNT_UNUSED: u32 = frame::REFCOUNT_UNUSED;
16
17/// Returns the metadata entry associated with the given physical address.
18pub fn get_block_meta(phys: PhysAddr) -> &'static BlockMeta {
19    frame::get_meta(phys)
20}
21
22/// Returns the metadata entry associated with the given block handle.
23#[inline]
24fn align_down_to_block_base(phys: PhysAddr, order: u8) -> PhysAddr {
25    let size = 4096u64.checked_shl(order as u32).unwrap_or(0);
26    if size == 0 {
27        return phys;
28    }
29    PhysAddr::new(phys.as_u64() & !(size - 1))
30}
31
32/// Resolves a physical address to the current block handle.
33/// If the address is not currently owned, a new handle is reconstructed from the metadata.
34///
35pub fn resolve_handle(phys: PhysAddr) -> BlockHandle {
36    if let Some(handle) = ownership_table().handle_containing(phys) {
37        return handle;
38    }
39
40    let meta = get_block_meta(phys);
41    let order = meta.get_order();
42    let handle = BlockHandle::new(align_down_to_block_base(phys, order), order);
43    debug_assert!(
44        handle.is_valid(),
45        "block_meta: reconstructed invalid handle for phys={:#x} order={}",
46        phys.as_u64(),
47        order
48    );
49    handle
50}