1use crate::errorcode::ErrorCode;
10use crate::process;
11use crate::process::ProcessId;
12use crate::processbuffer::UserspaceReadableProcessBuffer;
13use crate::syscall::SyscallReturn;
14
15pub struct CommandReturn(SyscallReturn);
26
27impl CommandReturn {
28 pub(crate) fn into_inner(self) -> SyscallReturn {
29 self.0
30 }
31
32 pub fn failure(rc: ErrorCode) -> Self {
34 CommandReturn(SyscallReturn::Failure(rc))
35 }
36
37 pub fn failure_u32(rc: ErrorCode, data0: u32) -> Self {
39 CommandReturn(SyscallReturn::FailureU32(rc, data0))
40 }
41
42 pub fn failure_u32_u32(rc: ErrorCode, data0: u32, data1: u32) -> Self {
44 CommandReturn(SyscallReturn::FailureU32U32(rc, data0, data1))
45 }
46
47 pub fn failure_u64(rc: ErrorCode, data0: u64) -> Self {
49 CommandReturn(SyscallReturn::FailureU64(rc, data0))
50 }
51
52 pub fn success() -> Self {
54 CommandReturn(SyscallReturn::Success)
55 }
56
57 pub fn success_u32(data0: u32) -> Self {
59 CommandReturn(SyscallReturn::SuccessU32(data0))
60 }
61
62 pub fn success_u32_u32(data0: u32, data1: u32) -> Self {
64 CommandReturn(SyscallReturn::SuccessU32U32(data0, data1))
65 }
66
67 pub fn success_u32_u32_u32(data0: u32, data1: u32, data2: u32) -> Self {
69 CommandReturn(SyscallReturn::SuccessU32U32U32(data0, data1, data2))
70 }
71
72 pub fn success_u64(data0: u64) -> Self {
74 CommandReturn(SyscallReturn::SuccessU64(data0))
75 }
76
77 pub fn success_u32_u64(data0: u32, data1: u64) -> Self {
79 CommandReturn(SyscallReturn::SuccessU32U64(data0, data1))
80 }
81
82 pub fn is_failure(&self) -> bool {
85 matches!(self.0, SyscallReturn::Failure(_))
86 }
87
88 pub fn is_failure_u32(&self) -> bool {
91 matches!(self.0, SyscallReturn::FailureU32(_, _))
92 }
93
94 pub fn is_failure_2_u32(&self) -> bool {
97 matches!(self.0, SyscallReturn::FailureU32U32(_, _, _))
98 }
99
100 pub fn is_failure_u64(&self) -> bool {
103 matches!(self.0, SyscallReturn::FailureU64(_, _))
104 }
105
106 pub fn is_success(&self) -> bool {
110 matches!(self.0, SyscallReturn::Success)
111 }
112
113 pub fn is_success_u32(&self) -> bool {
116 matches!(self.0, SyscallReturn::SuccessU32(_))
117 }
118
119 pub fn is_success_2_u32(&self) -> bool {
122 matches!(self.0, SyscallReturn::SuccessU32U32(_, _))
123 }
124
125 pub fn is_success_u64(&self) -> bool {
128 matches!(self.0, SyscallReturn::SuccessU64(_))
129 }
130
131 pub fn is_success_3_u32(&self) -> bool {
134 matches!(self.0, SyscallReturn::SuccessU32U32U32(_, _, _))
135 }
136
137 pub fn is_success_u32_u64(&self) -> bool {
140 matches!(self.0, SyscallReturn::SuccessU32U64(_, _))
141 }
142
143 pub fn get_failure(&self) -> Option<ErrorCode> {
146 match self.0 {
147 SyscallReturn::Failure(r1) => Some(r1),
148 _ => None,
149 }
150 }
151
152 pub fn get_failure_u32(&self) -> Option<(ErrorCode, u32)> {
155 match self.0 {
156 SyscallReturn::FailureU32(r1, r2) => Some((r1, r2)),
157 _ => None,
158 }
159 }
160
161 pub fn get_failure_2_u32(&self) -> Option<(ErrorCode, u32, u32)> {
164 match self.0 {
165 SyscallReturn::FailureU32U32(r1, r2, r3) => Some((r1, r2, r3)),
166 _ => None,
167 }
168 }
169
170 pub fn get_failure_u64(&self) -> Option<(ErrorCode, u64)> {
173 match self.0 {
174 SyscallReturn::FailureU64(r1, r2) => Some((r1, r2)),
175 _ => None,
176 }
177 }
178
179 pub fn get_success_u32(&self) -> Option<u32> {
182 match self.0 {
183 SyscallReturn::SuccessU32(r1) => Some(r1),
184 _ => None,
185 }
186 }
187
188 pub fn get_success_2_u32(&self) -> Option<(u32, u32)> {
191 match self.0 {
192 SyscallReturn::SuccessU32U32(r1, r2) => Some((r1, r2)),
193 _ => None,
194 }
195 }
196
197 pub fn get_success_u64(&self) -> Option<u64> {
200 match self.0 {
201 SyscallReturn::SuccessU64(r1) => Some(r1),
202 _ => None,
203 }
204 }
205
206 pub fn get_success_3_u32(&self) -> Option<(u32, u32, u32)> {
209 match self.0 {
210 SyscallReturn::SuccessU32U32U32(r1, r2, r3) => Some((r1, r2, r3)),
211 _ => None,
212 }
213 }
214
215 pub fn get_success_u32_u64(&self) -> Option<(u32, u64)> {
218 match self.0 {
219 SyscallReturn::SuccessU32U64(r1, r2) => Some((r1, r2)),
220 _ => None,
221 }
222 }
223}
224
225impl From<Result<(), ErrorCode>> for CommandReturn {
226 fn from(rc: Result<(), ErrorCode>) -> Self {
227 match rc {
228 Ok(()) => CommandReturn::success(),
229 Err(e) => CommandReturn::failure(e),
230 }
231 }
232}
233
234impl From<process::Error> for CommandReturn {
235 fn from(perr: process::Error) -> Self {
236 CommandReturn::failure(perr.into())
237 }
238}
239
240#[allow(unused_variables)]
256pub trait SyscallDriver {
257 fn command(
263 &self,
264 command_num: usize,
265 r2: usize,
266 r3: usize,
267 process_id: ProcessId,
268 ) -> CommandReturn {
269 CommandReturn::failure(ErrorCode::NOSUPPORT)
270 }
271
272 fn allow_userspace_readable(
283 &self,
284 app: ProcessId,
285 which: usize,
286 slice: UserspaceReadableProcessBuffer,
287 ) -> Result<UserspaceReadableProcessBuffer, (UserspaceReadableProcessBuffer, ErrorCode)> {
288 Err((slice, ErrorCode::NOSUPPORT))
289 }
290
291 fn allocate_grant(&self, process_id: ProcessId) -> Result<(), crate::process::Error>;
385}
386
387#[cfg(test)]
388mod test {
389 use crate::syscall_driver::CommandReturn;
390 use crate::ErrorCode;
391
392 #[test]
393 fn failure() {
394 let command_return = CommandReturn::failure(ErrorCode::RESERVE);
395 assert!(command_return.is_failure());
396 assert!(!command_return.is_failure_u32());
397 assert!(!command_return.is_failure_2_u32());
398 assert!(!command_return.is_failure_u64());
399 assert!(!command_return.is_success());
400 assert!(!command_return.is_success_u32());
401 assert!(!command_return.is_success_2_u32());
402 assert!(!command_return.is_success_u64());
403 assert!(!command_return.is_success_3_u32());
404 assert!(!command_return.is_success_u32_u64());
405 assert_eq!(command_return.get_failure(), Some(ErrorCode::RESERVE));
406 assert_eq!(command_return.get_failure_u32(), None);
407 assert_eq!(command_return.get_failure_2_u32(), None);
408 assert_eq!(command_return.get_failure_u64(), None);
409 assert_eq!(command_return.get_success_u32(), None);
410 assert_eq!(command_return.get_success_2_u32(), None);
411 assert_eq!(command_return.get_success_u64(), None);
412 assert_eq!(command_return.get_success_3_u32(), None);
413 assert_eq!(command_return.get_success_u32_u64(), None);
414 }
415
416 #[test]
417 fn failure_u32() {
418 let command_return = CommandReturn::failure_u32(ErrorCode::OFF, 1002);
419 assert!(!command_return.is_failure());
420 assert!(command_return.is_failure_u32());
421 assert!(!command_return.is_failure_2_u32());
422 assert!(!command_return.is_failure_u64());
423 assert!(!command_return.is_success());
424 assert!(!command_return.is_success_u32());
425 assert!(!command_return.is_success_2_u32());
426 assert!(!command_return.is_success_u64());
427 assert!(!command_return.is_success_3_u32());
428 assert!(!command_return.is_success_u32_u64());
429 assert_eq!(command_return.get_failure(), None);
430 assert_eq!(
431 command_return.get_failure_u32(),
432 Some((ErrorCode::OFF, 1002))
433 );
434 assert_eq!(command_return.get_failure_2_u32(), None);
435 assert_eq!(command_return.get_failure_u64(), None);
436 assert_eq!(command_return.get_success_u32(), None);
437 assert_eq!(command_return.get_success_2_u32(), None);
438 assert_eq!(command_return.get_success_u64(), None);
439 assert_eq!(command_return.get_success_3_u32(), None);
440 assert_eq!(command_return.get_success_u32_u64(), None);
441 }
442
443 #[test]
444 fn failure_2_u32() {
445 let command_return = CommandReturn::failure_u32_u32(ErrorCode::ALREADY, 1002, 1003);
446 assert!(!command_return.is_failure());
447 assert!(!command_return.is_failure_u32());
448 assert!(command_return.is_failure_2_u32());
449 assert!(!command_return.is_failure_u64());
450 assert!(!command_return.is_success());
451 assert!(!command_return.is_success_u32());
452 assert!(!command_return.is_success_2_u32());
453 assert!(!command_return.is_success_u64());
454 assert!(!command_return.is_success_3_u32());
455 assert!(!command_return.is_success_u32_u64());
456 assert_eq!(command_return.get_failure(), None);
457 assert_eq!(command_return.get_failure_u32(), None);
458 assert_eq!(
459 command_return.get_failure_2_u32(),
460 Some((ErrorCode::ALREADY, 1002, 1003))
461 );
462 assert_eq!(command_return.get_failure_u64(), None);
463 assert_eq!(command_return.get_success_u32(), None);
464 assert_eq!(command_return.get_success_2_u32(), None);
465 assert_eq!(command_return.get_success_u64(), None);
466 assert_eq!(command_return.get_success_3_u32(), None);
467 assert_eq!(command_return.get_success_u32_u64(), None);
468 }
469
470 #[test]
471 fn failure_u64() {
472 let command_return = CommandReturn::failure_u64(ErrorCode::BUSY, 0x0000_1003_0000_1002);
473 assert!(!command_return.is_failure());
474 assert!(!command_return.is_failure_u32());
475 assert!(!command_return.is_failure_2_u32());
476 assert!(command_return.is_failure_u64());
477 assert!(!command_return.is_success());
478 assert!(!command_return.is_success_u32());
479 assert!(!command_return.is_success_2_u32());
480 assert!(!command_return.is_success_u64());
481 assert!(!command_return.is_success_3_u32());
482 assert!(!command_return.is_success_u32_u64());
483 assert_eq!(command_return.get_failure(), None);
484 assert_eq!(command_return.get_failure_u32(), None);
485 assert_eq!(command_return.get_failure_2_u32(), None);
486 assert_eq!(
487 command_return.get_failure_u64(),
488 Some((ErrorCode::BUSY, 0x0000_1003_0000_1002))
489 );
490 assert_eq!(command_return.get_success_u32(), None);
491 assert_eq!(command_return.get_success_2_u32(), None);
492 assert_eq!(command_return.get_success_u64(), None);
493 assert_eq!(command_return.get_success_3_u32(), None);
494 assert_eq!(command_return.get_success_u32_u64(), None);
495 }
496
497 #[test]
498 fn success() {
499 let command_return = CommandReturn::success();
500 assert!(!command_return.is_failure());
501 assert!(!command_return.is_failure_u32());
502 assert!(!command_return.is_failure_2_u32());
503 assert!(!command_return.is_failure_u64());
504 assert!(command_return.is_success());
505 assert!(!command_return.is_success_u32());
506 assert!(!command_return.is_success_2_u32());
507 assert!(!command_return.is_success_u64());
508 assert!(!command_return.is_success_3_u32());
509 assert!(!command_return.is_success_u32_u64());
510 assert_eq!(command_return.get_failure(), None);
511 assert_eq!(command_return.get_failure_u32(), None);
512 assert_eq!(command_return.get_failure_2_u32(), None);
513 assert_eq!(command_return.get_failure_u64(), None);
514 assert_eq!(command_return.get_success_u32(), None);
515 assert_eq!(command_return.get_success_2_u32(), None);
516 assert_eq!(command_return.get_success_u64(), None);
517 assert_eq!(command_return.get_success_3_u32(), None);
518 assert_eq!(command_return.get_success_u32_u64(), None);
519 }
520
521 #[test]
522 fn success_u32() {
523 let command_return = CommandReturn::success_u32(1001);
524 assert!(!command_return.is_failure());
525 assert!(!command_return.is_failure_u32());
526 assert!(!command_return.is_failure_2_u32());
527 assert!(!command_return.is_failure_u64());
528 assert!(!command_return.is_success());
529 assert!(command_return.is_success_u32());
530 assert!(!command_return.is_success_2_u32());
531 assert!(!command_return.is_success_u64());
532 assert!(!command_return.is_success_3_u32());
533 assert!(!command_return.is_success_u32_u64());
534 assert_eq!(command_return.get_failure(), None);
535 assert_eq!(command_return.get_failure_u32(), None);
536 assert_eq!(command_return.get_failure_2_u32(), None);
537 assert_eq!(command_return.get_failure_u64(), None);
538 assert_eq!(command_return.get_success_u32(), Some(1001));
539 assert_eq!(command_return.get_success_2_u32(), None);
540 assert_eq!(command_return.get_success_u64(), None);
541 assert_eq!(command_return.get_success_3_u32(), None);
542 assert_eq!(command_return.get_success_u32_u64(), None);
543 }
544
545 #[test]
546 fn success_2_u32() {
547 let command_return = CommandReturn::success_u32_u32(1001, 1002);
548 assert!(!command_return.is_failure());
549 assert!(!command_return.is_failure_u32());
550 assert!(!command_return.is_failure_2_u32());
551 assert!(!command_return.is_failure_u64());
552 assert!(!command_return.is_success());
553 assert!(!command_return.is_success_u32());
554 assert!(command_return.is_success_2_u32());
555 assert!(!command_return.is_success_u64());
556 assert!(!command_return.is_success_3_u32());
557 assert!(!command_return.is_success_u32_u64());
558 assert_eq!(command_return.get_failure(), None);
559 assert_eq!(command_return.get_failure_u32(), None);
560 assert_eq!(command_return.get_failure_2_u32(), None);
561 assert_eq!(command_return.get_failure_u64(), None);
562 assert_eq!(command_return.get_success_u32(), None);
563 assert_eq!(command_return.get_success_2_u32(), Some((1001, 1002)));
564 assert_eq!(command_return.get_success_u64(), None);
565 assert_eq!(command_return.get_success_3_u32(), None);
566 assert_eq!(command_return.get_success_u32_u64(), None);
567 }
568
569 #[test]
570 fn success_u64() {
571 let command_return = CommandReturn::success_u64(0x0000_1002_0000_1001);
572 assert!(!command_return.is_failure());
573 assert!(!command_return.is_failure_u32());
574 assert!(!command_return.is_failure_2_u32());
575 assert!(!command_return.is_failure_u64());
576 assert!(!command_return.is_success());
577 assert!(!command_return.is_success_u32());
578 assert!(!command_return.is_success_2_u32());
579 assert!(command_return.is_success_u64());
580 assert!(!command_return.is_success_3_u32());
581 assert!(!command_return.is_success_u32_u64());
582 assert_eq!(command_return.get_failure(), None);
583 assert_eq!(command_return.get_failure_u32(), None);
584 assert_eq!(command_return.get_failure_2_u32(), None);
585 assert_eq!(command_return.get_failure_u64(), None);
586 assert_eq!(command_return.get_success_u32(), None);
587 assert_eq!(command_return.get_success_2_u32(), None);
588 assert_eq!(
589 command_return.get_success_u64(),
590 Some(0x0000_1002_0000_1001)
591 );
592 assert_eq!(command_return.get_success_3_u32(), None);
593 assert_eq!(command_return.get_success_u32_u64(), None);
594 }
595
596 #[test]
597 fn success_3_u32() {
598 let command_return = CommandReturn::success_u32_u32_u32(1001, 1002, 1003);
599 assert!(!command_return.is_failure());
600 assert!(!command_return.is_failure_u32());
601 assert!(!command_return.is_failure_2_u32());
602 assert!(!command_return.is_failure_u64());
603 assert!(!command_return.is_success());
604 assert!(!command_return.is_success_u32());
605 assert!(!command_return.is_success_2_u32());
606 assert!(!command_return.is_success_u64());
607 assert!(command_return.is_success_3_u32());
608 assert!(!command_return.is_success_u32_u64());
609 assert_eq!(command_return.get_failure(), None);
610 assert_eq!(command_return.get_failure_u32(), None);
611 assert_eq!(command_return.get_failure_2_u32(), None);
612 assert_eq!(command_return.get_failure_u64(), None);
613 assert_eq!(command_return.get_success_u32(), None);
614 assert_eq!(command_return.get_success_2_u32(), None);
615 assert_eq!(command_return.get_success_u64(), None);
616 assert_eq!(command_return.get_success_3_u32(), Some((1001, 1002, 1003)));
617 assert_eq!(command_return.get_success_u32_u64(), None);
618 }
619
620 #[test]
621 fn success_u32_u64() {
622 let command_return = CommandReturn::success_u32_u64(1001, 0x0000_1003_0000_1002);
623 assert!(!command_return.is_failure());
624 assert!(!command_return.is_failure_u32());
625 assert!(!command_return.is_failure_2_u32());
626 assert!(!command_return.is_failure_u64());
627 assert!(!command_return.is_success());
628 assert!(!command_return.is_success_u32());
629 assert!(!command_return.is_success_2_u32());
630 assert!(!command_return.is_success_u64());
631 assert!(!command_return.is_success_3_u32());
632 assert!(command_return.is_success_u32_u64());
633 assert_eq!(command_return.get_failure(), None);
634 assert_eq!(command_return.get_failure_u32(), None);
635 assert_eq!(command_return.get_failure_2_u32(), None);
636 assert_eq!(command_return.get_failure_u64(), None);
637 assert_eq!(command_return.get_success_u32(), None);
638 assert_eq!(command_return.get_success_2_u32(), None);
639 assert_eq!(command_return.get_success_u64(), None);
640 assert_eq!(command_return.get_success_3_u32(), None);
641 assert_eq!(
642 command_return.get_success_u32_u64(),
643 Some((1001, 0x0000_1003_0000_1002))
644 );
645 }
646}