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)]
262pub trait SyscallDriver {
263 fn command(
269 &self,
270 command_num: usize,
271 r2: usize,
272 r3: usize,
273 process_id: ProcessId,
274 ) -> CommandReturn {
275 CommandReturn::failure(ErrorCode::NOSUPPORT)
276 }
277
278 fn allow_userspace_readable(
289 &self,
290 app: ProcessId,
291 which: usize,
292 slice: UserspaceReadableProcessBuffer,
293 ) -> Result<UserspaceReadableProcessBuffer, (UserspaceReadableProcessBuffer, ErrorCode)> {
294 Err((slice, ErrorCode::NOSUPPORT))
295 }
296
297 fn allocate_grant(&self, process_id: ProcessId) -> Result<(), crate::process::Error>;
391}
392
393#[cfg(test)]
394mod test {
395 use crate::ErrorCode;
396 use crate::syscall_driver::CommandReturn;
397
398 #[test]
399 fn failure() {
400 let command_return = CommandReturn::failure(ErrorCode::RESERVE);
401 assert!(command_return.is_failure());
402 assert!(!command_return.is_failure_u32());
403 assert!(!command_return.is_failure_2_u32());
404 assert!(!command_return.is_failure_u64());
405 assert!(!command_return.is_success());
406 assert!(!command_return.is_success_u32());
407 assert!(!command_return.is_success_2_u32());
408 assert!(!command_return.is_success_u64());
409 assert!(!command_return.is_success_3_u32());
410 assert!(!command_return.is_success_u32_u64());
411 assert_eq!(command_return.get_failure(), Some(ErrorCode::RESERVE));
412 assert_eq!(command_return.get_failure_u32(), None);
413 assert_eq!(command_return.get_failure_2_u32(), None);
414 assert_eq!(command_return.get_failure_u64(), None);
415 assert_eq!(command_return.get_success_u32(), None);
416 assert_eq!(command_return.get_success_2_u32(), None);
417 assert_eq!(command_return.get_success_u64(), None);
418 assert_eq!(command_return.get_success_3_u32(), None);
419 assert_eq!(command_return.get_success_u32_u64(), None);
420 }
421
422 #[test]
423 fn failure_u32() {
424 let command_return = CommandReturn::failure_u32(ErrorCode::OFF, 1002);
425 assert!(!command_return.is_failure());
426 assert!(command_return.is_failure_u32());
427 assert!(!command_return.is_failure_2_u32());
428 assert!(!command_return.is_failure_u64());
429 assert!(!command_return.is_success());
430 assert!(!command_return.is_success_u32());
431 assert!(!command_return.is_success_2_u32());
432 assert!(!command_return.is_success_u64());
433 assert!(!command_return.is_success_3_u32());
434 assert!(!command_return.is_success_u32_u64());
435 assert_eq!(command_return.get_failure(), None);
436 assert_eq!(
437 command_return.get_failure_u32(),
438 Some((ErrorCode::OFF, 1002))
439 );
440 assert_eq!(command_return.get_failure_2_u32(), None);
441 assert_eq!(command_return.get_failure_u64(), None);
442 assert_eq!(command_return.get_success_u32(), None);
443 assert_eq!(command_return.get_success_2_u32(), None);
444 assert_eq!(command_return.get_success_u64(), None);
445 assert_eq!(command_return.get_success_3_u32(), None);
446 assert_eq!(command_return.get_success_u32_u64(), None);
447 }
448
449 #[test]
450 fn failure_2_u32() {
451 let command_return = CommandReturn::failure_u32_u32(ErrorCode::ALREADY, 1002, 1003);
452 assert!(!command_return.is_failure());
453 assert!(!command_return.is_failure_u32());
454 assert!(command_return.is_failure_2_u32());
455 assert!(!command_return.is_failure_u64());
456 assert!(!command_return.is_success());
457 assert!(!command_return.is_success_u32());
458 assert!(!command_return.is_success_2_u32());
459 assert!(!command_return.is_success_u64());
460 assert!(!command_return.is_success_3_u32());
461 assert!(!command_return.is_success_u32_u64());
462 assert_eq!(command_return.get_failure(), None);
463 assert_eq!(command_return.get_failure_u32(), None);
464 assert_eq!(
465 command_return.get_failure_2_u32(),
466 Some((ErrorCode::ALREADY, 1002, 1003))
467 );
468 assert_eq!(command_return.get_failure_u64(), None);
469 assert_eq!(command_return.get_success_u32(), None);
470 assert_eq!(command_return.get_success_2_u32(), None);
471 assert_eq!(command_return.get_success_u64(), None);
472 assert_eq!(command_return.get_success_3_u32(), None);
473 assert_eq!(command_return.get_success_u32_u64(), None);
474 }
475
476 #[test]
477 fn failure_u64() {
478 let command_return = CommandReturn::failure_u64(ErrorCode::BUSY, 0x0000_1003_0000_1002);
479 assert!(!command_return.is_failure());
480 assert!(!command_return.is_failure_u32());
481 assert!(!command_return.is_failure_2_u32());
482 assert!(command_return.is_failure_u64());
483 assert!(!command_return.is_success());
484 assert!(!command_return.is_success_u32());
485 assert!(!command_return.is_success_2_u32());
486 assert!(!command_return.is_success_u64());
487 assert!(!command_return.is_success_3_u32());
488 assert!(!command_return.is_success_u32_u64());
489 assert_eq!(command_return.get_failure(), None);
490 assert_eq!(command_return.get_failure_u32(), None);
491 assert_eq!(command_return.get_failure_2_u32(), None);
492 assert_eq!(
493 command_return.get_failure_u64(),
494 Some((ErrorCode::BUSY, 0x0000_1003_0000_1002))
495 );
496 assert_eq!(command_return.get_success_u32(), None);
497 assert_eq!(command_return.get_success_2_u32(), None);
498 assert_eq!(command_return.get_success_u64(), None);
499 assert_eq!(command_return.get_success_3_u32(), None);
500 assert_eq!(command_return.get_success_u32_u64(), None);
501 }
502
503 #[test]
504 fn success() {
505 let command_return = CommandReturn::success();
506 assert!(!command_return.is_failure());
507 assert!(!command_return.is_failure_u32());
508 assert!(!command_return.is_failure_2_u32());
509 assert!(!command_return.is_failure_u64());
510 assert!(command_return.is_success());
511 assert!(!command_return.is_success_u32());
512 assert!(!command_return.is_success_2_u32());
513 assert!(!command_return.is_success_u64());
514 assert!(!command_return.is_success_3_u32());
515 assert!(!command_return.is_success_u32_u64());
516 assert_eq!(command_return.get_failure(), None);
517 assert_eq!(command_return.get_failure_u32(), None);
518 assert_eq!(command_return.get_failure_2_u32(), None);
519 assert_eq!(command_return.get_failure_u64(), None);
520 assert_eq!(command_return.get_success_u32(), None);
521 assert_eq!(command_return.get_success_2_u32(), None);
522 assert_eq!(command_return.get_success_u64(), None);
523 assert_eq!(command_return.get_success_3_u32(), None);
524 assert_eq!(command_return.get_success_u32_u64(), None);
525 }
526
527 #[test]
528 fn success_u32() {
529 let command_return = CommandReturn::success_u32(1001);
530 assert!(!command_return.is_failure());
531 assert!(!command_return.is_failure_u32());
532 assert!(!command_return.is_failure_2_u32());
533 assert!(!command_return.is_failure_u64());
534 assert!(!command_return.is_success());
535 assert!(command_return.is_success_u32());
536 assert!(!command_return.is_success_2_u32());
537 assert!(!command_return.is_success_u64());
538 assert!(!command_return.is_success_3_u32());
539 assert!(!command_return.is_success_u32_u64());
540 assert_eq!(command_return.get_failure(), None);
541 assert_eq!(command_return.get_failure_u32(), None);
542 assert_eq!(command_return.get_failure_2_u32(), None);
543 assert_eq!(command_return.get_failure_u64(), None);
544 assert_eq!(command_return.get_success_u32(), Some(1001));
545 assert_eq!(command_return.get_success_2_u32(), None);
546 assert_eq!(command_return.get_success_u64(), None);
547 assert_eq!(command_return.get_success_3_u32(), None);
548 assert_eq!(command_return.get_success_u32_u64(), None);
549 }
550
551 #[test]
552 fn success_2_u32() {
553 let command_return = CommandReturn::success_u32_u32(1001, 1002);
554 assert!(!command_return.is_failure());
555 assert!(!command_return.is_failure_u32());
556 assert!(!command_return.is_failure_2_u32());
557 assert!(!command_return.is_failure_u64());
558 assert!(!command_return.is_success());
559 assert!(!command_return.is_success_u32());
560 assert!(command_return.is_success_2_u32());
561 assert!(!command_return.is_success_u64());
562 assert!(!command_return.is_success_3_u32());
563 assert!(!command_return.is_success_u32_u64());
564 assert_eq!(command_return.get_failure(), None);
565 assert_eq!(command_return.get_failure_u32(), None);
566 assert_eq!(command_return.get_failure_2_u32(), None);
567 assert_eq!(command_return.get_failure_u64(), None);
568 assert_eq!(command_return.get_success_u32(), None);
569 assert_eq!(command_return.get_success_2_u32(), Some((1001, 1002)));
570 assert_eq!(command_return.get_success_u64(), None);
571 assert_eq!(command_return.get_success_3_u32(), None);
572 assert_eq!(command_return.get_success_u32_u64(), None);
573 }
574
575 #[test]
576 fn success_u64() {
577 let command_return = CommandReturn::success_u64(0x0000_1002_0000_1001);
578 assert!(!command_return.is_failure());
579 assert!(!command_return.is_failure_u32());
580 assert!(!command_return.is_failure_2_u32());
581 assert!(!command_return.is_failure_u64());
582 assert!(!command_return.is_success());
583 assert!(!command_return.is_success_u32());
584 assert!(!command_return.is_success_2_u32());
585 assert!(command_return.is_success_u64());
586 assert!(!command_return.is_success_3_u32());
587 assert!(!command_return.is_success_u32_u64());
588 assert_eq!(command_return.get_failure(), None);
589 assert_eq!(command_return.get_failure_u32(), None);
590 assert_eq!(command_return.get_failure_2_u32(), None);
591 assert_eq!(command_return.get_failure_u64(), None);
592 assert_eq!(command_return.get_success_u32(), None);
593 assert_eq!(command_return.get_success_2_u32(), None);
594 assert_eq!(
595 command_return.get_success_u64(),
596 Some(0x0000_1002_0000_1001)
597 );
598 assert_eq!(command_return.get_success_3_u32(), None);
599 assert_eq!(command_return.get_success_u32_u64(), None);
600 }
601
602 #[test]
603 fn success_3_u32() {
604 let command_return = CommandReturn::success_u32_u32_u32(1001, 1002, 1003);
605 assert!(!command_return.is_failure());
606 assert!(!command_return.is_failure_u32());
607 assert!(!command_return.is_failure_2_u32());
608 assert!(!command_return.is_failure_u64());
609 assert!(!command_return.is_success());
610 assert!(!command_return.is_success_u32());
611 assert!(!command_return.is_success_2_u32());
612 assert!(!command_return.is_success_u64());
613 assert!(command_return.is_success_3_u32());
614 assert!(!command_return.is_success_u32_u64());
615 assert_eq!(command_return.get_failure(), None);
616 assert_eq!(command_return.get_failure_u32(), None);
617 assert_eq!(command_return.get_failure_2_u32(), None);
618 assert_eq!(command_return.get_failure_u64(), None);
619 assert_eq!(command_return.get_success_u32(), None);
620 assert_eq!(command_return.get_success_2_u32(), None);
621 assert_eq!(command_return.get_success_u64(), None);
622 assert_eq!(command_return.get_success_3_u32(), Some((1001, 1002, 1003)));
623 assert_eq!(command_return.get_success_u32_u64(), None);
624 }
625
626 #[test]
627 fn success_u32_u64() {
628 let command_return = CommandReturn::success_u32_u64(1001, 0x0000_1003_0000_1002);
629 assert!(!command_return.is_failure());
630 assert!(!command_return.is_failure_u32());
631 assert!(!command_return.is_failure_2_u32());
632 assert!(!command_return.is_failure_u64());
633 assert!(!command_return.is_success());
634 assert!(!command_return.is_success_u32());
635 assert!(!command_return.is_success_2_u32());
636 assert!(!command_return.is_success_u64());
637 assert!(!command_return.is_success_3_u32());
638 assert!(command_return.is_success_u32_u64());
639 assert_eq!(command_return.get_failure(), None);
640 assert_eq!(command_return.get_failure_u32(), None);
641 assert_eq!(command_return.get_failure_2_u32(), None);
642 assert_eq!(command_return.get_failure_u64(), None);
643 assert_eq!(command_return.get_success_u32(), None);
644 assert_eq!(command_return.get_success_2_u32(), None);
645 assert_eq!(command_return.get_success_u64(), None);
646 assert_eq!(command_return.get_success_3_u32(), None);
647 assert_eq!(
648 command_return.get_success_u32_u64(),
649 Some((1001, 0x0000_1003_0000_1002))
650 );
651 }
652}