Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions os/src/arch/loongarch/mm/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
//! LoongArch architecture memory management module
//!
//! This module provides LoongArch specific implementations for memory management.
//!
//! # TODO
//!
//! - [ ] define virtual address space start constant for LoongArch
//! - [ ] define physical address mask constant for LoongArch
//! - [ ] implement `vaddr_to_paddr` function
//! - [ ] implement `paddr_to_vaddr` function
//! - [ ] refine address translation logic based on LoongArch paging scheme
1 change: 1 addition & 0 deletions os/src/arch/loongarch/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mod mm;
8 changes: 8 additions & 0 deletions os/src/arch/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
mod loongarch;
mod riscv;

#[cfg(target_arch = "loongarch64")]
pub use self::loongarch::mm;

#[cfg(target_arch = "riscv64")]
pub use self::riscv::mm;
64 changes: 64 additions & 0 deletions os/src/arch/riscv/mm/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//! RISC-V architecture memory management module
//!
//! This module provides RISC-V specific implementations for memory management,
//! using the SV39 paging scheme.
//!
//! # SV39 Paging Scheme
//!
//! SV39 is a 39-bit virtual address paging scheme for RISC-V:
//! - Virtual address: 39 effective bits (bits 38-63 must match bit 38)
//! - Physical address: 56 bits (bits 0-55)
//! - Page size: 4 KiB
//!
//! # Address Translation
//!
//! This module uses direct mapping for address translation:
//! - Virtual address start: `0xffff_ffc0_0000_0000`
//! - Physical addresses are extracted using bitwise AND with `PADDR_MASK`
//! - Virtual addresses are created using bitwise OR with `VADDR_START`

/// starting address of the virtual address space in SV39
///
/// This constant defines the starting position of the kernel's high virtual address space.
/// In the SV39 paging scheme, this is a valid higher-half kernel address.
pub const VADDR_START: usize = 0xffff_ffc0_0000_0000;

/// physical address mask for extracting physical address from virtual address
///
/// This mask preserves the lower 38 bits (bits 0-37), which corresponds to
/// the physical address space size in SV39.
pub const PADDR_MASK: usize = 0x0000_3fff_ffff_ffff;

/// convert virtual address to physical address
///
/// # Parameters
///
/// * `vaddr` - virtual address
///
/// # Returns
///
/// The corresponding physical address
///
/// # Note
///
/// This function must be implemented in all architecture-specific mm modules.
pub const fn vaddr_to_paddr(vaddr: usize) -> usize {
vaddr & PADDR_MASK
}

/// convert physical address to virtual address
///
/// # Parameters
///
/// * `paddr` - physical address
///
/// # Returns
///
/// The corresponding virtual address
///
/// # Note
///
/// This function must be implemented in all architecture-specific mm modules.
pub const fn paddr_to_vaddr(paddr: usize) -> usize {
paddr | VADDR_START
}
1 change: 1 addition & 0 deletions os/src/arch/riscv/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod mm;
22 changes: 22 additions & 0 deletions os/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,33 @@
#![test_runner(crate::test_runner)]
#![reexport_test_harness_main = "test_main"]

extern crate alloc;

use core::alloc::{GlobalAlloc, Layout};

/// TODO: replace with proper heap allocator
/// Dummy allocator that always fails - placeholder until heap allocator is implemented
struct DummyAllocator;

unsafe impl GlobalAlloc for DummyAllocator {
unsafe fn alloc(&self, _layout: Layout) -> *mut u8 {
core::ptr::null_mut()
}

unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {
panic!("dealloc called on DummyAllocator");
}
}

#[global_allocator]
static ALLOCATOR: DummyAllocator = DummyAllocator;

#[macro_use]
mod console;
mod sbi;
mod config;
mod mm;
mod arch;

use core::arch::global_asm;
use core::panic::PanicInfo;
Expand Down
41 changes: 37 additions & 4 deletions os/src/mm/address/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,18 +110,54 @@ macro_rules! impl_address {
};
}

/// trait for converting physical addresses to virtual addresses
pub trait ConvertablePaddr {
/// check if the address is a valid physical address
fn is_valid_paddr(&self) -> bool;
/// convert physical address to virtual address
fn to_vaddr(&self) -> Vaddr;
}

