1use crate::{ok, sys, AsHandleRef, Handle, HandleBased, HandleRef, Port, Resource, Status, Vmar};
6
7#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
9#[repr(transparent)]
10pub struct GPAddr(pub usize);
11
12#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
16#[repr(transparent)]
17pub struct Guest(Handle);
18impl_handle_based!(Guest);
19
20impl Guest {
21 pub fn normal(hypervisor: &Resource) -> Result<(Guest, Vmar), Status> {
23 Self::create(hypervisor, sys::ZX_GUEST_OPT_NORMAL)
24 }
25
26 fn create(
27 hypervisor: &Resource,
28 options: sys::zx_guest_option_t,
29 ) -> Result<(Guest, Vmar), Status> {
30 unsafe {
31 let mut guest_handle = 0;
32 let mut vmar_handle = 0;
33 ok(sys::zx_guest_create(
34 hypervisor.raw_handle(),
35 options,
36 &mut guest_handle,
37 &mut vmar_handle,
38 ))?;
39 Ok((
40 Self::from(Handle::from_raw(guest_handle)),
41 Vmar::from(Handle::from_raw(vmar_handle)),
42 ))
43 }
44 }
45
46 pub fn set_trap_bell(
48 &self,
49 addr: GPAddr,
50 size: usize,
51 port: &Port,
52 key: u64,
53 ) -> Result<(), Status> {
54 ok(unsafe {
55 sys::zx_guest_set_trap(
56 self.raw_handle(),
57 sys::ZX_GUEST_TRAP_BELL,
58 addr.0,
59 size,
60 port.raw_handle(),
61 key,
62 )
63 })
64 }
65
66 pub fn set_mem_trap(&self, addr: GPAddr, size: usize, key: u64) -> Result<(), Status> {
70 ok(unsafe {
71 sys::zx_guest_set_trap(
72 self.raw_handle(),
73 sys::ZX_GUEST_TRAP_MEM,
74 addr.0,
75 size,
76 sys::ZX_HANDLE_INVALID,
77 key,
78 )
79 })
80 }
81
82 pub fn set_io_trap(&self, addr: u16, size: u16, key: u64) -> Result<(), Status> {
86 ok(unsafe {
87 sys::zx_guest_set_trap(
88 self.raw_handle(),
89 sys::ZX_GUEST_TRAP_IO,
90 addr.into(),
91 size.into(),
92 sys::ZX_HANDLE_INVALID,
93 key,
94 )
95 })
96 }
97}
98
99#[derive(Debug, Clone, Copy)]
104pub enum CSDefaultOperandSize {
105 Bits16 = 2,
106 Bits32 = 4,
107}
108
109#[derive(Debug, Clone, Copy)]
110pub enum MemAccessSize {
111 Bits8 = 1,
112 Bits16 = 2,
113 Bits32 = 4,
114 Bits64 = 8,
115}
116
117#[derive(Debug, Clone, Copy)]
118pub enum MemData {
119 Data8(u8),
120 Data16(u16),
121 Data32(u32),
122 Data64(u64),
123}
124
125#[derive(Debug, Clone, Copy)]
126pub enum PortAccessSize {
127 Bits8 = 1,
128 Bits16 = 2,
129 Bits32 = 4,
130}
131
132#[derive(Debug, Clone, Copy)]
133pub enum AccessType {
134 Read,
135 Write,
136}
137
138#[derive(Debug, Clone, Copy)]
139pub enum PortData {
140 Data8(u8),
141 Data16(u16),
142 Data32(u32),
143}
144
145#[cfg(test)]
146mod tests {
147 use super::*;
148 use fidl_fuchsia_kernel as fkernel;
149 use fuchsia_component::client::connect_to_protocol;
150 use zx::HandleBased;
151
152 async fn get_hypervisor() -> Resource {
153 let resource = connect_to_protocol::<fkernel::HypervisorResourceMarker>()
154 .unwrap()
155 .get()
156 .await
157 .unwrap();
158 unsafe { Resource::from(Handle::from_raw(resource.into_raw())) }
159 }
160
161 #[fuchsia::test]
162 async fn guest_normal_create() {
163 let hypervisor = get_hypervisor().await;
164 match Guest::normal(&hypervisor) {
165 Err(Status::NOT_SUPPORTED) => {
166 println!("Hypervisor not supported");
167 return;
168 }
169 result => result.unwrap(),
170 };
171 }
172}