Files
RedBear-OS/common/src/lib.rs
T
bjorn3 7935ed0248 Deduplicate setup_logging between all drivers
This will make it easier to change the way logging is done for all
drivers. This also fixes the log category for a couple of drivers as
well as makes failing to set the logger a fatal error. Only when a
logger is already set is it impossible to set another logger.
2024-07-24 22:00:40 +02:00

138 lines
3.1 KiB
Rust

#![feature(int_roundings)]
use libredox::call::MmapArgs;
use libredox::flag::{self, O_CLOEXEC, O_RDONLY, O_RDWR, O_WRONLY};
use libredox::{errno::EINVAL, error::*, Fd};
use syscall::PAGE_SIZE;
pub mod dma;
mod logger;
pub mod sgl;
pub use logger::setup_logging;
#[derive(Clone, Copy, Debug)]
pub enum MemoryType {
Writeback,
Uncacheable,
WriteCombining,
DeviceMemory,
}
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,
};
}
// TODO: Safe, as the kernel ensures it doesn't conflict with any other memory described in the
// memory map for regular RAM.
pub unsafe fn physmap(
base_phys: usize,
len: usize,
Prot { read, write }: Prot,
ty: MemoryType,
) -> Result<*mut ()> {
// TODO: arraystring?
let path = format!(
"/scheme/memory/physical@{}",
match ty {
MemoryType::Writeback => "wb",
MemoryType::Uncacheable => "uc",
MemoryType::WriteCombining => "wc",
MemoryType::DeviceMemory => "dev",
}
);
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 = 0;
if read {
prot |= flag::PROT_READ;
}
if write {
prot |= flag::PROT_WRITE;
}
let fd = Fd::open(&path, O_CLOEXEC | mode, 0)?;
Ok(libredox::call::mmap(MmapArgs {
fd: fd.raw(),
offset: base_phys as u64,
length: len.next_multiple_of(PAGE_SIZE),
flags: flag::MAP_SHARED,
prot,
addr: core::ptr::null_mut(),
})? as *mut ())
}
impl std::fmt::Display for MemoryType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Self::Writeback => "wb",
Self::Uncacheable => "uc",
Self::WriteCombining => "wc",
Self::DeviceMemory => "dev",
}
)
}
}
pub struct PhysBorrowed {
mem: *mut (),
len: usize,
}
impl PhysBorrowed {
pub fn map(base_phys: usize, len: usize, prot: Prot, ty: MemoryType) -> Result<Self> {
let mem = unsafe { physmap(base_phys, len, prot, ty)? };
Ok(Self {
mem,
len: len.next_multiple_of(PAGE_SIZE),
})
}
pub fn as_ptr(&self) -> *mut () {
self.mem
}
pub fn mapped_len(&self) -> usize {
self.len
}
}
impl Drop for PhysBorrowed {
fn drop(&mut self) {
unsafe {
let _ = libredox::call::munmap(self.mem, self.len);
}
}
}
pub fn acquire_port_io_rights() -> Result<()> {
unsafe {
syscall::iopl(3)?;
}
Ok(())
}