/// physical address
#[repr(transparent)]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Paddr(*const ());
impl_address!(Paddr);

impl ConvertablePaddr for Paddr {
fn is_valid_paddr(&self) -> bool {
self.as_usize() == crate::arch::mm::vaddr_to_paddr(self.as_usize())
}

fn to_vaddr(&self) -> Vaddr {
Vaddr::from_usize(crate::arch::mm::paddr_to_vaddr(self.as_usize()))
}
}

/// trait for converting virtual addresses to physical addresses
pub trait ConvertableVaddr {
/// check if the address is a valid virtual address
fn is_valid_vaddr(&self) -> bool;
/// convert virtual address to physical address
fn to_paddr(&self) -> Paddr;
}

/// virtual address
#[repr(transparent)]
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Vaddr(*const ());
impl_address!(Vaddr);

impl ConvertableVaddr for Vaddr {
fn is_valid_vaddr(&self) -> bool {
self.as_usize() == crate::arch::mm::paddr_to_vaddr(self.as_usize())
}

fn to_paddr(&self) -> Paddr {
Paddr::from_usize(crate::arch::mm::vaddr_to_paddr(self.as_usize()))
}
}

impl Vaddr {
/// create a virtual address from a reference
pub fn from_ref<T>(r: &T) -> Self {
Expand Down Expand Up @@ -177,10 +213,7 @@ where
{
/// create a new address range
pub fn new(start: T, end: T) -> Self {
Self {
start,
end,
}
Self { start, end }
}

/// create an address range from a Range<T>
Expand Down
26 changes: 23 additions & 3 deletions os/src/mm/address/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,33 @@
//! This module provides abstractions for working with physical and virtual addresses,
//! as well as page numbers in a memory management system.
//!
//! # Components
//! # Address Types
//!
//! - [`Address`]: Trait for representing memory addresses (physical or virtual)
//! - [`Paddr`]: Physical address type
//! - [`Vaddr`]: Virtual address type
//! - [`ConvertablePaddr`]: Trait for converting physical addresses to virtual addresses
//! - [`ConvertableVaddr`]: Trait for converting virtual addresses to physical addresses
//!
//! # Address Ranges
//!
//! - [`AddressRange`]: Generic range of addresses
//! - [`PaddrRange`]: Type alias for physical address range
//! - [`VaddrRange`]: Type alias for virtual address range
//! - [`AddressRangeIterator`]: Iterator for address ranges
//!
//! # Page Numbers
//!
//! - [`PageNum`]: Trait for representing page numbers
//! - [`Ppn`]: Physical page number
//! - [`Vpn`]: Virtual page number
//!
//! # Page Number Ranges
//!
//! - [`PageNumRange`]: Generic range of page numbers
//! - [`PpnRange`]: Type alias for physical page number range
//! - [`VpnRange`]: Type alias for virtual page number range
//! - [`PageNumRangeIterator`]: Iterator for page number ranges
//!
//! # Operations
//!
Expand All @@ -26,6 +43,9 @@ mod address;
mod operations;
mod page_num;

pub use address::{Address, AddressRange, Paddr, PaddrRange, Vaddr, VaddrRange};
pub use address::{
Address, AddressRange, AddressRangeIterator, ConvertablePaddr, ConvertableVaddr, Paddr,
PaddrRange, Vaddr, VaddrRange,
};
pub use operations::{AlignOps, CalcOps, UsizeConvert};
pub use page_num::{PageNum, Ppn, Vpn};
pub use page_num::{PageNum, PageNumRange, PageNumRangeIterator, Ppn, PpnRange, Vpn, VpnRange};
13 changes: 13 additions & 0 deletions os/src/mm/address/page_num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,16 @@ where
}
}

/// get the start page number
pub fn start(&self) -> T {
self.start
}

/// get the end page number
pub fn end(&self) -> T {
self.end
}

/// get the length of the range
pub fn len(&self) -> usize {
debug_assert!(self.end.as_usize() >= self.start.as_usize());
Expand Down Expand Up @@ -196,3 +206,6 @@ where
Some(result)
}
}

pub type PpnRange = PageNumRange<Ppn>;
pub type VpnRange = PageNumRange<Vpn>;
Empty file removed os/src/mm/allocation/.gitkeep
Empty file.
Loading