Skip to content

Commit

Permalink
Add Mux, transport binding and ctrl msg handling layers of MCTP capsu…
Browse files Browse the repository at this point in the history
…le (#36)

This PR adds the basic structure for the Mux MCTP driver layer, the transport binding layer, and the handling of MCTP control messages.
At this stage, the code remains untested, and the modules have yet to be instantiated.
The implementation includes the Set EID and Get EID commands, with plan to add other mandatory managed MCTP device commands once the basic commands have been tested and validated.
  • Loading branch information
parvathib authored Dec 2, 2024
1 parent c030dd5 commit 3c236b4
Show file tree
Hide file tree
Showing 14 changed files with 1,215 additions and 14 deletions.
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ members = [
"registers/systemrdl",
"rom",
"runtime",
"runtime/capsules",
"runtime/apps/pldm",
"runtime/i3c",
"tests/hello",
Expand Down Expand Up @@ -63,6 +64,7 @@ gdbstub_arch = "0.2.4"
getrandom = "0.2"
hex = "0.4.3"
i3c-driver = { path = "runtime/i3c" }
capsules-runtime = { path = "runtime/capsules" }
lazy_static = "1.4.0"
num-derive = "0.4.2"
num_enum = "0.7.2"
Expand Down
8 changes: 4 additions & 4 deletions docs/src/mctp.md
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ pub struct VirtualMCTPDriver {
pub trait MCTPSender {
/// Sets the client for the `MCTPSender` instance.
/// In this case it is MCTPTxState which is instantiated at the time of
fn set_client(&self, client: &dyn MCTPSendClient);
fn set_client(&self, client: &dyn MCTPTxClient);

/// Sends the message to the MCTP kernel stack.
fn send_msg(&self, dest_eid: u8, msg_tag: u8, msg_payload: SubSliceMut<'static, u8>);
Expand All @@ -313,15 +313,15 @@ pub trait MCTPSender {
/// message is sent.
/// The 'send_done' function in this trait is invoked after the MCTPSender
/// has completed sending the requested message.
pub trait MCTPSendClient {
pub trait MCTPTxClient {
fn send_done(&self, msg_tag: Option<u8>, result: Result<(), ErrorCode>, msg_payload: SubSliceMut<'static, u8> )
}

pub struct MCTPTxState<M:MCTPTransportBinding> {
/// MCTP Mux driver reference
mctp_mux_sender: &MuxMCTPDriver<M>,
/// Client to invoke when send done. This is set to the corresponding VirtualMCTPDriver instance.
client: OptionalCell<&dyn MCTPSendClient>,
client: OptionalCell<&dyn MCTPTxClient>,
/// next MCTPTxState node in the list
next: ListLink<MCTPTxState<M: MCTPTransportBinding>>,
/// The message buffer is set by the virtual MCTP driver when it issues the Tx request.
Expand All @@ -335,7 +335,7 @@ pub struct MCTPTxState<M:MCTPTransportBinding> {
/// This is the trait implemented by VirtualMCTPDriver instance to get notified of
/// the messages received on corresponding message_type.
pub trait MCTPRxClient {
fn receive(&self, dst_eid: u8, msg_type: u8, msg_Tag: u8, msg_payload: &[u8]);
fn receive(&self, dst_eid: u8, msg_type: u8, msg_tag: u8, msg_payload: &[u8]);
}

/// Receive state
Expand Down
1 change: 1 addition & 0 deletions runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ riscv = { git = "https://github.com/tock/tock.git", rev = "b128ae817b86706c8c4e3
riscv-csr = { git = "https://github.com/tock/tock.git", rev = "b128ae817b86706c8c4e39d27fae5c54b98659f1" }
rv32i = { git = "https://github.com/tock/tock.git", rev = "b128ae817b86706c8c4e39d27fae5c54b98659f1" }
tock-registers.workspace = true
capsules-runtime.workspace = true
15 changes: 15 additions & 0 deletions runtime/capsules/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Licensed under the Apache-2.0 license

[package]
name = "capsules-runtime"
version.workspace = true
authors.workspace = true
edition.workspace = true

[dependencies]
kernel = { git = "https://github.com/tock/tock.git", rev = "b128ae817b86706c8c4e39d27fae5c54b98659f1" }

capsules-extra = { git = "https://github.com/tock/tock.git", rev = "b128ae817b86706c8c4e39d27fae5c54b98659f1" }
i3c-driver.workspace = true
zerocopy.workspace = true
bitfield.workspace = true
6 changes: 6 additions & 0 deletions runtime/capsules/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Licensed under the Apache-2.0 license

#![cfg_attr(target_arch = "riscv32", no_std)]
#![forbid(unsafe_code)]

pub mod mctp;
103 changes: 103 additions & 0 deletions runtime/capsules/src/mctp/base_protocol.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Licensed under the Apache-2.0 license

//! This file contains the types, structs and methods associated with the
//! MCTP Transport header, including getter and setter methods and encode/decode
//! functionality necessary for transmission.
//!
use bitfield::bitfield;
use zerocopy::{FromBytes, Immutable, IntoBytes};

pub const MCTP_HDR_SIZE: usize = 4;

bitfield! {
#[repr(C)]
#[derive(Clone, FromBytes, IntoBytes, Immutable)]
pub struct MCTPHeader([u8]);
impl Debug;
u8;
rsvd, _: 4, 0;
pub hdr_version, set_hdr_version: 7, 4;
pub dest_eid, set_dest_eid: 15, 8;
pub src_eid, set_src_eid: 23, 16;
pub som, set_som: 24, 24;
pub eom, set_eom: 25, 25;
pub pkt_seq, set_pkt_seq: 27, 26;
pub tag_owner, set_tag_owner: 28, 28;
pub msg_tag, set_msg_tag: 31, 29;
}

impl Default for MCTPHeader<[u8; MCTP_HDR_SIZE]> {
fn default() -> Self {
Self::new()
}
}

impl MCTPHeader<[u8; MCTP_HDR_SIZE]> {
pub fn new() -> Self {
MCTPHeader([0; MCTP_HDR_SIZE])
}

#[allow(clippy::too_many_arguments)]
pub fn prepare_header(
&mut self,
dest_eid: u8,
src_eid: u8,
som: u8,
eom: u8,
pkt_seq: u8,
tag_owner: u8,
msg_tag: u8,
) {
self.set_hdr_version(1);
self.set_dest_eid(dest_eid);
self.set_src_eid(src_eid);
self.set_som(som);
self.set_eom(eom);
self.set_pkt_seq(pkt_seq);
self.set_tag_owner(tag_owner);
self.set_msg_tag(msg_tag);
}
}

#[derive(Debug, PartialEq)]
pub enum MessageType {
MCTPControl,
PLDM,
SPDM,
SSPDM,
VendorDefinedPCI,
Invalid,
}

impl From<u8> for MessageType {
fn from(val: u8) -> MessageType {
match val {
0 => MessageType::MCTPControl,
1 => MessageType::PLDM,
5 => MessageType::SPDM,
6 => MessageType::SSPDM,
0x7E => MessageType::VendorDefinedPCI,
_ => MessageType::Invalid,
}
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_mctp_header() {
let mut header = MCTPHeader::new();
header.prepare_header(0x10, 0x08, 1, 1, 0, 0, 0);
assert_eq!(header.hdr_version(), 1);
assert_eq!(header.dest_eid(), 0x10);
assert_eq!(header.src_eid(), 0x08);
assert_eq!(header.som(), 1);
assert_eq!(header.eom(), 1);
assert_eq!(header.pkt_seq(), 0);
assert_eq!(header.tag_owner(), 0);
assert_eq!(header.msg_tag(), 0);
}
}
Loading

0 comments on commit 3c236b4

Please sign in to comment.