Merge "Add basic mailbox driver camkes component + a test script in DebugConsole."

GitOrigin-RevId: 687148fc664b922d3b04ba8a8397fa0f5ff79e29
This commit is contained in:
Austin Appleby 2022-06-16 00:15:06 +00:00 committed by Sam Leffler
parent 8800dc4a96
commit 2b0dd2eb8b
15 changed files with 569 additions and 14 deletions

View File

@ -96,6 +96,17 @@ DeclareCAmkESComponent(TimerService
INCLUDES interfaces
)
RustAddLibrary(
mailbox_driver
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/components/MailboxDriver
LIB_FILENAME libmailbox_driver.a
)
DeclareCAmkESComponent(MailboxDriver
LIBS mailbox_driver
INCLUDES interfaces
)
DeclareCAmkESComponent(LogFibonacci
SOURCES
components/LogFibonacci/src/main.c

View File

@ -13,6 +13,7 @@ sel4-config = { path = "../../kata-os-common/src/sel4-config" }
[features]
default = [
"TEST_GLOBAL_ALLOCATOR",
"TEST_MAILBOX",
"TEST_MEMORY_MANAGER",
"TEST_ML_COORDINATOR",
"TEST_PANIC",
@ -25,6 +26,7 @@ CONFIG_KERNEL_MCS = []
FRINGE_CMDS = []
# Runtime tests for various services (please keep sorted)
TEST_GLOBAL_ALLOCATOR = []
TEST_MAILBOX = []
TEST_MEMORY_MANAGER = []
TEST_ML_COORDINATOR = []
TEST_PANIC = []

View File

@ -22,6 +22,7 @@ pub fn add_cmds(cmds: &mut HashMap::<&str, CmdFn>) {
("delete_key", delete_key_command as CmdFn),
("read_key", read_key_command as CmdFn),
("write_key", write_key_command as CmdFn),
("test_mailbox", test_mailbox_command as CmdFn),
]);
}
@ -157,3 +158,20 @@ fn write_key_command(
}
Ok(())
}
fn test_mailbox_command(
_args: &mut dyn Iterator<Item = &str>,
_input: &mut dyn io::BufRead,
output: &mut dyn io::Write,
_builtin_cpio: &[u8],
) -> Result<(), CommandError> {
match kata_security_test_mailbox() {
Ok(_) => {
writeln!(output, "Test mailbox OK.")?;
}
Err(_status) => {
writeln!(output, "Test mailbox failed.")?;
}
}
Ok(())
}

View File

@ -0,0 +1,8 @@
cargo-features = ["edition2021"]
[workspace]
members = [
"mailbox-driver",
]
resolver = "2"

View File

@ -0,0 +1,33 @@
/*
* CAmkES component for accessing Sparrow's SMC -> SEC mailbox.
*
* Copyright 2021, Google LLC
* Apache License 2.0
*/
import <MailboxInterface.camkes>;
import <MemoryInterface.camkes>;
import <LoggerInterface.camkes>;
component MailboxDriver {
provides MailboxAPI api;
// Mailbox registers
dataport Buf mailbox_mmio;
// Global mailbox lock
has mutex api_mutex;
// Mailbox arrival semaphore
has semaphore rx_semaphore;
// Mailbox interrupts
consumes Interrupt wtirq;
consumes Interrupt rtirq;
consumes Interrupt eirq;
// Enable KataOS CAmkES support.
attribute int kataos = true;
uses LoggerInterface logger;
}

View File

@ -0,0 +1,20 @@
cargo-features = ["edition2021"]
[package]
name = "mailbox-driver"
version = "0.1.0"
edition = "2018"
[features]
default = []
[dependencies]
kata-os-common = { path = "../../kata-os-common" }
log = "0.4"
cty = "0.2.1"
kata-memory-interface = { path = "../../MemoryManager/kata-memory-interface" }
[lib]
name = "mailbox_driver"
path = "src/lib.rs"
crate-type = ["staticlib"]

View File

