1use zerocopy::{FromBytes, IntoBytes};
2
3#[derive(Debug, Clone, Copy, FromBytes, IntoBytes)]
4#[repr(C)]
5pub struct TimeSpec {
6 pub tv_sec: i64,
7 pub tv_nsec: i64,
8}
9
10impl TimeSpec {
11 pub const fn zero() -> Self {
13 Self {
14 tv_sec: 0,
15 tv_nsec: 0,
16 }
17 }
18
19 pub fn to_nanos(&self) -> u64 {
21 (self.tv_sec as u64)
22 .saturating_mul(1_000_000_000)
23 .saturating_add(self.tv_nsec as u64)
24 }
25
26 pub fn from_nanos(nanos: u64) -> Self {
28 Self {
29 tv_sec: (nanos / 1_000_000_000) as i64,
30 tv_nsec: (nanos % 1_000_000_000) as i64,
31 }
32 }
33}
34
35#[derive(Debug, Clone, Copy, FromBytes, IntoBytes)]
36#[repr(C)]
37pub struct Stat {
38 pub st_dev: u64,
39 pub st_ino: u64,
40 pub st_nlink: u64,
41 pub st_mode: u32,
42 pub st_uid: u32,
43 pub st_gid: u32,
44 pub _padding0: u32,
45 pub st_rdev: u64,
46 pub st_size: u64,
47 pub st_blksize: u64,
48 pub st_blocks: u64,
49 pub st_atime: TimeSpec,
50 pub st_mtime: TimeSpec,
51 pub st_ctime: TimeSpec,
52}
53
54#[derive(Debug, Clone, Copy, FromBytes, IntoBytes)]
55#[repr(C)]
56pub struct StatVfs {
57 pub f_bsize: u64,
58 pub f_frsize: u64,
59 pub f_blocks: u64,
60 pub f_bfree: u64,
61 pub f_bavail: u64,
62 pub f_files: u64,
63 pub f_ffree: u64,
64 pub f_favail: u64,
65 pub f_fsid: u64,
66 pub f_flag: u64,
67 pub f_namemax: u64,
68}
69
70#[derive(Debug, Clone, Copy, FromBytes, IntoBytes)]
71#[repr(C)]
72pub struct Map {
73 pub offset: usize,
74 pub size: usize,
75 pub flags: u32,
76 pub _reserved: u32,
77 pub addr: usize,
78}
79
80#[derive(Debug, Clone, Copy, FromBytes, IntoBytes)]
81#[repr(C)]
82pub struct HandleInfo {
83 pub resource_type: u32,
84 pub permissions: u32,
85 pub resource: u64,
86}
87
88#[derive(Debug, Clone, Copy, FromBytes, IntoBytes)]
89#[repr(C)]
90pub struct MemoryRegionInfo {
91 pub size: u64,
92 pub page_size: u64,
93 pub flags: u32,
94 pub _reserved: u32,
95}
96
97pub const PCI_MATCH_VENDOR_ID: u32 = 1 << 0;
98pub const PCI_MATCH_DEVICE_ID: u32 = 1 << 1;
99pub const PCI_MATCH_CLASS_CODE: u32 = 1 << 2;
100pub const PCI_MATCH_SUBCLASS: u32 = 1 << 3;
101pub const PCI_MATCH_PROG_IF: u32 = 1 << 4;
102
103#[derive(Debug, Clone, Copy, FromBytes, IntoBytes)]
104#[repr(C, align(4))]
105pub struct PciAddress {
106 pub bus: u8,
107 pub device: u8,
108 pub function: u8,
109 pub _reserved: u8,
110}
111
112#[derive(Debug, Clone, Copy, FromBytes, IntoBytes)]
113#[repr(C)]
114pub struct PciProbeCriteria {
115 pub match_flags: u32,
116 pub vendor_id: u16,
117 pub device_id: u16,
118 pub class_code: u8,
119 pub subclass: u8,
120 pub prog_if: u8,
121 pub _reserved: u8,
122}
123
124#[derive(Debug, Clone, Copy, FromBytes, IntoBytes)]
125#[repr(C)]
126pub struct PciDeviceInfo {
127 pub address: PciAddress,
128 pub vendor_id: u16,
129 pub device_id: u16,
130 pub class_code: u8,
131 pub subclass: u8,
132 pub prog_if: u8,
133 pub revision: u8,
134 pub header_type: u8,
135 pub interrupt_line: u8,
136 pub interrupt_pin: u8,
137 pub _reserved: u8,
138}
139
140#[derive(Debug, Clone, Copy, FromBytes, IntoBytes)]
141#[repr(C)]
142pub struct FileStat {
143 pub st_dev: u64,
144 pub st_ino: u64,
145 pub st_mode: u32,
146 pub st_nlink: u32,
147 pub st_uid: u32,
148 pub st_gid: u32,
149 pub st_rdev: u64,
150 pub st_size: u64,
151 pub st_blksize: u64,
152 pub st_blocks: u64,
153 pub st_atime: TimeSpec,
154 pub st_mtime: TimeSpec,
155 pub st_ctime: TimeSpec,
156}
157
158impl FileStat {
159 pub const fn zeroed() -> Self {
161 FileStat {
162 st_dev: 0,
163 st_ino: 0,
164 st_mode: 0,
165 st_nlink: 0,
166 st_uid: 0,
167 st_gid: 0,
168 st_rdev: 0,
169 st_size: 0,
170 st_blksize: 0,
171 st_blocks: 0,
172 st_atime: TimeSpec::zero(),
173 st_mtime: TimeSpec::zero(),
174 st_ctime: TimeSpec::zero(),
175 }
176 }
177
178 pub fn is_dir(&self) -> bool {
180 (self.st_mode & 0o170000) == 0o040000
181 }
182
183 pub fn is_file(&self) -> bool {
185 (self.st_mode & 0o170000) == 0o100000
186 }
187}
188
189#[derive(Clone, Copy, FromBytes, IntoBytes)]
190#[repr(C, align(64))]
191pub struct IpcMessage {
192 pub sender: u64,
193 pub msg_type: u32,
194 pub flags: u32,
195 pub payload: [u8; 48],
196}
197
198impl IpcMessage {
199 pub const fn new(msg_type: u32) -> Self {
201 IpcMessage {
202 sender: 0,
203 msg_type,
204 flags: 0,
205 payload: [0u8; 48],
206 }
207 }
208
209 pub fn error_reply(sender: u64, status: i32) -> Self {
211 let mut msg = IpcMessage::new(0x80);
212 msg.sender = sender;
213 msg.payload[0..4].copy_from_slice(&(status as u32).to_le_bytes());
214 msg
215 }
216}
217
218impl core::fmt::Debug for IpcMessage {
219 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
221 f.debug_struct("IpcMessage")
222 .field("sender", &self.sender)
223 .field("msg_type", &format_args!("0x{:02x}", self.msg_type))
224 .field("flags", &self.flags)
225 .finish()
226 }
227}
228
229pub const SEEK_SET: usize = 0;
230pub const SEEK_CUR: usize = 1;
231pub const SEEK_END: usize = 2;
232
233pub const DT_UNKNOWN: u8 = 0;
235pub const DT_FIFO: u8 = 1;
236pub const DT_CHR: u8 = 2;
237pub const DT_DIR: u8 = 4;
238pub const DT_BLK: u8 = 6;
239pub const DT_REG: u8 = 8;
240pub const DT_LNK: u8 = 10;
241pub const DT_SOCK: u8 = 12;
242
243#[derive(Debug, Clone, Copy, FromBytes, IntoBytes)]
248#[repr(C, packed)]
249pub struct DirentHeader {
250 pub ino: u64,
251 pub file_type: u8,
252 pub name_len: u16,
253 pub _padding: u8,
254}
255
256impl DirentHeader {
257 pub const SIZE: usize = 12; pub const fn entry_size(&self) -> usize {
261 Self::SIZE + self.name_len as usize + 1
262 }
263}
264
265macro_rules! assert_abi_struct {
266 ($t:ty, $size:expr, $align:expr) => {
267 static_assertions::assert_eq_size!($t, [u8; $size]);
268 static_assertions::const_assert_eq!(core::mem::align_of::<$t>(), $align);
269 };
270}
271
272assert_abi_struct!(DirentHeader, 12, 1);
273assert_abi_struct!(Stat, 120, 8);
274assert_abi_struct!(StatVfs, 88, 8);
275assert_abi_struct!(Map, 32, 8);
276assert_abi_struct!(FileStat, 112, 8);
277assert_abi_struct!(IpcMessage, 64, 64);
278assert_abi_struct!(TimeSpec, 16, 8);
279assert_abi_struct!(HandleInfo, 16, 8);
280assert_abi_struct!(MemoryRegionInfo, 24, 8);
281assert_abi_struct!(PciAddress, 4, 4);
282assert_abi_struct!(PciProbeCriteria, 12, 4);
283assert_abi_struct!(PciDeviceInfo, 16, 4);