obkrnl/config/
mod.rs

1pub use self::dipsw::*;
2pub use self::param1::*;
3
4use alloc::boxed::Box;
5use alloc::sync::Arc;
6use config::{ConsoleId, ProductId, QaFlags};
7use core::num::NonZero;
8use macros::elf_note;
9
10mod dipsw;
11mod param1;
12
13pub const PAGE_SHIFT: usize = 14; // 16K
14pub const PAGE_SIZE: NonZero<usize> = NonZero::new(1 << PAGE_SHIFT).unwrap();
15pub const PAGE_MASK: NonZero<usize> = NonZero::new(PAGE_SIZE.get() - 1).unwrap();
16
17/// Runtime configurations for the kernel populated from [`config::Config`].
18pub struct Config {
19    max_cpu: NonZero<usize>,
20    unknown_dmem1: u8, // TODO: Figure out a correct name.
21    idps: &'static ConsoleId,
22    qa: bool,
23    qa_flags: &'static QaFlags,
24    env_vars: Box<[(&'static str, &'static str)]>, // kenvp
25}
26
27impl Config {
28    pub fn new(src: &'static ::config::Config) -> Arc<Self> {
29        let env_vars = Self::load_env(src);
30
31        Arc::new(Self {
32            max_cpu: src.max_cpu,
33            unknown_dmem1: 0,
34            idps: &src.idps,
35            qa: src.qa,
36            qa_flags: &src.qa_flags,
37            env_vars,
38        })
39    }
40
41    pub fn max_cpu(&self) -> NonZero<usize> {
42        self.max_cpu
43    }
44
45    pub fn unknown_dmem1(&self) -> u8 {
46        self.unknown_dmem1
47    }
48
49    pub fn idps(&self) -> &'static ConsoleId {
50        self.idps
51    }
52
53    /// See `getenv` on the Orbis for a reference.
54    ///
55    /// # Reference offsets
56    /// | Version | Offset |
57    /// |---------|--------|
58    /// |PS4 11.00|0x39D0A0|
59    pub fn env(&self, name: &str) -> Option<&'static str> {
60        for &(k, v) in &self.env_vars {
61            if k == name {
62                return Some(v);
63            }
64        }
65
66        None
67    }
68
69    /// See `sceSblRcMgrIsAllowDisablingAslr` on the Orbis for a reference.
70    ///
71    /// # Reference offsets
72    /// | Version | Offset |
73    /// |---------|--------|
74    /// |PS4 11.00|0x3CA8F0|
75    pub fn is_allow_disabling_aslr(&self) -> bool {
76        self.qa && self.qa_flags.internal_dev()
77    }
78
79    /// See `sceSblAIMgrIsDevKit` on the Orbis for a reference.
80    ///
81    /// # Reference offsets
82    /// | Version | Offset |
83    /// |---------|--------|
84    /// |PS4 11.00|0x078F50|
85    pub fn is_devkit(&self) -> bool {
86        self.idps.product == ProductId::DEVKIT
87    }
88
89    /// See `sceSblAIMgrIsTestKit` on the Orbis for a reference.
90    ///
91    /// # Reference offsets
92    /// | Version | Offset |
93    /// |---------|--------|
94    /// |PS4 11.00|0x0790A0|
95    pub fn is_testkit(&self) -> bool {
96        self.idps.product == ProductId::TESTKIT
97    }
98
99    /// See `sceKernelCheckDipsw` on the Orbis for a reference.
100    ///
101    /// # Reference offsets
102    /// | Version | Offset |
103    /// |---------|--------|
104    /// |PS4 11.00|0x654D70|
105    pub fn dipsw(&self, _: Dipsw) -> bool {
106        if !self.is_testkit() {
107            if !self.is_devkit() {
108                return false;
109            }
110        } else {
111            todo!()
112        }
113
114        todo!()
115    }
116
117    /// See `init_dynamic_kenv` on the Orbis for a reference.
118    ///
119    /// # Reference offsets
120    /// | Version | Offset |
121    /// |---------|--------|
122    /// |PS4 11.00|0x39DC90|
123    fn load_env(config: &'static ::config::Config) -> Box<[(&'static str, &'static str)]> {
124        config.env().collect()
125    }
126}
127
128#[elf_note(section = ".note.obkrnl.page-size", name = "obkrnl", ty = 0)]
129static NOTE_PAGE_SIZE: [u8; size_of::<usize>()] = PAGE_SIZE.get().to_ne_bytes();