@ -0,0 +1,262 @@
#![no_std]
// We want to keep all mailbox constants here even if they're currently unused.
#![allow(dead_code)]
#![allow(non_snake_case)]
use kata_os_common::logger::KataLogger;
use kata_os_common::sel4_sys::seL4_CPtr;
use log::{error, trace};
//------------------------------------------------------------------------------
// TODO(aappleby): Can we replace this with the register_struct! thing?
const REG_INTR_STATE: u32 = 0x000; // R/W1C
const REG_INTR_ENABLE: u32 = 0x004; // R/W
const REG_INTR_TEST: u32 = 0x008; // R/W
const REG_MBOXW: u32 = 0x00C; // W
const REG_MBOXR: u32 = 0x010; // R
const REG_STATUS: u32 = 0x014; // R
const REG_ERROR: u32 = 0x018; // R
const REG_WIRQT: u32 = 0x01C; // R/W
const REG_RIRQT: u32 = 0x020; // R/W
const REG_CTRL: u32 = 0x024; // R/W
const INTR_STATE_BIT_WTIRQ: u32 = 0b001;
const INTR_STATE_BIT_RTIRQ: u32 = 0b010;
const INTR_STATE_BIT_EIRQ: u32 = 0b100;
const INTR_STATE_MASK: u32 = 0b111;
const INTR_ENABLE_BIT_WTIRQ: u32 = 0b001;
const INTR_ENABLE_BIT_RTIRQ: u32 = 0b010;
const INTR_ENABLE_BIT_EIRQ: u32 = 0b100;
const INTR_ENABLE_MASK: u32 = 0b111;
const INTR_TEST_BIT_WTIRQ: u32 = 0b001;
const INTR_TEST_BIT_RTIRQ: u32 = 0b010;
const INTR_TEST_BIT_EIRQ: u32 = 0b100;
const INTR_TEST_MASK: u32 = 0b111;
const STATUS_BIT_EMPTY: u32 = 0b0001;
const STATUS_BIT_FULL: u32 = 0b0010;
const STATUS_BIT_WFIFOL: u32 = 0b0100;
const STATUS_BIT_RFIFOL: u32 = 0b1000;
const STATUS_MASK: u32 = 0b1111;
const ERROR_BIT_READ: u32 = 0b01;
const ERROR_BIT_WRITE: u32 = 0b10;
const ERROR_MASK: u32 = 0b11;
const FIFO_SIZE: u32 = 8;
const FIFO_MASK: u32 = FIFO_SIZE - 1;
const WIRQT_MASK: u32 = FIFO_MASK;
const RIRQT_MASK: u32 = FIFO_MASK;
const CTRL_BIT_FLUSH_WFIFO: u32 = 0b01;
const CTRL_BIT_FLUSH_RFIFO: u32 = 0b10;
const CTRL_MASK: u32 = 0b11;
// The high bit of the message header is used to distinguish between "inline"
// messages that fit in the mailbox and "long" messages that contain the
// physical address of a memory page containing the message.
const HEADER_FLAG_LONG_MESSAGE: u32 = 0x80000000;
//------------------------------------------------------------------------------
extern "C" {
// Mailbox registers
static mailbox_mmio: *mut u32;
// Global mailbox lock
fn api_mutex_lock() -> u32;
fn api_mutex_unlock() -> u32;
// Mailbox arrival semaphore
fn rx_semaphore_wait() -> u32;
fn rx_semaphore_post() -> u32;
// Mailbox interrupts
fn wtirq_acknowledge() -> u32;
fn rtirq_acknowledge() -> u32;
fn eirq_acknowledge() -> u32;
// Enable KataOS CAmkES support.
static SELF_CNODE: seL4_CPtr;
static SELF_VSPACE_ROOT: seL4_CPtr;
}
//------------------------------------------------------------------------------
// Directly manipulate the mailbox registers.
unsafe fn get_intr_state() -> u32 {
mailbox_mmio.offset(0).read_volatile()
}
unsafe fn get_INTR_ENABLE() -> u32 {
mailbox_mmio.offset(1).read_volatile()
}
unsafe fn get_INTR_TEST() -> u32 {
mailbox_mmio.offset(2).read_volatile()
}
unsafe fn get_MBOXW() -> u32 {
mailbox_mmio.offset(3).read_volatile()
}
unsafe fn get_MBOXR() -> u32 {
mailbox_mmio.offset(4).read_volatile()
}
unsafe fn get_STATUS() -> u32 {
mailbox_mmio.offset(5).read_volatile()
}
unsafe fn get_ERROR() -> u32 {
mailbox_mmio.offset(6).read_volatile()
}
unsafe fn get_WIRQT() -> u32 {
mailbox_mmio.offset(7).read_volatile()
}
unsafe fn get_RIRQT() -> u32 {
mailbox_mmio.offset(8).read_volatile()
}
unsafe fn get_CTRL() -> u32 {
mailbox_mmio.offset(9).read_volatile()
}
unsafe fn set_INTR_STATE(x: u32) {
mailbox_mmio.offset(0).write_volatile(x);
}
unsafe fn set_INTR_ENABLE(x: u32) {
mailbox_mmio.offset(1).write_volatile(x);
}
unsafe fn set_INTR_TEST(x: u32) {
mailbox_mmio.offset(2).write_volatile(x);
}
unsafe fn set_MBOXW(x: u32) {
mailbox_mmio.offset(3).write_volatile(x);
}
unsafe fn set_MBOXR(x: u32) {
mailbox_mmio.offset(4).write_volatile(x);
}
unsafe fn set_STATUS(x: u32) {
mailbox_mmio.offset(5).write_volatile(x);
}
unsafe fn set_ERROR(x: u32) {
mailbox_mmio.offset(6).write_volatile(x);
}
unsafe fn set_WIRQT(x: u32) {
mailbox_mmio.offset(7).write_volatile(x);
}
unsafe fn set_RIRQT(x: u32) {
mailbox_mmio.offset(8).write_volatile(x);
}
unsafe fn set_CTRL(x: u32) {
mailbox_mmio.offset(9).write_volatile(x);
}
//------------------------------------------------------------------------------
// Directly manipulate the hardware FIFOs. Synchronous and busy-waits. Not
// thread-safe, should only be used while holding the api_mutex lock.
fn enqueue_u32(x: u32) {
unsafe {
while (get_STATUS() & STATUS_BIT_FULL) == STATUS_BIT_FULL {}
set_MBOXW(x);
}
}
fn dequeue_u32() -> u32 {
unsafe {
while (get_STATUS() & STATUS_BIT_EMPTY) == STATUS_BIT_EMPTY {}
return get_MBOXR();
}
}
fn drain_read_fifo() {
unsafe {
while (get_STATUS() & STATUS_BIT_EMPTY) == 0 {
let _ = get_MBOXR();
}
}
}
//------------------------------------------------------------------------------
#[no_mangle]
pub unsafe extern "C" fn pre_init() {
static KATA_LOGGER: KataLogger = KataLogger;
log::set_logger(&KATA_LOGGER).unwrap();
log::set_max_level(log::LevelFilter::Trace);
// We always want our receive interrupt to fire as soon as anything appears
// in the mailbox, so set the threshold to 0.
set_RIRQT(0);
set_INTR_STATE(INTR_STATE_BIT_RTIRQ);
set_INTR_ENABLE(INTR_ENABLE_BIT_RTIRQ);
}
//------------------------------------------------------------------------------
// When outbox.count > write_threshold, this interrupt fires.
#[no_mangle]
pub unsafe extern "C" fn wtirq_handle() {
trace!("wtirq_handle()");
// We don't have anything to do here yet, so just clear the interrupt.
set_INTR_STATE(INTR_STATE_BIT_WTIRQ);
wtirq_acknowledge();
}
// When inbox.count > read_threshold, this interrupt fires.
#[no_mangle]
pub unsafe extern "C" fn rtirq_handle() {
trace!("rtirq_handle()");
// Unblock anyone waiting for a message. api_receive() below will clear
// the interrupt once the message has been deliverd to the client.
rx_semaphore_post();
}
// When an error occurs, this interrupt fires. We don't handle errors yet.
#[no_mangle]
pub unsafe extern "C" fn eirq_handle() {
error!("eirq_handle() - error flag is 0x{:X}", get_ERROR());
// We don't have anything to do here yet, so just clear the interrupt.
set_INTR_STATE(INTR_STATE_BIT_EIRQ);
eirq_acknowledge();
}
//------------------------------------------------------------------------------
// Send a message to the security core. The message must be at a _physical_
// address, as the security core knows nothing about seL4's virtual memory.
#[no_mangle]
pub unsafe extern "C" fn api_send(request_paddr: u32, request_size: u32) {
api_mutex_lock();
let request_header = request_size | HEADER_FLAG_LONG_MESSAGE;
enqueue_u32(request_header);
enqueue_u32(request_paddr);
api_mutex_unlock();
}
// Receive a message from the security core. Blocks the calling thread until a
// message arrives.
#[no_mangle]
pub unsafe extern "C" fn api_receive(response_paddr: *mut u32, response_size: *mut u32) {
api_mutex_lock();
// When a message arrives, the interrupt handler will raise the semaphore.
rx_semaphore_wait();
// Message arrived, dequeue it.
let message_header = dequeue_u32();
let message_paddr = dequeue_u32();
response_paddr.write(message_paddr);
response_size.write(message_header & !HEADER_FLAG_LONG_MESSAGE);
// The interrupt that raised the semaphore has been handled, clear it.
set_INTR_STATE(INTR_STATE_BIT_RTIRQ);
rtirq_acknowledge();
api_mutex_unlock();
}
//------------------------------------------------------------------------------

