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 #[sel4_cfg(IOMMU)]
67 pub fn io_frame_map(self, iospace: IOSpace, rights: CapRights, ioaddr: Word) -> Result<()> {
68 Error::wrap(self.invoke(|cptr, ipc_buffer| {
69 ipc_buffer.inner_mut().seL4_X86_Page_MapIO(
70 cptr.bits(),
71 iospace.bits(),
72 rights.into_inner(),
73 ioaddr,
74 )
75 }))
76 }
77
78 pub fn frame_unmap(self) -> Result<()> {
80 Error::wrap(
81 self.invoke(|cptr, ipc_buffer| ipc_buffer.inner_mut().seL4_X86_Page_Unmap(cptr.bits())),
82 )
83 }
84
85 pub fn frame_get_address(self) -> Result<usize> {
87 let ret = self.invoke(|cptr, ipc_buffer| {
88 ipc_buffer.inner_mut().seL4_X86_Page_GetAddress(cptr.bits())
89 });
90 match Error::from_sys(ret.error) {
91 None => Ok(ret.paddr.try_into().unwrap()),
92 Some(err) => Err(err),
93 }
94 }
95}
96
97impl<C: InvocationContext> PDPT<C> {
98 pub fn pdpt_map(self, vspace: VSpace, vaddr: usize, attr: VmAttributes) -> Result<()> {
99 Error::wrap(self.invoke(|cptr, ipc_buffer| {
100 ipc_buffer.inner_mut().seL4_X86_PDPT_Map(
101 cptr.bits(),
102 vspace.bits(),
103 vaddr.try_into().unwrap(),
104 attr.into_inner(),
105 )
106 }))
107 }
108}
109
110impl<C: InvocationContext> PageDirectory<C> {
111 pub fn page_directory_map(
112 self,
113 vspace: VSpace,
114 vaddr: usize,
115 attr: VmAttributes,
116 ) -> Result<()> {
117 Error::wrap(self.invoke(|cptr, ipc_buffer| {
118 ipc_buffer.inner_mut().seL4_X86_PageDirectory_Map(
119 cptr.bits(),
120 vspace.bits(),
121 vaddr.try_into().unwrap(),
122 attr.into_inner(),
123 )
124 }))
125 }
126}
127
128impl<C: InvocationContext> PageTable<C> {
129 pub fn page_table_map(self, vspace: VSpace, vaddr: usize, attr: VmAttributes) -> Result<()> {
130 Error::wrap(self.invoke(|cptr, ipc_buffer| {
131 ipc_buffer.inner_mut().seL4_X86_PageTable_Map(
132 cptr.bits(),
133 vspace.bits(),
134 vaddr.try_into().unwrap(),
135 attr.into_inner(),
136 )
137 }))
138 }
139}
140
141#[sel4_cfg(VTX)]
142impl<C: InvocationContext> EPTPDPT<C> {
143 pub fn eptpdpt_map(self, eptmpl4: EPTPML4, vaddr: usize, attr: VmAttributes) -> Result<()> {
144 Error::wrap(self.invoke(|cptr, ipc_buffer| {
145 ipc_buffer.inner_mut().seL4_X86_EPTPDPT_Map(
146 cptr.bits(),
147 eptmpl4.bits(),
148 vaddr.try_into().unwrap(),
149 attr.into_inner(),
150 )
151 }))
152 }
153}
154
155#[sel4_cfg(VTX)]
156impl<C: InvocationContext> EPTPageDirectory<C> {
157 pub fn ept_page_directory_map(
158 self,
159 eptmpl4: EPTPML4,
160 vaddr: usize,
161 attr: VmAttributes,
162 ) -> Result<()> {
163 Error::wrap(self.invoke(|cptr, ipc_buffer| {
164 ipc_buffer.inner_mut().seL4_X86_EPTPD_Map(
165 cptr.bits(),
166 eptmpl4.bits(),
167 vaddr.try_into().unwrap(),
168 attr.into_inner(),
169 )
170 }))
171 }
172}
173
174#[sel4_cfg(VTX)]
175impl<C: InvocationContext> EPTPageTable<C> {
176 pub fn ept_page_table_map(
177 self,
178 eptmpl4: EPTPML4,
179 vaddr: usize,
180 attr: VmAttributes,
181 ) -> Result<()> {
182 Error::wrap(self.invoke(|cptr, ipc_buffer| {
183 ipc_buffer.inner_mut().seL4_X86_EPTPT_Map(
184 cptr.bits(),
185 eptmpl4.bits(),
186 vaddr.try_into().unwrap(),
187 attr.into_inner(),
188 )
189 }))
190 }
191}
192
193#[sel4_cfg(IOMMU)]
194impl<C: InvocationContext> IOPageTable<C> {
195 pub fn io_page_table_map(self, iospace: IOSpace, ioaddr: Word) -> Result<()> {
196 Error::wrap(self.invoke(|cptr, ipc_buffer| {
197 ipc_buffer
198 .inner_mut()
199 .seL4_X86_IOPageTable_Map(cptr.bits(), iospace.bits(), ioaddr)
200 }))
201 }
202
203 pub fn io_page_table_unmap(self) -> Result<()> {
204 Error::wrap(self.invoke(|cptr, ipc_buffer| {
205 ipc_buffer
206 .inner_mut()
207 .seL4_X86_IOPageTable_Unmap(cptr.bits())
208 }))
209 }
210}
211
212impl<C: InvocationContext> Tcb<C> {
213 #[sel4_cfg(VTX)]
215 pub fn tcb_set_ept_root(self, eptmpl4: EPTPML4) -> Result<()> {
216 Error::wrap(self.invoke(|cptr, ipc_buffer| {
217 ipc_buffer
218 .inner_mut()
219 .seL4_TCB_SetEPTRoot(cptr.bits(), eptmpl4.bits())
220 }))
221 }
222}
223
224impl<C: InvocationContext> UnspecifiedIntermediateTranslationTable<C> {
225 pub fn generic_intermediate_translation_table_map(
226 self,
227 ty: TranslationTableObjectType,
228 vspace: VSpace,
229 vaddr: usize,
230 attr: VmAttributes,
231 ) -> Result<()> {
232 sel4_cfg_wrap_match! {
233 match ty {
234 #[sel4_cfg(ARCH_X86_64)]
235 TranslationTableObjectType::PDPT => self.cast::<cap_type::PDPT>().pdpt_map(vspace, vaddr, attr),
236 TranslationTableObjectType::PageDirectory => self
237 .cast::<cap_type::PageDirectory>()
238 .page_directory_map(vspace, vaddr, attr),
239 TranslationTableObjectType::PageTable => self
240 .cast::<cap_type::PageTable>()
241 .page_table_map(vspace, vaddr, attr),
242 _ => panic!(),
243 }
244 }
245 }
246
247 #[sel4_cfg(VTX)]
248 pub fn ept_intermediate_translation_table_map(
249 self,
250 ty: TranslationTableObjectType,
251 vspace: EPTPML4,
252 vaddr: usize,
253 attr: VmAttributes,
254 ) -> Result<()> {
255 sel4_cfg_wrap_match! {
256 match ty {
257 #[sel4_cfg(ARCH_X86_64)]
258 TranslationTableObjectType::EPTPDPT => self.cast::<cap_type::EPTPDPT>().eptpdpt_map(vspace, vaddr, attr),
259 TranslationTableObjectType::EPTPageDirectory => self
260 .cast::<cap_type::EPTPageDirectory>()
261 .ept_page_directory_map(vspace, vaddr, attr),
262 TranslationTableObjectType::EPTPageTable => self
263 .cast::<cap_type::EPTPageTable>()
264 .ept_page_table_map(vspace, vaddr, attr),
265 _ => panic!(),
266 }
267 }
268 }
269}
270
271impl<C: InvocationContext> IrqControl<C> {
272 pub fn irq_control_get_ioapic(
274 self,
275 ioapic: Word,
276 pin: Word,
277 level: Word,
278 polarity: Word,
279 vector: Word,
280 dst: &AbsoluteCPtr,
281 ) -> Result<()> {
282 Error::wrap(self.invoke(|cptr, ipc_buffer| {
283 ipc_buffer.inner_mut().seL4_IRQControl_GetIOAPIC(
284 cptr.bits(),
285 dst.root().bits(),
286 dst.path().bits(),
287 dst.path().depth_for_kernel(),
288 ioapic,
289 pin,
290 level,
291 polarity,
292 vector,
293 )
294 }))
295 }
296
297 pub fn irq_control_get_msi(
299 self,
300 pci_bus: Word,
301 pci_dev: Word,
302 pci_func: Word,
303 handle: Word,
304 vector: Word,
305 dst: &AbsoluteCPtr,
306 ) -> Result<()> {
307 Error::wrap(self.invoke(|cptr, ipc_buffer| {
308 ipc_buffer.inner_mut().seL4_IRQControl_GetMSI(
309 cptr.bits(),
310 dst.root().bits(),
311 dst.path().bits(),
312 dst.path().depth_for_kernel(),
313 pci_bus,
314 pci_dev,
315 pci_func,
316 handle,
317 vector,
318 )
319 }))
320 }
321}
322
323impl<C: InvocationContext> IOPortControl<C> {
324 pub fn ioport_control_issue(
326 self,
327 first_port: Word,
328 last_port: Word,
329 dst: &AbsoluteCPtr,
330 ) -> Result<()> {
331 Error::wrap(self.invoke(|cptr, ipc_buffer| {
332 ipc_buffer.inner_mut().seL4_X86_IOPortControl_Issue(
333 cptr.bits(),
334 first_port,
335 last_port,
336 dst.root().bits(),
337 dst.path().bits(),
338 dst.path().depth_for_kernel(),
339 )
340 }))
341 }
342}
343
344impl<C: InvocationContext> AsidControl<C> {
345 pub fn asid_control_make_pool(self, untyped: Untyped, dst: &AbsoluteCPtr) -> Result<()> {
347 Error::wrap(self.invoke(|cptr, ipc_buffer| {
348 ipc_buffer.inner_mut().seL4_X86_ASIDControl_MakePool(
349 cptr.bits(),
350 untyped.bits(),
351 dst.root().bits(),
352 dst.path().bits(),
353 dst.path().depth_for_kernel(),
354 )
355 }))
356 }
357}
358
359impl<C: InvocationContext> AsidPool<C> {
360 pub fn asid_pool_assign(self, vspace: VSpace) -> Result<()> {
362 Error::wrap(self.invoke(|cptr, ipc_buffer| {
363 ipc_buffer
364 .inner_mut()
365 .seL4_X86_ASIDPool_Assign(cptr.bits(), vspace.bits())
366 }))
367 }
368}