1use sel4_config::sel4_cfg;
8
9use crate::{
10 cap::*, cap_type, AbsoluteCPtr, Cap, CapRights, CapTypeForFrameObject, Error,
11 InvocationContext, Result, TranslationTableObjectType, VmAttributes, Word,
12};
13
14#[sel4_cfg(ARM_HYPERVISOR_SUPPORT)]
15use crate::VCpuReg;
16
17#[sel4_cfg(ARM_HYPERVISOR_SUPPORT)]
18impl<C: InvocationContext> VCpu<C> {
19 pub fn vcpu_set_tcb(self, tcb: Tcb) -> Result<()> {
21 Error::wrap(self.invoke(|cptr, ipc_buffer| {
22 ipc_buffer
23 .inner_mut()
24 .seL4_ARM_VCPU_SetTCB(cptr.bits(), tcb.bits())
25 }))
26 }
27
28 pub fn vcpu_read_regs(self, field: VCpuReg) -> Result<Word> {
30 let res = self.invoke(|cptr, ipc_buffer| {
31 ipc_buffer
32 .inner_mut()
33 .seL4_ARM_VCPU_ReadRegs(cptr.bits(), field.into_sys())
34 });
35 Error::or(res.error, res.value)
36 }
37
38 pub fn vcpu_write_regs(self, field: VCpuReg, value: Word) -> Result<()> {
40 Error::wrap(self.invoke(|cptr, ipc_buffer| {
41 ipc_buffer
42 .inner_mut()
43 .seL4_ARM_VCPU_WriteRegs(cptr.bits(), field.into_sys(), value)
44 }))
45 }
46
47 pub fn vcpu_ack_vppi(self, irq: Word) -> Result<()> {
49 Error::wrap(self.invoke(|cptr, ipc_buffer| {
50 ipc_buffer
51 .inner_mut()
52 .seL4_ARM_VCPU_AckVPPI(cptr.bits(), irq)
53 }))
54 }
55
56 pub fn vcpu_inject_irq(self, virq: u16, priority: u8, group: u8, index: u8) -> Result<()> {
58 Error::wrap(self.invoke(|cptr, ipc_buffer| {
59 ipc_buffer.inner_mut().seL4_ARM_VCPU_InjectIRQ(
60 cptr.bits(),
61 virq,
62 priority,
63 group,
64 index,
65 )
66 }))
67 }
68}
69
70impl<T: CapTypeForFrameObject, C: InvocationContext> Cap<T, C> {
71 pub fn frame_map(
73 self,
74 vspace: VSpace,
75 vaddr: usize,
76 rights: CapRights,
77 attrs: VmAttributes,
78 ) -> Result<()> {
79 Error::wrap(self.invoke(|cptr, ipc_buffer| {
80 ipc_buffer.inner_mut().seL4_ARM_Page_Map(
81 cptr.bits(),
82 vspace.bits(),
83 vaddr.try_into().unwrap(),
84 rights.into_inner(),
85 attrs.into_inner(),
86 )
87 }))
88 }
89
90 pub fn frame_unmap(self) -> Result<()> {
92 Error::wrap(
93 self.invoke(|cptr, ipc_buffer| ipc_buffer.inner_mut().seL4_ARM_Page_Unmap(cptr.bits())),
94 )
95 }
96
97 pub fn frame_get_address(self) -> Result<usize> {
99 let ret = self.invoke(|cptr, ipc_buffer| {
100 ipc_buffer.inner_mut().seL4_ARM_Page_GetAddress(cptr.bits())
101 });
102 match Error::from_sys(ret.error) {
103 None => Ok(ret.paddr.try_into().unwrap()),
104 Some(err) => Err(err),
105 }
106 }
107}
108
109impl<C: InvocationContext> PT<C> {
110 pub fn pt_map(self, vspace: VSpace, vaddr: usize, attr: VmAttributes) -> Result<()> {
111 Error::wrap(self.invoke(|cptr, ipc_buffer| {
112 ipc_buffer.inner_mut().seL4_ARM_PageTable_Map(
113 cptr.bits(),
114 vspace.bits(),
115 vaddr.try_into().unwrap(),
116 attr.into_inner(),
117 )
118 }))
119 }
120}
121
122impl<C: InvocationContext> UnspecifiedIntermediateTranslationTable<C> {
123 pub fn generic_intermediate_translation_table_map(
124 self,
125 ty: TranslationTableObjectType,
126 vspace: VSpace,
127 vaddr: usize,
128 attr: VmAttributes,
129 ) -> Result<()> {
130 match ty {
131 TranslationTableObjectType::PT => {
132 self.cast::<cap_type::PT>().pt_map(vspace, vaddr, attr)
133 }
134 _ => panic!(),
135 }
136 }
137}
138
139impl<C: InvocationContext> IrqControl<C> {
141 #[sel4_cfg(not(MAX_NUM_NODES = "1"))]
143 pub fn irq_control_get_trigger_core(
144 self,
145 irq: Word,
146 edge_triggered: bool,
147 target: Word,
148 dst: &AbsoluteCPtr,
149 ) -> Result<()> {
150 Error::wrap(self.invoke(|cptr, ipc_buffer| {
151 ipc_buffer.inner_mut().seL4_IRQControl_GetTriggerCore(
152 cptr.bits(),
153 irq,
154 edge_triggered.into(),
155 dst.root().bits(),
156 dst.path().bits(),
157 dst.path().depth_for_kernel(),
158 target,
159 )
160 }))
161 }
162
163 pub fn irq_control_get_trigger(
165 self,
166 irq: Word,
167 edge_triggered: bool,
168 dst: &AbsoluteCPtr,
169 ) -> Result<()> {
170 Error::wrap(self.invoke(|cptr, ipc_buffer| {
171 ipc_buffer.inner_mut().seL4_IRQControl_GetTrigger(
172 cptr.bits(),
173 irq,
174 edge_triggered.into(),
175 dst.root().bits(),
176 dst.path().bits(),
177 dst.path().depth_for_kernel(),
178 )
179 }))
180 }
181}
182
183impl<C: InvocationContext> AsidControl<C> {
184 pub fn asid_control_make_pool(self, untyped: Untyped, dst: &AbsoluteCPtr) -> Result<()> {
186 Error::wrap(self.invoke(|cptr, ipc_buffer| {
187 ipc_buffer.inner_mut().seL4_ARM_ASIDControl_MakePool(
188 cptr.bits(),
189 untyped.bits(),
190 dst.root().bits(),
191 dst.path().bits(),
192 dst.path().depth_for_kernel(),
193 )
194 }))
195 }
196}
197
198impl<C: InvocationContext> AsidPool<C> {
199 pub fn asid_pool_assign(self, vspace: VSpace) -> Result<()> {
201 Error::wrap(self.invoke(|cptr, ipc_buffer| {
202 ipc_buffer
203 .inner_mut()
204 .seL4_ARM_ASIDPool_Assign(cptr.bits(), vspace.bits())
205 }))
206 }
207}