1use crate::syscall::SyscallReturn;
13use crate::ErrorCode;
14
15#[inline]
20fn u64_to_be_u32s(src: u64) -> (u32, u32) {
21 let src_bytes = src.to_be_bytes();
22 let src_msb = u32::from_be_bytes([src_bytes[0], src_bytes[1], src_bytes[2], src_bytes[3]]);
23 let src_lsb = u32::from_be_bytes([src_bytes[4], src_bytes[5], src_bytes[6], src_bytes[7]]);
24
25 (src_msb, src_lsb)
26}
27
28#[repr(u32)]
34#[derive(Copy, Clone, Debug)]
35pub enum TRD104SyscallReturnVariant {
36 Failure = 0,
37 FailureU32 = 1,
38 FailureU32U32 = 2,
39 FailureU64 = 3,
40 Success = 128,
41 SuccessU32 = 129,
42 SuccessU32U32 = 130,
43 SuccessU64 = 131,
44 SuccessU32U32U32 = 132,
45 SuccessU32U64 = 133,
46}
47
48#[derive(Copy, Clone, Debug)]
54pub enum TRD104SyscallReturn {
55 Failure(ErrorCode),
56 FailureU32(ErrorCode, u32),
57 FailureU32U32(ErrorCode, u32, u32),
58 FailureU64(ErrorCode, u64),
59 Success,
60 SuccessU32(u32),
61 SuccessU32U32(u32, u32),
62 SuccessU32U32U32(u32, u32, u32),
63 SuccessU64(u64),
64 SuccessU32U64(u32, u64),
65 AllowReadWriteSuccess(*mut u8, usize),
66 AllowReadWriteFailure(ErrorCode, *mut u8, usize),
67 UserspaceReadableAllowSuccess(*mut u8, usize),
68 UserspaceReadableAllowFailure(ErrorCode, *mut u8, usize),
69 AllowReadOnlySuccess(*const u8, usize),
70 AllowReadOnlyFailure(ErrorCode, *const u8, usize),
71 SubscribeSuccess(*const (), usize),
72 SubscribeFailure(ErrorCode, *const (), usize),
73 YieldWaitFor(usize, usize, usize),
74}
75
76impl TRD104SyscallReturn {
77 pub fn from_syscall_return(syscall_return: SyscallReturn) -> Self {
81 match syscall_return {
82 SyscallReturn::Failure(a) => TRD104SyscallReturn::Failure(a),
84 SyscallReturn::FailureU32(a, b) => TRD104SyscallReturn::FailureU32(a, b),
85 SyscallReturn::FailureU32U32(a, b, c) => TRD104SyscallReturn::FailureU32U32(a, b, c),
86 SyscallReturn::FailureU64(a, b) => TRD104SyscallReturn::FailureU64(a, b),
87 SyscallReturn::Success => TRD104SyscallReturn::Success,
88 SyscallReturn::SuccessU32(a) => TRD104SyscallReturn::SuccessU32(a),
89 SyscallReturn::SuccessU32U32(a, b) => TRD104SyscallReturn::SuccessU32U32(a, b),
90 SyscallReturn::SuccessU32U32U32(a, b, c) => {
91 TRD104SyscallReturn::SuccessU32U32U32(a, b, c)
92 }
93 SyscallReturn::SuccessU64(a) => TRD104SyscallReturn::SuccessU64(a),
94 SyscallReturn::SuccessU32U64(a, b) => TRD104SyscallReturn::SuccessU32U64(a, b),
95 SyscallReturn::AllowReadWriteSuccess(a, b) => {
96 TRD104SyscallReturn::AllowReadWriteSuccess(a, b)
97 }
98 SyscallReturn::AllowReadWriteFailure(a, b, c) => {
99 TRD104SyscallReturn::AllowReadWriteFailure(a, b, c)
100 }
101 SyscallReturn::UserspaceReadableAllowSuccess(a, b) => {
102 TRD104SyscallReturn::UserspaceReadableAllowSuccess(a, b)
103 }
104 SyscallReturn::UserspaceReadableAllowFailure(a, b, c) => {
105 TRD104SyscallReturn::UserspaceReadableAllowFailure(a, b, c)
106 }
107 SyscallReturn::AllowReadOnlySuccess(a, b) => {
108 TRD104SyscallReturn::AllowReadOnlySuccess(a, b)
109 }
110 SyscallReturn::AllowReadOnlyFailure(a, b, c) => {
111 TRD104SyscallReturn::AllowReadOnlyFailure(a, b, c)
112 }
113 SyscallReturn::SubscribeSuccess(a, b) => TRD104SyscallReturn::SubscribeSuccess(a, b),
114 SyscallReturn::SubscribeFailure(a, b, c) => {
115 TRD104SyscallReturn::SubscribeFailure(a, b, c)
116 }
117 SyscallReturn::YieldWaitFor(a, b, c) => TRD104SyscallReturn::YieldWaitFor(a, b, c),
118
119 SyscallReturn::SuccessAddr(a) => TRD104SyscallReturn::SuccessU32(a as u32),
121 SyscallReturn::SuccessPtr(a) => {
122 TRD104SyscallReturn::SuccessU32(a.as_ptr::<()>() as u32)
123 }
124 }
125 }
126}
127
128pub fn encode_syscall_return_trd104(
132 syscall_return: &TRD104SyscallReturn,
133 a0: &mut u32,
134 a1: &mut u32,
135 a2: &mut u32,
136 a3: &mut u32,
137) {
138 match *syscall_return {
139 TRD104SyscallReturn::Failure(e) => {
140 *a0 = TRD104SyscallReturnVariant::Failure as u32;
141 *a1 = usize::from(e) as u32;
142 }
143 TRD104SyscallReturn::FailureU32(e, data0) => {
144 *a0 = TRD104SyscallReturnVariant::FailureU32 as u32;
145 *a1 = usize::from(e) as u32;
146 *a2 = data0;
147 }
148 TRD104SyscallReturn::FailureU32U32(e, data0, data1) => {
149 *a0 = TRD104SyscallReturnVariant::FailureU32U32 as u32;
150 *a1 = usize::from(e) as u32;
151 *a2 = data0;
152 *a3 = data1;
153 }
154 TRD104SyscallReturn::FailureU64(e, data0) => {
155 let (data0_msb, data0_lsb) = u64_to_be_u32s(data0);
156 *a0 = TRD104SyscallReturnVariant::FailureU64 as u32;
157 *a1 = usize::from(e) as u32;
158 *a2 = data0_lsb;
159 *a3 = data0_msb;
160 }
161 TRD104SyscallReturn::Success => {
162 *a0 = TRD104SyscallReturnVariant::Success as u32;
163 }
164 TRD104SyscallReturn::SuccessU32(data0) => {
165 *a0 = TRD104SyscallReturnVariant::SuccessU32 as u32;
166 *a1 = data0;
167 }
168 TRD104SyscallReturn::SuccessU32U32(data0, data1) => {
169 *a0 = TRD104SyscallReturnVariant::SuccessU32U32 as u32;
170 *a1 = data0;
171 *a2 = data1;
172 }
173 TRD104SyscallReturn::SuccessU32U32U32(data0, data1, data2) => {
174 *a0 = TRD104SyscallReturnVariant::SuccessU32U32U32 as u32;
175 *a1 = data0;
176 *a2 = data1;
177 *a3 = data2;
178 }
179 TRD104SyscallReturn::SuccessU64(data0) => {
180 let (data0_msb, data0_lsb) = u64_to_be_u32s(data0);
181
182 *a0 = TRD104SyscallReturnVariant::SuccessU64 as u32;
183 *a1 = data0_lsb;
184 *a2 = data0_msb;
185 }
186 TRD104SyscallReturn::SuccessU32U64(data0, data1) => {
187 let (data1_msb, data1_lsb) = u64_to_be_u32s(data1);
188
189 *a0 = TRD104SyscallReturnVariant::SuccessU32U64 as u32;
190 *a1 = data0;
191 *a2 = data1_lsb;
192 *a3 = data1_msb;
193 }
194 TRD104SyscallReturn::AllowReadWriteSuccess(ptr, len) => {
195 *a0 = TRD104SyscallReturnVariant::SuccessU32U32 as u32;
196 *a1 = ptr as u32;
197 *a2 = len as u32;
198 }
199 TRD104SyscallReturn::UserspaceReadableAllowSuccess(ptr, len) => {
200 *a0 = TRD104SyscallReturnVariant::SuccessU32U32 as u32;
201 *a1 = ptr as u32;
202 *a2 = len as u32;
203 }
204 TRD104SyscallReturn::AllowReadWriteFailure(err, ptr, len) => {
205 *a0 = TRD104SyscallReturnVariant::FailureU32U32 as u32;
206 *a1 = usize::from(err) as u32;
207 *a2 = ptr as u32;
208 *a3 = len as u32;
209 }
210 TRD104SyscallReturn::UserspaceReadableAllowFailure(err, ptr, len) => {
211 *a0 = TRD104SyscallReturnVariant::FailureU32U32 as u32;
212 *a1 = usize::from(err) as u32;
213 *a2 = ptr as u32;
214 *a3 = len as u32;
215 }
216 TRD104SyscallReturn::AllowReadOnlySuccess(ptr, len) => {
217 *a0 = TRD104SyscallReturnVariant::SuccessU32U32 as u32;
218 *a1 = ptr as u32;
219 *a2 = len as u32;
220 }
221 TRD104SyscallReturn::AllowReadOnlyFailure(err, ptr, len) => {
222 *a0 = TRD104SyscallReturnVariant::FailureU32U32 as u32;
223 *a1 = usize::from(err) as u32;
224 *a2 = ptr as u32;
225 *a3 = len as u32;
226 }
227 TRD104SyscallReturn::SubscribeSuccess(ptr, data) => {
228 *a0 = TRD104SyscallReturnVariant::SuccessU32U32 as u32;
229 *a1 = ptr as u32;
230 *a2 = data as u32;
231 }
232 TRD104SyscallReturn::SubscribeFailure(err, ptr, data) => {
233 *a0 = TRD104SyscallReturnVariant::FailureU32U32 as u32;
234 *a1 = usize::from(err) as u32;
235 *a2 = ptr as u32;
236 *a3 = data as u32;
237 }
238 TRD104SyscallReturn::YieldWaitFor(data0, data1, data2) => {
239 *a0 = data0 as u32;
240 *a1 = data1 as u32;
241 *a2 = data2 as u32;
242 }
243 }
244}