pub trait SyscallDriver {
    fn allocate_grant(&self, process_id: ProcessId) -> Result<(), Error>;

    fn command(
        command_num: usize,
        r2: usize,
        r3: usize,
        process_id: ProcessId
    ) -> CommandReturn { ... } fn allow_userspace_readable(
        app: ProcessId,
        which: usize,
        slice: UserspaceReadableProcessBuffer
    ) -> Result<UserspaceReadableProcessBuffer, (UserspaceReadableProcessBuffer, ErrorCode)> { ... } }
Expand description

Trait for capsules implementing peripheral driver system calls specified in TRD104. The kernel translates the values passed from userspace into Rust types and includes which process is making the call. All of these system calls perform very little synchronous work; long running computations or I/O should be split-phase, with an upcall indicating their completion.

The exact instances of each of these methods (which identifiers are valid and what they represents) are specific to the peripheral system call driver.

Note about subscribe, read-only allow, and read-write allow* syscalls: those are handled entirely by the core kernel, and there is no corresponding function for capsules to implement.

Required Methods

Request to allocate a capsule’s grant for a specific process.

The core kernel uses this function to instruct a capsule to ensure its grant (if it has one) is allocated for a specific process. The core kernel needs the capsule to initiate the allocation because only the capsule knows the type T (and therefore the size of T) that will be stored in the grant.

The typical implementation will look like:

fn allocate_grant(&self, processid: ProcessId) -> Result<(), kernel::process::Error> {
   self.apps.enter(processid, |_, _| {})

No default implementation is provided to help prevent accidentally forgetting to implement this function.

If a capsule fails to successfully implement this function, subscribe calls from userspace for the Driver may fail.

Provided Methods

System call for a process to perform a short synchronous operation or start a long-running split-phase operation (whose completion is signaled with an upcall). Command 0 is a reserved command to detect if a peripheral system call driver is installed and must always return a CommandReturn::Success.

System call for a process to pass a buffer (a UserspaceReadableProcessBuffer) to the kernel that the kernel can either read or write. The kernel calls this method only after it checks that the entire buffer is within memory the process can both read and write.

This is different to allow_readwrite() in that the app is allowed to read the buffer once it has been passed to the kernel. For more details on how this can be done safely see the userspace readable allow syscalls TRDXXX.