From 1f1a57e1f7cb47787f6905218553a3f4be6f4e38 Mon Sep 17 00:00:00 2001 From: Ivan Tan Date: Sat, 9 Dec 2023 11:58:42 +0800 Subject: [PATCH] support userspace program ioremapping device memory --- src/arch/aarch64/paging/entry.rs | 14 ++++++++++++++ src/arch/aarch64/paging/mod.rs | 1 + src/arch/aarch64/rmm.rs | 4 ++-- src/scheme/memory.rs | 12 ++++++++++-- 4 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 src/arch/aarch64/paging/entry.rs diff --git a/src/arch/aarch64/paging/entry.rs b/src/arch/aarch64/paging/entry.rs new file mode 100644 index 0000000000..289ce8d258 --- /dev/null +++ b/src/arch/aarch64/paging/entry.rs @@ -0,0 +1,14 @@ +//! # Page table entry +//! Some code borrowed from [Phil Opp's Blog](http://os.phil-opp.com/modifying-page-tables.html) + +/// A page table entry +#[repr(packed(8))] +pub struct Entry(u64); + +bitflags! { + pub struct EntryFlags: usize { + const NO_CACHE = 1 << 2; + const DEV_MEM = 2 << 2; + } +} + diff --git a/src/arch/aarch64/paging/mod.rs b/src/arch/aarch64/paging/mod.rs index fe806d9d8e..bfb00e6b4d 100644 --- a/src/arch/aarch64/paging/mod.rs +++ b/src/arch/aarch64/paging/mod.rs @@ -20,6 +20,7 @@ pub use super::CurrentRmmArch as RmmA; pub type PageMapper = rmm::PageMapper; pub use crate::rmm::KernelMapper; +pub mod entry; pub mod mapper; /// Number of entries per page table diff --git a/src/arch/aarch64/rmm.rs b/src/arch/aarch64/rmm.rs index 5c1aab6ddf..a320c49ce6 100644 --- a/src/arch/aarch64/rmm.rs +++ b/src/arch/aarch64/rmm.rs @@ -22,7 +22,7 @@ use rmm::{ }; use spin::Mutex; -use crate::{LogicalCpuId, init::device_tree::MEMORY_MAP}; +use crate::{LogicalCpuId, init::device_tree::MEMORY_MAP, paging::entry::EntryFlags}; use super::CurrentRmmArch as RmmA; @@ -186,7 +186,7 @@ unsafe fn inner( // mair_el1 == 0x00000000000044FF // set mem_attr == device memory let flags = page_flags::(virt) - .custom_flag(2 << 2, true); + .custom_flag(EntryFlags::DEV_MEM.bits(), true); let flush = mapper.map_phys( virt, phys, diff --git a/src/scheme/memory.rs b/src/scheme/memory.rs index fb4c3d2d30..5aecfe9618 100644 --- a/src/scheme/memory.rs +++ b/src/scheme/memory.rs @@ -9,7 +9,6 @@ use crate::memory::{free_frames, used_frames, PAGE_SIZE, Frame}; use crate::context::memory::{AddrSpace, Grant, PageSpan, handle_notify_files}; use crate::paging::VirtualAddress; -#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] use crate::paging::entry::EntryFlags; use crate::syscall::data::{Map, StatVfs}; @@ -29,6 +28,7 @@ enum Handle { PhysicalWb = 1, PhysicalUc = 2, PhysicalWc = 3, + PhysicalDev = 4, // TODO: More/make arch-specific? } @@ -36,6 +36,7 @@ pub enum MemoryType { Writeback, Uncacheable, WriteCombining, + DeviceMemory, } impl Handle { @@ -46,6 +47,7 @@ impl Handle { 1 => Self::PhysicalWb, 2 => Self::PhysicalUc, 3 => Self::PhysicalWc, + 4 => Self::PhysicalDev, _ => return None, }) @@ -96,10 +98,13 @@ impl MemoryScheme { #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] // TODO: AARCH64 MemoryType::WriteCombining => page_flags = page_flags.custom_flag(EntryFlags::HUGE_PAGE.bits(), true), - #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] // TODO: AARCH64 MemoryType::Uncacheable => page_flags = page_flags.custom_flag(EntryFlags::NO_CACHE.bits(), true), #[cfg(target_arch = "aarch64")] + MemoryType::DeviceMemory => page_flags = page_flags.custom_flag(EntryFlags::DEV_MEM.bits(), true), + + //x86 && x86_64 MemoryType::DeviceMemory unimplemented + //aarch64 MemoryType::WriteCombining unimplemented _ => (), } @@ -124,6 +129,7 @@ impl KernelScheme for MemoryScheme { "physical" | "physical@wb" => Handle::PhysicalWb, "physical@uc" => Handle::PhysicalUc, "physical@wc" => Handle::PhysicalWc, + "physical@dev" => Handle::PhysicalDev, _ => return Err(Error::new(ENOENT)), }; @@ -148,6 +154,7 @@ impl KernelScheme for MemoryScheme { Handle::PhysicalWb => Self::physmap(map.offset, map.size, map.flags, MemoryType::Writeback), Handle::PhysicalUc => Self::physmap(map.offset, map.size, map.flags, MemoryType::Uncacheable), Handle::PhysicalWc => Self::physmap(map.offset, map.size, map.flags, MemoryType::WriteCombining), + Handle::PhysicalDev => Self::physmap(map.offset, map.size, map.flags, MemoryType::DeviceMemory), } } fn kfpath(&self, id: usize, dst: UserSliceWo) -> Result { @@ -157,6 +164,7 @@ impl KernelScheme for MemoryScheme { Handle::PhysicalWb => "memory:physical@wb", Handle::PhysicalUc => "memory:physical@uc", Handle::PhysicalWc => "memory:physical@wc", + Handle::PhysicalDev => "memory:physical@dev", }; dst.copy_common_bytes_from_slice(src.as_bytes()) }