TDISP (TEE Device Interface Security Protocol) Support
Caliptra Subsystem supports handling of TDISP messages by processing them as VENDOR_DEFINED_REQUEST/VENDOR_DEFINED_RESPONSE message payloads. These messages are transported and processed within the secure session established between the host and the TDISP device as specified by Secured CMA/SPDM.
To facilitate the TDISP protocol, the devices must implement TdispDriver
trait as defined below.
#![allow(unused)] fn main() { /// Error codes returned by TDISP driver pub enum TdispDriverError { /// Input parameter is null or invalid. InvalidArgument, /// Memory allocation failed. NoMemory, /// The driver failed to get TDISP capabilities. GetTdispCapabilitiesFail, /// The driver failed to get the device interface state. GetDeviceInterfaceStateFail, /// The driver failed to lock the device interface. LockInterfaceReqFail, /// The driver failed to start the device interface. StartInterfaceReqFail, /// The driver failed to stop the device interface. StopInterfaceReqFail, /// The driver failed to get the device interface report. GetInterfaceReportFail, /// The driver failed to get the mmio ranges. GetMmioRangesFail, /// The driver function is not implemented. FunctionNotImplemented, } pub type TdispDriverResult<T> = Result<T, TdispDriverError>; /// FunctionID of the device hosting the TDI. bitfield! { #[derive(FromBytes, IntoBytes, Immutable, Default)] #[repr(C)] pub struct FunctionId(u32); impl Debug; u16; pub requester_id, set_requester_id: 15, 0; // Bits 15:0 Requester ID u8; pub requester_segment, set_requester_segment: 23, 16; // Bits 23:16 Requester Segment pub requester_segment_valid, set_requester_segment_valid: 24, 24; // Bit 24 Requester Segment Valid reserved, _: 31, 25; // Bits 31:25 Reserved } /// TDISP Responder Capabilities pub struct TdispResponderCapabilities { dsm_capabilities: u32, req_msgs_supported: [u8; 16], lock_interface_flags_supported: u16, reserved: [u8; 3], dev_addr_width: u8, num_req_this: u8, num_req_all: u8, } /// Parameters passed along with the LOCK_INTERFACE_REQUEST pub struct TdispLockInterfaceParam { flags: TdispLockInterfaceFlags, default_stream_id: u8, reserved: u8, mmio_reporting_offset: [u8; 8], bind_p2p_addr_mask: [u8; 8], } /// TDISP Interface flags bitfield! { #[repr(C)] pub struct TdispLockInterfaceFlags(u16); impl Debug; u8; pub no_fw_update, set_no_fw_update: 0, 0; // Bit 0 NO_FW_UPDATE pub system_cache_line_size, set_system_cache_line_size: 1, 1; // Bits 1:1 SYSTEM_CACHE_LINE_SIZE pub lock_msix, set_lock_msix: 2, 2; // Bit 2 LOCK_MSIX pub bind_p2p, set_bind_p2p: 3, 3; // Bit 3 BIND_P2P pub all_req_redirect, set_all_req_redirect: 4, 4; // Bit 4 ALL_REQUEST_REDIRECT pub reserved, _: 15, 5; // Bits 15:5 Reserved } /// TDISP Driver trait that defines the interface for TDISP operations. /// This trait is intended to be implemented by a TDISP driver /// that interacts with the TDISP device. #[async_trait] pub trait TdispDriver { /// Gets the TDISP device capabilities. /// /// # Arguments /// * `tsm_caps` - TSM capability flags /// /// # Returns /// `TdispResponderCapabilities` on success or an error on failure. async fn get_capabilities( &self, tsm_caps: u32, ) -> TdispDriverResult<TdispResponderCapabilities>; /// Lock Interface Request /// /// # Arguments /// * `function_id` - Device Interface Function ID /// * `param` - Lock Interface parameters from the request /// /// # Returns /// 0 on success or an error response code as per the TDISP specification on failure. async fn lock_interface( &self, function_id: FunctionId, param: TdispLockInterfaceParam, ) -> TdispDriverResult<u32>; /// Get the device interface report. /// /// # Arguments /// * `function_id` - Device Interface Function ID /// * `offset` - Offset from the start of the report requested /// * `report` - report buffer slice to fill /// * `copied` - Length of the TDI report copied /// * `remainder` - Remaining length of the TDI report /// /// /// # Returns /// 0 on success or an error response code as per the TDISP specification on failure. async fn get_device_interface_report( &self, function_id: FunctionId, offset: u16, report: &mut [u8], copied: &mut usize, remainder: &mut usize, ) -> TdispDriverResult<u32>; /// Get the device interface state. /// /// # Arguments /// * `function_id` - Device Interface Function ID /// * `tdi_state` - Device Interface State to fill /// /// # Returns /// 0 on success or an error response code as per the TDISP specification on failure. async fn get_device_interface_state( &self, function_id: FunctionId, tdi_state: &mut u8, ) -> TdispDriverResult<u32>; /// Start the device interface. /// /// # Arguments /// * `function_id` - Device Interface Function ID /// /// # Returns /// 0 on success or an error response code as per the TDISP specification on failure. async fn start_interface(&self, function_id: FunctionId) -> TdispDriverResult<u32>; /// Stop the device interface. /// /// # Arguments /// * `function_id` - Device Interface Function ID /// /// # Returns /// 0 on success or an error response code as per the TDISP specification on failure. async fn stop_interface(&self, function_id: FunctionId) -> TdispDriverResult<u32>; } }