capsules_extra/
syscall_return_test.rs1use kernel::grant::{AllowRoCount, AllowRwCount, Grant, GrantKernelData, UpcallCount};
36use kernel::process;
37use kernel::processbuffer::UserspaceReadableProcessBuffer;
38use kernel::syscall::{CommandReturn, SyscallDriver};
39use kernel::{ErrorCode, ProcessId};
40
41pub const DRIVER_NUM: usize = capsules_core::driver::NUM::SyscallReturnTest as usize;
42
43#[derive(Default)]
46pub struct App {
47 userspace_readable_buf: UserspaceReadableProcessBuffer,
48}
49
50pub struct SyscallReturnTest {
51 apps: Grant<App, UpcallCount<1>, AllowRoCount<1>, AllowRwCount<1>>,
52}
53
54impl SyscallReturnTest {
55 pub fn new(grant: Grant<App, UpcallCount<1>, AllowRoCount<1>, AllowRwCount<1>>) -> Self {
56 SyscallReturnTest { apps: grant }
57 }
58}
59
60impl SyscallDriver for SyscallReturnTest {
61 fn command(
62 &self,
63 command_num: usize,
64 _r2: usize,
65 _r3: usize,
66 _process_id: ProcessId,
67 ) -> CommandReturn {
68 match command_num {
69 0 => CommandReturn::success(),
70 1 => CommandReturn::failure(ErrorCode::FAIL),
71 2 => CommandReturn::failure_u32(ErrorCode::BUSY, 0x2000_0001),
72 3 => CommandReturn::failure_u32_u32(ErrorCode::NOMEM, 0x3000_0001, 0x3000_0002),
73 4 => CommandReturn::failure_u64(ErrorCode::INVAL, 0x4000_0000_0000_0001),
74 5 => CommandReturn::success(),
75 6 => CommandReturn::success_u32(0x6000_0001),
76 7 => CommandReturn::success_u32_u32(0x7000_0001, 0x7000_0002),
77 8 => CommandReturn::success_u64(0x8000_0000_0000_0001),
78 9 => CommandReturn::success_u32_u32_u32(0x9000_0001, 0x9000_0002, 0x9000_0003),
79 10 => CommandReturn::success_u32_u64(0xA000_0001, 0xA000_0000_0000_0002),
80 _ => CommandReturn::failure(ErrorCode::NOSUPPORT),
81 }
82 }
83
84 fn allow_userspace_readable(
90 &self,
91 processid: ProcessId,
92 which: usize,
93 mut slice: UserspaceReadableProcessBuffer,
94 ) -> Result<UserspaceReadableProcessBuffer, (UserspaceReadableProcessBuffer, ErrorCode)> {
95 if which == 0 {
96 let res = self.apps.enter(processid, |data, _: &GrantKernelData| {
97 core::mem::swap(&mut data.userspace_readable_buf, &mut slice);
98 });
99 match res {
100 Ok(()) => Ok(slice),
101 Err(e) => Err((slice, e.into())),
102 }
103 } else {
104 Err((slice, ErrorCode::NOSUPPORT))
105 }
106 }
107
108 fn allocate_grant(&self, process_id: ProcessId) -> Result<(), process::Error> {
109 self.apps.enter(process_id, |_, _| {})
110 }
111}