diff --git a/src/kernel/src/budget/mod.rs b/src/kernel/src/budget/mod.rs index 449f17fb4..c4ad31bf2 100644 --- a/src/kernel/src/budget/mod.rs +++ b/src/kernel/src/budget/mod.rs @@ -82,21 +82,18 @@ pub enum BudgetType { FdIpcSocket = 11, } -#[allow(dead_code)] #[repr(C)] #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ProcType { - BigApp, - MiniApp, - System, // TODO: Verify this. + BigApp = 0, + #[allow(unused)] + MiniApp = 1, + #[allow(unused)] + System = 2, // TODO: Verify this. } impl Into for ProcType { fn into(self) -> u32 { - match self { - ProcType::BigApp => 0, - ProcType::MiniApp => 1, - ProcType::System => 2, - } + self as u32 } } diff --git a/src/kernel/src/dev/dipsw.rs b/src/kernel/src/dev/dipsw.rs index 59beec616..ee8c604ca 100644 --- a/src/kernel/src/dev/dipsw.rs +++ b/src/kernel/src/dev/dipsw.rs @@ -31,13 +31,13 @@ impl DeviceDriver for Dipsw { let td = td.unwrap(); if !td.cred().is_system() { - todo!() - } else { match cmd { // TODO: properly implement this IoCmd::DIPSWCHECK2(val) => *val = false as i32, _ => todo!(), } + } else { + todo!() } Ok(()) diff --git a/src/kernel/src/dev/rng.rs b/src/kernel/src/dev/rng.rs index 14bf1927a..f12a10782 100644 --- a/src/kernel/src/dev/rng.rs +++ b/src/kernel/src/dev/rng.rs @@ -16,8 +16,8 @@ impl DeviceDriver for Rng { _: Option<&VThread>, ) -> Result<(), Box> { match cmd { - IoCmd::RNG1 => todo!(), - IoCmd::RNG2 => todo!(), + IoCmd::RNGGETGENUINE(_) => todo!(), + IoCmd::RNGFIPS(_) => todo!(), _ => todo!(), // ENOIOCTL, } } diff --git a/src/kernel/src/dev/ttyconsole.rs b/src/kernel/src/dev/ttyconsole.rs index b0ecb0317..97f2f2f30 100644 --- a/src/kernel/src/dev/ttyconsole.rs +++ b/src/kernel/src/dev/ttyconsole.rs @@ -87,12 +87,11 @@ impl Tty { } /// See `tty_ioctl` on the PS4 for a reference. - fn generic_ioctl(&self, cmd: IoCmd, td: Option<&VThread>) -> Result<(), TtyIoctlError> { + fn generic_ioctl(&self, cmd: IoCmd, _td: Option<&VThread>) -> Result<(), TtyIoctlError> { // TODO: implement ttydevsw_ioctl match cmd { - // TODO: implement this properly - IoCmd::TIOCSCTTY => return Ok(()), + IoCmd::TIOCSCTTY => todo!(), _ => todo!(), } } diff --git a/src/kernel/src/dmem/mod.rs b/src/kernel/src/dmem/mod.rs index b26afc621..aa45bbc81 100644 --- a/src/kernel/src/dmem/mod.rs +++ b/src/kernel/src/dmem/mod.rs @@ -1,7 +1,8 @@ use crate::dev::{Dmem, DmemContainer}; use crate::errno::EINVAL; use crate::fs::{ - make_dev, CharacterDevice, DriverFlags, Fs, MakeDevError, MakeDevFlags, Mode, VFile, VFileType, + make_dev, CharacterDevice, DriverFlags, Fs, MakeDevError, MakeDevFlags, Mode, VFile, + VFileFlags, VFileType, }; use crate::info; use crate::process::VThread; @@ -116,6 +117,8 @@ impl DmemManager { let dmem_container = td.proc().dmem_container_mut(); let current_container = *dmem_container; + info!("Getting dmem container"); + if dmem_id != -1 { todo!() } @@ -132,10 +135,14 @@ impl DmemManager { let bp = BlockPool::new(); + let flags = VFileFlags::from_bits_retain(flags) | VFileFlags::WRITE; + let fd = td .proc() .files() - .alloc(Arc::new(VFile::new(VFileType::Blockpool(bp)))); + .alloc(Arc::new(VFile::new(VFileType::Blockpool(bp), flags))); + + info!("Opened a blockpool at fd = {fd}"); Ok(fd.into()) } diff --git a/src/kernel/src/fs/dev/vnode.rs b/src/kernel/src/fs/dev/vnode.rs index ce0748469..57fc171ff 100644 --- a/src/kernel/src/fs/dev/vnode.rs +++ b/src/kernel/src/fs/dev/vnode.rs @@ -169,8 +169,7 @@ impl crate::fs::VnodeBackend for VnodeBackend { } fn revoke(&self, vn: &Arc, _flags: RevokeFlags) -> Result<(), Box> { - // TODO: Implement this. - Ok(()) + todo!() } fn read( diff --git a/src/kernel/src/fs/file.rs b/src/kernel/src/fs/file.rs index 60c4f4098..11c1ae75b 100644 --- a/src/kernel/src/fs/file.rs +++ b/src/kernel/src/fs/file.rs @@ -24,12 +24,12 @@ pub struct VFile { } impl VFile { - pub fn new(ty: VFileType) -> Self { + pub fn new(ty: VFileType, flags: VFileFlags) -> Self { let gg = GutexGroup::new(); Self { ty, - flags: VFileFlags::empty(), + flags, offset: gg.spawn(0), } } @@ -38,10 +38,6 @@ impl VFile { self.flags } - pub fn flags_mut(&mut self) -> &mut VFileFlags { - &mut self.flags - } - /// Checking if this returns `Some` is equivalent to when FreeBSD and the PS4 check /// fp->f_ops->fo_flags & DFLAG_SEEKABLE != 0, therefore we use this instead. pub fn seekable_vnode(&self) -> Option<&Arc> { diff --git a/src/kernel/src/fs/ioctl.rs b/src/kernel/src/fs/ioctl.rs index 57fd72b71..60587ac9c 100644 --- a/src/kernel/src/fs/ioctl.rs +++ b/src/kernel/src/fs/ioctl.rs @@ -93,6 +93,9 @@ commands! { /// sceKernelMemoryPoolGetBlockStats BPOOLSTATS(&mut BlockpoolStats) = 0x4010A802, + /// An unkown bnet command, called from libSceNet + BNETUNK(&Unknown36) = 0x802450c9, + /// Get media size in bytes. DIOCGMEDIASIZE(&mut i64) = 0x40086418, @@ -147,10 +150,10 @@ commands! { /// Seek hole. FIOSEEKHOLE(&mut i64) = 0xC0086662, - /// Unkown rng command - RNG1 = 0x40445301, - /// Unkown rng command - RNG2 = 0x40445302, + /// Get genuine random + RNGGETGENUINE(&mut Unknown68) = 0x40445301, + /// Fips186Prng + RNGFIPS(&mut Unknown68) = 0x40445302, /// Become controlling terminal. TIOCSCTTY = 0x20007461, @@ -160,6 +163,8 @@ commands! { type Unknown2 = Unknown<2>; type Unknown8 = Unknown<8>; type Unknown16 = Unknown<16>; +type Unknown36 = Unknown<36>; +type Unknown68 = Unknown<68>; /// A dummy type to be used as a placeholder for unknown data. #[derive(Debug)] diff --git a/src/kernel/src/fs/mod.rs b/src/kernel/src/fs/mod.rs index a2534722e..c38cadd09 100644 --- a/src/kernel/src/fs/mod.rs +++ b/src/kernel/src/fs/mod.rs @@ -170,7 +170,12 @@ impl Fs { self.root.read().clone() } - pub fn open(&self, path: impl AsRef, td: Option<&VThread>) -> Result { + pub fn open( + &self, + path: impl AsRef, + flags: VFileFlags, + td: Option<&VThread>, + ) -> Result { let vnode = self .lookup(path, true, td) .map_err(OpenError::LookupFailed)?; @@ -181,7 +186,7 @@ impl Fs { VFileType::Vnode(vnode.clone()) }; - Ok(VFile::new(ty)) + Ok(VFile::new(ty, flags)) } pub fn lookup( @@ -389,7 +394,6 @@ impl Fs { // Get arguments. let path = unsafe { i.args[0].to_path()?.unwrap() }; let flags: OpenFlags = i.args[1].try_into().unwrap(); - let mode: u32 = i.args[2].try_into().unwrap(); // Check flags. if flags.intersects(OpenFlags::O_EXEC) { @@ -409,16 +413,17 @@ impl Fs { todo!("open({path}) with flags & O_EXLOCK"); } else if flags.intersects(OpenFlags::O_TRUNC) { todo!("open({path}) with flags & O_TRUNC"); - } else if mode != 0 { - todo!("open({path}, {flags}) with mode = {mode}"); + } else { + let mode: u32 = i.args[2].try_into().unwrap(); + if mode != 0 { + todo!("open({path}, {flags}) with mode = {mode}"); + } } info!("Opening {path} with flags = {flags}."); // Lookup file. - let mut file = self.open(path, Some(td))?; - - *file.flags_mut() = flags.into_fflags(); + let mut file = self.open(path, flags.into_fflags(), Some(td))?; // Install to descriptor table. let fd = td.proc().files().alloc(Arc::new(file)); diff --git a/src/kernel/src/kqueue/mod.rs b/src/kernel/src/kqueue/mod.rs index 72ce736d5..9c1043571 100644 --- a/src/kernel/src/kqueue/mod.rs +++ b/src/kernel/src/kqueue/mod.rs @@ -38,9 +38,11 @@ impl KernelQueueManager { filedesc.insert_kqueue(kq.clone()); - Ok(VFileType::KernelQueue(kq)) + Ok(VFile::new( + VFileType::KernelQueue(kq), + VFileFlags::READ | VFileFlags::WRITE, + )) }, - VFileFlags::READ | VFileFlags::WRITE, BudgetType::FdEqueue, )?; diff --git a/src/kernel/src/net/mod.rs b/src/kernel/src/net/mod.rs index 6d6203849..c1602025b 100644 --- a/src/kernel/src/net/mod.rs +++ b/src/kernel/src/net/mod.rs @@ -1,7 +1,7 @@ use crate::budget::BudgetType; use crate::errno::{Errno, EFAULT, EINVAL}; -use crate::fs::{IoVec, VFileFlags, VFileType}; -use crate::info; +use crate::fs::{IoVec, VFile, VFileFlags, VFileType}; +use crate::{arnd, info}; use crate::{ process::VThread, syscalls::{SysErr, SysIn, SysOut, Syscalls}, @@ -30,6 +30,7 @@ impl NetManager { sys.register(28, &net, Self::sys_sendmsg); sys.register(29, &net, Self::sys_recvfrom); sys.register(97, &net, Self::sys_socket); + sys.register(99, &net, Self::sys_netcontrol); sys.register(105, &net, Self::sys_setsockopt); sys.register(113, &net, Self::sys_socketex); sys.register(114, &net, Self::sys_socketclose); @@ -77,6 +78,58 @@ impl NetManager { todo!() } + fn sys_netcontrol(self: &Arc, td: &VThread, i: &SysIn) -> Result { + let fd: i32 = i.args[0].try_into().unwrap(); + let op: i32 = i.args[1].try_into().unwrap(); + let ptr: *mut u8 = i.args[2].into(); + let buflen: u32 = i.args[3].try_into().unwrap(); + + info!("Netcontrol called with op = {op}."); + + let mut buf = if ptr.is_null() { + None + } else { + if buflen > 160 { + return Err(SysErr::Raw(EINVAL)); + } + + let buf = Box::new([0u8; 160]); + + if op & 0x30000000 != 0 { + // TODO: copyin + todo!() + } + + Some(buf) + }; + + let _ = if fd < 0 { + } else { + todo!() + }; + + match buf.as_mut() { + Some(buf) => match op { + // bnet_get_secure_seed + 0x14 if buflen > 3 => arnd::rand_bytes(&mut buf[..4]), + _ => todo!("netcontrol with op = {op}"), + }, + None => todo!("netcontrol with buf = null"), + } + + if fd > -1 { + todo!() + } + + if let Some(buf) = buf { + if op & 0x30000000 != 0x20000000 { + unsafe { std::ptr::copy_nonoverlapping(buf.as_ptr(), ptr, buflen as usize) }; + } + } + + Ok(SysOut::ZERO) + } + fn sys_setsockopt(self: &Arc, td: &VThread, i: &SysIn) -> Result { let fd: i32 = i.args[0].try_into().unwrap(); let level: i32 = i.args[1].try_into().unwrap(); @@ -110,12 +163,13 @@ impl NetManager { VFileType::Socket(so) }; - Ok(ty) + Ok(VFile::new(ty, VFileFlags::READ | VFileFlags::WRITE)) }, - VFileFlags::WRITE | VFileFlags::READ, budget, )?; + info!("Opened a socket at fd {fd}."); + Ok(fd.into()) } @@ -153,12 +207,17 @@ impl NetManager { VFileType::Socket(so) }; - Ok(ty) + Ok(VFile::new(ty, VFileFlags::READ | VFileFlags::WRITE)) }, - VFileFlags::WRITE | VFileFlags::READ, budget, )?; + if let Some(name) = name { + info!("Opened a socket with name = {name} at fd {fd}."); + } else { + info!("Opened a socket at fd {fd}."); + } + Ok(fd.into()) } diff --git a/src/kernel/src/process/filedesc.rs b/src/kernel/src/process/filedesc.rs index d57675529..184fbd613 100644 --- a/src/kernel/src/process/filedesc.rs +++ b/src/kernel/src/process/filedesc.rs @@ -1,6 +1,6 @@ use crate::budget::BudgetType; use crate::errno::{Errno, EBADF}; -use crate::fs::{VFile, VFileFlags, VFileType, Vnode}; +use crate::fs::{VFile, VFileFlags, Vnode}; use crate::kqueue::KernelQueue; use gmtx::{Gutex, GutexGroup}; use macros::Errno; @@ -55,20 +55,40 @@ impl FileDesc { #[allow(unused_variables)] // TODO: remove when implementing; add budget argument pub fn alloc_with_budget( &self, - constructor: impl FnOnce(i32) -> Result, - flags: VFileFlags, - budget: BudgetType, + constructor: impl FnOnce(i32) -> Result, + _budget: BudgetType, ) -> Result> { - todo!() + // TODO: check budget + + self.alloc_without_budget(constructor) } #[allow(unused_variables)] // TODO: remove when implementing; pub fn alloc_without_budget( &self, - constructor: impl FnOnce(i32) -> Result, - flags: VFileFlags, + constructor: impl FnOnce(i32) -> Result, ) -> Result> { - todo!() + // TODO: Implement fdalloc. + let mut files = self.files.write(); + + for i in 0..=(i32::MAX) as usize { + if i == files.len() { + let file = constructor(i as i32).map_err(FileAllocError::Inner)?; + + files.push(Some(Arc::new(file))); + } else if files[i].is_none() { + let file = constructor(i as i32).map_err(FileAllocError::Inner)?; + + files[i] = Some(Arc::new(file)); + } else { + continue; + } + + return Ok(i as i32); + } + + // This should never happen. + panic!("Too many files has been opened."); } /// See `finstall` on the PS4 for a reference. diff --git a/src/kernel/src/process/proc.rs b/src/kernel/src/process/proc.rs index e10fea634..56cbbf3a6 100644 --- a/src/kernel/src/process/proc.rs +++ b/src/kernel/src/process/proc.rs @@ -8,6 +8,7 @@ use crate::errno::Errno; use crate::errno::{EINVAL, ERANGE, ESRCH}; use crate::fs::Vnode; use crate::idt::Idt; +use crate::info; use crate::signal::{SignalSet, SIGKILL, SIGSTOP, SIG_BLOCK, SIG_SETMASK, SIG_UNBLOCK}; use crate::syscalls::{SysErr, SysIn, SysOut, Syscalls}; use crate::sysent::ProcAbi; @@ -482,6 +483,8 @@ impl VProc { fn sys_get_proc_type_info(self: &Arc, td: &VThread, i: &SysIn) -> Result { let info = unsafe { &mut *Into::<*mut ProcTypeInfo>::into(i.args[0]) }; + info!("Getting process type information."); + if info.len != size_of::() { return Err(SysErr::Raw(EINVAL)); } diff --git a/src/kernel/src/rtld/mod.rs b/src/kernel/src/rtld/mod.rs index 26c559117..c4b9bb0fd 100644 --- a/src/kernel/src/rtld/mod.rs +++ b/src/kernel/src/rtld/mod.rs @@ -4,6 +4,7 @@ use self::resolver::{ResolveFlags, SymbolResolver}; use crate::budget::ProcType; use crate::ee::native::{NativeEngine, SetupModuleError}; use crate::errno::{Errno, EINVAL, ENOENT, ENOEXEC, ENOMEM, EPERM, ESRCH}; +use crate::fs::VFileFlags; use crate::fs::{Fs, OpenError, VPath, VPathBuf}; use crate::idt::Entry; use crate::imgact::orbis::{DynamicFlags, Elf, FileType, ReadProgramError, Relocation, Symbol}; @@ -91,7 +92,7 @@ impl RuntimeLinker { let path = path.as_ref(); let file = self .fs - .open(path, Some(td)) + .open(path, VFileFlags::READ, Some(td)) .map_err(ExecError::OpenExeFailed)?; let elf = Elf::open(path.as_str(), file).map_err(ExecError::ReadExeFailed)?; @@ -209,7 +210,7 @@ impl RuntimeLinker { } // Get file. - let file = match self.fs.open(path, Some(td)) { + let file = match self.fs.open(path, VFileFlags::READ, Some(td)) { Ok(v) => v, Err(e) => return Err(LoadError::OpenFileFailed(e)), }; diff --git a/src/kernel/src/shm/mod.rs b/src/kernel/src/shm/mod.rs index e0df17d4e..0b9f58415 100644 --- a/src/kernel/src/shm/mod.rs +++ b/src/kernel/src/shm/mod.rs @@ -49,17 +49,14 @@ impl SharedMemoryManager { #[allow(unused_variables)] // TODO: remove when implementing. let mode = mode & filedesc.cmask() & 0o7777; - let fd = filedesc.alloc_without_budget::( - |_| match path { - ShmPath::Anon => { - todo!() - } - ShmPath::Path(_) => { - todo!() - } - }, - (flags & OpenFlags::O_ACCMODE).into_fflags(), - )?; + let fd = filedesc.alloc_without_budget::(|_| match path { + ShmPath::Anon => { + todo!() + } + ShmPath::Path(_) => { + todo!() + } + })?; Ok(fd.into()) }