moa_mm 0.1.3

内存管理基础(页表、虚拟地址布局)
Documentation
//! 页表定义
//!
//! 三级页表:PGD(1GB) → PMD(2MB) → PTE(4KB)
//! 叶子可出现在任意级别,支持 4KB / 2MB / 1GB 页。

#![no_std]

cfg_if::cfg_if! {
    if #[cfg(aarch64_moana)] {
        #[path = "aarch64.rs"]
        mod arch;
    } else if #[cfg(riscv64_moana)] {
        #[path = "riscv64.rs"]
        mod arch;
    } else {
        #[path = "stub.rs"]
        mod arch;
    }
}

// 架构特定的 boot 页表常量 re-export
cfg_if::cfg_if! {
    if #[cfg(any(aarch64_moana, riscv64_moana))] {
        pub use arch::*;
    }
}

// ---- 页级别 ----

/// 页大小级别
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum PageLevel {
    /// 4KB 小页(PTE 级叶子)
    Page4K,
    /// 2MB 大页(PMD 级叶子)
    Page2M,
    /// 1GB 巨页(PGD 级叶子)
    Page1G,
}

impl PageLevel {
    /// 该级别对应的页大小(字节)
    pub const fn size(self) -> usize {
        match self {
            PageLevel::Page4K => PAGE_SIZE,
            PageLevel::Page2M => PMD_SIZE,
            PageLevel::Page1G => PGD_SIZE,
        }
    }

    /// 该级别对应的地址对齐掩码
    pub const fn mask(self) -> usize {
        !(self.size() - 1)
    }
}

// ---- 保护属性 ----

bitflags::bitflags! {
    /// 架构无关的页保护属性
    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
    pub struct PageProt: usize {
        /// 可读
        const R  = 1 << 0;
        /// 可写
        const W  = 1 << 1;
        /// 可执行
        const X  = 1 << 2;
        /// 用户态可访问
        const U  = 1 << 3;
        /// Non-cacheable(普通非缓存内存,如 DMA 缓冲区)
        const NC = 1 << 4;
        /// Device IO(MMIO,隐含不可缓存 + 严格顺序)
        const IO = 1 << 5;
    }
}

// ---- 页表常量 ----

/// 页大小(4KB)
pub const PAGE_SIZE: usize = 1 << PAGE_SHIFT;
/// 页偏移位数
pub const PAGE_SHIFT: usize = 12;
/// 页掩码
pub const PAGE_MASK: usize = !(PAGE_SIZE - 1);
/// 每级页表条目数
pub const PTRS_PER_TABLE: usize = 512;

/// PMD 级大小(2MB)
pub const PMD_SIZE: usize = 1 << PMD_SHIFT;
/// PMD 级偏移位数
pub const PMD_SHIFT: usize = 21;
/// PMD 级掩码
pub const PMD_MASK: usize = !(PMD_SIZE - 1);

/// PGD 级大小(1GB)
pub const PGD_SIZE: usize = 1 << PGD_SHIFT;
/// PGD 级偏移位数
pub const PGD_SHIFT: usize = 30;
/// PGD 级掩码
pub const PGD_MASK: usize = !(PGD_SIZE - 1);

// ---- 架构编解码接口 ----

/// 物理地址 → 非叶子条目(table pointer)
#[inline(always)]
pub fn paddr_to_table(paddr: usize) -> usize {
    arch::paddr_to_table(paddr)
}

/// 非叶子条目 → 物理地址
#[inline(always)]
pub fn table_to_paddr(entry: usize) -> usize {
    arch::table_to_paddr(entry)
}

/// 物理地址 + 保护属性 → 叶子条目
#[inline(always)]
pub fn paddr_to_leaf(paddr: usize, prot: PageProt, level: PageLevel) -> usize {
    arch::paddr_to_leaf(paddr, prot, level)
}

/// 叶子条目 → 物理地址
#[inline(always)]
pub fn leaf_to_paddr(entry: usize) -> usize {
    arch::leaf_to_paddr(entry)
}

/// 条目是否有效
#[inline(always)]
pub fn entry_is_valid(entry: usize) -> bool {
    arch::entry_is_valid(entry)
}

/// 条目是否为叶子(非 table pointer)
#[inline(always)]
pub fn entry_is_leaf(entry: usize) -> bool {
    arch::entry_is_leaf(entry)
}

// ---------------------------------------------------------------------------
// 内核虚拟地址布局
// ---------------------------------------------------------------------------

use moa_const_sizes::{SZ_1G, SZ_4G, SZ_8K, SZ_16K, SZ_32G};

/// 虚拟地址有效位宽
pub const VA_BITS: usize = 39;

/// 用户态地址空间起始
pub const USER_ADDR_START: usize = 0;
/// 用户态地址空间结束
pub const USER_ADDR_END: usize = (1 << (VA_BITS - 1)) - 1;

/// 内核地址空间起始
pub const KERNEL_ADDR_START: usize = !((1 << (VA_BITS - 1)) - 1);
/// 内核地址空间结束
pub const KERNEL_ADDR_END: usize = usize::MAX;

/// 内核镜像区域起始
pub const KIMAGE_ADDR_START: usize = KERNEL_ADDR_START;
/// 内核镜像区域大小
pub const KIMAGE_ADDR_SIZE: usize = SZ_4G;

/// Fixmap 区域起始(KIMAGE 末尾 2MB)
pub const KFIXMAP_ADDR_START: usize = KIMAGE_ADDR_START + KIMAGE_ADDR_SIZE - PMD_SIZE;
/// Fixmap 页数
pub const KFIXMAP_NR_PAGES: usize = PTRS_PER_TABLE;

/// 内核 FDT 区域起始
pub const KFDT_ADDR_START: usize = KIMAGE_ADDR_START + KIMAGE_ADDR_SIZE;
/// 内核 FDT 区域大小
pub const KFDT_ADDR_SIZE: usize = SZ_1G;

/// 内核 IO 映射区域起始
pub const KIO_ADDR_START: usize = KFDT_ADDR_START + KFDT_ADDR_SIZE;
/// 内核 IO 映射区域大小
pub const KIO_ADDR_SIZE: usize = SZ_4G;

/// 内核页元数据区域起始
pub const KPAGE_ADDR_START: usize = KIO_ADDR_START + KIO_ADDR_SIZE;
/// 内核页元数据区域大小
pub const KPAGE_ADDR_SIZE: usize = SZ_32G;

/// 内核线性映射区域起始
pub const KMEM_ADDR_START: usize = KPAGE_ADDR_START + KPAGE_ADDR_SIZE;
/// 内核线性映射区域结束
pub const KMEM_ADDR_END: usize = usize::MAX;

// ---------------------------------------------------------------------------
// 栈大小
// ---------------------------------------------------------------------------

/// 内核线程栈大小(16KB)
pub const KERNEL_STACK_SIZE: usize = SZ_16K;

/// Boot 阶段 per-CPU 栈大小(8KB)
pub const BOOT_STACK_SIZE: usize = SZ_8K;