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