1use crate::{AsHandleRef, Handle, HandleBased, HandleRef, Port, Resource, Status, Vmar, ok, sys};
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 create(hypervisor: &Resource) -> Result<(Guest, Vmar), Status> {
22 unsafe {
23 let mut guest_handle = 0;
24 let mut vmar_handle = 0;
25 ok(sys::zx_guest_create(
26 hypervisor.raw_handle(),
27 0,
28 &mut guest_handle,
29 &mut vmar_handle,
30 ))?;
31 Ok((
32 Self::from(Handle::from_raw(guest_handle)),
33 Vmar::from(Handle::from_raw(vmar_handle)),
34 ))
35 }
36 }
37
38 pub fn set_trap_bell(
40 &self,
41 addr: GPAddr,
42 size: usize,
43 port: &Port,
44 key: u64,
45 ) -> Result<(), Status> {
46 ok(unsafe {
47 sys::zx_guest_set_trap(
48 self.raw_handle(),
49 sys::ZX_GUEST_TRAP_BELL,
50 addr.0,
51 size,
52 port.raw_handle(),
53 key,
54 )
55 })
56 }
57
58 pub fn set_mem_trap(&self, addr: GPAddr, size: usize, key: u64) -> Result<(), Status> {
62 ok(unsafe {
63 sys::zx_guest_set_trap(
64 self.raw_handle(),
65 sys::ZX_GUEST_TRAP_MEM,
66 addr.0,
67 size,
68 sys::ZX_HANDLE_INVALID,
69 key,
70 )
71 })
72 }
73
74 pub fn set_io_trap(&self, addr: u16, size: u16, key: u64) -> Result<(), Status> {
78 ok(unsafe {
79 sys::zx_guest_set_trap(
80 self.raw_handle(),
81 sys::ZX_GUEST_TRAP_IO,
82 addr.into(),
83 size.into(),
84 sys::ZX_HANDLE_INVALID,
85 key,
86 )
87 })
88 }
89}
90
91#[derive(Debug, Clone, Copy)]
96pub enum CSDefaultOperandSize {
97 Bits16 = 2,
98 Bits32 = 4,
99}
100
101#[derive(Debug, Clone, Copy)]
102pub enum MemAccessSize {
103 Bits8 = 1,
104 Bits16 = 2,
105 Bits32 = 4,
106 Bits64 = 8,
107}
108
109#[derive(Debug, Clone, Copy)]
110pub enum MemData {
111 Data8(u8),
112 Data16(u16),
113 Data32(u32),
114 Data64(u64),
115}
116
117#[derive(Debug, Clone, Copy)]
118pub enum PortAccessSize {
119 Bits8 = 1,
120 Bits16 = 2,
121 Bits32 = 4,
122}
123
124#[derive(Debug, Clone, Copy)]
125pub enum AccessType {
126 Read,
127 Write,
128}
129
130#[derive(Debug, Clone, Copy)]
131pub enum PortData {
132 Data8(u8),
133 Data16(u16),
134 Data32(u32),
135}
136
137#[cfg(test)]
138mod tests {
139 use super::*;
140 use fidl_fuchsia_kernel as fkernel;
141 use fuchsia_component::client::connect_to_protocol;
142 use zx::HandleBased;
143
144 async fn get_hypervisor() -> Resource {
145 let resource = connect_to_protocol::<fkernel::HypervisorResourceMarker>()
146 .unwrap()
147 .get()
148 .await
149 .unwrap();
150 unsafe { Resource::from(Handle::from_raw(resource.into_raw())) }
151 }
152
153 #[fuchsia::test]
154 async fn guest_create() {
155 let hypervisor = get_hypervisor().await;
156 match Guest::create(&hypervisor) {
157 Err(Status::NOT_SUPPORTED) => {
158 println!("Hypervisor not supported");
159 return;
160 }
161 result => result.unwrap(),
162 };
163 }
164}