1pub use self::arch::*;
2pub use self::dipsw::*;
3
4use alloc::boxed::Box;
5use alloc::sync::Arc;
6use alloc::vec::Vec;
7use config::{ConsoleId, ProductId, QaFlags};
8use core::num::NonZero;
9use krt::warn;
10use macros::elf_note;
11
12#[cfg_attr(target_arch = "aarch64", path = "aarch64.rs")]
13#[cfg_attr(target_arch = "x86_64", path = "x86_64.rs")]
14mod arch;
15mod dipsw;
16
17pub const PAGE_SIZE: NonZero<usize> = NonZero::new(1 << PAGE_SHIFT).unwrap();
18pub const PAGE_MASK: NonZero<usize> = NonZero::new(PAGE_SIZE.get() - 1).unwrap();
19
20pub struct Config {
22 max_cpu: NonZero<usize>,
23 unknown_dmem1: u8, idps: &'static ConsoleId,
25 qa: bool,
26 qa_flags: &'static QaFlags,
27 env_vars: Box<[&'static str]>, }
29
30impl Config {
31 pub fn new(src: &'static ::config::Config) -> Arc<Self> {
32 let env_vars = Self::load_env(src);
33
34 Arc::new(Self {
35 max_cpu: src.max_cpu,
36 unknown_dmem1: 0,
37 idps: &src.idps,
38 qa: src.qa,
39 qa_flags: &src.qa_flags,
40 env_vars,
41 })
42 }
43
44 pub fn max_cpu(&self) -> NonZero<usize> {
45 self.max_cpu
46 }
47
48 pub fn unknown_dmem1(&self) -> u8 {
49 self.unknown_dmem1
50 }
51
52 pub fn idps(&self) -> &'static ConsoleId {
53 self.idps
54 }
55
56 pub fn env(&self, name: &str) -> Option<&'static str> {
63 for &v in &self.env_vars {
64 let v = match v.strip_prefix(name) {
66 Some(v) => v,
67 None => continue,
68 };
69
70 let mut iter = v.chars();
72
73 if iter.next().is_some_and(|c| c == '=') {
74 return Some(iter.as_str());
75 }
76 }
77
78 None
79 }
80
81 pub fn is_allow_disabling_aslr(&self) -> bool {
88 self.qa && self.qa_flags.internal_dev()
89 }
90
91 pub fn is_devkit(&self) -> bool {
98 self.idps.product == ProductId::DEVKIT
99 }
100
101 pub fn is_testkit(&self) -> bool {
108 self.idps.product == ProductId::TESTKIT
109 }
110
111 pub fn dipsw(&self, _: Dipsw) -> bool {
118 if !self.is_testkit() {
119 if !self.is_devkit() {
120 return false;
121 }
122 } else {
123 todo!()
124 }
125
126 todo!()
127 }
128
129 fn load_env(config: &'static ::config::Config) -> Box<[&'static str]> {
136 let mut list = Vec::with_capacity(0x1000);
139 let mut rem = config.env_vars.as_slice();
140 let mut n = -1;
141
142 while !rem.is_empty() {
143 let v = match rem.iter().position(|&b| b == 0) {
146 Some(i) => {
147 let v = &rem[..i];
148 rem = &rem[(i + 1)..];
149 v
150 }
151 None => core::mem::replace(&mut rem, b""),
152 };
153
154 if v.is_empty() {
157 break;
158 }
159
160 n += 1;
161
162 let v = match core::str::from_utf8(v) {
164 Ok(v) => v,
165 Err(_) => {
166 warn!("Ignoring non-UTF-8 kenv string #{n}.");
167 continue;
168 }
169 };
170
171 if (v.len() + 1) >= 259 {
172 warn!("Too long kenv string, ignoring {v}.");
173 continue;
174 } else if list.len() > 511 {
175 warn!("Too many kenv strings, ignoring {v}.");
176 continue;
177 }
178
179 list.push(v);
180 }
181
182 list.into_boxed_slice()
183 }
184}
185
186#[elf_note(section = ".note.obkrnl.page-size", name = "obkrnl", ty = 0)]
187static NOTE_PAGE_SIZE: [u8; size_of::<usize>()] = PAGE_SIZE.get().to_ne_bytes();