Merge "Add test_timer commands."

GitOrigin-RevId: 15cc9f8793813dde2f5272ae99b6ce81a71818ef
This commit is contained in:
Adam Jesionowski
2022-05-12 15:25:32 +00:00
committed by Sam Leffler
parent 2378b38d71
commit eb46d7c817
5 changed files with 124 additions and 1 deletions

View File

@@ -5,6 +5,7 @@ import <MlCoordinatorInterface.camkes>;
import <MemoryInterface.camkes>;
import <SecurityCoordinatorInterface.camkes>;
import <StorageInterface.camkes>;
import <TimerServiceInterface.camkes>;
component DebugConsole {
control;
@@ -30,4 +31,6 @@ component DebugConsole {
// Add a bunch of free slots for test code to use.
attribute int cnode_headroom = 64;
uses Timer timer;
}

View File

@@ -25,5 +25,6 @@ kata-proc-interface = { path = "../../ProcessManager/kata-proc-interface" }
kata-os-common = { path = "../../kata-os-common" }
kata-security-interface = { path = "../../SecurityCoordinator/kata-security-interface" }
kata-storage-interface = { path = "../../StorageManager/kata-storage-interface" }
kata-timer-interface = { path = "../../TimerService/kata-timer-interface" }
log = "0.4"
zmodem = { path = "../zmodem" }

View File

@@ -11,8 +11,8 @@ use log;
use kata_io as io;
use kata_line_reader::LineReader;
use kata_os_common::sel4_sys;
use kata_memory_interface::*;
use kata_os_common::sel4_sys;
use kata_proc_interface::kata_pkg_mgmt_install;
use kata_proc_interface::kata_pkg_mgmt_uninstall;
use kata_proc_interface::kata_proc_ctrl_get_running_bundles;
@@ -21,6 +21,10 @@ use kata_proc_interface::kata_proc_ctrl_stop;
use kata_storage_interface::kata_storage_delete;
use kata_storage_interface::kata_storage_read;
use kata_storage_interface::kata_storage_write;
use kata_timer_interface::TimerServiceError;
use kata_timer_interface::timer_service_completed_timers;
use kata_timer_interface::timer_service_oneshot;
use kata_timer_interface::timer_service_wait;
use sel4_sys::seL4_CPtr;
use sel4_sys::seL4_MinSchedContextBits;
@@ -133,6 +137,9 @@ fn dispatch_command(cmdline: &str, input: &mut dyn io::BufRead, output: &mut dyn
"test_mlcontinuous" => test_mlcontinuous_command(&mut args),
"test_obj_alloc" => test_obj_alloc_command(output),
"test_panic" => test_panic_command(),
"test_timer_async" => test_timer_async_command(&mut args, output),
"test_timer_blocking" => test_timer_blocking_command(&mut args, output),
"test_timer_completed" => test_timer_completed_command(output),
_ => Err(CommandError::UnknownCommand),
};
@@ -630,3 +637,55 @@ fn test_obj_alloc_command(output: &mut dyn io::Write) -> Result<(), CommandError
Ok(writeln!(output, "All tests passed!")?)
}
/// Implements a command that starts a timer, but does not wait on the
/// notification.
fn test_timer_async_command(
args: &mut dyn Iterator<Item = &str>,
output: &mut dyn io::Write,
) -> Result<(), CommandError> {
let id_str = args.next().ok_or(CommandError::BadArgs)?;
let id = id_str.parse::<u32>()?;
let time_str = args.next().ok_or(CommandError::BadArgs)?;
let time_ms = time_str.parse::<u32>()?;
writeln!(output, "Starting timer {} for {} ms.", id, time_ms)?;
match timer_service_oneshot(id, time_ms) {
TimerServiceError::TimerOk => (),
_ => return Err(CommandError::BadArgs),
}
timer_service_oneshot(id, time_ms);
return Ok(());
}
/// Implements a command that starts a timer, blocking until the timer has
/// completed.
fn test_timer_blocking_command(
args: &mut dyn Iterator<Item = &str>,
output: &mut dyn io::Write,
) -> Result<(), CommandError> {
let time_str = args.next().ok_or(CommandError::BadArgs)?;
let time_ms = time_str.parse::<u32>()?;
writeln!(output, "Blocking {} ms waiting for timer.", time_ms)?;
// Set timer_id to 0, we don't need to use multiple timers here.
match timer_service_oneshot(0, time_ms) {
TimerServiceError::TimerOk => (),
_ => return Err(CommandError::BadArgs),
}
timer_service_wait();
return Ok(writeln!(output, "Timer completed.")?);
}
/// Implements a command that checks the completed timers.
fn test_timer_completed_command(
output: &mut dyn io::Write,
) -> Result<(), CommandError> {
return Ok(writeln!(output, "Timers completed: {:#032b}", timer_service_completed_timers())?);
}

View File

@@ -1,6 +1,7 @@
#![no_std]
use core::time::Duration;
use kata_os_common::sel4_sys::{seL4_CPtr, seL4_Wait, seL4_Word};
pub type Ticks = u64;
pub type TimerId = u32;
@@ -23,3 +24,60 @@ pub enum TimerServiceError {
NoSuchTimer,
TimerAlreadyExists,
}
#[inline]
#[allow(dead_code)]
pub fn timer_service_completed_timers() -> u32 {
extern "C" {
fn timer_completed_timers() -> u32;
}
unsafe { timer_completed_timers() }
}
#[inline]
#[allow(dead_code)]
pub fn timer_service_oneshot(timer_id: u32, duration_in_ms: u32) -> TimerServiceError {
extern "C" {
fn timer_oneshot(timer_id: u32, duration_in_ms: u32) -> TimerServiceError;
}
unsafe { timer_oneshot(timer_id, duration_in_ms) }
}
#[inline]
#[allow(dead_code)]
pub fn timer_service_periodic(timer_id: u32, duration_in_ms: u32) -> TimerServiceError {
extern "C" {
fn timer_periodic(timer_id: u32, duration_in_ms: u32) -> TimerServiceError;
}
unsafe { timer_periodic(timer_id, duration_in_ms) }
}
#[inline]
#[allow(dead_code)]
pub fn timer_service_cancel(timer_id: u32) -> TimerServiceError {
extern "C" {
fn timer_cancel(timer_id: u32) -> TimerServiceError;
}
unsafe { timer_cancel(timer_id) }
}
#[inline]
#[allow(dead_code)]
pub fn timer_service_notification() -> seL4_CPtr {
extern "C" {
fn timer_notification() -> seL4_CPtr;
}
unsafe { timer_notification() }
}
#[inline]
#[allow(dead_code)]
pub fn timer_service_wait() -> seL4_Word {
let mut notification_badge: seL4_Word = 0;
unsafe {
seL4_Wait(timer_service_notification(), &mut notification_badge);
}
notification_badge
}

View File

@@ -105,6 +105,8 @@ assembly {
to timer.csr);
connection seL4HardwareInterrupt timer_interrupt(from timer.timer_interrupt,
to timer_service.timer_interrupt);
connection seL4RPCCallSignal timer_rpc(from debug_console.timer,
to timer_service.timer);
// Hookup ProcessManager to DebugConsole for shell commands.
connection seL4RPCCall shell_process(from debug_console.proc_ctrl,