Skip to content

Commit

Permalink
Implements dmem1 ioctl (#512)
Browse files Browse the repository at this point in the history
Co-authored-by: tompro <[email protected]>
  • Loading branch information
SuchAFuriousDeath and SuchAFuriousDeath authored Dec 16, 2023
1 parent 3f392a2 commit 0060571
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 47 deletions.
51 changes: 26 additions & 25 deletions src/kernel/src/fs/dev/dipsw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use crate::errno::{Errno, EINVAL};
use crate::fs::{IoctlCom, VFile, VFileOps, VPath};
use crate::process::VThread;
use crate::ucred::Ucred;
use byteorder::{LittleEndian, WriteBytesExt};
use macros::vpath;
use std::fmt::{Display, Formatter};
use std::num::NonZeroI32;
Expand All @@ -15,22 +14,24 @@ pub struct Dipsw {}
impl Dipsw {
pub const PATH: &VPath = vpath!("/dev/dipsw");

pub const DIPSW_GRP: u8 = 0x88;

const COM1: IoctlCom = IoctlCom::iow::<i16>(Self::DIPSW_GRP, 1); //TODO: figure out actual type
const COM2: IoctlCom = IoctlCom::iow::<i16>(Self::DIPSW_GRP, 2); //TODO: figure out actual type
const COM3: IoctlCom = IoctlCom::iowr::<i64>(Self::DIPSW_GRP, 3); //TODO: figure out actual type
const COM4: IoctlCom = IoctlCom::iow::<(i64, i64)>(Self::DIPSW_GRP, 4); //TODO: figure out actual type, probably a struct
const COM5: IoctlCom = IoctlCom::iow::<(i64, i64)>(Self::DIPSW_GRP, 5); //TODO: figure out actual type, probably a struct
const COM6: IoctlCom = IoctlCom::ior::<i32>(Self::DIPSW_GRP, 6);
const COM7: IoctlCom = IoctlCom::ior::<i32>(Self::DIPSW_GRP, 7); //TODO: figure out actual type
const COM8: IoctlCom = IoctlCom::ior::<i64>(Self::DIPSW_GRP, 8); //TODO: figure out actual type
const COM9: IoctlCom = IoctlCom::ior::<i64>(Self::DIPSW_GRP, 9); //TODO: figure out actual type
const COM10: IoctlCom = IoctlCom::iow::<(i64, i64)>(Self::DIPSW_GRP, 10); //TODO: figure out actual type, probably a struct

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

const COM1: IoctlCom = IoctlCom::iow::<i16>(0x88, 1); //TODO: figure out actual type
const COM2: IoctlCom = IoctlCom::iow::<i16>(0x88, 2); //TODO: figure out actual type
const COM3: IoctlCom = IoctlCom::iowr::<i64>(0x88, 3); //TODO: figure out actual type
const COM4: IoctlCom = IoctlCom::iow::<(i64, i64)>(0x88, 4); //TODO: figure out actual type, probably a struct
const COM5: IoctlCom = IoctlCom::iow::<(i64, i64)>(0x88, 5); //TODO: figure out actual type, probably a struct
const COM6: IoctlCom = IoctlCom::ior::<i32>(0x88, 6);
const COM7: IoctlCom = IoctlCom::ior::<i32>(0x88, 7); //TODO: figure out actual type
const COM8: IoctlCom = IoctlCom::ior::<i64>(0x88, 8); //TODO: figure out actual type
const COM9: IoctlCom = IoctlCom::ior::<i64>(0x88, 9); //TODO: figure out actual type
const COM10: IoctlCom = IoctlCom::iow::<(i64, i64)>(0x88, 10); //TODO: figure out actual type, probably a struct

impl VFileOps for Dipsw {
fn write(
&self,
Expand All @@ -46,25 +47,25 @@ impl VFileOps for Dipsw {
&self,
_: &VFile,
com: IoctlCom,
mut data: &mut [u8],
data: &mut [u8],
_: &Ucred,
_: &VThread,
) -> Result<(), Box<dyn Errno>> {
match com {
COM1 => todo!("dipsw ioctl 0x80028801"),
COM2 => todo!("dipsw ioctl 0x80028802"),
COM3 => todo!("dipsw ioctl 0xc0088803"),
COM4 => todo!("dipsw ioctl 0x80108804"),
COM5 => todo!("dipsw ioctl 0x80108805"),
COM6 => {
Self::COM1 => todo!("dipsw ioctl 0x80028801"),
Self::COM2 => todo!("dipsw ioctl 0x80028802"),
Self::COM3 => todo!("dipsw ioctl 0xc0088803"),
Self::COM4 => todo!("dipsw ioctl 0x80108804"),
Self::COM5 => todo!("dipsw ioctl 0x80108805"),
Self::COM6 => {
//todo write the correct value if unk_func1() = false and
// unk_func2() = true
data.write_i32::<LittleEndian>(false as i32).unwrap();
data.copy_from_slice(&(false as i32).to_ne_bytes());
}
COM7 => todo!("dipsw ioctl 0x40048807"),
COM8 => todo!("dipsw ioctl 0x40088808"),
COM9 => todo!("dipsw ioctl 0x40088809"),
COM10 => todo!("dipsw ioctl 0x8010880a"),
Self::COM7 => todo!("dipsw ioctl 0x40048807"),
Self::COM8 => todo!("dipsw ioctl 0x40088808"),
Self::COM9 => todo!("dipsw ioctl 0x40088809"),
Self::COM10 => todo!("dipsw ioctl 0x8010880a"),
_ => return Err(Box::new(IoctlErr::InvalidCommand)),
}

Expand All @@ -80,7 +81,7 @@ impl Display for Dipsw {

#[derive(Error, Debug)]
enum IoctlErr {
#[error("invalid command passed to Dipsw::ioctl")]
#[error("invalid command passed to dipsw ioctl")]
InvalidCommand,
}

Expand Down
62 changes: 53 additions & 9 deletions src/kernel/src/fs/dev/dmem1.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
use crate::errno::Errno;
use crate::errno::{Errno, EPERM};
use crate::fs::{IoctlCom, VFile, VFileOps, VPath};
use crate::process::VThread;
use crate::process::{VProc, VThread};
use crate::ucred::Ucred;
use macros::vpath;
use std::fmt::{Display, Formatter};
use std::num::NonZeroI32;
use std::sync::Arc;
use thiserror::Error;

#[derive(Debug)]
pub struct Dmem1 {}
pub struct Dmem1 {
vp: Arc<VProc>,
total_size: usize,
number: i32,
}

impl Dmem1 {
pub const PATH: &VPath = vpath!("/dev/dmem1");

pub fn new() -> Self {
Self {}
pub const DMEM_GRP: u8 = 0x80;

pub const COM10: IoctlCom = IoctlCom::ior::<usize>(Self::DMEM_GRP, 0xa);

pub fn new(vp: &Arc<VProc>) -> Self {
Self {
vp: vp.clone(),
total_size: 0x13C_000_000, // TODO figure out the real value
number: 1,
}
}
}

Expand All @@ -24,12 +39,27 @@ impl VFileOps for Dmem1 {
fn ioctl(
&self,
_: &crate::fs::VFile,
_com: IoctlCom,
_: &mut [u8],
_: &Ucred,
com: IoctlCom,
data: &mut [u8],
cred: &Ucred,
_: &VThread,
) -> Result<(), Box<dyn Errno>> {
todo!()
if cred.is_unk1() || cred.is_unk2() {
return Err(Box::new(IoctlErr::BadCredentials));
}

if self.number != 2 && self.number != *self.vp.dmem_container() && !cred.is_system() {
return Err(Box::new(IoctlErr::BadCredentials));
}

match com {
Self::COM10 => {
data.copy_from_slice(&self.total_size.to_ne_bytes());
}
_ => todo!("dmem1 ioctl with com = ({com})"),
}

Ok(())
}
}

Expand All @@ -38,3 +68,17 @@ impl Display for Dmem1 {
Self::PATH.fmt(f)
}
}

#[derive(Error, Debug)]
enum IoctlErr {
#[error("bad credentials")]
BadCredentials,
}

impl Errno for IoctlErr {
fn errno(&self) -> NonZeroI32 {
match self {
Self::BadCredentials => EPERM,
}
}
}
15 changes: 9 additions & 6 deletions src/kernel/src/fs/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ use super::{
dev::{deci_tty6::DeciTty6, dipsw::Dipsw, dmem0::Dmem0, dmem1::Dmem1, dmem2::Dmem2},
FsError, VFileOps, VPath, VPathBuf,
};
use crate::fs::dev::console::Console;
use std::path::{Path, PathBuf};
use crate::{fs::dev::console::Console, process::VProc};
use std::{
path::{Path, PathBuf},
sync::Arc,
};

/// An item in the virtual filesystem.
pub enum FsItem {
Expand Down Expand Up @@ -42,11 +45,11 @@ impl FsItem {
}
}

pub fn open(&self) -> Result<Box<dyn VFileOps>, FsError> {
pub fn open(&self, vp: &Arc<VProc>) -> Result<Box<dyn VFileOps>, FsError> {
match self {
Self::Directory(_) => todo!("VFileOps for host directory"),
Self::File(_) => todo!("VFileOps for host file"),
Self::Device(d) => d.open(),
Self::Device(d) => d.open(vp),
}
}
}
Expand Down Expand Up @@ -102,13 +105,13 @@ pub enum VDev {
}

impl VDev {
pub fn open(&self) -> Result<Box<dyn VFileOps>, FsError> {
pub fn open(&self, vp: &Arc<VProc>) -> Result<Box<dyn VFileOps>, FsError> {
let ops: Box<dyn VFileOps> = match self {
Self::Console => Box::new(Console::new()),
Self::Dipsw => Box::new(Dipsw::new()),
Self::DeciTty6 => Box::new(DeciTty6::new()),
Self::Dmem0 => Box::new(Dmem0::new()),
Self::Dmem1 => Box::new(Dmem1::new()),
Self::Dmem1 => Box::new(Dmem1::new(vp)),
Self::Dmem2 => Box::new(Dmem2::new()),
};

Expand Down
2 changes: 1 addition & 1 deletion src/kernel/src/fs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ impl Fs {
};

*file.flags_mut() = flags.to_fflags();
file.set_ops(Some(self.namei(&mut nd)?.open()?));
file.set_ops(Some(self.namei(&mut nd)?.open(&self.vp)?));

// Install to descriptor table.
let fd = self.vp.files().alloc(Arc::new(file));
Expand Down
8 changes: 8 additions & 0 deletions src/kernel/src/process/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,8 @@ impl VProc {
let name: Option<&str> = unsafe { i.args[1].to_str(32) }?;

if tid == -1 {
info!("Setting process name to '{}'.", name.unwrap_or("NULL"));

self.set_name(name);
} else {
let threads = self.threads.read();
Expand All @@ -431,6 +433,12 @@ impl VProc {
.find(|t| t.id().get() == tid)
.ok_or(SysErr::Raw(ESRCH))?;

info!(
"Setting name of thread {} to '{}'.",
thr.id(),
name.unwrap_or("NULL")
);

thr.set_name(name);
}

Expand Down
4 changes: 4 additions & 0 deletions src/kernel/src/regmgr/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ impl RegKey {
pub const NET_WIFI_FREQ_BAND: Self = Self(0x141E0500);
pub const NP_DEBUG: Self = Self(0x19810000);
pub const BROWSER_DEBUG_NOTIFICATION: Self = Self(0x3CC80700);
pub const MORPHEUS_DEBUG_VR_CAPTURE: Self = Self(0x58800C00);
pub const DEVENV_TOOL_BOOT_PARAM: Self = Self(0x78020300);
pub const DEVENV_TOOL_TRC_NOTIFY: Self = Self(0x78026400);
pub const DEVENV_TOOL_USE_DEFAULT_LIB: Self = Self(0x78028300);
Expand Down Expand Up @@ -135,6 +136,9 @@ impl Display for RegKey {
Self::BROWSER_DEBUG_NOTIFICATION => {
f.write_str("SCE_REGMGR_ENT_KEY_BROWSER_DEBUG_notification")
}
Self::MORPHEUS_DEBUG_VR_CAPTURE => {
f.write_str("SCE_REGMGR_ENT_KEY_MORPHEUS_DEBUG_vr_capture")
}
Self::DEVENV_TOOL_BOOT_PARAM => {
f.write_str("SCE_REGMGR_ENT_KEY_DEVENV_TOOL_boot_param")
}
Expand Down
2 changes: 1 addition & 1 deletion src/kernel/src/sysctl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ impl Sysctl {
) -> Result<(), SysErr> {
//TODO write RuntimeLinker flags if unknown_function() = true

req.write(&(0u32).to_le_bytes())?;
req.write(&(0u32).to_ne_bytes())?;
Ok(())
}

Expand Down
29 changes: 24 additions & 5 deletions src/kernel/src/ucred/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
pub struct AuthInfo {
pub paid: AuthPaid,
pub caps: AuthCaps,
pub attrs: [u64; 4],
pub attrs: AuthAttrs,
pub unk: [u8; 0x40],
}

Expand All @@ -17,12 +17,12 @@ impl AuthInfo {
0x0000000000000000,
0x0000000000000000,
]),
attrs: [
attrs: AuthAttrs([
0x4000400080000000,
0x8000000000000000,
0x0800000000000000,
0xF0000000FFFF4000,
],
]),
unk: [0; 0x40],
};

Expand All @@ -45,12 +45,12 @@ impl AuthInfo {
0x0000000000000000,
0x0000000000000000,
]),
attrs: [
attrs: AuthAttrs([
0x4000400040000000,
0x4000000000000000,
0x0080000000000002,
0xF0000000FFFF4000,
],
]),
unk: [0; 0x40],
})
}
Expand Down Expand Up @@ -90,10 +90,29 @@ impl AuthCaps {
(self.0[0] & 0x4000000000000000) != 0
}

pub fn is_unk1(&self) -> bool {
(self.0[1] & 0x4000000000000000) != 0
}

pub fn clear_non_type(&mut self) {
self.0[0] &= 0x7000000000000000;
self.0[1] = 0;
self.0[2] = 0;
self.0[3] = 0;
}
}

/// A wrapper type for `caps` field of [`AuthAttrs`].
#[repr(transparent)]
#[derive(Debug, Clone)]
pub struct AuthAttrs([u64; 4]);

impl AuthAttrs {
pub fn is_unk1(&self) -> bool {
(self.0[0] & 0x800000) != 0
}

pub fn is_unk2(&self) -> bool {
(self.0[0] & 0x400000) != 0
}
}
8 changes: 8 additions & 0 deletions src/kernel/src/ucred/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ impl Ucred {
self.auth.caps.is_system()
}

pub fn is_unk1(&self) -> bool {
self.auth.caps.is_unk1() && self.auth.attrs.is_unk1()
}

pub fn is_unk2(&self) -> bool {
self.auth.caps.is_unk1() && self.auth.attrs.is_unk2()
}

/// See `priv_check_cred` on the PS4 for a reference.
pub fn priv_check(&self, p: Privilege) -> Result<(), PrivilegeError> {
// TODO: Check suser_enabled.
Expand Down

0 comments on commit 0060571

Please sign in to comment.