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}