View File

@ -3,16 +3,21 @@
import <LoggerInterface.camkes>;
import <MemoryInterface.camkes>;
import <SecurityCoordinatorInterface.camkes>;
import <MailboxInterface.camkes>;
component SecurityCoordinator {
provides SecurityCoordinatorInterface security;
uses LoggerInterface logger;
uses MemoryInterface memory;
uses MailboxAPI mailbox_api;
// Enable KataOS CAmkES support.
attribute int kataos = true;
// Add free slots for processing requests.
attribute int cnode_headroom = 32;
// For mailbox use. What should we call this?
has copyregion COPYREGION;
}

View File

@ -232,6 +232,12 @@ fn delete_key_request(
unsafe { KATA_SECURITY.delete_key(request.bundle_id, request.key) }
}
fn test_mailbox_request(
) -> Result<(), SecurityRequestError> {
trace!("TEST MAILBOX");
unsafe { KATA_SECURITY.test_mailbox() }
}
#[no_mangle]
pub unsafe extern "C" fn security_request(
c_request: SecurityRequest,
@ -263,5 +269,7 @@ pub unsafe extern "C" fn security_request(
write_key_request(request_buffer, reply_buffer),
SecurityRequest::SrDeleteKey =>
delete_key_request(request_buffer, reply_buffer),
SecurityRequest::SrTestMailbox =>
test_mailbox_request(),
}.map_or_else(|e| e, |_v| SecurityRequestError::SreSuccess)
}

