diff --git a/Cargo.toml b/Cargo.toml index c7c25c1e42..2c9b8d6e06 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ members = [ "alxd", "bgad", "block-io-wrapper", + "common", "e1000d", "ided", "ihdad", diff --git a/common/Cargo.toml b/common/Cargo.toml new file mode 100644 index 0000000000..7313a2eb95 --- /dev/null +++ b/common/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "common" +version = "0.1.0" +edition = "2021" +authors = ["4lDO2 <4lDO2@protonmail.com>"] +license = "MIT" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +redox_syscall = "0.3" diff --git a/common/src/lib.rs b/common/src/lib.rs new file mode 100644 index 0000000000..85f976f332 --- /dev/null +++ b/common/src/lib.rs @@ -0,0 +1,57 @@ +#![feature(int_roundings)] + +use syscall::PAGE_SIZE; +use syscall::error::{Error, Result, EINVAL}; +use syscall::flag::{MapFlags, O_CLOEXEC, O_RDONLY, O_RDWR, O_WRONLY}; + +#[derive(Clone, Copy, Debug)] +pub enum MemoryType { + Writeback, + Uncacheable, + WriteCombining, +} +impl Default for MemoryType { + fn default() -> Self { + Self::Writeback + } +} + +#[derive(Clone, Copy, Debug)] +pub struct Prot { + pub read: bool, + pub write: bool, +} +impl Prot { + pub const RO: Self = Self { read: true, write: false }; + pub const WO: Self = Self { read: false, write: true }; + pub const RW: Self = Self { read: true, write: true }; +} + +pub unsafe fn physmap(base_phys: usize, len: usize, Prot { read, write }: Prot, ty: MemoryType) -> Result<*mut ()> { + // TODO: arraystring? + let path = format!("memory:physical@{}", match ty { + MemoryType::Writeback => "wb", + MemoryType::Uncacheable => "uc", + MemoryType::WriteCombining => "wc", + }); + let mode = match (read, write) { + (true, true) => O_RDWR, + (true, false) => O_RDONLY, + (false, true) => O_WRONLY, + (false, false) => return Err(Error::new(EINVAL)), + }; + let mut prot = MapFlags::empty(); + prot.set(MapFlags::PROT_READ, read); + prot.set(MapFlags::PROT_WRITE, write); + + let file = syscall::open(path, O_CLOEXEC | mode)?; + let base = syscall::fmap(file, &syscall::Map { + offset: base_phys, + size: len.next_multiple_of(PAGE_SIZE), + flags: MapFlags::MAP_SHARED | prot, + address: 0, + }); + let _ = syscall::close(file); + + Ok(base? as *mut ()) +}