Skip to content

Commit

Permalink
Refactors character devices (obhq#729)
Browse files Browse the repository at this point in the history
  • Loading branch information
SuchAFuriousDeath authored Mar 24, 2024
1 parent 6bca86f commit 024f5a8
Show file tree
Hide file tree
Showing 28 changed files with 575 additions and 518 deletions.
30 changes: 0 additions & 30 deletions src/kernel/src/debug/deci.rs

This file was deleted.

64 changes: 0 additions & 64 deletions src/kernel/src/debug/mod.rs

This file was deleted.

119 changes: 119 additions & 0 deletions src/kernel/src/dev/deci.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
use crate::fs::{
make_dev, CharacterDevice, DeviceDriver, DriverFlags, MakeDevError, MakeDevFlags, Mode,
OpenFlags, Uio, UioMut,
};
use crate::ucred::{Gid, Uid};
use crate::{errno::Errno, process::VThread};
use std::sync::Arc;
use thiserror::Error;

#[derive(Debug)]
struct Driver {}

impl Driver {
pub fn new() -> Self {
Self {}
}
}

impl DeviceDriver for Driver {
#[allow(unused_variables)] // TODO: remove when implementing
fn open(
&self,
dev: &Arc<CharacterDevice>,
mode: OpenFlags,
devtype: i32,
td: Option<&VThread>,
) -> Result<(), Box<dyn Errno>> {
todo!()
}

#[allow(unused_variables)] // TODO: remove when implementing
fn read(
&self,
dev: &Arc<CharacterDevice>,
data: &mut UioMut,
td: Option<&VThread>,
) -> Result<usize, Box<dyn Errno>> {
todo!()
}

#[allow(unused_variables)] // TODO: remove when implementing
fn write(
&self,
dev: &Arc<CharacterDevice>,
data: &mut Uio,
td: Option<&VThread>,
) -> Result<usize, Box<dyn Errno>> {
todo!()
}
}

/// Encapsulates a deci device (e.g. `deci_stdout`).
#[allow(dead_code)]
pub struct Deci {
name: &'static str,
dev: Arc<CharacterDevice>,
}

impl Deci {
pub const NAMES: [&'static str; 12] = [
"deci_stdout",
"deci_stderr",
"deci_tty2",
"deci_tty3",
"deci_tty4",
"deci_tty5",
"deci_tty6",
"deci_tty7",
"deci_ttya0",
"deci_ttyb0",
"deci_ttyc0",
"deci_coredump",
];

pub(super) fn new(name: &'static str, dev: Arc<CharacterDevice>) -> Self {
Self { name, dev }
}
}

/// An implementation of debugging functionalities of the PS4 (not Obliteration debugging).
///
/// It is unclear what deci is stand for. Probably Debug Console Interface?
#[allow(dead_code)]
pub struct DebugManager {
deci_devs: Vec<Deci>, // decitty_XX
}

impl DebugManager {
pub fn new() -> Result<Arc<Self>, DebugManagerInitError> {
// Create deci devices.
let mut deci_devs = Vec::with_capacity(Deci::NAMES.len());

for name in Deci::NAMES {
match make_dev(
Driver::new(),
DriverFlags::from_bits_retain(0x80080000),
0,
name,
Uid::ROOT,
Gid::ROOT,
Mode::new(0o666).unwrap(),
None,
MakeDevFlags::empty(),
) {
Ok(v) => deci_devs.push(Deci::new(name, v)),
Err(e) => return Err(DebugManagerInitError::CreateDeciFailed(name, e)),
}
}

Ok(Arc::new(Self { deci_devs }))
}
}

/// Represents an error when [`DebugManager`] is failed to initialize.
#[derive(Debug, Error)]
pub enum DebugManagerInitError {
#[error("couldn't create {0}")]
CreateDeciFailed(&'static str, #[source] MakeDevError),
}
25 changes: 25 additions & 0 deletions src/kernel/src/dev/dipsw.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use crate::{
errno::Errno,
fs::{CharacterDevice, DeviceDriver, IoCmd},
process::VThread,
};
use std::sync::Arc;

#[derive(Debug)]
struct Dipsw {}

impl DeviceDriver for Dipsw {
#[allow(unused_variables)]
fn ioctl(
&self,
dev: &Arc<CharacterDevice>,
cmd: IoCmd,
td: &VThread,
) -> Result<(), Box<dyn Errno>> {
if !td.cred().is_system() {
todo!()
} else {
todo!()
}
}
}
57 changes: 57 additions & 0 deletions src/kernel/src/dev/dmem.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use crate::{
errno::{Errno, EPERM},
fs::{CharacterDevice, DeviceDriver, IoCmd},
process::VThread,
};
use macros::Errno;
use std::sync::Arc;
use thiserror::Error;

#[derive(Debug)]
struct Dmem {
total_size: usize, // TODO: Should be 0x13C_000_000
container: DmemContainer,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
enum DmemContainer {
Zero,
One,
Two,
}

impl DeviceDriver for Dmem {
fn ioctl(
&self,
dev: &Arc<CharacterDevice>,
cmd: IoCmd,
td: &VThread,
) -> Result<(), Box<dyn Errno>> {
let cred = td.cred();

if cred.is_unk1() || cred.is_unk2() {
return Err(Box::new(IoctlErr::InsufficientCredentials));
}

if self.container != DmemContainer::Two
&& self.container as usize != td.proc().dmem_container()
&& !cred.is_system()
{
return Err(Box::new(IoctlErr::InsufficientCredentials));
}

match cmd {
IoCmd::DMEM10(size) => *size = self.total_size,
_ => todo!(),
}

Ok(())
}
}

#[derive(Error, Debug, Errno)]
enum IoctlErr {
#[error("bad credentials")]
#[errno(EPERM)]
InsufficientCredentials,
}
32 changes: 32 additions & 0 deletions src/kernel/src/dev/gc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use crate::{
errno::Errno,
fs::{CharacterDevice, DeviceDriver, IoCmd, OpenFlags},
process::VThread,
};
use std::sync::Arc;

#[derive(Debug)]
struct Gc {}

impl DeviceDriver for Gc {
#[allow(unused_variables)] // TODO: remove when implementing
fn open(
&self,
dev: &Arc<CharacterDevice>,
mode: OpenFlags,
devtype: i32,
td: Option<&VThread>,
) -> Result<(), Box<dyn Errno>> {
todo!()
}

#[allow(unused_variables)] // TODO: remove when implementing
fn ioctl(
&self,
dev: &Arc<CharacterDevice>,
cmd: IoCmd,
td: &VThread,
) -> Result<(), Box<dyn Errno>> {
todo!()
}
}
31 changes: 31 additions & 0 deletions src/kernel/src/dev/hid.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use crate::{
errno::Errno,
fs::{CharacterDevice, DeviceDriver, IoCmd, UioMut},
process::VThread,
};
use std::sync::Arc;

#[derive(Debug)]
struct Hid {}

impl DeviceDriver for Hid {
#[allow(unused_variables)] // TODO: remove when implementing
fn read(
&self,
dev: &Arc<CharacterDevice>,
data: &mut UioMut,
td: Option<&VThread>,
) -> Result<usize, Box<dyn Errno>> {
todo!()
}

#[allow(unused_variables)] // TODO: remove when implementing
fn ioctl(
&self,
dev: &Arc<CharacterDevice>,
cmd: IoCmd,
td: &VThread,
) -> Result<(), Box<dyn Errno>> {
todo!()
}
}
19 changes: 19 additions & 0 deletions src/kernel/src/dev/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
pub use deci::*;
pub use dipsw::*;
pub use dmem::*;
pub use gc::*;
pub use hid::*;
pub use random::*;
pub use rng::*;
pub use sbl_srv::*;
pub use ttyconsole::*;

mod deci;
mod dipsw;
mod dmem;
mod gc;
mod hid;
mod random;
mod rng;
mod sbl_srv;
mod ttyconsole;
Loading

0 comments on commit 024f5a8

Please sign in to comment.