Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implements socket creation, initializes rng, gc and camera devices #819

Merged
merged 10 commits into from
Apr 11, 2024
92 changes: 92 additions & 0 deletions src/kernel/src/dev/camera.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
use crate::{
errno::Errno,
fs::{
make_dev, CharacterDevice, DeviceDriver, DriverFlags, IoCmd, MakeDevError, MakeDevFlags,
Mode, OpenFlags, Uio, UioMut,
},
process::VThread,
ucred::{Gid, Uid},
};
use std::sync::Arc;
use thiserror::Error;

#[derive(Debug)]
struct Camera {}

impl Camera {
fn new() -> Self {
Self {}
}
}

impl DeviceDriver for Camera {
#[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<(), Box<dyn Errno>> {
todo!()
}

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

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

pub struct CameraManager {
camera: Arc<CharacterDevice>,
}

impl CameraManager {
pub fn new() -> Result<Arc<Self>, CameraInitError> {
let camera = make_dev(
Camera::new(),
DriverFlags::from_bits_retain(0x80000004),
0,
"camera",
Uid::ROOT,
Gid::ROOT,
Mode::new(0o666).unwrap(),
None,
MakeDevFlags::MAKEDEV_ETERNAL,
)?;

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

/// Represents an error when [`CameraManager`] fails to initialize.
#[derive(Debug, Error)]
pub enum CameraInitError {
#[error("cannot create camera device")]
CreateGcFailed(#[from] MakeDevError),
}
6 changes: 3 additions & 3 deletions src/kernel/src/dev/dipsw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl DeviceDriver for Dipsw {
if !td.cred().is_system() {
match cmd {
// TODO: properly implement this
IoCmd::DIPSWCHECK2(val) => *val = false as i32,
IoCmd::DIPSWCHECK2(val) | IoCmd::DIPSWUNK(val) => *val = false as i32,
_ => todo!(),
}
} else {
Expand Down Expand Up @@ -66,9 +66,9 @@ impl DipswManager {
}
}

/// Represents an error when [`TtyManager`] fails to initialize.
/// Represents an error when [`DipswManager`] fails to initialize.
#[derive(Debug, Error)]
pub enum DipswInitError {
#[error("cannot create dipsw device")]
CreateConsoleFailed(#[from] MakeDevError),
CreateDipswFailed(#[from] MakeDevError),
}
56 changes: 51 additions & 5 deletions src/kernel/src/dev/gc.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
use crate::{
errno::Errno,
fs::{CharacterDevice, DeviceDriver, IoCmd, OpenFlags},
fs::{
make_dev, CharacterDevice, DeviceDriver, DriverFlags, IoCmd, MakeDevError, MakeDevFlags,
Mode, OpenFlags,
},
process::VThread,
ucred::{Gid, Uid},
};
use std::sync::Arc;
use thiserror::Error;

#[derive(Debug)]
struct Gc {}

impl Gc {
fn new() -> Self {
Self {}
}
}

impl DeviceDriver for Gc {
#[allow(unused_variables)] // TODO: remove when implementing
fn open(
Expand All @@ -20,13 +31,48 @@ impl DeviceDriver for Gc {
todo!()
}

#[allow(unused_variables)] // TODO: remove when implementing
fn ioctl(
&self,
dev: &Arc<CharacterDevice>,
_: &Arc<CharacterDevice>,
cmd: IoCmd,
td: Option<&VThread>,
_: Option<&VThread>,
) -> Result<(), Box<dyn Errno>> {
todo!()
match cmd {
IoCmd::GC12(_) => todo!("GC12 ioctl"),
IoCmd::GC16(_) => todo!("GC16 ioctl"),
IoCmd::GC25(_) => todo!("GC25 ioctl"),
IoCmd::GC27(_) => todo!("GC27 ioctl"),
IoCmd::GC31(_) => todo!("GC31 ioctl"),
_ => todo!(),
}
}
}

pub struct GcManager {
gc: Arc<CharacterDevice>,
}

impl GcManager {
pub fn new() -> Result<Arc<Self>, GcInitError> {
let gc = make_dev(
Gc::new(),
DriverFlags::from_bits_retain(0x80000004),
0,
"gc",
Uid::ROOT,
Gid::ROOT,
Mode::new(0o666).unwrap(),
None,
MakeDevFlags::MAKEDEV_ETERNAL,
)?;

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

/// Represents an error when [`GcManager`] fails to initialize.
#[derive(Debug, Error)]
pub enum GcInitError {
#[error("cannot create gc device")]
CreateGcFailed(#[from] MakeDevError),
}
2 changes: 2 additions & 0 deletions src/kernel/src/dev/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub use camera::*;
pub use deci::*;
pub use dipsw::*;
pub use dmem::*;
Expand All @@ -8,6 +9,7 @@ pub use rng::*;
pub use sbl_srv::*;
pub use ttyconsole::*;

mod camera;
mod deci;
mod dipsw;
mod dmem;
Expand Down
64 changes: 60 additions & 4 deletions src/kernel/src/dev/rng.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,80 @@
use crate::{
arnd,
errno::Errno,
fs::{CharacterDevice, DeviceDriver, IoCmd},
fs::{
make_dev, CharacterDevice, DeviceDriver, DriverFlags, IoCmd, MakeDevError, MakeDevFlags,
Mode,
},
process::VThread,
ucred::{Gid, Uid},
};
use std::sync::Arc;
use thiserror::Error;

#[derive(Debug)]
struct Rng {}

impl Rng {
fn new() -> Self {
Self {}
}
}

impl DeviceDriver for Rng {
fn ioctl(
&self,
dev: &Arc<CharacterDevice>,
_: &Arc<CharacterDevice>,
cmd: IoCmd,
_: Option<&VThread>,
) -> Result<(), Box<dyn Errno>> {
match cmd {
IoCmd::RNGGETGENUINE(_) => todo!(),
IoCmd::RNGFIPS(_) => todo!(),
// TODO: these are separate algorithms, and should be implemented as such,
// however arc4rand seems sufficient for now
IoCmd::RNGGETGENUINE(input) | IoCmd::RNGFIPS(input) => {
input.error = 0;

arnd::rand_bytes(&mut input.data);

Ok(())
}
_ => todo!(), // ENOIOCTL,
}
}
}

#[repr(C)]
#[derive(Debug)]
pub struct RngInput {
/// This field seems to be treated as an error
error: i32,
data: [u8; 64],
}

pub struct RngManager {
dipsw: Arc<CharacterDevice>,
}

impl RngManager {
pub fn new() -> Result<Arc<Self>, RngInitError> {
let rng = make_dev(
Rng::new(),
DriverFlags::from_bits_retain(0x80000004),
0,
"rng",
Uid::ROOT,
Gid::ROOT,
Mode::new(0o444).unwrap(),
None,
MakeDevFlags::MAKEDEV_ETERNAL,
)?;

Ok(Arc::new(Self { dipsw: rng }))
}
}

/// Represents an error when [`RngManager`] fails to initialize.
#[derive(Debug, Error)]
pub enum RngInitError {
#[error("cannot create rng device")]
CreateRngFailed(#[from] MakeDevError),
}
2 changes: 1 addition & 1 deletion src/kernel/src/fs/dev/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ impl Devices {
/// Represents an error when [`make_dev()`] is failed.
#[derive(Debug, Error, Errno)]
pub enum MakeDevError {
#[error("the device with the same name already exist")]
#[error("the device with the same name already exists")]
#[errno(EEXIST)]
AlreadyExist(String),
}
Expand Down
32 changes: 28 additions & 4 deletions src/kernel/src/fs/ioctl.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::FioDeviceGetNameArg;
use crate::dev::{DmemAllocate, DmemAvailable, DmemQuery, PrtAperture};
use crate::dev::{DmemAllocate, DmemAvailable, DmemQuery, PrtAperture, RngInput};
use crate::dmem::{BlockpoolExpandArgs, BlockpoolStats};
use crate::errno::ENOTTY;
use crate::syscalls::SysErr;
Expand Down Expand Up @@ -113,6 +113,8 @@ commands! {
DIPSWWRITE(&Unknown16) = 0x80108805,
/// sceKernelCheckDipsw
DIPSWCHECK2(&mut i32) = 0x40048806,
/// Unkown dipsw command
DIPSWUNK(&mut i32) = 0x40048807,

/// Get total size?
DMEMTOTAL(&mut usize) = 0x4008800a,
Expand Down Expand Up @@ -145,15 +147,36 @@ commands! {
FIOGETLBA(&mut i32) = 0x40046679,
/// Get dev. name
FIODGNAME(&FioDeviceGetNameArg) = 0x80106678,
/// Get # bytes (yet) to write
FIONWRITE(&mut i32) = 0x40046677,
/// Get space in send queue
FIONSPACE(&mut i32) = 0x40046676,
/// Seek data.
FIOSEEKDATA(&mut i64) = 0xC0086661,
/// Seek hole.
FIOSEEKHOLE(&mut i64) = 0xC0086662,

GC12(&mut Unknown16) = 0xc010810b,
/// Currently unknown gc command
GC16(&mut Unknown12) = 0xc00c8110,
/// Currently unknown gc command
GC25(&mut Unknown132) = 0xc0848119,
/// Currently unknown gc command
GC27(&mut Unknown8) = 0xc008811b,
/// Currently unknown gc command
GC31(&mut i32) = 0xc004811f,

/// Get genuine random
RNGGETGENUINE(&mut Unknown68) = 0x40445301,
RNGGETGENUINE(&mut RngInput) = 0x40445301,
/// Fips186Prng
RNGFIPS(&mut Unknown68) = 0x40445302,
RNGFIPS(&mut RngInput) = 0x40445302,

/// Cat oob mark?
SIOCATMARK(&mut i32) = 0x40047307,
/// Set process group
SIOCSPGRP(&i32) = 0x80047308,
/// Get process group
SIOCGPGRP(&mut i32) = 0x40047309,

/// Become controlling terminal.
TIOCSCTTY = 0x20007461,
Expand All @@ -162,9 +185,10 @@ commands! {

type Unknown2 = Unknown<2>;
type Unknown8 = Unknown<8>;
type Unknown12 = Unknown<12>;
type Unknown16 = Unknown<16>;
type Unknown36 = Unknown<36>;
type Unknown68 = Unknown<68>;
type Unknown132 = Unknown<132>;

/// A dummy type to be used as a placeholder for unknown data.
#[derive(Debug)]
Expand Down
Loading