zx_types/
lib.rs

1// Copyright 2024 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#![allow(non_camel_case_types)]
6
7use std::fmt::{self, Debug};
8use std::hash::{Hash, Hasher};
9use std::sync::atomic::AtomicI32;
10#[cfg(feature = "zerocopy")]
11use zerocopy::{FromBytes, FromZeros, Immutable, IntoBytes, KnownLayout};
12
13pub type zx_addr_t = usize;
14pub type zx_stream_seek_origin_t = u32;
15pub type zx_clock_t = u32;
16pub type zx_duration_t = i64;
17pub type zx_duration_mono_t = i64;
18pub type zx_duration_mono_ticks_t = i64;
19pub type zx_duration_boot_t = i64;
20pub type zx_duration_boot_ticks_t = i64;
21pub type zx_futex_t = AtomicI32;
22pub type zx_gpaddr_t = usize;
23pub type zx_guest_option_t = u32;
24pub type zx_vcpu_option_t = u32;
25pub type zx_guest_trap_t = u32;
26pub type zx_handle_t = u32;
27pub type zx_handle_op_t = u32;
28pub type zx_koid_t = u64;
29pub type zx_obj_type_t = u32;
30pub type zx_object_info_topic_t = u32;
31pub type zx_info_maps_type_t = u32;
32pub type zx_instant_boot_t = i64;
33pub type zx_instant_boot_ticks_t = i64;
34pub type zx_instant_mono_t = i64;
35pub type zx_instant_mono_ticks_t = i64;
36pub type zx_iob_access_t = u32;
37pub type zx_iob_allocate_id_options_t = u32;
38pub type zx_iob_discipline_type_t = u64;
39pub type zx_iob_region_type_t = u32;
40pub type zx_iob_write_options_t = u64;
41pub type zx_off_t = u64;
42pub type zx_paddr_t = usize;
43pub type zx_rights_t = u32;
44pub type zx_rsrc_flags_t = u32;
45pub type zx_rsrc_kind_t = u32;
46pub type zx_signals_t = u32;
47pub type zx_ssize_t = isize;
48pub type zx_status_t = i32;
49pub type zx_rsrc_system_base_t = u64;
50pub type zx_ticks_t = i64;
51pub type zx_time_t = i64;
52pub type zx_txid_t = u32;
53pub type zx_vaddr_t = usize;
54pub type zx_vm_option_t = u32;
55pub type zx_thread_state_topic_t = u32;
56pub type zx_vcpu_state_topic_t = u32;
57pub type zx_restricted_reason_t = u64;
58pub type zx_processor_power_level_options_t = u64;
59pub type zx_processor_power_control_t = u64;
60pub type zx_system_memory_stall_type_t = u32;
61pub type zx_system_suspend_option_t = u64;
62pub type zx_system_wake_report_entry_flag_t = u32;
63
64macro_rules! const_assert {
65    ($e:expr $(,)?) => {
66        const _: [(); 1 - { const ASSERT: bool = $e; ASSERT as usize }] = [];
67    };
68}
69macro_rules! const_assert_eq {
70    ($lhs:expr, $rhs:expr $(,)?) => {
71        const_assert!($lhs == $rhs);
72    };
73}
74
75// TODO: magically coerce this to &`static str somehow?
76#[repr(C)]
77#[derive(Debug, Copy, Clone, Eq, PartialEq)]
78pub struct zx_string_view_t {
79    pub c_str: *const u8, // Guaranteed NUL-terminated valid UTF-8.
80    pub length: usize,
81}
82
83pub const ZX_MAX_NAME_LEN: usize = 32;
84
85// TODO: combine these macros with the bitflags and assoc consts macros below
86// so that we only have to do one macro invocation.
87// The result would look something like:
88// multiconst!(bitflags, zx_rights_t, Rights, [RIGHT_NONE => ZX_RIGHT_NONE = 0; ...]);
89// multiconst!(assoc_consts, zx_status_t, Status, [OK => ZX_OK = 0; ...]);
90// Note that the actual name of the inner macro (e.g. `bitflags`) can't be a variable.
91// It'll just have to be matched on manually
92macro_rules! multiconst {
93    ($typename:ident, [$($(#[$attr:meta])* $rawname:ident = $value:expr;)*]) => {
94        $(
95            $(#[$attr])*
96            pub const $rawname: $typename = $value;
97        )*
98    }
99}
100
101multiconst!(zx_handle_t, [
102    ZX_HANDLE_INVALID = 0;
103]);
104
105multiconst!(zx_handle_op_t, [
106    ZX_HANDLE_OP_MOVE = 0;
107    ZX_HANDLE_OP_DUPLICATE = 1;
108]);
109
110multiconst!(zx_koid_t, [
111    ZX_KOID_INVALID = 0;
112    ZX_KOID_KERNEL = 1;
113    ZX_KOID_FIRST = 1024;
114]);
115
116multiconst!(zx_time_t, [
117    ZX_TIME_INFINITE = i64::MAX;
118    ZX_TIME_INFINITE_PAST = ::std::i64::MIN;
119]);
120
121multiconst!(zx_rights_t, [
122    ZX_RIGHT_NONE           = 0;
123    ZX_RIGHT_DUPLICATE      = 1 << 0;
124    ZX_RIGHT_TRANSFER       = 1 << 1;
125    ZX_RIGHT_READ           = 1 << 2;
126    ZX_RIGHT_WRITE          = 1 << 3;
127    ZX_RIGHT_EXECUTE        = 1 << 4;
128    ZX_RIGHT_MAP            = 1 << 5;
129    ZX_RIGHT_GET_PROPERTY   = 1 << 6;
130    ZX_RIGHT_SET_PROPERTY   = 1 << 7;
131    ZX_RIGHT_ENUMERATE      = 1 << 8;
132    ZX_RIGHT_DESTROY        = 1 << 9;
133    ZX_RIGHT_SET_POLICY     = 1 << 10;
134    ZX_RIGHT_GET_POLICY     = 1 << 11;
135    ZX_RIGHT_SIGNAL         = 1 << 12;
136    ZX_RIGHT_SIGNAL_PEER    = 1 << 13;
137    ZX_RIGHT_WAIT           = 1 << 14;
138    ZX_RIGHT_INSPECT        = 1 << 15;
139    ZX_RIGHT_MANAGE_JOB     = 1 << 16;
140    ZX_RIGHT_MANAGE_PROCESS = 1 << 17;
141    ZX_RIGHT_MANAGE_THREAD  = 1 << 18;
142    ZX_RIGHT_APPLY_PROFILE  = 1 << 19;
143    ZX_RIGHT_MANAGE_SOCKET  = 1 << 20;
144    ZX_RIGHT_OP_CHILDREN    = 1 << 21;
145    ZX_RIGHT_RESIZE         = 1 << 22;
146    ZX_RIGHT_ATTACH_VMO     = 1 << 23;
147    ZX_RIGHT_MANAGE_VMO     = 1 << 24;
148    ZX_RIGHT_SAME_RIGHTS    = 1 << 31;
149]);
150
151multiconst!(u32, [
152    ZX_VMO_RESIZABLE = 1 << 1;
153    ZX_VMO_DISCARDABLE = 1 << 2;
154    ZX_VMO_TRAP_DIRTY = 1 << 3;
155    ZX_VMO_UNBOUNDED = 1 << 4;
156]);
157
158multiconst!(u64, [
159    ZX_VMO_DIRTY_RANGE_IS_ZERO = 1;
160]);
161
162multiconst!(u32, [
163    ZX_INFO_VMO_TYPE_PAGED = 1 << 0;
164    ZX_INFO_VMO_RESIZABLE = 1 << 1;
165    ZX_INFO_VMO_IS_COW_CLONE = 1 << 2;
166    ZX_INFO_VMO_VIA_HANDLE = 1 << 3;
167    ZX_INFO_VMO_VIA_MAPPING = 1 << 4;
168    ZX_INFO_VMO_PAGER_BACKED = 1 << 5;
169    ZX_INFO_VMO_CONTIGUOUS = 1 << 6;
170    ZX_INFO_VMO_DISCARDABLE = 1 << 7;
171    ZX_INFO_VMO_IMMUTABLE = 1 << 8;
172    ZX_INFO_VMO_VIA_IOB_HANDLE = 1 << 9;
173]);
174
175multiconst!(u32, [
176    ZX_VMO_OP_COMMIT = 1;
177    ZX_VMO_OP_DECOMMIT = 2;
178    ZX_VMO_OP_LOCK = 3;
179    ZX_VMO_OP_UNLOCK = 4;
180    ZX_VMO_OP_CACHE_SYNC = 6;
181    ZX_VMO_OP_CACHE_INVALIDATE = 7;
182    ZX_VMO_OP_CACHE_CLEAN = 8;
183    ZX_VMO_OP_CACHE_CLEAN_INVALIDATE = 9;
184    ZX_VMO_OP_ZERO = 10;
185    ZX_VMO_OP_TRY_LOCK = 11;
186    ZX_VMO_OP_DONT_NEED = 12;
187    ZX_VMO_OP_ALWAYS_NEED = 13;
188    ZX_VMO_OP_PREFETCH = 14;
189]);
190
191multiconst!(u32, [
192    ZX_VMAR_OP_COMMIT = 1;
193    ZX_VMAR_OP_DECOMMIT = 2;
194    ZX_VMAR_OP_MAP_RANGE = 3;
195    ZX_VMAR_OP_ZERO = 10;
196    ZX_VMAR_OP_DONT_NEED = 12;
197    ZX_VMAR_OP_ALWAYS_NEED = 13;
198    ZX_VMAR_OP_PREFETCH = 14;
199]);
200
201multiconst!(zx_vm_option_t, [
202    ZX_VM_PERM_READ                    = 1 << 0;
203    ZX_VM_PERM_WRITE                   = 1 << 1;
204    ZX_VM_PERM_EXECUTE                 = 1 << 2;
205    ZX_VM_COMPACT                      = 1 << 3;
206    ZX_VM_SPECIFIC                     = 1 << 4;
207    ZX_VM_SPECIFIC_OVERWRITE           = 1 << 5;
208    ZX_VM_CAN_MAP_SPECIFIC             = 1 << 6;
209    ZX_VM_CAN_MAP_READ                 = 1 << 7;
210    ZX_VM_CAN_MAP_WRITE                = 1 << 8;
211    ZX_VM_CAN_MAP_EXECUTE              = 1 << 9;
212    ZX_VM_MAP_RANGE                    = 1 << 10;
213    ZX_VM_REQUIRE_NON_RESIZABLE        = 1 << 11;
214    ZX_VM_ALLOW_FAULTS                 = 1 << 12;
215    ZX_VM_OFFSET_IS_UPPER_LIMIT        = 1 << 13;
216    ZX_VM_PERM_READ_IF_XOM_UNSUPPORTED = 1 << 14;
217    ZX_VM_FAULT_BEYOND_STREAM_SIZE     = 1 << 15;
218
219    // VM alignment options
220    ZX_VM_ALIGN_BASE                   = 24;
221    ZX_VM_ALIGN_1KB                    = 10 << ZX_VM_ALIGN_BASE;
222    ZX_VM_ALIGN_2KB                    = 11 << ZX_VM_ALIGN_BASE;
223    ZX_VM_ALIGN_4KB                    = 12 << ZX_VM_ALIGN_BASE;
224    ZX_VM_ALIGN_8KB                    = 13 << ZX_VM_ALIGN_BASE;
225    ZX_VM_ALIGN_16KB                   = 14 << ZX_VM_ALIGN_BASE;
226    ZX_VM_ALIGN_32KB                   = 15 << ZX_VM_ALIGN_BASE;
227    ZX_VM_ALIGN_64KB                   = 16 << ZX_VM_ALIGN_BASE;
228    ZX_VM_ALIGN_128KB                  = 17 << ZX_VM_ALIGN_BASE;
229    ZX_VM_ALIGN_256KB                  = 18 << ZX_VM_ALIGN_BASE;
230    ZX_VM_ALIGN_512KB                  = 19 << ZX_VM_ALIGN_BASE;
231    ZX_VM_ALIGN_1MB                    = 20 << ZX_VM_ALIGN_BASE;
232    ZX_VM_ALIGN_2MB                    = 21 << ZX_VM_ALIGN_BASE;
233    ZX_VM_ALIGN_4MB                    = 22 << ZX_VM_ALIGN_BASE;
234    ZX_VM_ALIGN_8MB                    = 23 << ZX_VM_ALIGN_BASE;
235    ZX_VM_ALIGN_16MB                   = 24 << ZX_VM_ALIGN_BASE;
236    ZX_VM_ALIGN_32MB                   = 25 << ZX_VM_ALIGN_BASE;
237    ZX_VM_ALIGN_64MB                   = 26 << ZX_VM_ALIGN_BASE;
238    ZX_VM_ALIGN_128MB                  = 27 << ZX_VM_ALIGN_BASE;
239    ZX_VM_ALIGN_256MB                  = 28 << ZX_VM_ALIGN_BASE;
240    ZX_VM_ALIGN_512MB                  = 29 << ZX_VM_ALIGN_BASE;
241    ZX_VM_ALIGN_1GB                    = 30 << ZX_VM_ALIGN_BASE;
242    ZX_VM_ALIGN_2GB                    = 31 << ZX_VM_ALIGN_BASE;
243    ZX_VM_ALIGN_4GB                    = 32 << ZX_VM_ALIGN_BASE;
244]);
245
246multiconst!(u32, [
247    ZX_PROCESS_SHARED = 1 << 0;
248]);
249
250// matches ///zircon/system/public/zircon/errors.h
251multiconst!(zx_status_t, [
252    ZX_OK                         = 0;
253    ZX_ERR_INTERNAL               = -1;
254    ZX_ERR_NOT_SUPPORTED          = -2;
255    ZX_ERR_NO_RESOURCES           = -3;
256    ZX_ERR_NO_MEMORY              = -4;
257    ZX_ERR_INTERRUPTED_RETRY      = -6;
258    ZX_ERR_INVALID_ARGS           = -10;
259    ZX_ERR_BAD_HANDLE             = -11;
260    ZX_ERR_WRONG_TYPE             = -12;
261    ZX_ERR_BAD_SYSCALL            = -13;
262    ZX_ERR_OUT_OF_RANGE           = -14;
263    ZX_ERR_BUFFER_TOO_SMALL       = -15;
264    ZX_ERR_BAD_STATE              = -20;
265    ZX_ERR_TIMED_OUT              = -21;
266    ZX_ERR_SHOULD_WAIT            = -22;
267    ZX_ERR_CANCELED               = -23;
268    ZX_ERR_PEER_CLOSED            = -24;
269    ZX_ERR_NOT_FOUND              = -25;
270    ZX_ERR_ALREADY_EXISTS         = -26;
271    ZX_ERR_ALREADY_BOUND          = -27;
272    ZX_ERR_UNAVAILABLE            = -28;
273    ZX_ERR_ACCESS_DENIED          = -30;
274    ZX_ERR_IO                     = -40;
275    ZX_ERR_IO_REFUSED             = -41;
276    ZX_ERR_IO_DATA_INTEGRITY      = -42;
277    ZX_ERR_IO_DATA_LOSS           = -43;
278    ZX_ERR_IO_NOT_PRESENT         = -44;
279    ZX_ERR_IO_OVERRUN             = -45;
280    ZX_ERR_IO_MISSED_DEADLINE     = -46;
281    ZX_ERR_IO_INVALID             = -47;
282    ZX_ERR_BAD_PATH               = -50;
283    ZX_ERR_NOT_DIR                = -51;
284    ZX_ERR_NOT_FILE               = -52;
285    ZX_ERR_FILE_BIG               = -53;
286    ZX_ERR_NO_SPACE               = -54;
287    ZX_ERR_NOT_EMPTY              = -55;
288    ZX_ERR_STOP                   = -60;
289    ZX_ERR_NEXT                   = -61;
290    ZX_ERR_ASYNC                  = -62;
291    ZX_ERR_PROTOCOL_NOT_SUPPORTED = -70;
292    ZX_ERR_ADDRESS_UNREACHABLE    = -71;
293    ZX_ERR_ADDRESS_IN_USE         = -72;
294    ZX_ERR_NOT_CONNECTED          = -73;
295    ZX_ERR_CONNECTION_REFUSED     = -74;
296    ZX_ERR_CONNECTION_RESET       = -75;
297    ZX_ERR_CONNECTION_ABORTED     = -76;
298]);
299
300multiconst!(zx_signals_t, [
301    ZX_SIGNAL_NONE              = 0;
302    ZX_OBJECT_SIGNAL_ALL        = 0x00ffffff;
303    ZX_USER_SIGNAL_ALL          = 0xff000000;
304    ZX_OBJECT_SIGNAL_0          = 1 << 0;
305    ZX_OBJECT_SIGNAL_1          = 1 << 1;
306    ZX_OBJECT_SIGNAL_2          = 1 << 2;
307    ZX_OBJECT_SIGNAL_3          = 1 << 3;
308    ZX_OBJECT_SIGNAL_4          = 1 << 4;
309    ZX_OBJECT_SIGNAL_5          = 1 << 5;
310    ZX_OBJECT_SIGNAL_6          = 1 << 6;
311    ZX_OBJECT_SIGNAL_7          = 1 << 7;
312    ZX_OBJECT_SIGNAL_8          = 1 << 8;
313    ZX_OBJECT_SIGNAL_9          = 1 << 9;
314    ZX_OBJECT_SIGNAL_10         = 1 << 10;
315    ZX_OBJECT_SIGNAL_11         = 1 << 11;
316    ZX_OBJECT_SIGNAL_12         = 1 << 12;
317    ZX_OBJECT_SIGNAL_13         = 1 << 13;
318    ZX_OBJECT_SIGNAL_14         = 1 << 14;
319    ZX_OBJECT_SIGNAL_15         = 1 << 15;
320    ZX_OBJECT_SIGNAL_16         = 1 << 16;
321    ZX_OBJECT_SIGNAL_17         = 1 << 17;
322    ZX_OBJECT_SIGNAL_18         = 1 << 18;
323    ZX_OBJECT_SIGNAL_19         = 1 << 19;
324    ZX_OBJECT_SIGNAL_20         = 1 << 20;
325    ZX_OBJECT_SIGNAL_21         = 1 << 21;
326    ZX_OBJECT_SIGNAL_22         = 1 << 22;
327    ZX_OBJECT_HANDLE_CLOSED     = 1 << 23;
328    ZX_USER_SIGNAL_0            = 1 << 24;
329    ZX_USER_SIGNAL_1            = 1 << 25;
330    ZX_USER_SIGNAL_2            = 1 << 26;
331    ZX_USER_SIGNAL_3            = 1 << 27;
332    ZX_USER_SIGNAL_4            = 1 << 28;
333    ZX_USER_SIGNAL_5            = 1 << 29;
334    ZX_USER_SIGNAL_6            = 1 << 30;
335    ZX_USER_SIGNAL_7            = 1 << 31;
336
337    ZX_OBJECT_READABLE          = ZX_OBJECT_SIGNAL_0;
338    ZX_OBJECT_WRITABLE          = ZX_OBJECT_SIGNAL_1;
339    ZX_OBJECT_PEER_CLOSED       = ZX_OBJECT_SIGNAL_2;
340
341    // Cancelation (handle was closed while waiting with it)
342    ZX_SIGNAL_HANDLE_CLOSED     = ZX_OBJECT_HANDLE_CLOSED;
343
344    // Event
345    ZX_EVENT_SIGNALED           = ZX_OBJECT_SIGNAL_3;
346
347    // EventPair
348    ZX_EVENTPAIR_SIGNALED       = ZX_OBJECT_SIGNAL_3;
349    ZX_EVENTPAIR_PEER_CLOSED    = ZX_OBJECT_SIGNAL_2;
350
351    // Task signals (process, thread, job)
352    ZX_TASK_TERMINATED          = ZX_OBJECT_SIGNAL_3;
353
354    // Channel
355    ZX_CHANNEL_READABLE         = ZX_OBJECT_SIGNAL_0;
356    ZX_CHANNEL_WRITABLE         = ZX_OBJECT_SIGNAL_1;
357    ZX_CHANNEL_PEER_CLOSED      = ZX_OBJECT_SIGNAL_2;
358
359    // Clock
360    ZX_CLOCK_STARTED            = ZX_OBJECT_SIGNAL_4;
361    ZX_CLOCK_UPDATED            = ZX_OBJECT_SIGNAL_5;
362
363    // Socket
364    ZX_SOCKET_READABLE            = ZX_OBJECT_READABLE;
365    ZX_SOCKET_WRITABLE            = ZX_OBJECT_WRITABLE;
366    ZX_SOCKET_PEER_CLOSED         = ZX_OBJECT_PEER_CLOSED;
367    ZX_SOCKET_PEER_WRITE_DISABLED = ZX_OBJECT_SIGNAL_4;
368    ZX_SOCKET_WRITE_DISABLED      = ZX_OBJECT_SIGNAL_5;
369    ZX_SOCKET_READ_THRESHOLD      = ZX_OBJECT_SIGNAL_10;
370    ZX_SOCKET_WRITE_THRESHOLD     = ZX_OBJECT_SIGNAL_11;
371
372    // Resource
373    ZX_RESOURCE_DESTROYED       = ZX_OBJECT_SIGNAL_3;
374    ZX_RESOURCE_READABLE        = ZX_OBJECT_READABLE;
375    ZX_RESOURCE_WRITABLE        = ZX_OBJECT_WRITABLE;
376    ZX_RESOURCE_CHILD_ADDED     = ZX_OBJECT_SIGNAL_4;
377
378    // Fifo
379    ZX_FIFO_READABLE            = ZX_OBJECT_READABLE;
380    ZX_FIFO_WRITABLE            = ZX_OBJECT_WRITABLE;
381    ZX_FIFO_PEER_CLOSED         = ZX_OBJECT_PEER_CLOSED;
382
383    // Iob
384    ZX_IOB_PEER_CLOSED           = ZX_OBJECT_PEER_CLOSED;
385    ZX_IOB_SHARED_REGION_UPDATED = ZX_OBJECT_SIGNAL_3;
386
387    // Job
388    ZX_JOB_TERMINATED           = ZX_OBJECT_SIGNAL_3;
389    ZX_JOB_NO_JOBS              = ZX_OBJECT_SIGNAL_4;
390    ZX_JOB_NO_PROCESSES         = ZX_OBJECT_SIGNAL_5;
391
392    // Process
393    ZX_PROCESS_TERMINATED       = ZX_OBJECT_SIGNAL_3;
394
395    // Thread
396    ZX_THREAD_TERMINATED        = ZX_OBJECT_SIGNAL_3;
397    ZX_THREAD_RUNNING           = ZX_OBJECT_SIGNAL_4;
398    ZX_THREAD_SUSPENDED         = ZX_OBJECT_SIGNAL_5;
399
400    // Log
401    ZX_LOG_READABLE             = ZX_OBJECT_READABLE;
402    ZX_LOG_WRITABLE             = ZX_OBJECT_WRITABLE;
403
404    // Timer
405    ZX_TIMER_SIGNALED           = ZX_OBJECT_SIGNAL_3;
406
407    // Vmo
408    ZX_VMO_ZERO_CHILDREN        = ZX_OBJECT_SIGNAL_3;
409
410    // Counter
411    ZX_COUNTER_SIGNALED          = ZX_OBJECT_SIGNAL_3;
412    ZX_COUNTER_POSITIVE          = ZX_OBJECT_SIGNAL_4;
413    ZX_COUNTER_NON_POSITIVE      = ZX_OBJECT_SIGNAL_5;
414]);
415
416multiconst!(zx_obj_type_t, [
417    ZX_OBJ_TYPE_NONE                = 0;
418    ZX_OBJ_TYPE_PROCESS             = 1;
419    ZX_OBJ_TYPE_THREAD              = 2;
420    ZX_OBJ_TYPE_VMO                 = 3;
421    ZX_OBJ_TYPE_CHANNEL             = 4;
422    ZX_OBJ_TYPE_EVENT               = 5;
423    ZX_OBJ_TYPE_PORT                = 6;
424    ZX_OBJ_TYPE_INTERRUPT           = 9;
425    ZX_OBJ_TYPE_PCI_DEVICE          = 11;
426    ZX_OBJ_TYPE_DEBUGLOG            = 12;
427    ZX_OBJ_TYPE_SOCKET              = 14;
428    ZX_OBJ_TYPE_RESOURCE            = 15;
429    ZX_OBJ_TYPE_EVENTPAIR           = 16;
430    ZX_OBJ_TYPE_JOB                 = 17;
431    ZX_OBJ_TYPE_VMAR                = 18;
432    ZX_OBJ_TYPE_FIFO                = 19;
433    ZX_OBJ_TYPE_GUEST               = 20;
434    ZX_OBJ_TYPE_VCPU                = 21;
435    ZX_OBJ_TYPE_TIMER               = 22;
436    ZX_OBJ_TYPE_IOMMU               = 23;
437    ZX_OBJ_TYPE_BTI                 = 24;
438    ZX_OBJ_TYPE_PROFILE             = 25;
439    ZX_OBJ_TYPE_PMT                 = 26;
440    ZX_OBJ_TYPE_SUSPEND_TOKEN       = 27;
441    ZX_OBJ_TYPE_PAGER               = 28;
442    ZX_OBJ_TYPE_EXCEPTION           = 29;
443    ZX_OBJ_TYPE_CLOCK               = 30;
444    ZX_OBJ_TYPE_STREAM              = 31;
445    ZX_OBJ_TYPE_MSI                 = 32;
446    ZX_OBJ_TYPE_IOB                 = 33;
447    ZX_OBJ_TYPE_COUNTER             = 34;
448]);
449
450// System ABI commits to having no more than 64 object types.
451//
452// See zx_info_process_handle_stats_t for an example of a binary interface that
453// depends on having an upper bound for the number of object types.
454pub const ZX_OBJ_TYPE_UPPER_BOUND: usize = 64;
455
456// TODO: add an alias for this type in the C headers.
457multiconst!(u32, [
458    // Argument is a char[ZX_MAX_NAME_LEN].
459    ZX_PROP_NAME                      = 3;
460
461    // Argument is a uintptr_t.
462    #[cfg(target_arch = "x86_64")]
463    ZX_PROP_REGISTER_GS               = 2;
464    #[cfg(target_arch = "x86_64")]
465    ZX_PROP_REGISTER_FS               = 4;
466
467    // Argument is the value of ld.so's _dl_debug_addr, a uintptr_t.
468    ZX_PROP_PROCESS_DEBUG_ADDR        = 5;
469
470    // Argument is the base address of the vDSO mapping (or zero), a uintptr_t.
471    ZX_PROP_PROCESS_VDSO_BASE_ADDRESS = 6;
472
473    // Whether the dynamic loader should issue a debug trap when loading a shared
474    // library, either initially or when running (e.g. dlopen).
475    ZX_PROP_PROCESS_BREAK_ON_LOAD = 7;
476
477    // Argument is a size_t.
478    ZX_PROP_SOCKET_RX_THRESHOLD       = 12;
479    ZX_PROP_SOCKET_TX_THRESHOLD       = 13;
480
481    // Argument is a size_t, describing the number of packets a channel
482    // endpoint can have pending in its tx direction.
483    ZX_PROP_CHANNEL_TX_MSG_MAX        = 14;
484
485    // Terminate this job if the system is low on memory.
486    ZX_PROP_JOB_KILL_ON_OOM           = 15;
487
488    // Exception close behavior.
489    ZX_PROP_EXCEPTION_STATE           = 16;
490
491    // The size of the content in a VMO, in bytes.
492    ZX_PROP_VMO_CONTENT_SIZE          = 17;
493
494    // How an exception should be handled.
495    ZX_PROP_EXCEPTION_STRATEGY        = 18;
496
497    // Whether the stream is in append mode or not.
498    ZX_PROP_STREAM_MODE_APPEND        = 19;
499]);
500
501// Value for ZX_THREAD_STATE_SINGLE_STEP. The value can be 0 (not single-stepping), or 1
502// (single-stepping). Other values will give ZX_ERR_INVALID_ARGS.
503pub type zx_thread_state_single_step_t = u32;
504
505// Possible values for "kind" in zx_thread_read_state and zx_thread_write_state.
506multiconst!(zx_thread_state_topic_t, [
507    ZX_THREAD_STATE_GENERAL_REGS       = 0;
508    ZX_THREAD_STATE_FP_REGS            = 1;
509    ZX_THREAD_STATE_VECTOR_REGS        = 2;
510    // No 3 at the moment.
511    ZX_THREAD_STATE_DEBUG_REGS         = 4;
512    ZX_THREAD_STATE_SINGLE_STEP        = 5;
513]);
514
515// Possible values for "kind" in zx_vcpu_read_state and zx_vcpu_write_state.
516multiconst!(zx_vcpu_state_topic_t, [
517    ZX_VCPU_STATE   = 0;
518    ZX_VCPU_IO      = 1;
519]);
520
521// From //zircon/system/public/zircon/features.h
522multiconst!(u32, [
523    ZX_FEATURE_KIND_CPU                        = 0;
524    ZX_FEATURE_KIND_HW_BREAKPOINT_COUNT        = 1;
525    ZX_FEATURE_KIND_HW_WATCHPOINT_COUNT        = 2;
526    ZX_FEATURE_KIND_ADDRESS_TAGGING            = 3;
527    ZX_FEATURE_KIND_VM                         = 4;
528]);
529
530// From //zircon/system/public/zircon/features.h
531multiconst!(u32, [
532    ZX_HAS_CPU_FEATURES                   = 1 << 0;
533
534    ZX_VM_FEATURE_CAN_MAP_XOM             = 1 << 0;
535
536    ZX_ARM64_FEATURE_ISA_FP               = 1 << 1;
537    ZX_ARM64_FEATURE_ISA_ASIMD            = 1 << 2;
538    ZX_ARM64_FEATURE_ISA_AES              = 1 << 3;
539    ZX_ARM64_FEATURE_ISA_PMULL            = 1 << 4;
540    ZX_ARM64_FEATURE_ISA_SHA1             = 1 << 5;
541    ZX_ARM64_FEATURE_ISA_SHA256           = 1 << 6;
542    ZX_ARM64_FEATURE_ISA_CRC32            = 1 << 7;
543    ZX_ARM64_FEATURE_ISA_ATOMICS          = 1 << 8;
544    ZX_ARM64_FEATURE_ISA_RDM              = 1 << 9;
545    ZX_ARM64_FEATURE_ISA_SHA3             = 1 << 10;
546    ZX_ARM64_FEATURE_ISA_SM3              = 1 << 11;
547    ZX_ARM64_FEATURE_ISA_SM4              = 1 << 12;
548    ZX_ARM64_FEATURE_ISA_DP               = 1 << 13;
549    ZX_ARM64_FEATURE_ISA_DPB              = 1 << 14;
550    ZX_ARM64_FEATURE_ISA_FHM              = 1 << 15;
551    ZX_ARM64_FEATURE_ISA_TS               = 1 << 16;
552    ZX_ARM64_FEATURE_ISA_RNDR             = 1 << 17;
553    ZX_ARM64_FEATURE_ISA_SHA512           = 1 << 18;
554    ZX_ARM64_FEATURE_ISA_I8MM             = 1 << 19;
555    ZX_ARM64_FEATURE_ISA_SVE              = 1 << 20;
556    ZX_ARM64_FEATURE_ISA_ARM32            = 1 << 21;
557    ZX_ARM64_FEATURE_ISA_SHA2             = 1 << 6;
558    ZX_ARM64_FEATURE_ADDRESS_TAGGING_TBI  = 1 << 0;
559]);
560
561// From //zircon/system/public/zircon/syscalls/resource.h
562multiconst!(zx_rsrc_kind_t, [
563    ZX_RSRC_KIND_MMIO       = 0;
564    ZX_RSRC_KIND_IRQ        = 1;
565    ZX_RSRC_KIND_IOPORT     = 2;
566    ZX_RSRC_KIND_ROOT       = 3;
567    ZX_RSRC_KIND_SMC        = 4;
568    ZX_RSRC_KIND_SYSTEM     = 5;
569]);
570
571// From //zircon/system/public/zircon/syscalls/resource.h
572multiconst!(zx_rsrc_system_base_t, [
573    ZX_RSRC_SYSTEM_HYPERVISOR_BASE  = 0;
574    ZX_RSRC_SYSTEM_VMEX_BASE        = 1;
575    ZX_RSRC_SYSTEM_DEBUG_BASE       = 2;
576    ZX_RSRC_SYSTEM_INFO_BASE        = 3;
577    ZX_RSRC_SYSTEM_CPU_BASE         = 4;
578    ZX_RSRC_SYSTEM_POWER_BASE       = 5;
579    ZX_RSRC_SYSTEM_MEXEC_BASE       = 6;
580    ZX_RSRC_SYSTEM_ENERGY_INFO_BASE = 7;
581    ZX_RSRC_SYSTEM_IOMMU_BASE       = 8;
582    ZX_RSRC_SYSTEM_FRAMEBUFFER_BASE = 9;
583    ZX_RSRC_SYSTEM_PROFILE_BASE     = 10;
584    ZX_RSRC_SYSTEM_MSI_BASE         = 11;
585    ZX_RSRC_SYSTEM_DEBUGLOG_BASE    = 12;
586    ZX_RSRC_SYSTEM_STALL_BASE       = 13;
587    ZX_RSRC_SYSTEM_TRACING_BASE     = 14;
588]);
589
590// clock ids
591multiconst!(zx_clock_t, [
592    ZX_CLOCK_MONOTONIC = 0;
593    ZX_CLOCK_BOOT      = 1;
594]);
595
596// from //zircon/system/public/zircon/syscalls/clock.h
597multiconst!(u64, [
598    ZX_CLOCK_OPT_MONOTONIC = 1 << 0;
599    ZX_CLOCK_OPT_CONTINUOUS = 1 << 1;
600    ZX_CLOCK_OPT_AUTO_START = 1 << 2;
601    ZX_CLOCK_OPT_BOOT = 1 << 3;
602    ZX_CLOCK_OPT_MAPPABLE = 1 << 4;
603
604    // v1 clock update flags
605    ZX_CLOCK_UPDATE_OPTION_VALUE_VALID = 1 << 0;
606    ZX_CLOCK_UPDATE_OPTION_RATE_ADJUST_VALID = 1 << 1;
607    ZX_CLOCK_UPDATE_OPTION_ERROR_BOUND_VALID = 1 << 2;
608
609    // Additional v2 clock update flags
610    ZX_CLOCK_UPDATE_OPTION_REFERENCE_VALUE_VALID = 1 << 3;
611    ZX_CLOCK_UPDATE_OPTION_SYNTHETIC_VALUE_VALID = ZX_CLOCK_UPDATE_OPTION_VALUE_VALID;
612
613    ZX_CLOCK_ARGS_VERSION_1 = 1 << 58;
614    ZX_CLOCK_ARGS_VERSION_2 = 2 << 58;
615]);
616
617// from //zircon/system/public/zircon/syscalls/exception.h
618multiconst!(u32, [
619    ZX_EXCEPTION_CHANNEL_DEBUGGER = 1 << 0;
620    ZX_EXCEPTION_TARGET_JOB_DEBUGGER = 1 << 0;
621
622    // Returned when probing a thread for its blocked state.
623    ZX_EXCEPTION_CHANNEL_TYPE_NONE = 0;
624    ZX_EXCEPTION_CHANNEL_TYPE_DEBUGGER = 1;
625    ZX_EXCEPTION_CHANNEL_TYPE_THREAD = 2;
626    ZX_EXCEPTION_CHANNEL_TYPE_PROCESS = 3;
627    ZX_EXCEPTION_CHANNEL_TYPE_JOB = 4;
628    ZX_EXCEPTION_CHANNEL_TYPE_JOB_DEBUGGER = 5;
629]);
630
631/// A byte used only to control memory alignment. All padding bytes are considered equal
632/// regardless of their content.
633///
634/// Note that the kernel C/C++ struct definitions use explicit padding fields to ensure no implicit
635/// padding is added. This is important for security since implicit padding bytes are not always
636/// safely initialized. These explicit padding fields are mirrored in the Rust struct definitions
637/// to minimize the opportunities for mistakes and inconsistencies.
638#[repr(transparent)]
639#[derive(Copy, Clone, Eq, Default)]
640#[cfg_attr(feature = "zerocopy", derive(FromBytes, Immutable, IntoBytes))]
641pub struct PadByte(u8);
642
643impl PartialEq for PadByte {
644    fn eq(&self, _other: &Self) -> bool {
645        true
646    }
647}
648
649impl Hash for PadByte {
650    fn hash<H: Hasher>(&self, state: &mut H) {
651        state.write_u8(0);
652    }
653}
654
655impl Debug for PadByte {
656    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
657        f.write_str("-")
658    }
659}
660
661#[repr(C)]
662#[derive(Debug, Clone, Eq, PartialEq)]
663pub struct zx_clock_create_args_v1_t {
664    pub backstop_time: zx_time_t,
665}
666
667#[repr(C)]
668#[derive(Debug, Default, Clone, Eq, PartialEq)]
669pub struct zx_clock_rate_t {
670    pub synthetic_ticks: u32,
671    pub reference_ticks: u32,
672}
673
674#[repr(C)]
675#[derive(Debug, Default, Clone, Eq, PartialEq)]
676pub struct zx_clock_transformation_t {
677    pub reference_offset: i64,
678    pub synthetic_offset: i64,
679    pub rate: zx_clock_rate_t,
680}
681
682#[repr(C)]
683#[derive(Debug, Default, Clone, Eq, PartialEq)]
684pub struct zx_clock_details_v1_t {
685    pub options: u64,
686    pub backstop_time: zx_time_t,
687    pub reference_ticks_to_synthetic: zx_clock_transformation_t,
688    pub reference_to_synthetic: zx_clock_transformation_t,
689    pub error_bound: u64,
690    pub query_ticks: zx_ticks_t,
691    pub last_value_update_ticks: zx_ticks_t,
692    pub last_rate_adjust_update_ticks: zx_ticks_t,
693    pub last_error_bounds_update_ticks: zx_ticks_t,
694    pub generation_counter: u32,
695    padding1: [PadByte; 4],
696}
697
698#[repr(C)]
699#[derive(Debug, Clone, Eq, PartialEq)]
700pub struct zx_clock_update_args_v1_t {
701    pub rate_adjust: i32,
702    padding1: [PadByte; 4],
703    pub value: i64,
704    pub error_bound: u64,
705}
706
707#[repr(C)]
708#[derive(Debug, Default, Clone, Eq, PartialEq)]
709pub struct zx_clock_update_args_v2_t {
710    pub rate_adjust: i32,
711    padding1: [PadByte; 4],
712    pub synthetic_value: i64,
713    pub reference_value: i64,
714    pub error_bound: u64,
715}
716
717multiconst!(zx_stream_seek_origin_t, [
718    ZX_STREAM_SEEK_ORIGIN_START        = 0;
719    ZX_STREAM_SEEK_ORIGIN_CURRENT      = 1;
720    ZX_STREAM_SEEK_ORIGIN_END          = 2;
721]);
722
723// Stream constants
724pub const ZX_STREAM_MODE_READ: u32 = 1 << 0;
725pub const ZX_STREAM_MODE_WRITE: u32 = 1 << 1;
726pub const ZX_STREAM_MODE_APPEND: u32 = 1 << 2;
727
728pub const ZX_STREAM_APPEND: u32 = 1 << 0;
729
730pub const ZX_CPRNG_ADD_ENTROPY_MAX_LEN: usize = 256;
731
732// Socket flags and limits.
733pub const ZX_SOCKET_STREAM: u32 = 0;
734pub const ZX_SOCKET_DATAGRAM: u32 = 1 << 0;
735pub const ZX_SOCKET_DISPOSITION_WRITE_DISABLED: u32 = 1 << 0;
736pub const ZX_SOCKET_DISPOSITION_WRITE_ENABLED: u32 = 1 << 1;
737
738// VM Object clone flags
739pub const ZX_VMO_CHILD_SNAPSHOT: u32 = 1 << 0;
740pub const ZX_VMO_CHILD_SNAPSHOT_AT_LEAST_ON_WRITE: u32 = 1 << 4;
741pub const ZX_VMO_CHILD_RESIZABLE: u32 = 1 << 2;
742pub const ZX_VMO_CHILD_SLICE: u32 = 1 << 3;
743pub const ZX_VMO_CHILD_NO_WRITE: u32 = 1 << 5;
744pub const ZX_VMO_CHILD_REFERENCE: u32 = 1 << 6;
745pub const ZX_VMO_CHILD_SNAPSHOT_MODIFIED: u32 = 1 << 7;
746
747// channel write size constants
748pub const ZX_CHANNEL_MAX_MSG_HANDLES: u32 = 64;
749pub const ZX_CHANNEL_MAX_MSG_BYTES: u32 = 65536;
750pub const ZX_CHANNEL_MAX_MSG_IOVEC: u32 = 8192;
751
752// fifo write size constants
753pub const ZX_FIFO_MAX_SIZE_BYTES: u32 = 4096;
754
755// Min/max page size constants
756#[cfg(target_arch = "x86_64")]
757pub const ZX_MIN_PAGE_SHIFT: u32 = 12;
758#[cfg(target_arch = "x86_64")]
759pub const ZX_MAX_PAGE_SHIFT: u32 = 21;
760
761#[cfg(target_arch = "aarch64")]
762pub const ZX_MIN_PAGE_SHIFT: u32 = 12;
763#[cfg(target_arch = "aarch64")]
764pub const ZX_MAX_PAGE_SHIFT: u32 = 16;
765
766#[cfg(target_arch = "riscv64")]
767pub const ZX_MIN_PAGE_SHIFT: u32 = 12;
768#[cfg(target_arch = "riscv64")]
769pub const ZX_MAX_PAGE_SHIFT: u32 = 21;
770
771// Task response codes if a process is externally killed
772pub const ZX_TASK_RETCODE_SYSCALL_KILL: i64 = -1024;
773pub const ZX_TASK_RETCODE_OOM_KILL: i64 = -1025;
774pub const ZX_TASK_RETCODE_POLICY_KILL: i64 = -1026;
775pub const ZX_TASK_RETCODE_VDSO_KILL: i64 = -1027;
776pub const ZX_TASK_RETCODE_EXCEPTION_KILL: i64 = -1028;
777
778// Resource flags.
779pub const ZX_RSRC_FLAG_EXCLUSIVE: zx_rsrc_flags_t = 0x00010000;
780
781// Topics for CPU performance info syscalls
782pub const ZX_CPU_PERF_SCALE: u32 = 1;
783pub const ZX_CPU_DEFAULT_PERF_SCALE: u32 = 2;
784pub const ZX_CPU_POWER_LIMIT: u32 = 3;
785
786// Cache policy flags.
787pub const ZX_CACHE_POLICY_CACHED: u32 = 0;
788pub const ZX_CACHE_POLICY_UNCACHED: u32 = 1;
789pub const ZX_CACHE_POLICY_UNCACHED_DEVICE: u32 = 2;
790pub const ZX_CACHE_POLICY_WRITE_COMBINING: u32 = 3;
791
792// Flag bits for zx_cache_flush.
793multiconst!(u32, [
794    ZX_CACHE_FLUSH_INSN         = 1 << 0;
795    ZX_CACHE_FLUSH_DATA         = 1 << 1;
796    ZX_CACHE_FLUSH_INVALIDATE   = 1 << 2;
797]);
798
799#[repr(C)]
800#[derive(Debug, Copy, Clone, Eq, PartialEq)]
801pub struct zx_wait_item_t {
802    pub handle: zx_handle_t,
803    pub waitfor: zx_signals_t,
804    pub pending: zx_signals_t,
805}
806
807#[repr(C)]
808#[derive(Debug, Copy, Clone, Eq, PartialEq)]
809pub struct zx_waitset_result_t {
810    pub cookie: u64,
811    pub status: zx_status_t,
812    pub observed: zx_signals_t,
813}
814
815#[repr(C)]
816#[derive(Debug, Copy, Clone, Eq, PartialEq)]
817pub struct zx_handle_info_t {
818    pub handle: zx_handle_t,
819    pub ty: zx_obj_type_t,
820    pub rights: zx_rights_t,
821    pub unused: u32,
822}
823
824pub const ZX_CHANNEL_READ_MAY_DISCARD: u32 = 1;
825pub const ZX_CHANNEL_WRITE_USE_IOVEC: u32 = 2;
826
827#[repr(C)]
828#[derive(Debug, Copy, Clone, Eq, PartialEq)]
829pub struct zx_channel_call_args_t {
830    pub wr_bytes: *const u8,
831    pub wr_handles: *const zx_handle_t,
832    pub rd_bytes: *mut u8,
833    pub rd_handles: *mut zx_handle_t,
834    pub wr_num_bytes: u32,
835    pub wr_num_handles: u32,
836    pub rd_num_bytes: u32,
837    pub rd_num_handles: u32,
838}
839
840#[repr(C)]
841#[derive(Debug, Copy, Clone, Eq, PartialEq)]
842pub struct zx_channel_call_etc_args_t {
843    pub wr_bytes: *const u8,
844    pub wr_handles: *mut zx_handle_disposition_t,
845    pub rd_bytes: *mut u8,
846    pub rd_handles: *mut zx_handle_info_t,
847    pub wr_num_bytes: u32,
848    pub wr_num_handles: u32,
849    pub rd_num_bytes: u32,
850    pub rd_num_handles: u32,
851}
852
853#[repr(C)]
854#[derive(Debug, Copy, Clone, Eq, PartialEq)]
855pub struct zx_channel_iovec_t {
856    pub buffer: *const u8,
857    pub capacity: u32,
858    padding1: [PadByte; 4],
859}
860
861impl Default for zx_channel_iovec_t {
862    fn default() -> Self {
863        Self {
864            buffer: std::ptr::null(),
865            capacity: Default::default(),
866            padding1: Default::default(),
867        }
868    }
869}
870
871#[repr(C)]
872#[derive(Debug, Copy, Clone, Eq, PartialEq)]
873pub struct zx_handle_disposition_t {
874    pub operation: zx_handle_op_t,
875    pub handle: zx_handle_t,
876    pub type_: zx_obj_type_t,
877    pub rights: zx_rights_t,
878    pub result: zx_status_t,
879}
880
881#[repr(C)]
882#[derive(Debug, Copy, Clone)]
883pub struct zx_iovec_t {
884    pub buffer: *const u8,
885    pub capacity: usize,
886}
887
888pub type zx_pci_irq_swizzle_lut_t = [[[u32; 4]; 8]; 32];
889
890#[repr(C)]
891#[derive(Debug, Copy, Clone, Eq, PartialEq)]
892pub struct zx_pci_init_arg_t {
893    pub dev_pin_to_global_irq: zx_pci_irq_swizzle_lut_t,
894    pub num_irqs: u32,
895    pub irqs: [zx_irq_t; 32],
896    pub ecam_window_count: u32,
897    // Note: the ecam_windows field is actually a variable size array.
898    // We use a fixed size array to match the C repr.
899    pub ecam_windows: [zx_ecam_window_t; 1],
900}
901
902#[repr(C)]
903#[derive(Debug, Copy, Clone, Eq, PartialEq)]
904pub struct zx_irq_t {
905    pub global_irq: u32,
906    pub level_triggered: bool,
907    pub active_high: bool,
908}
909
910#[repr(C)]
911#[derive(Debug, Copy, Clone, Eq, PartialEq)]
912pub struct zx_ecam_window_t {
913    pub base: u64,
914    pub size: usize,
915    pub bus_start: u8,
916    pub bus_end: u8,
917}
918
919#[repr(C)]
920#[derive(Debug, Copy, Clone, Eq, PartialEq)]
921pub struct zx_pcie_device_info_t {
922    pub vendor_id: u16,
923    pub device_id: u16,
924    pub base_class: u8,
925    pub sub_class: u8,
926    pub program_interface: u8,
927    pub revision_id: u8,
928    pub bus_id: u8,
929    pub dev_id: u8,
930    pub func_id: u8,
931}
932
933#[repr(C)]
934#[derive(Debug, Copy, Clone, Eq, PartialEq)]
935pub struct zx_pci_resource_t {
936    pub type_: u32,
937    pub size: usize,
938    // TODO: Actually a union
939    pub pio_addr: usize,
940}
941
942// TODO: Actually a union
943pub type zx_rrec_t = [u8; 64];
944
945// Ports V2
946#[repr(u32)]
947#[derive(Debug, Copy, Clone, Eq, PartialEq)]
948pub enum zx_packet_type_t {
949    ZX_PKT_TYPE_USER = 0,
950    ZX_PKT_TYPE_SIGNAL_ONE = 1,
951    ZX_PKT_TYPE_GUEST_BELL = 3,
952    ZX_PKT_TYPE_GUEST_MEM = 4,
953    ZX_PKT_TYPE_GUEST_IO = 5,
954    ZX_PKT_TYPE_GUEST_VCPU = 6,
955    ZX_PKT_TYPE_INTERRUPT = 7,
956    ZX_PKT_TYPE_PAGE_REQUEST = 9,
957    ZX_PKT_TYPE_PROCESSOR_POWER_LEVEL_TRANSITION_REQUEST = 10,
958    #[doc(hidden)]
959    __Nonexhaustive,
960}
961
962impl Default for zx_packet_type_t {
963    fn default() -> Self {
964        zx_packet_type_t::ZX_PKT_TYPE_USER
965    }
966}
967
968#[repr(u32)]
969#[derive(Debug, Copy, Clone, Default, Eq, PartialEq)]
970pub enum zx_packet_guest_vcpu_type_t {
971    #[default]
972    ZX_PKT_GUEST_VCPU_INTERRUPT = 0,
973    ZX_PKT_GUEST_VCPU_STARTUP = 1,
974    ZX_PKT_GUEST_VCPU_EXIT = 2,
975    #[doc(hidden)]
976    __Nonexhaustive,
977}
978
979#[repr(C)]
980#[derive(Debug, Copy, Clone, Eq, PartialEq)]
981pub struct zx_packet_signal_t {
982    pub trigger: zx_signals_t,
983    pub observed: zx_signals_t,
984    pub count: u64,
985    pub timestamp: zx_time_t,
986}
987
988pub const ZX_WAIT_ASYNC_TIMESTAMP: u32 = 1;
989pub const ZX_WAIT_ASYNC_EDGE: u32 = 2;
990pub const ZX_WAIT_ASYNC_BOOT_TIMESTAMP: u32 = 4;
991
992// Actually a union of different integer types, but this should be good enough.
993pub type zx_packet_user_t = [u8; 32];
994
995#[repr(C)]
996#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
997pub struct zx_port_packet_t {
998    pub key: u64,
999    pub packet_type: zx_packet_type_t,
1000    pub status: i32,
1001    pub union: [u8; 32],
1002}
1003
1004#[repr(C)]
1005#[derive(Debug, Copy, Clone, Eq, PartialEq)]
1006pub struct zx_packet_guest_bell_t {
1007    pub addr: zx_gpaddr_t,
1008}
1009
1010#[repr(C)]
1011#[derive(Debug, Copy, Clone, Eq, PartialEq)]
1012pub struct zx_packet_guest_io_t {
1013    pub port: u16,
1014    pub access_size: u8,
1015    pub input: bool,
1016    pub data: [u8; 4],
1017}
1018
1019#[repr(C)]
1020#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
1021#[cfg_attr(feature = "zerocopy", derive(FromBytes, Immutable))]
1022pub struct zx_packet_guest_vcpu_interrupt_t {
1023    pub mask: u64,
1024    pub vector: u8,
1025    padding1: [PadByte; 7],
1026}
1027
1028#[repr(C)]
1029#[derive(Debug, Copy, Clone, Eq, PartialEq)]
1030#[cfg_attr(feature = "zerocopy", derive(FromBytes, Immutable))]
1031pub struct zx_packet_guest_vcpu_startup_t {
1032    pub id: u64,
1033    pub entry: zx_gpaddr_t,
1034}
1035
1036#[repr(C)]
1037#[derive(Debug, Copy, Clone, Default, Eq, PartialEq)]
1038#[cfg_attr(feature = "zerocopy", derive(FromBytes, Immutable))]
1039pub struct zx_packet_guest_vcpu_exit_t {
1040    pub retcode: i64,
1041    padding1: [PadByte; 8],
1042}
1043
1044#[repr(C)]
1045#[derive(Copy, Clone)]
1046#[cfg_attr(feature = "zerocopy", derive(FromBytes, Immutable))]
1047pub union zx_packet_guest_vcpu_union_t {
1048    pub interrupt: zx_packet_guest_vcpu_interrupt_t,
1049    pub startup: zx_packet_guest_vcpu_startup_t,
1050    pub exit: zx_packet_guest_vcpu_exit_t,
1051}
1052
1053#[cfg(feature = "zerocopy")]
1054impl Default for zx_packet_guest_vcpu_union_t {
1055    fn default() -> Self {
1056        Self::new_zeroed()
1057    }
1058}
1059
1060#[repr(C)]
1061#[derive(Copy, Clone, Default)]
1062pub struct zx_packet_guest_vcpu_t {
1063    pub r#type: zx_packet_guest_vcpu_type_t,
1064    padding1: [PadByte; 4],
1065    pub union: zx_packet_guest_vcpu_union_t,
1066    padding2: [PadByte; 8],
1067}
1068
1069impl PartialEq for zx_packet_guest_vcpu_t {
1070    fn eq(&self, other: &Self) -> bool {
1071        if self.r#type != other.r#type {
1072            return false;
1073        }
1074        match self.r#type {
1075            zx_packet_guest_vcpu_type_t::ZX_PKT_GUEST_VCPU_INTERRUPT => unsafe {
1076                self.union.interrupt == other.union.interrupt
1077            },
1078            zx_packet_guest_vcpu_type_t::ZX_PKT_GUEST_VCPU_STARTUP => unsafe {
1079                self.union.startup == other.union.startup
1080            },
1081            zx_packet_guest_vcpu_type_t::ZX_PKT_GUEST_VCPU_EXIT => unsafe {
1082                self.union.exit == other.union.exit
1083            },
1084            // No equality relationship is defined for invalid types.
1085            _ => false,
1086        }
1087    }
1088}
1089
1090impl Eq for zx_packet_guest_vcpu_t {}
1091
1092impl Debug for zx_packet_guest_vcpu_t {
1093    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1094        match self.r#type {
1095            zx_packet_guest_vcpu_type_t::ZX_PKT_GUEST_VCPU_INTERRUPT => {
1096                write!(f, "type: {:?} union: {:?}", self.r#type, unsafe { self.union.interrupt })
1097            }
1098            zx_packet_guest_vcpu_type_t::ZX_PKT_GUEST_VCPU_STARTUP => {
1099                write!(f, "type: {:?} union: {:?}", self.r#type, unsafe { self.union.startup })
1100            }
1101            zx_packet_guest_vcpu_type_t::ZX_PKT_GUEST_VCPU_EXIT => {
1102                write!(f, "type: {:?} union: {:?}", self.r#type, unsafe { self.union.exit })
1103            }
1104            _ => panic!("unexpected VCPU packet type"),
1105        }
1106    }
1107}
1108
1109#[repr(C)]
1110#[derive(Debug, Copy, Clone, Default, Eq, PartialEq)]
1111pub struct zx_packet_page_request_t {
1112    pub command: zx_page_request_command_t,
1113    pub flags: u16,
1114    padding1: [PadByte; 4],
1115    pub offset: u64,
1116    pub length: u64,
1117    padding2: [PadByte; 8],
1118}
1119
1120#[repr(u16)]
1121#[derive(Debug, Copy, Clone, Default, Eq, PartialEq)]
1122pub enum zx_page_request_command_t {
1123    #[default]
1124    ZX_PAGER_VMO_READ = 0x0000,
1125    ZX_PAGER_VMO_COMPLETE = 0x0001,
1126    ZX_PAGER_VMO_DIRTY = 0x0002,
1127    #[doc(hidden)]
1128    __Nonexhaustive,
1129}
1130
1131multiconst!(u32, [
1132    ZX_PAGER_OP_FAIL = 1;
1133    ZX_PAGER_OP_DIRTY = 2;
1134    ZX_PAGER_OP_WRITEBACK_BEGIN = 3;
1135    ZX_PAGER_OP_WRITEBACK_END = 4;
1136]);
1137
1138pub type zx_excp_type_t = u32;
1139
1140multiconst!(zx_excp_type_t, [
1141    ZX_EXCP_GENERAL               = 0x008;
1142    ZX_EXCP_FATAL_PAGE_FAULT      = 0x108;
1143    ZX_EXCP_UNDEFINED_INSTRUCTION = 0x208;
1144    ZX_EXCP_SW_BREAKPOINT         = 0x308;
1145    ZX_EXCP_HW_BREAKPOINT         = 0x408;
1146    ZX_EXCP_UNALIGNED_ACCESS      = 0x508;
1147
1148    ZX_EXCP_SYNTH                 = 0x8000;
1149
1150    ZX_EXCP_THREAD_STARTING       = 0x008 | ZX_EXCP_SYNTH;
1151    ZX_EXCP_THREAD_EXITING        = 0x108 | ZX_EXCP_SYNTH;
1152    ZX_EXCP_POLICY_ERROR          = 0x208 | ZX_EXCP_SYNTH;
1153    ZX_EXCP_PROCESS_STARTING      = 0x308 | ZX_EXCP_SYNTH;
1154    ZX_EXCP_USER                  = 0x309 | ZX_EXCP_SYNTH;
1155]);
1156
1157multiconst!(u32, [
1158    ZX_EXCP_USER_CODE_PROCESS_NAME_CHANGED = 0x0001;
1159
1160    ZX_EXCP_USER_CODE_USER0                = 0xF000;
1161    ZX_EXCP_USER_CODE_USER1                = 0xF001;
1162    ZX_EXCP_USER_CODE_USER2                = 0xF002;
1163]);
1164
1165#[repr(C)]
1166#[derive(Debug, Copy, Clone, Eq, PartialEq)]
1167#[cfg_attr(feature = "zerocopy", derive(FromBytes, Immutable, IntoBytes))]
1168pub struct zx_exception_info_t {
1169    pub pid: zx_koid_t,
1170    pub tid: zx_koid_t,
1171    pub type_: zx_excp_type_t,
1172    padding1: [PadByte; 4],
1173}
1174
1175#[repr(C)]
1176#[derive(Default, Copy, Clone, Eq, PartialEq, KnownLayout, FromBytes, Immutable)]
1177pub struct zx_x86_64_exc_data_t {
1178    pub vector: u64,
1179    pub err_code: u64,
1180    pub cr2: u64,
1181}
1182
1183impl Debug for zx_x86_64_exc_data_t {
1184    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1185        write!(f, "vector 0x{:x} err_code {} cr2 0x{:x}", self.vector, self.err_code, self.cr2)
1186    }
1187}
1188
1189#[repr(C)]
1190#[derive(Default, Copy, Clone, Eq, PartialEq, FromBytes, Immutable)]
1191pub struct zx_arm64_exc_data_t {
1192    pub esr: u32,
1193    padding1: [PadByte; 4],
1194    pub far: u64,
1195    padding2: [PadByte; 8],
1196}
1197
1198impl Debug for zx_arm64_exc_data_t {
1199    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1200        write!(f, "esr 0x{:x} far 0x{:x}", self.esr, self.far)
1201    }
1202}
1203
1204#[repr(C)]
1205#[derive(Default, Copy, Clone, Eq, PartialEq, FromBytes, Immutable)]
1206pub struct zx_riscv64_exc_data_t {
1207    pub cause: u64,
1208    pub tval: u64,
1209    padding1: [PadByte; 8],
1210}
1211
1212impl Debug for zx_riscv64_exc_data_t {
1213    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1214        write!(f, "cause {} tval {}", self.cause, self.tval)
1215    }
1216}
1217
1218#[repr(C)]
1219#[derive(Copy, Clone, KnownLayout, FromBytes, Immutable)]
1220pub union zx_exception_header_arch_t {
1221    pub x86_64: zx_x86_64_exc_data_t,
1222    pub arm_64: zx_arm64_exc_data_t,
1223    pub riscv_64: zx_riscv64_exc_data_t,
1224}
1225
1226impl Debug for zx_exception_header_arch_t {
1227    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1228        write!(f, "zx_exception_header_arch_t ")?;
1229        #[cfg(target_arch = "x86_64")]
1230        {
1231            // SAFETY: Exception reports are presumed to be from the target architecture.
1232            // Even if it was not, it's sound to treat the union as another variant as
1233            // the size and alignment are the same, there is no internal padding, and
1234            // the variants have no validity invariants.
1235            let x86_64 = unsafe { self.x86_64 };
1236            write!(f, "{x86_64:?}")
1237        }
1238        #[cfg(target_arch = "aarch64")]
1239        {
1240            // SAFETY: Exception reports are presumed to be from the target architecture.
1241            // Even if it was not, it's sound to treat the union as another variant as
1242            // the size and alignment are the same, there is no internal padding, and
1243            // the variants have no validity invariants.
1244            let arm_64 = unsafe { self.arm_64 };
1245            write!(f, "{arm_64:?}")
1246        }
1247        #[cfg(target_arch = "riscv64")]
1248        {
1249            // SAFETY: Exception reports are presumed to be from the target architecture.
1250            // Even if it was not, it's sound to treat the union as another variant as
1251            // the size and alignment are the same, there is no internal padding, and
1252            // the variants have no validity invariants.
1253            let riscv_64 = unsafe { self.riscv_64 };
1254            write!(f, "{riscv_64:?}")
1255        }
1256    }
1257}
1258
1259#[repr(C)]
1260#[derive(Debug, Copy, Clone, Eq, PartialEq, KnownLayout, FromBytes, Immutable)]
1261pub struct zx_exception_header_t {
1262    pub size: u32,
1263    pub type_: zx_excp_type_t,
1264}
1265
1266pub type zx_excp_policy_code_t = u32;
1267
1268multiconst!(zx_excp_policy_code_t, [
1269    ZX_EXCP_POLICY_CODE_BAD_HANDLE              = 0;
1270    ZX_EXCP_POLICY_CODE_WRONG_OBJECT            = 1;
1271    ZX_EXCP_POLICY_CODE_VMAR_WX                 = 2;
1272    ZX_EXCP_POLICY_CODE_NEW_ANY                 = 3;
1273    ZX_EXCP_POLICY_CODE_NEW_VMO                 = 4;
1274    ZX_EXCP_POLICY_CODE_NEW_CHANNEL             = 5;
1275    ZX_EXCP_POLICY_CODE_NEW_EVENT               = 6;
1276    ZX_EXCP_POLICY_CODE_NEW_EVENTPAIR           = 7;
1277    ZX_EXCP_POLICY_CODE_NEW_PORT                = 8;
1278    ZX_EXCP_POLICY_CODE_NEW_SOCKET              = 9;
1279    ZX_EXCP_POLICY_CODE_NEW_FIFO                = 10;
1280    ZX_EXCP_POLICY_CODE_NEW_TIMER               = 11;
1281    ZX_EXCP_POLICY_CODE_NEW_PROCESS             = 12;
1282    ZX_EXCP_POLICY_CODE_NEW_PROFILE             = 13;
1283    ZX_EXCP_POLICY_CODE_NEW_PAGER               = 14;
1284    ZX_EXCP_POLICY_CODE_AMBIENT_MARK_VMO_EXEC   = 15;
1285    ZX_EXCP_POLICY_CODE_CHANNEL_FULL_WRITE      = 16;
1286    ZX_EXCP_POLICY_CODE_PORT_TOO_MANY_PACKETS   = 17;
1287    ZX_EXCP_POLICY_CODE_BAD_SYSCALL             = 18;
1288    ZX_EXCP_POLICY_CODE_PORT_TOO_MANY_OBSERVERS = 19;
1289    ZX_EXCP_POLICY_CODE_HANDLE_LEAK             = 20;
1290    ZX_EXCP_POLICY_CODE_NEW_IOB                 = 21;
1291]);
1292
1293#[repr(C)]
1294#[derive(Debug, Copy, Clone, KnownLayout, FromBytes, Immutable)]
1295pub struct zx_exception_context_t {
1296    pub arch: zx_exception_header_arch_t,
1297    pub synth_code: zx_excp_policy_code_t,
1298    pub synth_data: u32,
1299}
1300
1301#[repr(C)]
1302#[derive(Debug, Copy, Clone, KnownLayout, FromBytes, Immutable)]
1303pub struct zx_exception_report_t {
1304    pub header: zx_exception_header_t,
1305    pub context: zx_exception_context_t,
1306}
1307
1308pub type zx_exception_state_t = u32;
1309
1310multiconst!(zx_exception_state_t, [
1311    ZX_EXCEPTION_STATE_TRY_NEXT    = 0;
1312    ZX_EXCEPTION_STATE_HANDLED     = 1;
1313    ZX_EXCEPTION_STATE_THREAD_EXIT = 2;
1314]);
1315
1316pub type zx_exception_strategy_t = u32;
1317
1318multiconst!(zx_exception_state_t, [
1319    ZX_EXCEPTION_STRATEGY_FIRST_CHANCE   = 0;
1320    ZX_EXCEPTION_STRATEGY_SECOND_CHANCE  = 1;
1321]);
1322
1323#[cfg(target_arch = "x86_64")]
1324#[repr(C)]
1325#[derive(Default, Copy, Clone, Eq, PartialEq, KnownLayout, FromBytes, Immutable)]
1326pub struct zx_thread_state_general_regs_t {
1327    pub rax: u64,
1328    pub rbx: u64,
1329    pub rcx: u64,
1330    pub rdx: u64,
1331    pub rsi: u64,
1332    pub rdi: u64,
1333    pub rbp: u64,
1334    pub rsp: u64,
1335    pub r8: u64,
1336    pub r9: u64,
1337    pub r10: u64,
1338    pub r11: u64,
1339    pub r12: u64,
1340    pub r13: u64,
1341    pub r14: u64,
1342    pub r15: u64,
1343    pub rip: u64,
1344    pub rflags: u64,
1345    pub fs_base: u64,
1346    pub gs_base: u64,
1347}
1348
1349#[cfg(target_arch = "x86_64")]
1350impl std::fmt::Debug for zx_thread_state_general_regs_t {
1351    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1352        f.debug_struct(std::any::type_name::<Self>())
1353            .field("rax", &format_args!("{:#x}", self.rax))
1354            .field("rbx", &format_args!("{:#x}", self.rbx))
1355            .field("rcx", &format_args!("{:#x}", self.rcx))
1356            .field("rdx", &format_args!("{:#x}", self.rdx))
1357            .field("rsi", &format_args!("{:#x}", self.rsi))
1358            .field("rdi", &format_args!("{:#x}", self.rdi))
1359            .field("rbp", &format_args!("{:#x}", self.rbp))
1360            .field("rsp", &format_args!("{:#x}", self.rsp))
1361            .field("r8", &format_args!("{:#x}", self.r8))
1362            .field("r9", &format_args!("{:#x}", self.r9))
1363            .field("r10", &format_args!("{:#x}", self.r10))
1364            .field("r11", &format_args!("{:#x}", self.r11))
1365            .field("r12", &format_args!("{:#x}", self.r12))
1366            .field("r13", &format_args!("{:#x}", self.r13))
1367            .field("r14", &format_args!("{:#x}", self.r14))
1368            .field("r15", &format_args!("{:#x}", self.r15))
1369            .field("rip", &format_args!("{:#x}", self.rip))
1370            .field("rflags", &format_args!("{:#x}", self.rflags))
1371            .field("fs_base", &format_args!("{:#x}", self.fs_base))
1372            .field("gs_base", &format_args!("{:#x}", self.gs_base))
1373            .finish()
1374    }
1375}
1376
1377#[cfg(target_arch = "x86_64")]
1378impl From<&zx_restricted_state_t> for zx_thread_state_general_regs_t {
1379    fn from(state: &zx_restricted_state_t) -> Self {
1380        Self {
1381            rdi: state.rdi,
1382            rsi: state.rsi,
1383            rbp: state.rbp,
1384            rbx: state.rbx,
1385            rdx: state.rdx,
1386            rcx: state.rcx,
1387            rax: state.rax,
1388            rsp: state.rsp,
1389            r8: state.r8,
1390            r9: state.r9,
1391            r10: state.r10,
1392            r11: state.r11,
1393            r12: state.r12,
1394            r13: state.r13,
1395            r14: state.r14,
1396            r15: state.r15,
1397            rip: state.ip,
1398            rflags: state.flags,
1399            fs_base: state.fs_base,
1400            gs_base: state.gs_base,
1401        }
1402    }
1403}
1404
1405#[cfg(target_arch = "aarch64")]
1406multiconst!(u64, [
1407    ZX_REG_CPSR_ARCH_32_MASK = 0x10;
1408    ZX_REG_CPSR_THUMB_MASK = 0x20;
1409]);
1410
1411#[cfg(target_arch = "aarch64")]
1412#[repr(C)]
1413#[derive(Default, Copy, Clone, Eq, PartialEq)]
1414pub struct zx_thread_state_general_regs_t {
1415    pub r: [u64; 30],
1416    pub lr: u64,
1417    pub sp: u64,
1418    pub pc: u64,
1419    pub cpsr: u64,
1420    pub tpidr: u64,
1421}
1422
1423#[cfg(target_arch = "aarch64")]
1424impl std::fmt::Debug for zx_thread_state_general_regs_t {
1425    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1426        struct RegisterAsHex(u64);
1427        impl std::fmt::Debug for RegisterAsHex {
1428            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1429                write!(f, "{:#x}", self.0)
1430            }
1431        }
1432
1433        f.debug_struct(std::any::type_name::<Self>())
1434            .field("r", &self.r.map(RegisterAsHex))
1435            .field("lr", &format_args!("{:#x}", self.lr))
1436            .field("sp", &format_args!("{:#x}", self.sp))
1437            .field("pc", &format_args!("{:#x}", self.pc))
1438            .field("cpsr", &format_args!("{:#x}", self.cpsr))
1439            .field("tpidr", &format_args!("{:#x}", self.tpidr))
1440            .finish()
1441    }
1442}
1443
1444#[cfg(target_arch = "aarch64")]
1445impl From<&zx_restricted_state_t> for zx_thread_state_general_regs_t {
1446    fn from(state: &zx_restricted_state_t) -> Self {
1447        if state.cpsr as u64 & ZX_REG_CPSR_ARCH_32_MASK == ZX_REG_CPSR_ARCH_32_MASK {
1448            // aarch32
1449            Self {
1450                r: [
1451                    state.r[0],
1452                    state.r[1],
1453                    state.r[2],
1454                    state.r[3],
1455                    state.r[4],
1456                    state.r[5],
1457                    state.r[6],
1458                    state.r[7],
1459                    state.r[8],
1460                    state.r[9],
1461                    state.r[10],
1462                    state.r[11],
1463                    state.r[12],
1464                    state.r[13],
1465                    state.r[14],
1466                    state.pc, // ELR overwrites this.
1467                    state.r[16],
1468                    state.r[17],
1469                    state.r[18],
1470                    state.r[19],
1471                    state.r[20],
1472                    state.r[21],
1473                    state.r[22],
1474                    state.r[23],
1475                    state.r[24],
1476                    state.r[25],
1477                    state.r[26],
1478                    state.r[27],
1479                    state.r[28],
1480                    state.r[29],
1481                ],
1482                lr: state.r[14], // R[14] for aarch32
1483                sp: state.r[13], // R[13] for aarch32
1484                // TODO(https://fxbug.dev/379669623) Should it be checked for thumb and make
1485                // sure it isn't over incrementing?
1486                pc: state.pc, // Zircon populated this from elr.
1487                cpsr: state.cpsr as u64,
1488                tpidr: state.tpidr_el0,
1489            }
1490        } else {
1491            Self {
1492                r: [
1493                    state.r[0],
1494                    state.r[1],
1495                    state.r[2],
1496                    state.r[3],
1497                    state.r[4],
1498                    state.r[5],
1499                    state.r[6],
1500                    state.r[7],
1501                    state.r[8],
1502                    state.r[9],
1503                    state.r[10],
1504                    state.r[11],
1505                    state.r[12],
1506                    state.r[13],
1507                    state.r[14],
1508                    state.r[15],
1509                    state.r[16],
1510                    state.r[17],
1511                    state.r[18],
1512                    state.r[19],
1513                    state.r[20],
1514                    state.r[21],
1515                    state.r[22],
1516                    state.r[23],
1517                    state.r[24],
1518                    state.r[25],
1519                    state.r[26],
1520                    state.r[27],
1521                    state.r[28],
1522                    state.r[29],
1523                ],
1524                lr: state.r[30],
1525                sp: state.sp,
1526                pc: state.pc,
1527                cpsr: state.cpsr as u64,
1528                tpidr: state.tpidr_el0,
1529            }
1530        }
1531    }
1532}
1533
1534#[cfg(target_arch = "riscv64")]
1535#[repr(C)]
1536#[derive(Default, Copy, Clone, Eq, PartialEq)]
1537pub struct zx_thread_state_general_regs_t {
1538    pub pc: u64,
1539    pub ra: u64,  // x1
1540    pub sp: u64,  // x2
1541    pub gp: u64,  // x3
1542    pub tp: u64,  // x4
1543    pub t0: u64,  // x5
1544    pub t1: u64,  // x6
1545    pub t2: u64,  // x7
1546    pub s0: u64,  // x8
1547    pub s1: u64,  // x9
1548    pub a0: u64,  // x10
1549    pub a1: u64,  // x11
1550    pub a2: u64,  // x12
1551    pub a3: u64,  // x13
1552    pub a4: u64,  // x14
1553    pub a5: u64,  // x15
1554    pub a6: u64,  // x16
1555    pub a7: u64,  // x17
1556    pub s2: u64,  // x18
1557    pub s3: u64,  // x19
1558    pub s4: u64,  // x20
1559    pub s5: u64,  // x21
1560    pub s6: u64,  // x22
1561    pub s7: u64,  // x23
1562    pub s8: u64,  // x24
1563    pub s9: u64,  // x25
1564    pub s10: u64, // x26
1565    pub s11: u64, // x27
1566    pub t3: u64,  // x28
1567    pub t4: u64,  // x29
1568    pub t5: u64,  // x30
1569    pub t6: u64,  // x31
1570}
1571
1572#[cfg(target_arch = "riscv64")]
1573impl std::fmt::Debug for zx_thread_state_general_regs_t {
1574    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1575        f.debug_struct(std::any::type_name::<Self>())
1576            .field("pc", &format_args!("{:#x}", self.pc))
1577            .field("ra", &format_args!("{:#x}", self.ra)) // x1
1578            .field("sp", &format_args!("{:#x}", self.sp)) // x2
1579            .field("gp", &format_args!("{:#x}", self.gp)) // x3
1580            .field("tp", &format_args!("{:#x}", self.tp)) // x4
1581            .field("t0", &format_args!("{:#x}", self.t0)) // x5
1582            .field("t1", &format_args!("{:#x}", self.t1)) // x6
1583            .field("t2", &format_args!("{:#x}", self.t2)) // x7
1584            .field("s0", &format_args!("{:#x}", self.s0)) // x8
1585            .field("s1", &format_args!("{:#x}", self.s1)) // x9
1586            .field("a0", &format_args!("{:#x}", self.a0)) // x10
1587            .field("a1", &format_args!("{:#x}", self.a1)) // x11
1588            .field("a2", &format_args!("{:#x}", self.a2)) // x12
1589            .field("a3", &format_args!("{:#x}", self.a3)) // x13
1590            .field("a4", &format_args!("{:#x}", self.a4)) // x14
1591            .field("a5", &format_args!("{:#x}", self.a5)) // x15
1592            .field("a6", &format_args!("{:#x}", self.a6)) // x16
1593            .field("a7", &format_args!("{:#x}", self.a7)) // x17
1594            .field("s2", &format_args!("{:#x}", self.s2)) // x18
1595            .field("s3", &format_args!("{:#x}", self.s3)) // x19
1596            .field("s4", &format_args!("{:#x}", self.s4)) // x20
1597            .field("s5", &format_args!("{:#x}", self.s5)) // x21
1598            .field("s6", &format_args!("{:#x}", self.s6)) // x22
1599            .field("s7", &format_args!("{:#x}", self.s7)) // x23
1600            .field("s8", &format_args!("{:#x}", self.s8)) // x24
1601            .field("s9", &format_args!("{:#x}", self.s9)) // x25
1602            .field("s10", &format_args!("{:#x}", self.s10)) // x26
1603            .field("s11", &format_args!("{:#x}", self.s11)) // x27
1604            .field("t3", &format_args!("{:#x}", self.t3)) // x28
1605            .field("t4", &format_args!("{:#x}", self.t4)) // x29
1606            .field("t5", &format_args!("{:#x}", self.t5)) // x30
1607            .field("t6", &format_args!("{:#x}", self.t6)) // x31
1608            .finish()
1609    }
1610}
1611
1612multiconst!(zx_restricted_reason_t, [
1613    ZX_RESTRICTED_REASON_SYSCALL = 0;
1614    ZX_RESTRICTED_REASON_EXCEPTION = 1;
1615    ZX_RESTRICTED_REASON_KICK = 2;
1616]);
1617
1618#[cfg(target_arch = "x86_64")]
1619#[repr(C)]
1620#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
1621pub struct zx_restricted_state_t {
1622    pub rdi: u64,
1623    pub rsi: u64,
1624    pub rbp: u64,
1625    pub rbx: u64,
1626    pub rdx: u64,
1627    pub rcx: u64,
1628    pub rax: u64,
1629    pub rsp: u64,
1630    pub r8: u64,
1631    pub r9: u64,
1632    pub r10: u64,
1633    pub r11: u64,
1634    pub r12: u64,
1635    pub r13: u64,
1636    pub r14: u64,
1637    pub r15: u64,
1638    pub ip: u64,
1639    pub flags: u64,
1640    pub fs_base: u64,
1641    pub gs_base: u64,
1642}
1643
1644#[cfg(target_arch = "x86_64")]
1645impl From<&zx_thread_state_general_regs_t> for zx_restricted_state_t {
1646    fn from(registers: &zx_thread_state_general_regs_t) -> Self {
1647        Self {
1648            rdi: registers.rdi,
1649            rsi: registers.rsi,
1650            rbp: registers.rbp,
1651            rbx: registers.rbx,
1652            rdx: registers.rdx,
1653            rcx: registers.rcx,
1654            rax: registers.rax,
1655            rsp: registers.rsp,
1656            r8: registers.r8,
1657            r9: registers.r9,
1658            r10: registers.r10,
1659            r11: registers.r11,
1660            r12: registers.r12,
1661            r13: registers.r13,
1662            r14: registers.r14,
1663            r15: registers.r15,
1664            ip: registers.rip,
1665            flags: registers.rflags,
1666            fs_base: registers.fs_base,
1667            gs_base: registers.gs_base,
1668        }
1669    }
1670}
1671
1672#[cfg(target_arch = "aarch64")]
1673#[repr(C)]
1674#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
1675pub struct zx_restricted_state_t {
1676    pub r: [u64; 31], // Note: r[30] is `lr` which is separated out in the general regs.
1677    pub sp: u64,
1678    pub pc: u64,
1679    pub tpidr_el0: u64,
1680    // Contains only the user-controllable upper 4-bits (NZCV).
1681    pub cpsr: u32,
1682    padding1: [PadByte; 4],
1683}
1684
1685#[cfg(target_arch = "aarch64")]
1686impl From<&zx_thread_state_general_regs_t> for zx_restricted_state_t {
1687    fn from(registers: &zx_thread_state_general_regs_t) -> Self {
1688        Self {
1689            r: [
1690                registers.r[0],
1691                registers.r[1],
1692                registers.r[2],
1693                registers.r[3],
1694                registers.r[4],
1695                registers.r[5],
1696                registers.r[6],
1697                registers.r[7],
1698                registers.r[8],
1699                registers.r[9],
1700                registers.r[10],
1701                registers.r[11],
1702                registers.r[12],
1703                registers.r[13],
1704                registers.r[14],
1705                registers.r[15],
1706                registers.r[16],
1707                registers.r[17],
1708                registers.r[18],
1709                registers.r[19],
1710                registers.r[20],
1711                registers.r[21],
1712                registers.r[22],
1713                registers.r[23],
1714                registers.r[24],
1715                registers.r[25],
1716                registers.r[26],
1717                registers.r[27],
1718                registers.r[28],
1719                registers.r[29],
1720                registers.lr, // for compat this works nicely with zircon.
1721            ],
1722            pc: registers.pc,
1723            tpidr_el0: registers.tpidr,
1724            sp: registers.sp,
1725            cpsr: registers.cpsr as u32,
1726            padding1: Default::default(),
1727        }
1728    }
1729}
1730
1731#[cfg(target_arch = "riscv64")]
1732pub type zx_restricted_state_t = zx_thread_state_general_regs_t;
1733
1734#[cfg(target_arch = "riscv64")]
1735impl From<&zx_thread_state_general_regs_t> for zx_restricted_state_t {
1736    fn from(registers: &zx_thread_state_general_regs_t) -> Self {
1737        *registers
1738    }
1739}
1740
1741#[repr(C)]
1742#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
1743#[cfg(any(target_arch = "aarch64", target_arch = "x86_64", target_arch = "riscv64"))]
1744pub struct zx_restricted_syscall_t {
1745    pub state: zx_restricted_state_t,
1746}
1747
1748#[repr(C)]
1749#[derive(Copy, Clone)]
1750#[cfg(any(target_arch = "aarch64", target_arch = "x86_64", target_arch = "riscv64"))]
1751pub struct zx_restricted_exception_t {
1752    pub state: zx_restricted_state_t,
1753    pub exception: zx_exception_report_t,
1754}
1755
1756#[cfg(target_arch = "x86_64")]
1757#[repr(C)]
1758#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
1759pub struct zx_vcpu_state_t {
1760    pub rax: u64,
1761    pub rcx: u64,
1762    pub rdx: u64,
1763    pub rbx: u64,
1764    pub rsp: u64,
1765    pub rbp: u64,
1766    pub rsi: u64,
1767    pub rdi: u64,
1768    pub r8: u64,
1769    pub r9: u64,
1770    pub r10: u64,
1771    pub r11: u64,
1772    pub r12: u64,
1773    pub r13: u64,
1774    pub r14: u64,
1775    pub r15: u64,
1776    // Contains only the user-controllable lower 32-bits.
1777    pub rflags: u64,
1778}
1779
1780#[cfg(target_arch = "aarch64")]
1781#[repr(C)]
1782#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
1783pub struct zx_vcpu_state_t {
1784    pub x: [u64; 31],
1785    pub sp: u64,
1786    // Contains only the user-controllable upper 4-bits (NZCV).
1787    pub cpsr: u32,
1788    padding1: [PadByte; 4],
1789}
1790
1791#[cfg(target_arch = "riscv64")]
1792#[repr(C)]
1793#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
1794pub struct zx_vcpu_state_t {
1795    pub empty: u32,
1796}
1797
1798#[repr(C)]
1799#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
1800pub struct zx_vcpu_io_t {
1801    pub access_size: u8,
1802    padding1: [PadByte; 3],
1803    pub data: [u8; 4],
1804}
1805
1806#[cfg(target_arch = "aarch64")]
1807#[repr(C)]
1808#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
1809pub struct zx_packet_guest_mem_t {
1810    pub addr: zx_gpaddr_t,
1811    pub access_size: u8,
1812    pub sign_extend: bool,
1813    pub xt: u8,
1814    pub read: bool,
1815    pub data: u64,
1816}
1817
1818#[cfg(target_arch = "riscv64")]
1819#[repr(C)]
1820#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
1821pub struct zx_packet_guest_mem_t {
1822    pub addr: zx_gpaddr_t,
1823    padding1: [PadByte; 24],
1824}
1825
1826pub const X86_MAX_INST_LEN: usize = 15;
1827
1828#[cfg(target_arch = "x86_64")]
1829#[repr(C)]
1830#[derive(Debug, Copy, Clone, Eq, PartialEq)]
1831pub struct zx_packet_guest_mem_t {
1832    pub addr: zx_gpaddr_t,
1833    pub cr3: zx_gpaddr_t,
1834    pub rip: zx_vaddr_t,
1835    pub instruction_size: u8,
1836    pub default_operand_size: u8,
1837}
1838
1839#[repr(C)]
1840#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
1841pub struct zx_packet_interrupt_t {
1842    pub timestamp: zx_time_t,
1843    padding1: [PadByte; 24],
1844}
1845
1846// Helper for constructing topics that have been versioned.
1847const fn info_topic(topic: u32, version: u32) -> u32 {
1848    (version << 28) | topic
1849}
1850
1851multiconst!(zx_object_info_topic_t, [
1852    ZX_INFO_NONE                       = 0;
1853    ZX_INFO_HANDLE_VALID               = 1;
1854    ZX_INFO_HANDLE_BASIC               = 2;  // zx_info_handle_basic_t[1]
1855    ZX_INFO_PROCESS                    = info_topic(3, 1);  // zx_info_process_t[1]
1856    ZX_INFO_PROCESS_THREADS            = 4;  // zx_koid_t[n]
1857    ZX_INFO_VMAR                       = 7;  // zx_info_vmar_t[1]
1858    ZX_INFO_JOB_CHILDREN               = 8;  // zx_koid_t[n]
1859    ZX_INFO_JOB_PROCESSES              = 9;  // zx_koid_t[n]
1860    ZX_INFO_THREAD                     = 10; // zx_info_thread_t[1]
1861    ZX_INFO_THREAD_EXCEPTION_REPORT    = info_topic(11, 1); // zx_exception_report_t[1]
1862    ZX_INFO_TASK_STATS                 = info_topic(12, 1); // zx_info_task_stats_t[1]
1863    ZX_INFO_PROCESS_MAPS               = info_topic(13, 2); // zx_info_maps_t[n]
1864    ZX_INFO_PROCESS_VMOS               = info_topic(14, 3); // zx_info_vmo_t[n]
1865    ZX_INFO_THREAD_STATS               = 15; // zx_info_thread_stats_t[1]
1866    ZX_INFO_CPU_STATS                  = 16; // zx_info_cpu_stats_t[n]
1867    ZX_INFO_KMEM_STATS                 = info_topic(17, 1); // zx_info_kmem_stats_t[1]
1868    ZX_INFO_RESOURCE                   = 18; // zx_info_resource_t[1]
1869    ZX_INFO_HANDLE_COUNT               = 19; // zx_info_handle_count_t[1]
1870    ZX_INFO_BTI                        = 20; // zx_info_bti_t[1]
1871    ZX_INFO_PROCESS_HANDLE_STATS       = 21; // zx_info_process_handle_stats_t[1]
1872    ZX_INFO_SOCKET                     = 22; // zx_info_socket_t[1]
1873    ZX_INFO_VMO                        = info_topic(23, 3); // zx_info_vmo_t[1]
1874    ZX_INFO_JOB                        = 24; // zx_info_job_t[1]
1875    ZX_INFO_TIMER                      = 25; // zx_info_timer_t[1]
1876    ZX_INFO_STREAM                     = 26; // zx_info_stream_t[1]
1877    ZX_INFO_HANDLE_TABLE               = 27; // zx_info_handle_extended_t[n]
1878    ZX_INFO_MSI                        = 28; // zx_info_msi_t[1]
1879    ZX_INFO_GUEST_STATS                = 29; // zx_info_guest_stats_t[1]
1880    ZX_INFO_TASK_RUNTIME               = info_topic(30, 1); // zx_info_task_runtime_t[1]
1881    ZX_INFO_KMEM_STATS_EXTENDED        = 31; // zx_info_kmem_stats_extended_t[1]
1882    ZX_INFO_VCPU                       = 32; // zx_info_vcpu_t[1]
1883    ZX_INFO_KMEM_STATS_COMPRESSION     = 33; // zx_info_kmem_stats_compression_t[1]
1884    ZX_INFO_IOB                        = 34; // zx_info_iob_t[1]
1885    ZX_INFO_IOB_REGIONS                = 35; // zx_iob_region_info_t[n]
1886    ZX_INFO_VMAR_MAPS                  = 36; // zx_info_maps_t[n]
1887    ZX_INFO_POWER_DOMAINS              = 37; // zx_info_power_domain_info_t[n]
1888    ZX_INFO_MEMORY_STALL               = 38; // zx_info_memory_stall_t[1]
1889    ZX_INFO_CLOCK_MAPPED_SIZE          = 40; // usize[1]
1890]);
1891
1892multiconst!(zx_system_memory_stall_type_t, [
1893    ZX_SYSTEM_MEMORY_STALL_SOME        = 0;
1894    ZX_SYSTEM_MEMORY_STALL_FULL        = 1;
1895]);
1896
1897// This macro takes struct-like syntax and creates another macro that can be used to create
1898// different instances of the struct with different names. This is used to keep struct definitions
1899// from drifting between this crate and the fuchsia-zircon crate where they are identical other
1900// than in name and location.
1901macro_rules! struct_decl_macro {
1902    ( $(#[$attrs:meta])* $vis:vis struct <$macro_name:ident> $($any:tt)* ) => {
1903        #[macro_export]
1904        macro_rules! $macro_name {
1905            ($name:ident) => {
1906                $(#[$attrs])* $vis struct $name $($any)*
1907            }
1908        }
1909    }
1910}
1911
1912// Don't need struct_decl_macro for this, the wrapper is different.
1913#[repr(C)]
1914#[derive(Default, Debug, Copy, Clone, Eq, KnownLayout, FromBytes, Immutable, PartialEq)]
1915pub struct zx_info_handle_basic_t {
1916    pub koid: zx_koid_t,
1917    pub rights: zx_rights_t,
1918    pub type_: zx_obj_type_t,
1919    pub related_koid: zx_koid_t,
1920    padding1: [PadByte; 4],
1921}
1922
1923struct_decl_macro! {
1924    #[repr(C)]
1925    #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
1926    #[derive(zerocopy::FromBytes, zerocopy::Immutable)]
1927    pub struct <zx_info_handle_count_t> {
1928        pub handle_count: u32,
1929    }
1930}
1931
1932zx_info_handle_count_t!(zx_info_handle_count_t);
1933
1934// Don't need struct_decl_macro for this, the wrapper is different.
1935#[repr(C)]
1936#[derive(Default, Debug, Copy, Clone, Eq, PartialEq, KnownLayout, FromBytes, Immutable)]
1937pub struct zx_info_socket_t {
1938    pub options: u32,
1939    pub rx_buf_max: usize,
1940    pub rx_buf_size: usize,
1941    pub rx_buf_available: usize,
1942    pub tx_buf_max: usize,
1943    pub tx_buf_size: usize,
1944}
1945
1946multiconst!(u32, [
1947    ZX_INFO_PROCESS_FLAG_STARTED = 1 << 0;
1948    ZX_INFO_PROCESS_FLAG_EXITED = 1 << 1;
1949    ZX_INFO_PROCESS_FLAG_DEBUGGER_ATTACHED = 1 << 2;
1950]);
1951
1952struct_decl_macro! {
1953    #[repr(C)]
1954    #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
1955    #[derive(zerocopy::FromBytes, zerocopy::Immutable)]
1956    pub struct <zx_info_process_t> {
1957        pub return_code: i64,
1958        pub start_time: zx_time_t,
1959        pub flags: u32,
1960    }
1961}
1962
1963zx_info_process_t!(zx_info_process_t);
1964
1965struct_decl_macro! {
1966    #[repr(C)]
1967    #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
1968    #[derive(zerocopy::FromBytes, zerocopy::Immutable)]
1969    pub struct <zx_info_job_t> {
1970        pub return_code: i64,
1971        pub exited: u8,
1972        pub kill_on_oom: u8,
1973        pub debugger_attached: u8,
1974    }
1975}
1976
1977zx_info_job_t!(zx_info_job_t);
1978
1979struct_decl_macro! {
1980    #[repr(C)]
1981    #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
1982    #[derive(zerocopy::FromBytes, zerocopy::IntoBytes, zerocopy::Immutable)]
1983    pub struct <zx_info_timer_t> {
1984        pub options: u32,
1985        pub clock_id: zx_clock_t,
1986        pub deadline: zx_time_t,
1987        pub slack: zx_duration_t,
1988    }
1989}
1990
1991zx_info_timer_t!(zx_info_timer_t);
1992
1993#[repr(C)]
1994#[derive(Debug, Copy, Clone, Eq, PartialEq)]
1995pub struct zx_policy_basic {
1996    pub condition: u32,
1997    pub policy: u32,
1998}
1999
2000#[repr(C)]
2001#[derive(Debug, Copy, Clone, Eq, PartialEq)]
2002pub struct zx_policy_timer_slack {
2003    pub min_slack: zx_duration_t,
2004    pub default_mode: u32,
2005}
2006
2007multiconst!(u32, [
2008    // policy options
2009    ZX_JOB_POL_RELATIVE = 0;
2010    ZX_JOB_POL_ABSOLUTE = 1;
2011
2012    // policy topic
2013    ZX_JOB_POL_BASIC = 0;
2014    ZX_JOB_POL_TIMER_SLACK = 1;
2015
2016    // policy conditions
2017    ZX_POL_BAD_HANDLE            = 0;
2018    ZX_POL_WRONG_OBJECT          = 1;
2019    ZX_POL_VMAR_WX               = 2;
2020    ZX_POL_NEW_ANY               = 3;
2021    ZX_POL_NEW_VMO               = 4;
2022    ZX_POL_NEW_CHANNEL           = 5;
2023    ZX_POL_NEW_EVENT             = 6;
2024    ZX_POL_NEW_EVENTPAIR         = 7;
2025    ZX_POL_NEW_PORT              = 8;
2026    ZX_POL_NEW_SOCKET            = 9;
2027    ZX_POL_NEW_FIFO              = 10;
2028    ZX_POL_NEW_TIMER             = 11;
2029    ZX_POL_NEW_PROCESS           = 12;
2030    ZX_POL_NEW_PROFILE           = 13;
2031    ZX_POL_NEW_PAGER             = 14;
2032    ZX_POL_AMBIENT_MARK_VMO_EXEC = 15;
2033
2034    // policy actions
2035    ZX_POL_ACTION_ALLOW           = 0;
2036    ZX_POL_ACTION_DENY            = 1;
2037    ZX_POL_ACTION_ALLOW_EXCEPTION = 2;
2038    ZX_POL_ACTION_DENY_EXCEPTION  = 3;
2039    ZX_POL_ACTION_KILL            = 4;
2040
2041    // timer slack default modes
2042    ZX_TIMER_SLACK_CENTER = 0;
2043    ZX_TIMER_SLACK_EARLY  = 1;
2044    ZX_TIMER_SLACK_LATE   = 2;
2045]);
2046
2047multiconst!(u32, [
2048    // critical options
2049    ZX_JOB_CRITICAL_PROCESS_RETCODE_NONZERO = 1 << 0;
2050]);
2051
2052// Don't use struct_decl_macro, wrapper is different.
2053#[repr(C)]
2054#[derive(
2055    Default, Debug, Copy, Clone, Eq, PartialEq, KnownLayout, FromBytes, Immutable, IntoBytes,
2056)]
2057pub struct zx_info_vmo_t {
2058    pub koid: zx_koid_t,
2059    pub name: [u8; ZX_MAX_NAME_LEN],
2060    pub size_bytes: u64,
2061    pub parent_koid: zx_koid_t,
2062    pub num_children: usize,
2063    pub num_mappings: usize,
2064    pub share_count: usize,
2065    pub flags: u32,
2066    padding1: [PadByte; 4],
2067    pub committed_bytes: u64,
2068    pub handle_rights: zx_rights_t,
2069    pub cache_policy: u32,
2070    pub metadata_bytes: u64,
2071    pub committed_change_events: u64,
2072    pub populated_bytes: u64,
2073    pub committed_private_bytes: u64,
2074    pub populated_private_bytes: u64,
2075    pub committed_scaled_bytes: u64,
2076    pub populated_scaled_bytes: u64,
2077    pub committed_fractional_scaled_bytes: u64,
2078    pub populated_fractional_scaled_bytes: u64,
2079}
2080
2081struct_decl_macro! {
2082    #[repr(C)]
2083    #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
2084    #[derive(zerocopy::FromBytes, zerocopy::Immutable)]
2085    pub struct <zx_info_cpu_stats_t> {
2086        pub cpu_number: u32,
2087        pub flags: u32,
2088        pub idle_time: zx_duration_t,
2089        pub reschedules: u64,
2090        pub context_switches: u64,
2091        pub irq_preempts: u64,
2092        pub preempts: u64,
2093        pub yields: u64,
2094        pub ints: u64,
2095        pub timer_ints: u64,
2096        pub timers: u64,
2097        pub page_faults: u64,
2098        pub exceptions: u64,
2099        pub syscalls: u64,
2100        pub reschedule_ipis: u64,
2101        pub generic_ipis: u64,
2102    }
2103}
2104
2105zx_info_cpu_stats_t!(zx_info_cpu_stats_t);
2106
2107struct_decl_macro! {
2108    #[repr(C)]
2109    #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
2110    #[derive(zerocopy::FromBytes, zerocopy::Immutable)]
2111    pub struct <zx_info_kmem_stats_t> {
2112        pub total_bytes: u64,
2113        pub free_bytes: u64,
2114        pub free_loaned_bytes: u64,
2115        pub wired_bytes: u64,
2116        pub total_heap_bytes: u64,
2117        pub free_heap_bytes: u64,
2118        pub vmo_bytes: u64,
2119        pub mmu_overhead_bytes: u64,
2120        pub ipc_bytes: u64,
2121        pub cache_bytes: u64,
2122        pub slab_bytes: u64,
2123        pub zram_bytes: u64,
2124        pub other_bytes: u64,
2125        pub vmo_reclaim_total_bytes: u64,
2126        pub vmo_reclaim_newest_bytes: u64,
2127        pub vmo_reclaim_oldest_bytes: u64,
2128        pub vmo_reclaim_disabled_bytes: u64,
2129        pub vmo_discardable_locked_bytes: u64,
2130        pub vmo_discardable_unlocked_bytes: u64,
2131    }
2132}
2133
2134zx_info_kmem_stats_t!(zx_info_kmem_stats_t);
2135
2136struct_decl_macro! {
2137    #[repr(C)]
2138    #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
2139    #[derive(zerocopy::FromBytes, zerocopy::Immutable)]
2140    pub struct <zx_info_kmem_stats_extended_t> {
2141        pub total_bytes: u64,
2142        pub free_bytes: u64,
2143        pub wired_bytes: u64,
2144        pub total_heap_bytes: u64,
2145        pub free_heap_bytes: u64,
2146        pub vmo_bytes: u64,
2147        pub vmo_pager_total_bytes: u64,
2148        pub vmo_pager_newest_bytes: u64,
2149        pub vmo_pager_oldest_bytes: u64,
2150        pub vmo_discardable_locked_bytes: u64,
2151        pub vmo_discardable_unlocked_bytes: u64,
2152        pub mmu_overhead_bytes: u64,
2153        pub ipc_bytes: u64,
2154        pub other_bytes: u64,
2155        pub vmo_reclaim_disable_bytes: u64,
2156    }
2157}
2158
2159zx_info_kmem_stats_extended_t!(zx_info_kmem_stats_extended_t);
2160
2161struct_decl_macro! {
2162    #[repr(C)]
2163    #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
2164    #[derive(zerocopy::FromBytes, zerocopy::Immutable)]
2165    pub struct <zx_info_kmem_stats_compression_t> {
2166        pub uncompressed_storage_bytes: u64,
2167        pub compressed_storage_bytes: u64,
2168        pub compressed_fragmentation_bytes: u64,
2169        pub compression_time: zx_duration_t,
2170        pub decompression_time: zx_duration_t,
2171        pub total_page_compression_attempts: u64,
2172        pub failed_page_compression_attempts: u64,
2173        pub total_page_decompressions: u64,
2174        pub compressed_page_evictions: u64,
2175        pub eager_page_compressions: u64,
2176        pub memory_pressure_page_compressions: u64,
2177        pub critical_memory_page_compressions: u64,
2178        pub pages_decompressed_unit_ns: u64,
2179        pub pages_decompressed_within_log_time: [u64; 8],
2180    }
2181}
2182
2183zx_info_kmem_stats_compression_t!(zx_info_kmem_stats_compression_t);
2184
2185struct_decl_macro! {
2186    #[repr(C)]
2187    #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
2188    #[derive(zerocopy::FromBytes, zerocopy::Immutable)]
2189    pub struct <zx_info_resource_t> {
2190        pub kind: u32,
2191        pub flags: u32,
2192        pub base: u64,
2193        pub size: usize,
2194        pub name: [u8; ZX_MAX_NAME_LEN],
2195    }
2196}
2197
2198pub type zx_thread_state_t = u32;
2199
2200multiconst!(zx_thread_state_t, [
2201    ZX_THREAD_STATE_NEW = 0x0000;
2202    ZX_THREAD_STATE_RUNNING = 0x0001;
2203    ZX_THREAD_STATE_SUSPENDED = 0x0002;
2204    ZX_THREAD_STATE_BLOCKED = 0x0003;
2205    ZX_THREAD_STATE_DYING = 0x0004;
2206    ZX_THREAD_STATE_DEAD = 0x0005;
2207    ZX_THREAD_STATE_BLOCKED_EXCEPTION = 0x0103;
2208    ZX_THREAD_STATE_BLOCKED_SLEEPING = 0x0203;
2209    ZX_THREAD_STATE_BLOCKED_FUTEX = 0x0303;
2210    ZX_THREAD_STATE_BLOCKED_PORT = 0x0403;
2211    ZX_THREAD_STATE_BLOCKED_CHANNEL = 0x0503;
2212    ZX_THREAD_STATE_BLOCKED_WAIT_ONE = 0x0603;
2213    ZX_THREAD_STATE_BLOCKED_WAIT_MANY = 0x0703;
2214    ZX_THREAD_STATE_BLOCKED_INTERRUPT = 0x0803;
2215    ZX_THREAD_STATE_BLOCKED_PAGER = 0x0903;
2216]);
2217
2218#[repr(C)]
2219#[derive(Default, Debug, Copy, Clone, Eq, PartialEq, zerocopy::FromBytes, zerocopy::Immutable)]
2220pub struct zx_info_thread_t {
2221    pub state: zx_thread_state_t,
2222    pub wait_exception_channel_type: u32,
2223    pub cpu_affinity_mask: zx_cpu_set_t,
2224}
2225
2226struct_decl_macro! {
2227    #[repr(C)]
2228    #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
2229    #[derive(zerocopy::FromBytes, zerocopy::Immutable)]
2230    pub struct <zx_info_thread_stats_t> {
2231        pub total_runtime: zx_duration_t,
2232        pub last_scheduled_cpu: u32,
2233    }
2234}
2235
2236zx_info_thread_stats_t!(zx_info_thread_stats_t);
2237
2238zx_info_resource_t!(zx_info_resource_t);
2239
2240struct_decl_macro! {
2241    #[repr(C)]
2242    #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
2243    #[derive(zerocopy::FromBytes, zerocopy::Immutable)]
2244    pub struct <zx_info_vmar_t> {
2245        pub base: usize,
2246        pub len: usize,
2247    }
2248}
2249
2250zx_info_vmar_t!(zx_info_vmar_t);
2251
2252struct_decl_macro! {
2253    #[repr(C)]
2254    #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
2255    #[derive(zerocopy::FromBytes, zerocopy::Immutable)]
2256    pub struct <zx_info_task_stats_t> {
2257        pub mem_mapped_bytes: usize,
2258        pub mem_private_bytes: usize,
2259        pub mem_shared_bytes: usize,
2260        pub mem_scaled_shared_bytes: usize,
2261        pub mem_fractional_scaled_shared_bytes: u64,
2262    }
2263}
2264
2265zx_info_task_stats_t!(zx_info_task_stats_t);
2266
2267struct_decl_macro! {
2268    #[repr(C)]
2269    #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
2270    #[derive(zerocopy::FromBytes, zerocopy::Immutable)]
2271    pub struct <zx_info_task_runtime_t> {
2272        pub cpu_time: zx_duration_t,
2273        pub queue_time: zx_duration_t,
2274        pub page_fault_time: zx_duration_t,
2275        pub lock_contention_time: zx_duration_t,
2276    }
2277}
2278
2279zx_info_task_runtime_t!(zx_info_task_runtime_t);
2280
2281multiconst!(zx_info_maps_type_t, [
2282    ZX_INFO_MAPS_TYPE_NONE    = 0;
2283    ZX_INFO_MAPS_TYPE_ASPACE  = 1;
2284    ZX_INFO_MAPS_TYPE_VMAR    = 2;
2285    ZX_INFO_MAPS_TYPE_MAPPING = 3;
2286]);
2287
2288struct_decl_macro! {
2289    #[repr(C)]
2290    #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
2291    #[derive(zerocopy::FromBytes, zerocopy::Immutable, IntoBytes)]
2292    pub struct <zx_info_maps_mapping_t> {
2293        pub mmu_flags: zx_vm_option_t,
2294        padding1: [PadByte; 4],
2295        pub vmo_koid: zx_koid_t,
2296        pub vmo_offset: u64,
2297        pub committed_bytes: usize,
2298        pub populated_bytes: usize,
2299        pub committed_private_bytes: usize,
2300        pub populated_private_bytes: usize,
2301        pub committed_scaled_bytes: usize,
2302        pub populated_scaled_bytes: usize,
2303        pub committed_fractional_scaled_bytes: u64,
2304        pub populated_fractional_scaled_bytes: u64,
2305    }
2306}
2307
2308zx_info_maps_mapping_t!(zx_info_maps_mapping_t);
2309
2310#[repr(C)]
2311#[derive(Copy, Clone, KnownLayout, FromBytes, Immutable)]
2312pub union InfoMapsTypeUnion {
2313    pub mapping: zx_info_maps_mapping_t,
2314}
2315
2316struct_decl_macro! {
2317    #[repr(C)]
2318    #[derive(Copy, Clone)]
2319    #[derive(zerocopy::FromBytes, zerocopy::Immutable)]
2320    pub struct <zx_info_maps_t> {
2321        pub name: [u8; ZX_MAX_NAME_LEN],
2322        pub base: zx_vaddr_t,
2323        pub size: usize,
2324        pub depth: usize,
2325        pub r#type: zx_info_maps_type_t,
2326        pub u: InfoMapsTypeUnion,
2327    }
2328}
2329
2330zx_info_maps_t!(zx_info_maps_t);
2331
2332struct_decl_macro! {
2333    #[repr(C)]
2334    #[derive(Debug, Copy, Clone, Eq, PartialEq)]
2335    #[derive(zerocopy::FromBytes, zerocopy::Immutable)]
2336    pub struct <zx_info_process_handle_stats_t> {
2337        pub handle_count: [u32; ZX_OBJ_TYPE_UPPER_BOUND],
2338    }
2339}
2340
2341impl Default for zx_info_process_handle_stats_t {
2342    fn default() -> Self {
2343        Self { handle_count: [0; ZX_OBJ_TYPE_UPPER_BOUND] }
2344    }
2345}
2346
2347zx_info_process_handle_stats_t!(zx_info_process_handle_stats_t);
2348
2349struct_decl_macro! {
2350    #[repr(C)]
2351    #[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
2352    #[derive(zerocopy::FromBytes, zerocopy::Immutable, zerocopy::IntoBytes)]
2353    pub struct <zx_info_memory_stall_t> {
2354        pub stall_time_some: zx_duration_mono_t,
2355        pub stall_time_full: zx_duration_mono_t,
2356    }
2357}
2358
2359zx_info_memory_stall_t!(zx_info_memory_stall_t);
2360
2361// from //zircon/system/public/zircon/syscalls/hypervisor.h
2362multiconst!(zx_guest_option_t, [
2363    ZX_GUEST_OPT_NORMAL = 0;
2364]);
2365
2366multiconst!(zx_guest_trap_t, [
2367    ZX_GUEST_TRAP_BELL = 0;
2368    ZX_GUEST_TRAP_MEM  = 1;
2369    ZX_GUEST_TRAP_IO   = 2;
2370]);
2371
2372pub const ZX_LOG_RECORD_MAX: usize = 256;
2373pub const ZX_LOG_RECORD_DATA_MAX: usize = 216;
2374
2375pub const DEBUGLOG_TRACE: u8 = 0x10;
2376pub const DEBUGLOG_DEBUG: u8 = 0x20;
2377pub const DEBUGLOG_INFO: u8 = 0x30;
2378pub const DEBUGLOG_WARNING: u8 = 0x40;
2379pub const DEBUGLOG_ERROR: u8 = 0x50;
2380pub const DEBUGLOG_FATAL: u8 = 0x60;
2381
2382struct_decl_macro! {
2383    #[repr(C)]
2384    #[derive(Debug, Copy, Clone, Eq, PartialEq)]
2385    #[derive(zerocopy::FromBytes, zerocopy::Immutable)]
2386    pub struct <zx_log_record_t> {
2387        pub sequence: u64,
2388        padding1: [PadByte; 4],
2389        pub datalen: u16,
2390        pub severity: u8,
2391        pub flags: u8,
2392        pub timestamp: zx_instant_boot_t,
2393        pub pid: u64,
2394        pub tid: u64,
2395        pub data: [u8; ZX_LOG_RECORD_DATA_MAX],
2396    }
2397}
2398const_assert_eq!(std::mem::size_of::<zx_log_record_t>(), ZX_LOG_RECORD_MAX);
2399
2400zx_log_record_t!(zx_log_record_t);
2401
2402impl Default for zx_log_record_t {
2403    fn default() -> zx_log_record_t {
2404        zx_log_record_t {
2405            sequence: 0,
2406            padding1: Default::default(),
2407            datalen: 0,
2408            severity: 0,
2409            flags: 0,
2410            timestamp: 0,
2411            pid: 0,
2412            tid: 0,
2413            data: [0; ZX_LOG_RECORD_DATA_MAX],
2414        }
2415    }
2416}
2417
2418multiconst!(u32, [
2419    ZX_LOG_FLAG_READABLE = 0x40000000;
2420]);
2421
2422// For C, the below types are currently forward declared for syscalls.h.
2423// We might want to investigate a better solution for Rust or removing those
2424// forward declarations.
2425//
2426// These are hand typed translations from C types into Rust structures using a C
2427// layout
2428
2429// source: zircon/system/public/zircon/syscalls/system.h
2430#[repr(C)]
2431pub struct zx_system_powerctl_arg_t {
2432    // rust can't express anonymous unions at this time
2433    // https://github.com/rust-lang/rust/issues/49804
2434    pub powerctl_internal: zx_powerctl_union,
2435}
2436
2437#[repr(C)]
2438#[derive(Copy, Clone)]
2439pub union zx_powerctl_union {
2440    acpi_transition_s_state: acpi_transition_s_state,
2441    x86_power_limit: x86_power_limit,
2442}
2443
2444#[repr(C)]
2445#[derive(Default, Debug, PartialEq, Copy, Clone)]
2446pub struct acpi_transition_s_state {
2447    target_s_state: u8, // Value between 1 and 5 indicating which S-state
2448    sleep_type_a: u8,   // Value from ACPI VM (SLP_TYPa)
2449    sleep_type_b: u8,   // Value from ACPI VM (SLP_TYPb)
2450    padding1: [PadByte; 9],
2451}
2452
2453#[repr(C)]
2454#[derive(Default, Debug, PartialEq, Copy, Clone)]
2455pub struct x86_power_limit {
2456    power_limit: u32, // PL1 value in milliwatts
2457    time_window: u32, // PL1 time window in microseconds
2458    clamp: u8,        // PL1 clamping enable
2459    enable: u8,       // PL1 enable
2460    padding1: [PadByte; 2],
2461}
2462
2463// source: zircon/system/public/zircon/syscalls/pci.h
2464pub type zx_pci_bar_types_t = u32;
2465
2466multiconst!(zx_pci_bar_types_t, [
2467            ZX_PCI_BAR_TYPE_UNUSED = 0;
2468            ZX_PCI_BAR_TYPE_MMIO = 1;
2469            ZX_PCI_BAR_TYPE_PIO = 2;
2470]);
2471
2472#[repr(C)]
2473pub struct zx_pci_bar_t {
2474    pub id: u32,
2475    pub ty: u32,
2476    pub size: usize,
2477    // rust can't express anonymous unions at this time
2478    // https://github.com/rust-lang/rust/issues/49804
2479    pub zx_pci_bar_union: zx_pci_bar_union,
2480}
2481
2482#[repr(C)]
2483#[derive(Copy, Clone)]
2484pub union zx_pci_bar_union {
2485    addr: usize,
2486    zx_pci_bar_union_struct: zx_pci_bar_union_struct,
2487}
2488
2489#[repr(C)]
2490#[derive(Default, Debug, PartialEq, Copy, Clone)]
2491pub struct zx_pci_bar_union_struct {
2492    handle: zx_handle_t,
2493    padding1: [PadByte; 4],
2494}
2495
2496// source: zircon/system/public/zircon/syscalls/smc.h
2497#[repr(C)]
2498#[derive(Debug, Copy, Clone, Default, Eq, PartialEq)]
2499pub struct zx_smc_parameters_t {
2500    pub func_id: u32,
2501    padding1: [PadByte; 4],
2502    pub arg1: u64,
2503    pub arg2: u64,
2504    pub arg3: u64,
2505    pub arg4: u64,
2506    pub arg5: u64,
2507    pub arg6: u64,
2508    pub client_id: u16,
2509    pub secure_os_id: u16,
2510    padding2: [PadByte; 4],
2511}
2512
2513#[repr(C)]
2514#[derive(Debug, Copy, Clone, Eq, PartialEq)]
2515pub struct zx_smc_result_t {
2516    pub arg0: u64,
2517    pub arg1: u64,
2518    pub arg2: u64,
2519    pub arg3: u64,
2520    pub arg6: u64,
2521}
2522
2523pub const ZX_CPU_SET_MAX_CPUS: usize = 512;
2524pub const ZX_CPU_SET_BITS_PER_WORD: usize = 64;
2525
2526#[repr(C)]
2527#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, zerocopy::FromBytes, zerocopy::Immutable)]
2528pub struct zx_cpu_set_t {
2529    pub mask: [u64; ZX_CPU_SET_MAX_CPUS / ZX_CPU_SET_BITS_PER_WORD],
2530}
2531
2532// source: zircon/system/public/zircon/syscalls/scheduler.h
2533#[repr(C)]
2534#[derive(Copy, Clone)]
2535pub struct zx_profile_info_t {
2536    pub flags: u32,
2537    padding1: [PadByte; 4],
2538    pub zx_profile_info_union: zx_profile_info_union,
2539    pub cpu_affinity_mask: zx_cpu_set_t,
2540}
2541
2542#[cfg(feature = "zerocopy")]
2543impl Default for zx_profile_info_t {
2544    fn default() -> Self {
2545        Self {
2546            flags: Default::default(),
2547            padding1: Default::default(),
2548            zx_profile_info_union: FromZeros::new_zeroed(),
2549            cpu_affinity_mask: Default::default(),
2550        }
2551    }
2552}
2553
2554#[repr(C)]
2555#[derive(Copy, Clone)]
2556#[cfg_attr(feature = "zerocopy", derive(FromBytes, Immutable))]
2557pub struct priority_params {
2558    pub priority: i32,
2559    padding1: [PadByte; 20],
2560}
2561
2562#[repr(C)]
2563#[derive(Copy, Clone)]
2564#[cfg_attr(feature = "zerocopy", derive(FromBytes, Immutable))]
2565pub union zx_profile_info_union {
2566    pub priority_params: priority_params,
2567    pub deadline_params: zx_sched_deadline_params_t,
2568}
2569
2570#[repr(C)]
2571#[derive(Debug, Copy, Clone, Eq, PartialEq)]
2572#[cfg_attr(feature = "zerocopy", derive(FromBytes, Immutable, KnownLayout))]
2573pub struct zx_sched_deadline_params_t {
2574    pub capacity: zx_duration_t,
2575    pub relative_deadline: zx_duration_t,
2576    pub period: zx_duration_t,
2577}
2578
2579#[repr(C)]
2580#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
2581pub struct zx_cpu_performance_scale_t {
2582    pub integer_part: u32,
2583    pub fractional_part: u32,
2584}
2585
2586#[repr(C)]
2587#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
2588pub struct zx_cpu_performance_info_t {
2589    pub logical_cpu_number: u32,
2590    pub performance_scale: zx_cpu_performance_scale_t,
2591}
2592
2593#[repr(C)]
2594#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
2595pub struct zx_cpu_power_limit_t {
2596    pub logical_cpu_number: u32,
2597    padding1: [PadByte; 4],
2598    pub max_power_nw: u64,
2599}
2600
2601#[repr(C)]
2602#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
2603pub struct zx_iommu_desc_dummy_t {
2604    padding1: PadByte,
2605}
2606
2607multiconst!(u32, [
2608    ZX_IOMMU_TYPE_DUMMY = 0;
2609    ZX_IOMMU_TYPE_INTEL = 1;
2610]);
2611
2612#[repr(C)]
2613#[derive(Debug, Copy, Clone)]
2614pub struct zx_sampler_config_t {
2615    pub period: zx_duration_t,
2616    pub buffer_size: usize,
2617    pub iobuffer_discipline: u64,
2618}
2619
2620multiconst!(zx_processor_power_level_options_t, [
2621    ZX_PROCESSOR_POWER_LEVEL_OPTIONS_DOMAIN_INDEPENDENT = 1 << 0;
2622]);
2623
2624multiconst!(zx_processor_power_control_t, [
2625    ZX_PROCESSOR_POWER_CONTROL_CPU_DRIVER = 0;
2626    ZX_PROCESSOR_POWER_CONTROL_ARM_PSCI = 1;
2627    ZX_PROCESSOR_POWER_CONTROL_ARM_WFI = 2;
2628    ZX_PROCESSOR_POWER_CONTROL_RISCV_SBI = 3;
2629    ZX_PROCESSOR_POWER_CONTROL_RISCV_WFI = 4;
2630]);
2631
2632#[repr(C)]
2633#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
2634pub struct zx_processor_power_level_t {
2635    pub options: zx_processor_power_level_options_t,
2636    pub processing_rate: u64,
2637    pub power_coefficient_nw: u64,
2638    pub control_interface: zx_processor_power_control_t,
2639    pub control_argument: u64,
2640    pub diagnostic_name: [u8; ZX_MAX_NAME_LEN],
2641    padding1: [PadByte; 32],
2642}
2643
2644#[repr(C)]
2645#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
2646pub struct zx_processor_power_level_transition_t {
2647    pub latency: zx_duration_t,
2648    pub energy: u64,
2649    pub from: u8,
2650    pub to: u8,
2651    padding1: [PadByte; 6],
2652}
2653
2654#[repr(C)]
2655#[derive(Debug, Copy, Clone, Default, Eq, PartialEq)]
2656pub struct zx_packet_processor_power_level_transition_request_t {
2657    pub domain_id: u32,
2658    pub options: u32,
2659    pub control_interface: u64,
2660    pub control_argument: u64,
2661    padding1: [PadByte; 8],
2662}
2663
2664#[repr(C)]
2665#[derive(Debug, Copy, Clone, Eq, PartialEq)]
2666pub struct zx_processor_power_state_t {
2667    pub domain_id: u32,
2668    pub options: u32,
2669    pub control_interface: u64,
2670    pub control_argument: u64,
2671}
2672
2673#[repr(C)]
2674#[derive(Debug, Copy, Clone, Default, Eq, PartialEq)]
2675pub struct zx_processor_power_domain_t {
2676    pub cpus: zx_cpu_set_t,
2677    pub domain_id: u32,
2678    padding1: [PadByte; 4],
2679}
2680
2681#[repr(C)]
2682#[derive(Debug, Copy, Clone, Eq, PartialEq)]
2683pub struct zx_power_domain_info_t {
2684    pub cpus: zx_cpu_set_t,
2685    pub domain_id: u32,
2686    pub idle_power_levels: u8,
2687    pub active_power_levels: u8,
2688    padding1: [PadByte; 2],
2689}
2690
2691multiconst!(u32, [
2692    ZX_BTI_PERM_READ = 1 << 0;
2693    ZX_BTI_PERM_WRITE = 1 << 1;
2694    ZX_BTI_PERM_EXECUTE = 1 << 2;
2695    ZX_BTI_COMPRESS = 1 << 3;
2696    ZX_BTI_CONTIGUOUS = 1 << 4;
2697]);
2698
2699// Options for zx_port_create
2700multiconst!(u32, [
2701    ZX_PORT_BIND_TO_INTERRUPT = 1 << 0;
2702]);
2703
2704// Options for zx_interrupt_create
2705multiconst!(u32, [
2706    ZX_INTERRUPT_VIRTUAL = 0x10;
2707    ZX_INTERRUPT_TIMESTAMP_MONO = 1 << 6;
2708]);
2709
2710// Options for zx_interrupt_bind
2711multiconst!(u32, [
2712    ZX_INTERRUPT_BIND = 0;
2713    ZX_INTERRUPT_UNBIND = 1;
2714]);
2715
2716#[repr(C)]
2717pub struct zx_iob_region_t {
2718    pub r#type: zx_iob_region_type_t,
2719    pub access: zx_iob_access_t,
2720    pub size: u64,
2721    pub discipline: zx_iob_discipline_t,
2722    pub extension: zx_iob_region_extension_t,
2723}
2724
2725multiconst!(zx_iob_region_type_t, [
2726    ZX_IOB_REGION_TYPE_PRIVATE = 0;
2727    ZX_IOB_REGION_TYPE_SHARED = 1;
2728]);
2729
2730multiconst!(zx_iob_access_t, [
2731    ZX_IOB_ACCESS_EP0_CAN_MAP_READ = 1 << 0;
2732    ZX_IOB_ACCESS_EP0_CAN_MAP_WRITE = 1 << 1;
2733    ZX_IOB_ACCESS_EP0_CAN_MEDIATED_READ = 1 << 2;
2734    ZX_IOB_ACCESS_EP0_CAN_MEDIATED_WRITE = 1 << 3;
2735    ZX_IOB_ACCESS_EP1_CAN_MAP_READ = 1 << 4;
2736    ZX_IOB_ACCESS_EP1_CAN_MAP_WRITE = 1 << 5;
2737    ZX_IOB_ACCESS_EP1_CAN_MEDIATED_READ = 1 << 6;
2738    ZX_IOB_ACCESS_EP1_CAN_MEDIATED_WRITE = 1 << 7;
2739]);
2740
2741#[repr(C)]
2742#[derive(Copy, Clone)]
2743pub struct zx_iob_discipline_t {
2744    pub r#type: zx_iob_discipline_type_t,
2745    pub extension: zx_iob_discipline_extension_t,
2746}
2747
2748#[repr(C)]
2749#[derive(Copy, Clone)]
2750pub union zx_iob_discipline_extension_t {
2751    // This is in vdso-next.
2752    pub ring_buffer: zx_iob_discipline_mediated_write_ring_buffer_t,
2753    pub reserved: [PadByte; 64],
2754}
2755
2756#[repr(C)]
2757#[derive(Debug, Copy, Clone)]
2758pub struct zx_iob_discipline_mediated_write_ring_buffer_t {
2759    pub tag: u64,
2760    pub padding: [PadByte; 56],
2761}
2762
2763multiconst!(zx_iob_discipline_type_t, [
2764    ZX_IOB_DISCIPLINE_TYPE_NONE = 0;
2765    ZX_IOB_DISCIPLINE_TYPE_MEDIATED_WRITE_RING_BUFFER = 2;
2766]);
2767
2768#[repr(C)]
2769#[derive(Clone, Copy, Default)]
2770pub struct zx_iob_region_private_t {
2771    options: u32,
2772    padding: [PadByte; 28],
2773}
2774
2775#[repr(C)]
2776#[derive(Clone, Copy)]
2777pub struct zx_iob_region_shared_t {
2778    pub options: u32,
2779    pub shared_region: zx_handle_t,
2780    pub padding: [PadByte; 24],
2781}
2782
2783#[repr(C)]
2784pub union zx_iob_region_extension_t {
2785    pub private_region: zx_iob_region_private_t,
2786    pub shared_region: zx_iob_region_shared_t,
2787    pub max_extension: [u8; 32],
2788}
2789
2790#[repr(C)]
2791pub struct zx_wake_source_report_entry_t {
2792    pub koid: zx_koid_t,
2793    pub name: [u8; ZX_MAX_NAME_LEN],
2794    pub initial_signal_time: zx_instant_boot_t,
2795    pub last_signal_time: zx_instant_boot_t,
2796    pub last_ack_time: zx_instant_boot_t,
2797    pub signal_count: u32,
2798    pub flags: u32,
2799}
2800
2801#[repr(C)]
2802pub struct zx_wake_source_report_header_t {
2803    pub report_time: zx_instant_boot_t,
2804    pub suspend_start_time: zx_instant_boot_t,
2805    pub total_wake_sources: u32,
2806    pub unreported_wake_report_entries: u32,
2807}
2808
2809#[cfg(test)]
2810mod test {
2811    use super::*;
2812
2813    #[test]
2814    fn padded_struct_equality() {
2815        let test_struct = zx_clock_update_args_v1_t {
2816            rate_adjust: 222,
2817            padding1: Default::default(),
2818            value: 333,
2819            error_bound: 444,
2820        };
2821
2822        let different_data = zx_clock_update_args_v1_t { rate_adjust: 999, ..test_struct.clone() };
2823
2824        let different_padding = zx_clock_update_args_v1_t {
2825            padding1: [PadByte(0), PadByte(1), PadByte(2), PadByte(3)],
2826            ..test_struct.clone()
2827        };
2828
2829        // Structures with different data should not be equal.
2830        assert_ne!(test_struct, different_data);
2831        // Structures with only different padding should not be equal.
2832        assert_eq!(test_struct, different_padding);
2833    }
2834
2835    #[test]
2836    fn padded_struct_debug() {
2837        let test_struct = zx_clock_update_args_v1_t {
2838            rate_adjust: 222,
2839            padding1: Default::default(),
2840            value: 333,
2841            error_bound: 444,
2842        };
2843        let expectation = "zx_clock_update_args_v1_t { \
2844            rate_adjust: 222, \
2845            padding1: [-, -, -, -], \
2846            value: 333, \
2847            error_bound: 444 }";
2848        assert_eq!(format!("{:?}", test_struct), expectation);
2849    }
2850}