Skip to content

Commit 39ceb71

Browse files
authored
Switches fork1 flags from bitfield to bitflag (#1290)
1 parent ea6b151 commit 39ceb71

File tree

12 files changed

+249
-84
lines changed

12 files changed

+249
-84
lines changed

Cargo.lock

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ members = [
66
"config",
77
"gui",
88
"kernel",
9+
"lib/bitflag",
910
"lib/krt",
1011
"macros",
1112
]

kernel/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ edition = "2024"
55

66
[dependencies]
77
bitfield-struct = "0.9.2"
8+
bitflag = { path = "../lib/bitflag" }
89
config = { path = "../config" }
910
hashbrown = "0.14.5"
1011
krt = { path = "../lib/krt" }

kernel/src/main.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,16 @@ fn init_vm(procs: &Arc<ProcMgr>) -> Arc<Uma> {
9191
Uma::new(vm)
9292
}
9393

94-
/// See `create_init` function on the PS4 for a reference.
94+
/// See `create_init` function on the Orbis for a reference.
95+
///
96+
/// # Reference offsets
97+
/// | Version | Offset |
98+
/// |---------|--------|
99+
/// |PS4 11.00|0x2BEF30|
95100
fn create_init() {
96101
let pmgr = current_procmgr().unwrap();
97102
let abi = Arc::new(Ps4Abi);
98-
let flags = Fork::new().with_copy_fd(true).with_create_process(true);
103+
let flags = Fork::CopyFd | Fork::CreateProcess;
99104

100105
pmgr.fork(abi, flags).unwrap();
101106

kernel/src/proc/mod.rs

+19-35
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ use crate::lock::{MappedMutex, Mutex, MutexGuard};
88
use crate::signal::Signal;
99
use crate::subsystem::Subsystem;
1010
use alloc::sync::{Arc, Weak};
11-
use bitfield_struct::bitfield;
1211
use core::error::Error;
1312
use core::fmt::{Display, Formatter};
1413
use hashbrown::HashMap;
14+
use macros::bitflag;
1515

1616
mod abi;
1717
mod cell;
@@ -48,19 +48,24 @@ impl ProcMgr {
4848
MutexGuard::map(self.procs.lock(), |procs| procs.values())
4949
}
5050

51-
/// We imply `RFSTOPPED` to make [`ProcMgr`] not depend on a scheduler.
51+
/// We imply `RFSTOPPED` to make [`ProcMgr`] not depend on the scheduler.
5252
///
53-
/// See `fork1` on the PS4 for a reference.
53+
/// See `fork1` on the Orbis for a reference.
54+
///
55+
/// # Reference offsets
56+
/// | Version | Offset |
57+
/// |---------|--------|
58+
/// |PS4 11.00|0x14B830|
5459
pub fn fork(&self, abi: Arc<dyn ProcAbi>, flags: Fork) -> Result<Arc<Proc>, ForkError> {
5560
// TODO: Refactor this for readability.
56-
if (flags.into_bits() & 0x60008f8b) != 0
57-
|| flags.copy_fd() && flags.clear_fd()
58-
|| flags.parent_signal().into_bits() != 0 && !flags.custom_signal()
61+
if (u32::from(flags) & 0x60008f8b) != 0
62+
|| flags.has_all(Fork::CopyFd | Fork::ClearFd)
63+
|| flags.has_any(Fork::ParentSignal.mask()) && !flags.has_any(Fork::CustomSignal)
5964
{
6065
return Err(ForkError::InvalidFlags);
6166
}
6267

63-
if !flags.create_process() {
68+
if !flags.has_any(Fork::CreateProcess) {
6469
todo!()
6570
}
6671

@@ -89,52 +94,31 @@ pub struct ProcEvents {
8994
}
9095

9196
/// Flags to control behavior of [`ProcMgr::fork()`].
92-
#[bitfield(u32)]
93-
pub struct Fork {
94-
__: bool,
95-
__: bool,
97+
#[bitflag(u32)]
98+
pub enum Fork {
9699
/// Duplicate file descriptor table to the child instead of sharing it with the parent. Cannot
97100
/// used together with [`Self::clear_fd()`].
98101
///
99102
/// This has the same value as `RFFDG`.
100-
pub copy_fd: bool,
101-
__: bool,
103+
CopyFd = 0x4,
102104
/// Create a child process.
103105
///
104106
/// This has the same value as `RFPROC`.
105-
pub create_process: bool,
106-
__: bool,
107-
__: bool,
108-
__: bool,
109-
__: bool,
110-
__: bool,
111-
__: bool,
112-
__: bool,
107+
CreateProcess = 0x10,
113108
/// Create an empty file descriptor table for the child. Cannot used together with
114109
/// [`Self::copy_fd()`].
115110
///
116111
/// This has the same value as `RFCFDG`.
117-
pub clear_fd: bool,
118-
__: bool,
119-
__: bool,
120-
__: bool,
121-
__: bool,
122-
__: bool,
123-
__: bool,
112+
ClearFd = 0x1000,
124113
/// Enable [`Self::parent_signal()`].
125114
///
126115
/// This has the same value as `RFTSIGZMB`.
127-
pub custom_signal: bool,
116+
CustomSignal = 0x80000,
128117
/// Use this signal instead of `SIGCHLD` to notify the parent. Requires
129118
/// [`Self::custom_signal()`] to be enabled.
130119
///
131120
/// This has the same value produced by `RFTSIGNUM` macro.
132-
#[bits(8)]
133-
pub parent_signal: Signal,
134-
__: bool,
135-
__: bool,
136-
__: bool,
137-
__: bool,
121+
ParentSignal(Signal) = 0xFF00000,
138122
}
139123

140124
/// Represents an error when [`ProcMgr::fork()`] fails.

kernel/src/uma/keg.rs

+16-16
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,21 @@ impl UmaKeg {
3737
align: usize,
3838
mut flags: UmaFlags,
3939
) -> Self {
40-
if flags.has(UmaFlags::Vm) {
40+
if flags.has_any(UmaFlags::Vm) {
4141
todo!()
4242
}
4343

44-
if flags.has(UmaFlags::ZInit) {
44+
if flags.has_any(UmaFlags::ZInit) {
4545
todo!()
4646
}
4747

48-
if flags.has(UmaFlags::Malloc | UmaFlags::RefCnt) {
48+
if flags.has_any(UmaFlags::Malloc | UmaFlags::RefCnt) {
4949
flags |= UmaFlags::VToSlab;
5050
}
5151

5252
// Get header layout.
5353
let hdr = Layout::new::<Slab<()>>();
54-
let (mut hdr, off) = if flags.has(UmaFlags::RefCnt) {
54+
let (mut hdr, off) = if flags.has_any(UmaFlags::RefCnt) {
5555
hdr.extend(Layout::new::<RcFree>()).unwrap()
5656
} else {
5757
hdr.extend(Layout::new::<Free>()).unwrap()
@@ -64,7 +64,7 @@ impl UmaKeg {
6464
let available = PAGE_SIZE.get() - hdr.size();
6565

6666
// Get uk_ppera and uk_ipers.
67-
let (ppera, ipers) = if flags.has(UmaFlags::CacheSpread) {
67+
let (ppera, ipers) = if flags.has_any(UmaFlags::CacheSpread) {
6868
// Round size.
6969
let rsize = if (size.get() & align) == 0 {
7070
size.get()
@@ -93,10 +93,10 @@ impl UmaKeg {
9393
// TODO: Not sure why we need space at least for 2 free item?
9494
if (size.get() + free_item) > available {
9595
// TODO: Set uk_ppera and uk_rsize.
96-
if !flags.has(UmaFlags::Internal) {
96+
if !flags.has_any(UmaFlags::Internal) {
9797
flags |= UmaFlags::Offpage;
9898

99-
if !flags.has(UmaFlags::VToSlab) {
99+
if !flags.has_any(UmaFlags::VToSlab) {
100100
flags |= UmaFlags::Hash;
101101
}
102102
}
@@ -123,7 +123,7 @@ impl UmaKeg {
123123
let ipers = available / (rsize + free_item);
124124

125125
// TODO: Verify if this valid for PAGE_SIZE < 0x4000.
126-
if !flags.has(UmaFlags::Internal | UmaFlags::CacheOnly)
126+
if !flags.has_any(UmaFlags::Internal | UmaFlags::CacheOnly)
127127
&& (available % (rsize + free_item)) >= Uma::MAX_WASTE.get()
128128
&& (PAGE_SIZE.get() / rsize) > ipers
129129
{
@@ -134,8 +134,8 @@ impl UmaKeg {
134134
}
135135
};
136136

137-
if flags.has(UmaFlags::Offpage) {
138-
if flags.has(UmaFlags::RefCnt) {
137+
if flags.has_any(UmaFlags::Offpage) {
138+
if flags.has_any(UmaFlags::RefCnt) {
139139
// TODO: Set uk_slabzone to slabrefzone.
140140
} else {
141141
// TODO: Set uk_slabzone to slabzone.
@@ -150,11 +150,11 @@ impl UmaKeg {
150150
Self::page_alloc
151151
};
152152

153-
if flags.has(UmaFlags::MtxClass) {
153+
if flags.has_any(UmaFlags::MtxClass) {
154154
todo!()
155155
}
156156

157-
if !flags.has(UmaFlags::Offpage) {
157+
if !flags.has_any(UmaFlags::Offpage) {
158158
let space = ppera * PAGE_SIZE.get();
159159
let pgoff = (space - hdr.size()) - ipers * free_item;
160160

@@ -164,7 +164,7 @@ impl UmaKeg {
164164
}
165165
}
166166

167-
if flags.has(UmaFlags::Hash) {
167+
if flags.has_any(UmaFlags::Hash) {
168168
todo!()
169169
}
170170

@@ -207,7 +207,7 @@ impl UmaKeg {
207207
/// |PS4 11.00|0x141E20|
208208
pub fn fetch_slab(&mut self, _: &UmaZone, flags: Alloc) -> Option<()> {
209209
while self.free == 0 {
210-
if flags.has(Alloc::NoVm) {
210+
if flags.has_any(Alloc::NoVm) {
211211
return None;
212212
}
213213

@@ -233,10 +233,10 @@ impl UmaKeg {
233233
/// |---------|--------|
234234
/// |PS4 11.00|0x13FBA0|
235235
fn alloc_slab(&self, flags: Alloc) {
236-
if self.flags.has(UmaFlags::Offpage) {
236+
if self.flags.has_any(UmaFlags::Offpage) {
237237
todo!()
238238
} else {
239-
let flags = if self.flags.has(UmaFlags::Malloc) {
239+
let flags = if self.flags.has_any(UmaFlags::Malloc) {
240240
flags & !Alloc::Zero
241241
} else {
242242
flags | Alloc::Zero

kernel/src/uma/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ impl Uma {
100100
name: impl Into<String>,
101101
size: NonZero<usize>,
102102
align: Option<usize>,
103-
flags: UmaFlags,
103+
flags: impl Into<UmaFlags>,
104104
) -> UmaZone {
105105
// The Orbis will allocate a new zone from masterzone_z. We choose to remove this since it
106106
// does not idomatic to Rust, which mean our uma_zone itself can live on the stack.

kernel/src/uma/zone.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,11 @@ impl UmaZone {
5353
keg: Option<UmaKeg>,
5454
size: NonZero<usize>,
5555
align: Option<usize>,
56-
flags: UmaFlags,
56+
flags: impl Into<UmaFlags>,
5757
) -> Self {
5858
let name = name.into();
59-
let (keg, mut flags) = if flags.has(UmaFlags::Secondary) {
59+
let flags = flags.into();
60+
let (keg, mut flags) = if flags.has_any(UmaFlags::Secondary) {
6061
todo!()
6162
} else {
6263
// We use a different approach here to make it idiomatic to Rust. On Orbis it will
@@ -74,8 +75,8 @@ impl UmaZone {
7475
let mut ty = ZoneType::Other;
7576
let mut count = 0;
7677

77-
if !keg.flags().has(UmaFlags::Internal) {
78-
count = if !keg.flags().has(UmaFlags::MaxBucket) {
78+
if !keg.flags().has_any(UmaFlags::Internal) {
79+
count = if !keg.flags().has_any(UmaFlags::MaxBucket) {
7980
min(keg.item_per_slab(), Uma::BUCKET_MAX)
8081
} else {
8182
Uma::BUCKET_MAX
@@ -148,7 +149,7 @@ impl UmaZone {
148149
/// |---------|--------|
149150
/// |PS4 11.00|0x13E750|
150151
pub fn alloc(&self, flags: Alloc) -> *mut u8 {
151-
if flags.has(Alloc::Wait) {
152+
if flags.has_any(Alloc::Wait) {
152153
// TODO: The Orbis also modify td_pflags on a certain condition.
153154
let td = current_thread();
154155

@@ -210,7 +211,7 @@ impl UmaZone {
210211
| ZoneType::Mbuf
211212
| ZoneType::MbufCluster
212213
) {
213-
if flags.has(Alloc::Wait) {
214+
if flags.has_any(Alloc::Wait) {
214215
todo!()
215216
}
216217

@@ -272,7 +273,7 @@ impl UmaZone {
272273
// Get allocation flags.
273274
let mut flags = flags & !Alloc::Zero;
274275

275-
if self.flags.has(UmaFlags::CacheOnly) {
276+
if self.flags.has_any(UmaFlags::CacheOnly) {
276277
flags |= Alloc::NoVm;
277278
}
278279

@@ -317,13 +318,13 @@ impl UmaZone {
317318
let mut kegs = self.kegs.write();
318319
let keg = keg.unwrap_or(kegs.front_mut().unwrap());
319320

320-
if !keg.flags().has(UmaFlags::Bucket) || keg.recurse() == 0 {
321+
if !keg.flags().has_any(UmaFlags::Bucket) || keg.recurse() == 0 {
321322
loop {
322323
if let Some(v) = keg.fetch_slab(self, flags) {
323324
return Some(v);
324325
}
325326

326-
if flags.has(Alloc::NoWait | Alloc::NoVm) {
327+
if flags.has_any(Alloc::NoWait | Alloc::NoVm) {
327328
break;
328329
}
329330
}

lib/bitflag/Cargo.toml

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[package]
2+
name = "bitflag"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
[dependencies]

lib/bitflag/src/lib.rs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#![no_std]
2+
3+
pub use self::mask::*;
4+
5+
use core::ops::{BitOr, Not};
6+
7+
mod mask;
8+
9+
/// Type of bit flag.
10+
pub trait Type: From<Self::Raw> {
11+
type Raw: Raw;
12+
}
13+
14+
/// Underlying type of [`Type`].
15+
pub trait Raw: BitOr<Output = Self> + Not<Output = Self> + Copy {}
16+
17+
impl Raw for u32 {}

0 commit comments

Comments
 (0)