sel4/arch/x86/
invocations.rs

1//
2// Copyright 2023, Colias Group, LLC
3//
4// SPDX-License-Identifier: MIT
5//
6
7use crate::{
8    cap::*, cap_type, sel4_cfg_wrap_match, AbsoluteCPtr, Cap, CapRights, CapTypeForFrameObject,
9    Error, InvocationContext, Result, TranslationTableObjectType, VmAttributes, Word,
10};
11
12impl<T: CapTypeForFrameObject, C: InvocationContext> Cap<T, C> {
13    /// Corresponds to `seL4_X86_Page_Map`.
14    pub fn frame_map(
15        self,
16        vspace: VSpace,
17        vaddr: usize,
18        rights: CapRights,
19        attrs: VmAttributes,
20    ) -> Result<()> {
21        Error::wrap(self.invoke(|cptr, ipc_buffer| {
22            ipc_buffer.inner_mut().seL4_X86_Page_Map(
23                cptr.bits(),
24                vspace.bits(),
25                vaddr.try_into().unwrap(),
26                rights.into_inner(),
27                attrs.into_inner(),
28            )
29        }))
30    }
31
32    /// Corresponds to `seL4_X86_Page_Unmap`.
33    pub fn frame_unmap(self) -> Result<()> {
34        Error::wrap(
35            self.invoke(|cptr, ipc_buffer| ipc_buffer.inner_mut().seL4_X86_Page_Unmap(cptr.bits())),
36        )
37    }
38
39    /// Corresponds to `seL4_X86_Page_GetAddress`.
40    pub fn frame_get_address(self) -> Result<usize> {
41        let ret = self.invoke(|cptr, ipc_buffer| {
42            ipc_buffer.inner_mut().seL4_X86_Page_GetAddress(cptr.bits())
43        });
44        match Error::from_sys(ret.error) {
45            None => Ok(ret.paddr.try_into().unwrap()),
46            Some(err) => Err(err),
47        }
48    }
49}
50
51impl<C: InvocationContext> PDPT<C> {
52    pub fn pdpt_map(self, vspace: VSpace, vaddr: usize, attr: VmAttributes) -> Result<()> {
53        Error::wrap(self.invoke(|cptr, ipc_buffer| {
54            ipc_buffer.inner_mut().seL4_X86_PDPT_Map(
55                cptr.bits(),
56                vspace.bits(),
57                vaddr.try_into().unwrap(),
58                attr.into_inner(),
59            )
60        }))
61    }
62}
63
64impl<C: InvocationContext> PageDirectory<C> {
65    pub fn page_directory_map(
66        self,
67        vspace: VSpace,
68        vaddr: usize,
69        attr: VmAttributes,
70    ) -> Result<()> {
71        Error::wrap(self.invoke(|cptr, ipc_buffer| {
72            ipc_buffer.inner_mut().seL4_X86_PageDirectory_Map(
73                cptr.bits(),
74                vspace.bits(),
75                vaddr.try_into().unwrap(),
76                attr.into_inner(),
77            )
78        }))
79    }
80}
81
82impl<C: InvocationContext> PageTable<C> {
83    pub fn page_table_map(self, vspace: VSpace, vaddr: usize, attr: VmAttributes) -> Result<()> {
84        Error::wrap(self.invoke(|cptr, ipc_buffer| {
85            ipc_buffer.inner_mut().seL4_X86_PageTable_Map(
86                cptr.bits(),
87                vspace.bits(),
88                vaddr.try_into().unwrap(),
89                attr.into_inner(),
90            )
91        }))
92    }
93}
94
95impl<C: InvocationContext> UnspecifiedIntermediateTranslationTable<C> {
96    pub fn generic_intermediate_translation_table_map(
97        self,
98        ty: TranslationTableObjectType,
99        vspace: VSpace,
100        vaddr: usize,
101        attr: VmAttributes,
102    ) -> Result<()> {
103        sel4_cfg_wrap_match! {
104            match ty {
105                #[sel4_cfg(ARCH_X86_64)]
106                TranslationTableObjectType::PDPT => self.cast::<cap_type::PDPT>().pdpt_map(vspace, vaddr, attr),
107                TranslationTableObjectType::PageDirectory => self
108                    .cast::<cap_type::PageDirectory>()
109                    .page_directory_map(vspace, vaddr, attr),
110                TranslationTableObjectType::PageTable => self
111                    .cast::<cap_type::PageTable>()
112                    .page_table_map(vspace, vaddr, attr),
113                _ => panic!(),
114            }
115        }
116    }
117}
118
119impl<C: InvocationContext> IrqControl<C> {
120    /// Corresponds to `seL4_IRQControl_GetIOAPIC`.
121    pub fn irq_control_get_ioapic(
122        self,
123        ioapic: Word,
124        pin: Word,
125        level: Word,
126        polarity: Word,
127        vector: Word,
128        dst: &AbsoluteCPtr,
129    ) -> Result<()> {
130        Error::wrap(self.invoke(|cptr, ipc_buffer| {
131            ipc_buffer.inner_mut().seL4_IRQControl_GetIOAPIC(
132                cptr.bits(),
133                dst.root().bits(),
134                dst.path().bits(),
135                dst.path().depth_for_kernel(),
136                ioapic,
137                pin,
138                level,
139                polarity,
140                vector,
141            )
142        }))
143    }
144
145    /// Corresponds to `seL4_IRQControl_GetMSI`.
146    pub fn irq_control_get_msi(
147        self,
148        pci_bus: Word,
149        pci_dev: Word,
150        pci_func: Word,
151        handle: Word,
152        vector: Word,
153        dst: &AbsoluteCPtr,
154    ) -> Result<()> {
155        Error::wrap(self.invoke(|cptr, ipc_buffer| {
156            ipc_buffer.inner_mut().seL4_IRQControl_GetMSI(
157                cptr.bits(),
158                dst.root().bits(),
159                dst.path().bits(),
160                dst.path().depth_for_kernel(),
161                pci_bus,
162                pci_dev,
163                pci_func,
164                handle,
165                vector,
166            )
167        }))
168    }
169}
170
171impl<C: InvocationContext> IOPortControl<C> {
172    /// Corresponds to `seL4_X86_IOPortControl_Issue`.
173    pub fn ioport_control_issue(
174        self,
175        first_port: Word,
176        last_port: Word,
177        dst: &AbsoluteCPtr,
178    ) -> Result<()> {
179        Error::wrap(self.invoke(|cptr, ipc_buffer| {
180            ipc_buffer.inner_mut().seL4_X86_IOPortControl_Issue(
181                cptr.bits(),
182                first_port,
183                last_port,
184                dst.root().bits(),
185                dst.path().bits(),
186                dst.path().depth_for_kernel(),
187            )
188        }))
189    }
190}
191
192impl<C: InvocationContext> AsidControl<C> {
193    /// Corresponds to `seL4_X86_ASIDControl_MakePool`.
194    pub fn asid_control_make_pool(self, untyped: Untyped, dst: &AbsoluteCPtr) -> Result<()> {
195        Error::wrap(self.invoke(|cptr, ipc_buffer| {
196            ipc_buffer.inner_mut().seL4_X86_ASIDControl_MakePool(
197                cptr.bits(),
198                untyped.bits(),
199                dst.root().bits(),
200                dst.path().bits(),
201                dst.path().depth_for_kernel(),
202            )
203        }))
204    }
205}
206
207impl<C: InvocationContext> AsidPool<C> {
208    /// Corresponds to `seL4_X86_ASIDPool_Assign`.
209    pub fn asid_pool_assign(self, vspace: VSpace) -> Result<()> {
210        Error::wrap(self.invoke(|cptr, ipc_buffer| {
211            ipc_buffer
212                .inner_mut()
213                .seL4_X86_ASIDPool_Assign(cptr.bits(), vspace.bits())
214        }))
215    }
216}