Skip to content

Commit

Permalink
capsules: add restrict resource utility
Browse files Browse the repository at this point in the history
This allows for a kernel to allocate specific ranges of enumerated
resources (think LEDs, buttons, etc.) to specific apps.
  • Loading branch information
bradjc committed Jan 14, 2024
1 parent d94a450 commit 8f2cdfb
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
1 change: 1 addition & 0 deletions capsules/extra/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ pub mod proximity;
pub mod public_key_crypto;
pub mod pwm;
pub mod read_only_state;
pub mod restrict_resource;
pub mod rf233;
pub mod rf233_const;
pub mod screen;
Expand Down
76 changes: 76 additions & 0 deletions capsules/extra/src/restrict_resource.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Licensed under the Apache License, Version 2.0 or the MIT License.
// SPDX-License-Identifier: Apache-2.0 OR MIT
// Copyright Tock Contributors 2024.

//! Utility to partition SyscallDriver resources by app.

use kernel::syscall::{CommandReturn, SyscallDriver};
use kernel::ErrorCode;
use kernel::ProcessId;

pub struct AppPermittedData {
app_id: kernel::process::ShortID,
range_start: usize,
range_end: usize,
}

/// Holds the array of LEDs and implements a `Driver` interface to
/// control them.
pub struct RestrictResource<'a, D: kernel::syscall::SyscallDriver> {
driver: &'a D,
command_num_num: usize,
permitted: &'a [AppPermittedData],
}

impl<'a, D: kernel::syscall::SyscallDriver> RestrictResource<'a, D> {
pub fn new(driver: &'a D, permitted: &'a [AppPermittedData], command_num_num: usize) -> Self {
Self {
driver,
command_num_num,
permitted,
}
}

fn get_app_permitted(&self, processid: ProcessId) -> Option<&AppPermittedData> {
for perm in self.permitted {
if processid.short_app_id() == perm.app_id {
return Some(&perm);
}
}
None
}
}

impl<'a, D: kernel::syscall::SyscallDriver> SyscallDriver for RestrictResource<'a, D> {
fn command(
&self,
command_num: usize,
data: usize,
arg2: usize,
processid: ProcessId,
) -> CommandReturn {
match command_num {
0 => self.driver.command(0, data, arg2, processid),

_ => match self.get_app_permitted(processid) {
Some(perm) => {
if command_num == self.command_num_num {
CommandReturn::success_u32((perm.range_end - perm.range_start) as u32)
} else {
let new_data = perm.range_start;
if new_data < perm.range_end {
self.driver.command(0, new_data, arg2, processid)
} else {
CommandReturn::failure(ErrorCode::NOSUPPORT)
}
}
}
None => CommandReturn::failure(ErrorCode::NOSUPPORT),
},
}
}

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

0 comments on commit 8f2cdfb

Please sign in to comment.