1use sel4_config::sel4_cfg;
8
9use crate::{
10 AbsoluteCPtr, Cap, CapRights, CapTypeForFrameObject, Error, InvocationContext, Result,
11 TranslationTableObjectType, VmAttributes, Word, cap::*, cap_type, sel4_cfg_wrap_match,
12};
13
14#[sel4_cfg(VTX)]
15impl<C: InvocationContext> VCpu<C> {
16 pub fn vcpu_set_tcb(self, tcb: Tcb) -> Result<()> {
18 Error::wrap(self.invoke(|cptr, ipc_buffer| {
19 ipc_buffer
20 .inner_mut()
21 .seL4_X86_VCPU_SetTCB(cptr.bits(), tcb.bits())
22 }))
23 }
24}
25
26impl<T: CapTypeForFrameObject, C: InvocationContext> Cap<T, C> {
27 pub fn frame_map(
29 self,
30 vspace: VSpace,
31 vaddr: usize,
32 rights: CapRights,
33 attrs: VmAttributes,
34 ) -> Result<()> {
35 Error::wrap(self.invoke(|cptr, ipc_buffer| {
36 ipc_buffer.inner_mut().seL4_X86_Page_Map(
37 cptr.bits(),
38 vspace.bits(),
39 vaddr.try_into().unwrap(),
40 rights.into_inner(),
41 attrs.into_inner(),
42 )
43 }))
44 }
45
46 #[sel4_cfg(VTX)]
48 pub fn ept_frame_map(
49 self,
50 eptmpl4: EPTPML4,
51 vaddr: usize,
52 rights: CapRights,
53 attrs: VmAttributes,
54 ) -> Result<()> {
55 Error::wrap(self.invoke(|cptr, ipc_buffer| {
56 ipc_buffer.inner_mut().seL4_X86_Page_MapEPT(
57 cptr.bits(),
58 eptmpl4.bits(),
59 vaddr.try_into().unwrap(),
60 rights.into_inner(),
61 attrs.into_inner(),
62 )
63 }))
64 }
65
66 pub fn frame_unmap(self) -> Result<()> {
68 Error::wrap(
69 self.invoke(|cptr, ipc_buffer| ipc_buffer.inner_mut().seL4_X86_Page_Unmap(cptr.bits())),
70 )
71 }
72
73 pub fn frame_get_address(self) -> Result<usize> {
75 let ret = self.invoke(|cptr, ipc_buffer| {
76 ipc_buffer.inner_mut().seL4_X86_Page_GetAddress(cptr.bits())
77 });
78 match Error::from_sys(ret.error) {
79 None => Ok(ret.paddr.try_into().unwrap()),
80 Some(err) => Err(err),
81 }
82 }
83}
84
85impl<C: InvocationContext> PDPT<C> {
86 pub fn pdpt_map(self, vspace: VSpace, vaddr: usize, attr: VmAttributes) -> Result<()> {
87 Error::wrap(self.invoke(|cptr, ipc_buffer| {
88 ipc_buffer.inner_mut().seL4_X86_PDPT_Map(
89 cptr.bits(),
90 vspace.bits(),
91 vaddr.try_into().unwrap(),
92 attr.into_inner(),
93 )
94 }))
95 }
96}
97
98impl<C: InvocationContext> PageDirectory<C> {
99 pub fn page_directory_map(
100 self,
101 vspace: VSpace,
102 vaddr: usize,
103 attr: VmAttributes,
104 ) -> Result<()> {
105 Error::wrap(self.invoke(|cptr, ipc_buffer| {
106 ipc_buffer.inner_mut().seL4_X86_PageDirectory_Map(
107 cptr.bits(),
108 vspace.bits(),
109 vaddr.try_into().unwrap(),
110 attr.into_inner(),
111 )
112 }))
113 }
114}
115
116impl<C: InvocationContext> PageTable<C> {
117 pub fn page_table_map(self, vspace: VSpace, vaddr: usize, attr: VmAttributes) -> Result<()> {
118 Error::wrap(self.invoke(|cptr, ipc_buffer| {
119 ipc_buffer.inner_mut().seL4_X86_PageTable_Map(
120 cptr.bits(),
121 vspace.bits(),
122 vaddr.try_into().unwrap(),
123 attr.into_inner(),
124 )
125 }))
126 }
127}
128
129#[sel4_cfg(VTX)]
130impl<C: InvocationContext> EPTPDPT<C> {
131 pub fn eptpdpt_map(self, eptmpl4: EPTPML4, vaddr: usize, attr: VmAttributes) -> Result<()> {
132 Error::wrap(self.invoke(|cptr, ipc_buffer| {
133 ipc_buffer.inner_mut().seL4_X86_EPTPDPT_Map(
134 cptr.bits(),
135 eptmpl4.bits(),
136 vaddr.try_into().unwrap(),
137 attr.into_inner(),
138 )
139 }))
140 }
141}
142
143#[sel4_cfg(VTX)]
144impl<C: InvocationContext> EPTPageDirectory<C> {
145 pub fn ept_page_directory_map(
146 self,
147 eptmpl4: EPTPML4,
148 vaddr: usize,
149 attr: VmAttributes,
150 ) -> Result<()> {
151 Error::wrap(self.invoke(|cptr, ipc_buffer| {
152 ipc_buffer.inner_mut().seL4_X86_EPTPD_Map(
153 cptr.bits(),
154 eptmpl4.bits(),
155 vaddr.try_into().unwrap(),
156 attr.into_inner(),
157 )
158 }))
159 }
160}
161
162#[sel4_cfg(VTX)]
163impl<C: InvocationContext> EPTPageTable<C> {
164 pub fn ept_page_table_map(
165 self,
166 eptmpl4: EPTPML4,
167 vaddr: usize,
168 attr: VmAttributes,
169 ) -> Result<()> {
170 Error::wrap(self.invoke(|cptr, ipc_buffer| {
171 ipc_buffer.inner_mut().seL4_X86_EPTPT_Map(
172 cptr.bits(),
173 eptmpl4.bits(),
174 vaddr.try_into().unwrap(),
175 attr.into_inner(),
176 )
177 }))
178 }
179}
180
181impl<C: InvocationContext> Tcb<C> {
182 #[sel4_cfg(VTX)]
184 pub fn tcb_set_ept_root(self, eptmpl4: EPTPML4) -> Result<()> {
185 Error::wrap(self.invoke(|cptr, ipc_buffer| {
186 ipc_buffer
187 .inner_mut()
188 .seL4_TCB_SetEPTRoot(cptr.bits(), eptmpl4.bits())
189 }))
190 }
191}
192
193impl<C: InvocationContext> UnspecifiedIntermediateTranslationTable<C> {
194 pub fn generic_intermediate_translation_table_map(
195 self,
196 ty: TranslationTableObjectType,
197 vspace: VSpace,
198 vaddr: usize,
199 attr: VmAttributes,
200 ) -> Result<()> {
201 sel4_cfg_wrap_match! {
202 match ty {
203 #[sel4_cfg(ARCH_X86_64)]
204 TranslationTableObjectType::PDPT => self.cast::<cap_type::PDPT>().pdpt_map(vspace, vaddr, attr),
205 TranslationTableObjectType::PageDirectory => self
206 .cast::<cap_type::PageDirectory>()
207 .page_directory_map(vspace, vaddr, attr),
208 TranslationTableObjectType::PageTable => self
209 .cast::<cap_type::PageTable>()
210 .page_table_map(vspace, vaddr, attr),
211 _ => panic!(),
212 }
213 }
214 }
215
216 #[sel4_cfg(VTX)]
217 pub fn ept_intermediate_translation_table_map(
218 self,
219 ty: TranslationTableObjectType,
220 vspace: EPTPML4,
221 vaddr: usize,
222 attr: VmAttributes,
223 ) -> Result<()> {
224 sel4_cfg_wrap_match! {
225 match ty {
226 #[sel4_cfg(ARCH_X86_64)]
227 TranslationTableObjectType::EPTPDPT => self.cast::<cap_type::EPTPDPT>().eptpdpt_map(vspace, vaddr, attr),
228 TranslationTableObjectType::EPTPageDirectory => self
229 .cast::<cap_type::EPTPageDirectory>()
230 .ept_page_directory_map(vspace, vaddr, attr),
231 TranslationTableObjectType::EPTPageTable => self
232 .cast::<cap_type::EPTPageTable>()
233 .ept_page_table_map(vspace, vaddr, attr),
234 _ => panic!(),
235 }
236 }
237 }
238}
239
240impl<C: InvocationContext> IrqControl<C> {
241 pub fn irq_control_get_ioapic(
243 self,
244 ioapic: Word,
245 pin: Word,
246 level: Word,
247 polarity: Word,
248 vector: Word,
249 dst: &AbsoluteCPtr,
250 ) -> Result<()> {
251 Error::wrap(self.invoke(|cptr, ipc_buffer| {
252 ipc_buffer.inner_mut().seL4_IRQControl_GetIOAPIC(
253 cptr.bits(),
254 dst.root().bits(),
255 dst.path().bits(),
256 dst.path().depth_for_kernel(),
257 ioapic,
258 pin,
259 level,
260 polarity,
261 vector,
262 )
263 }))
264 }
265
266 pub fn irq_control_get_msi(
268 self,
269 pci_bus: Word,
270 pci_dev: Word,
271 pci_func: Word,
272 handle: Word,
273 vector: Word,
274 dst: &AbsoluteCPtr,
275 ) -> Result<()> {
276 Error::wrap(self.invoke(|cptr, ipc_buffer| {
277 ipc_buffer.inner_mut().seL4_IRQControl_GetMSI(
278 cptr.bits(),
279 dst.root().bits(),
280 dst.path().bits(),
281 dst.path().depth_for_kernel(),
282 pci_bus,
283 pci_dev,
284 pci_func,
285 handle,
286 vector,
287 )
288 }))
289 }
290}
291
292impl<C: InvocationContext> IOPortControl<C> {
293 pub fn ioport_control_issue(
295 self,
296 first_port: Word,
297 last_port: Word,
298 dst: &AbsoluteCPtr,
299 ) -> Result<()> {
300 Error::wrap(self.invoke(|cptr, ipc_buffer| {
301 ipc_buffer.inner_mut().seL4_X86_IOPortControl_Issue(
302 cptr.bits(),
303 first_port,
304 last_port,
305 dst.root().bits(),
306 dst.path().bits(),
307 dst.path().depth_for_kernel(),
308 )
309 }))
310 }
311}
312
313impl<C: InvocationContext> AsidControl<C> {
314 pub fn asid_control_make_pool(self, untyped: Untyped, dst: &AbsoluteCPtr) -> Result<()> {
316 Error::wrap(self.invoke(|cptr, ipc_buffer| {
317 ipc_buffer.inner_mut().seL4_X86_ASIDControl_MakePool(
318 cptr.bits(),
319 untyped.bits(),
320 dst.root().bits(),
321 dst.path().bits(),
322 dst.path().depth_for_kernel(),
323 )
324 }))
325 }
326}
327
328impl<C: InvocationContext> AsidPool<C> {
329 pub fn asid_pool_assign(self, vspace: VSpace) -> Result<()> {
331 Error::wrap(self.invoke(|cptr, ipc_buffer| {
332 ipc_buffer
333 .inner_mut()
334 .seL4_X86_ASIDPool_Assign(cptr.bits(), vspace.bits())
335 }))
336 }
337}