View File

@ -3,11 +3,13 @@
extern crate alloc;
use alloc::fmt;
use alloc::string::{String, ToString};
use core::mem::size_of;
use hashbrown::HashMap;
use kata_memory_interface::ObjDescBundle;
use kata_memory_interface::kata_object_free_in_cnode;
use kata_memory_interface::*;
use kata_os_common::sel4_sys::*;
use kata_security_interface::*;
use kata_storage_interface::KeyValueData;
use log::trace;
struct BundleData {
pkg_contents: ObjDescBundle,
@ -21,7 +23,8 @@ impl BundleData {
BundleData {
pkg_contents: pkg_contents.clone(),
pkg_size: size_bytes,
manifest: String::from(r##"
manifest: String::from(
r##"
# Comments like this
[Manifest]
BundleId=com.google.cerebra.hw.HelloWorld
@ -32,7 +35,8 @@ Model=NeuralNetworkName
[Storage]
Required=1
"##,),
"##,
),
keys: HashMap::with_capacity(2),
}
}
@ -84,7 +88,10 @@ impl SecurityCoordinatorInterface for FakeSecurityCoordinator {
if self.bundles.contains_key(&bundle_id) {
return Err(SecurityRequestError::SreDeleteFirst);
}
assert!(self.bundles.insert(bundle_id.clone(), BundleData::new(pkg_contents)).is_none());
assert!(self
.bundles
.insert(bundle_id.clone(), BundleData::new(pkg_contents))
.is_none());
Ok(bundle_id)
}
fn uninstall(&mut self, bundle_id: &str) -> Result<(), SecurityRequestError> {
@ -104,7 +111,11 @@ impl SecurityCoordinatorInterface for FakeSecurityCoordinator {
// XXX just return the package for now
Ok(bundle_data.pkg_contents.clone())
}
fn load_model(&self, bundle_id: &str, _model_id: &str) -> Result<ObjDescBundle, SecurityRequestError> {
fn load_model(
&self,
bundle_id: &str,
_model_id: &str,
) -> Result<ObjDescBundle, SecurityRequestError> {
let bundle_data = self.get_bundle(bundle_id)?;
// TODO(sleffler): check model id
// XXX just return the package for now
@ -112,9 +123,17 @@ impl SecurityCoordinatorInterface for FakeSecurityCoordinator {
}
fn read_key(&self, bundle_id: &str, key: &str) -> Result<&KeyValueData, SecurityRequestError> {
let bundle = self.get_bundle(bundle_id)?;
bundle.keys.get(key).ok_or(SecurityRequestError::SreKeyNotFound)
bundle
.keys
.get(key)
.ok_or(SecurityRequestError::SreKeyNotFound)
}
fn write_key(&mut self, bundle_id: &str, key: &str, value: &KeyValueData) -> Result<(), SecurityRequestError> {
fn write_key(
&mut self,
bundle_id: &str,
key: &str,
value: &KeyValueData,
) -> Result<(), SecurityRequestError> {
let bundle = self.get_bundle_mut(bundle_id)?;
let _ = bundle.keys.insert(key.to_string(), *value);
Ok(())
@ -125,4 +144,98 @@ impl SecurityCoordinatorInterface for FakeSecurityCoordinator {
let _ = bundle.keys.remove(key);
Ok(())
}
fn test_mailbox(&mut self) -> Result<(), SecurityRequestError> {
trace!("test_mailbox_command()");
const PAGE_SIZE: usize = 1 << seL4_PageBits;
const MESSAGE_SIZE_DWORDS: usize = 17; // Just a random message size for testing.
extern "C" {
fn mailbox_api_send(paddr: u32, size: u32);
fn mailbox_api_receive(paddr: *mut u32, size: *mut u32);
static SELF_VSPACE_ROOT: seL4_CPtr;
// This is not actually a block of memory, it's a reserved range in
// the virtual address space that we can map physical memory into.
static mut COPYREGION: [u32; 1024];
}
// Allocate a 4k page to serve as our message buffer.
let frame_bundle =
kata_frame_alloc(PAGE_SIZE).map_err(|_| SecurityRequestError::SreTestFailed)?;
trace!("test_mailbox: Frame {:?}", frame_bundle);
unsafe {
// Map the message buffer into our copyregion so we can access it.
// FIXME(aappleby): We need a drop() impl here somewhere so this
// doesn't leak if something fails.
let message_ptr = core::ptr::addr_of_mut!(COPYREGION[0]);
seL4_Page_Map(
/*sel4_page=*/ frame_bundle.objs[0].cptr,
/*seL4_pd=*/ SELF_VSPACE_ROOT,
/*vaddr=*/ message_ptr as usize,
seL4_CapRights::new(
// NB: RW 'cuz W-only silently gets upgraded by kernel
/*grant_reply=*/
0, /*grant=*/ 0, /*read=1*/ 1, /*write=*/ 1,
),
seL4_Default_VMAttributes,
)
.map_err(|_| SecurityRequestError::SreTestFailed)?;
// Write to the message buffer through the copyregion.
let offset_a = 0 as isize;
let offset_b = (MESSAGE_SIZE_DWORDS - 1) as isize;
message_ptr.offset(offset_a).write(0xDEADBEEF);
message_ptr.offset(offset_b).write(0xF00DCAFE);
trace!(
"test_mailbox: old buf contents 0x{:X} 0x{:X}",
message_ptr.offset(offset_a).read(),
message_ptr.offset(offset_b).read()
);
// Send the _physical_ address of the message buffer to the security
// core.
let paddr = seL4_Page_GetAddress(frame_bundle.objs[0].cptr);
mailbox_api_send(
paddr.paddr as u32,
(MESSAGE_SIZE_DWORDS * size_of::<u32>()) as u32,
);
// Wait for the response to arrive.
let mut response_paddr: u32 = 0;
let mut response_size: u32 = 0;
mailbox_api_receive(
&mut response_paddr as *mut u32,
&mut response_size as *mut u32,
);
// The security core should have replaced the first and last dwords
// with 0x12345678 and 0x87654321.
trace!("test_mailbox: expected contents 0x12345678 0x87654321");
trace!(
"test_mailbox: new buf contents 0x{:X} 0x{:X}",
message_ptr.offset(offset_a).read(),
message_ptr.offset(offset_b).read()
);
let dword_a = message_ptr.offset(offset_a).read();
let dword_b = message_ptr.offset(offset_b).read();
seL4_Page_Unmap(frame_bundle.objs[0].cptr)
.map_err(|_| SecurityRequestError::SreTestFailed)?;
// Done, free the message buffer.
kata_object_free_toplevel(&frame_bundle)
.map_err(|_| SecurityRequestError::SreTestFailed)?;
if dword_a != 0x12345678 || dword_b != 0x87654321 {
return Err(SecurityRequestError::SreTestFailed);
}
}
trace!("test_mailbox_command() done");
Ok(())
}
}

View File

@ -84,8 +84,9 @@ impl SecurityCoordinatorInterface for SeL4SecurityCoordinator {
Err(SreGetManifestFailed)
}
SecurityRequest::SrLoadApplication => {
let mut request = postcard::from_bytes::<LoadApplicationRequest>(&request_buffer[..])
.map_err(deserialize_failure)?;
let mut request =
postcard::from_bytes::<LoadApplicationRequest>(&request_buffer[..])
.map_err(deserialize_failure)?;
request.set_container_cap(unsafe { SECURITY_RECV_SLOT });
trace!(
"LOAD APPLICATION bundle_id {} app_binary {:?}",

View File

@ -57,16 +57,34 @@ impl SecurityCoordinatorInterface for KataSecurityCoordinator {
fn load_application(&self, bundle_id: &str) -> Result<ObjDescBundle, SecurityRequestError> {
self.manager.as_ref().unwrap().load_application(bundle_id)
}
fn load_model(&self, bundle_id: &str, model_id: &str) -> Result<ObjDescBundle, SecurityRequestError> {
self.manager.as_ref().unwrap().load_model(bundle_id, model_id)
fn load_model(
&self,
bundle_id: &str,
model_id: &str,
) -> Result<ObjDescBundle, SecurityRequestError> {
self.manager
.as_ref()
.unwrap()
.load_model(bundle_id, model_id)
}
fn read_key(&self, bundle_id: &str, key: &str) -> Result<&KeyValueData, SecurityRequestError> {
self.manager.as_ref().unwrap().read_key(bundle_id, key)
}
fn write_key(&mut self, bundle_id: &str, key: &str, value: &KeyValueData) -> Result<(), SecurityRequestError> {
self.manager.as_mut().unwrap().write_key(bundle_id, key, value)
fn write_key(
&mut self,
bundle_id: &str,
key: &str,
value: &KeyValueData,
) -> Result<(), SecurityRequestError> {
self.manager
.as_mut()
.unwrap()
.write_key(bundle_id, key, value)
}
fn delete_key(&mut self, bundle_id: &str, key: &str) -> Result<(), SecurityRequestError> {
self.manager.as_mut().unwrap().delete_key(bundle_id, key)
}
fn test_mailbox(&mut self) -> Result<(), SecurityRequestError> {
self.manager.as_mut().unwrap().test_mailbox()
}
}

View File

@ -166,6 +166,12 @@ pub struct DeleteKeyRequest<'a> {
}
impl<'a> SecurityCapability for DeleteKeyRequest<'a> {}
// SecurityRequestTestMailbox
#[derive(Debug, Serialize, Deserialize)]
pub struct TestMailboxRequest {
}
impl SecurityCapability for TestMailboxRequest {}
// NB: this is the union of InstallInterface & StorageInterface because
// the camkes-generated interface code uses basic C which does not
// tolerate overlapping member names.
@ -197,6 +203,7 @@ pub enum SecurityRequestError {
SreReadFailed,
SreWriteFailed,
SreDeleteFailed,
SreTestFailed,
}
impl From<SecurityRequestError> for StorageError {
@ -232,6 +239,8 @@ pub enum SecurityRequest {
SrReadKey, // Read key value [bundle_id, key] -> value
SrWriteKey, // Write key value [bundle_id, key, value]
SrDeleteKey, // Delete key [bundle_id, key]
SrTestMailbox, // Run mailbox tests
}
// Interface to underlying facilities; also used to inject fakes for unit tests.
@ -245,6 +254,7 @@ pub trait SecurityCoordinatorInterface {
fn read_key(&self, bundle_id: &str, key: &str) -> Result<&KeyValueData, SecurityRequestError>;
fn write_key(&mut self, bundle_id: &str, key: &str, value: &KeyValueData) -> Result<(), SecurityRequestError>;
fn delete_key(&mut self, bundle_id: &str, key: &str) -> Result<(), SecurityRequestError>;
fn test_mailbox(&mut self) -> Result<(), SecurityRequestError>;
}
#[inline]
@ -462,3 +472,13 @@ pub fn kata_security_delete_key(
&mut [0u8; SECURITY_REPLY_DATA_SIZE],
)
}
#[inline]
#[allow(dead_code)]
pub fn kata_security_test_mailbox() -> Result<(), SecurityRequestError> {
kata_security_request(
SecurityRequest::SrTestMailbox,
&TestMailboxRequest {},
&mut [0u8; SECURITY_REPLY_DATA_SIZE],
)
}

View File

@ -0,0 +1,4 @@
procedure MailboxAPI {
void send(in uint32_t request_paddr, in uint32_t request_size);
void receive(out uint32_t response_paddr, out uint32_t response_size);
};

View File

@ -21,6 +21,7 @@ import "components/MemoryManager/MemoryManager.camkes";
import "components/StorageManager/StorageManager.camkes";
import "components/SecurityCoordinator/SecurityCoordinator.camkes";
import "components/TimerService/TimerService.camkes";
import "components/MailboxDriver/MailboxDriver.camkes";
component OpenTitanUART {
hardware;
@ -55,6 +56,14 @@ component BuiltinCpioArchive {
dataport Buf(0x1000000) cpio;
}
component MailboxHardware {
hardware;
dataport Buf mmio;
emits Interrupt wtirq;
emits Interrupt rtirq;
emits Interrupt eirq;
}
assembly {
composition {
component VectorCoreHw vctop;
@ -76,6 +85,20 @@ assembly {
connection seL4HardwareMMIO cpio_archive(from debug_console.cpio_archive,
to cpio.cpio);
// MailboxDriver
component MailboxHardware mailbox_hardware;
component MailboxDriver mailbox_driver;
connection seL4HardwareMMIO mailbox_driver_mmio(
from mailbox_driver.mailbox_mmio, to mailbox_hardware.mmio);
connection seL4HardwareInterrupt mailbox_driver_wtirq(
from mailbox_hardware.wtirq, to mailbox_driver.wtirq);
connection seL4HardwareInterrupt mailbox_driver_rtirq(
from mailbox_hardware.rtirq, to mailbox_driver.rtirq);
connection seL4HardwareInterrupt mailbox_driver_eirq(
from mailbox_hardware.eirq, to mailbox_driver.eirq);
connection seL4RPCCall security_coordinator_to_mailbox_api(
from security_coordinator.mailbox_api, to mailbox_driver.api);
// OpenTitanUARTDriver
connection seL4HardwareMMIO uart_mem(from uart_driver.mmio_region,
to uart.mmio_region);
@ -165,6 +188,7 @@ assembly {
from security_coordinator.logger,
from storage_manager.logger,
from timer_service.logger,
from mailbox_driver.logger,
to debug_console.logger);
}
@ -172,6 +196,14 @@ assembly {
cpio.cpio_paddr = 0x46000000;
cpio.cpio_size = 0x1000000;
mailbox_hardware.mmio_paddr = 0x540F1000;
mailbox_hardware.mmio_size = 0x00001000;
mailbox_hardware.wtirq_irq_number = 10; // kTopMatchaPlicIrqIdMailboxSmcWtirq
mailbox_hardware.rtirq_irq_number = 11; // kTopMatchaPlicIrqIdMailboxSmcRtirq
mailbox_hardware.eirq_irq_number = 12; // kTopMatchaPlicIrqIdMailboxSmcEirq
mailbox_driver.rx_semaphore_value = 0;
uart.mmio_region_paddr = 0x50000000;
uart.mmio_region_size = 0x1000;
uart.tx_watermark_irq_number = 1;