Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
spdm_transport: generic: refactor IO buffers
Browse files Browse the repository at this point in the history
This allows us to remove alot of repeated code for buffer `set/get`. This
approach uses a heap allocated vector and just passes a reference to
`libspdm` when required.

The associated memory shall be explicitly freed
by taking ownership when the buffers are no longer required. Which can be
done by calling `libspdm_drop_io_buffers()`.

Signed-off-by: Wilfred Mallawa <[email protected]>
twilfredo committed Nov 8, 2024
1 parent 1bf3c1b commit 05a7aed
Showing 7 changed files with 145 additions and 683 deletions.
140 changes: 4 additions & 136 deletions src/doe_pci_cfg.rs
Original file line number Diff line number Diff line change
@@ -24,8 +24,6 @@ use std::slice::{from_raw_parts, from_raw_parts_mut};
const SEND_RECEIVE_BUFFER_LEN: usize = LIBSPDM_MAX_SPDM_MSG_SIZE as usize;
const LIBSPDM_STATUS_ERROR_PEER: u32 =
libspdm_status_construct!(LIBSPDM_SEVERITY_ERROR, LIBSPDM_SOURCE_CORE, 0x000a);
static mut SEND_BUFFER: OnceCell<[u8; SEND_RECEIVE_BUFFER_LEN]> = OnceCell::new();
static mut RECEIVE_BUFFER: OnceCell<[u8; SEND_RECEIVE_BUFFER_LEN]> = OnceCell::new();

const DOE_CONTROL: i32 = 0x08;
const DOE_CONTROL_GO: u32 = 1 << 31;
@@ -180,122 +178,6 @@ unsafe extern "C" fn doe_pci_cfg_receive_message(
0
}

/// # Summary
///
/// A helper function to capture the SEND_BUFFER into `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `max_msg_size`: Returns the length of the sender buffer
/// * `msg_buf_ptr`: Returns a pointer to the sender buffer (mutable)
///
/// # Returns
///
/// (0) on success
///
/// # Panics
///
/// Panics if the SEND_BUFFER is not available
#[no_mangle]
unsafe extern "C" fn doe_pci_cfg_acquire_sender_buffer(
_context: *mut c_void,
msg_buf_ptr: *mut *mut c_void,
) -> u32 {
let mut buf = SEND_BUFFER.take().unwrap();
let buf_ptr = buf.as_mut_ptr() as *mut _ as *mut c_void;

*msg_buf_ptr = buf_ptr;

0
}

/// # Summary
///
/// A helper function to reset the SEND_BUFFER from `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `msg_buf_ptr`: A pointer representing the sender buffer.
///
/// # Returns
///
/// (0) on success
///
/// # Panics
///
/// Panics if the `msg_buf_ptr` is invalid or has less elements
/// than `SEND_RECEIVE_BUFFER_LEN`
#[no_mangle]
unsafe extern "C" fn doe_pci_cfg_release_sender_buffer(
_context: *mut c_void,
msg_buf_ptr: *const c_void,
) {
let message = msg_buf_ptr as *const u8;
let msg_buf = from_raw_parts(message, SEND_RECEIVE_BUFFER_LEN);

SEND_BUFFER.set(msg_buf.try_into().unwrap()).unwrap();
}

/// # Summary
///
/// A helper function to capture the RECEIVE_BUFFER into `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `max_msg_size`: Returns the length of the receiver buffer
/// * `msg_buf_ptr`: Returns a pointer to the receiver buffer (mutable)
///
/// # Returns
///
/// (0) on success
///
/// # Panics
///
/// Panics if the SEND_BUFFER is not available
#[no_mangle]
unsafe extern "C" fn doe_pci_cfg_acquire_receiver_buffer(
_context: *mut c_void,
msg_buf_ptr: *mut *mut c_void,
) -> u32 {
let mut buf = RECEIVE_BUFFER.take().unwrap();
let buf_ptr = buf.as_mut_ptr() as *mut _ as *mut c_void;

*msg_buf_ptr = buf_ptr;

0
}

/// # Summary
///
/// A helper function to reset the RECEIVE_BUFFER from `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `msg_buf_ptr`: A pointer representing the receiver buffer.
///
/// # Returns
///
/// (0) on success
///
/// # Panics
///
/// Panics if the `msg_buf_ptr` is invalid or has less elements
/// than `SEND_RECEIVE_BUFFER_LEN`
#[no_mangle]
unsafe extern "C" fn doe_pci_cfg_release_receiver_buffer(
_context: *mut c_void,
msg_buf_ptr: *const c_void,
) {
let message = msg_buf_ptr as *const u8;
let msg_buf = from_raw_parts(message, SEND_RECEIVE_BUFFER_LEN);

RECEIVE_BUFFER.set(msg_buf.try_into().unwrap()).unwrap();
}

/// # Summary
///
/// Registers the SPDM `context` for a PCIe DOE backend.
@@ -314,21 +196,11 @@ unsafe extern "C" fn doe_pci_cfg_release_receiver_buffer(
///
/// Panics if `SEND_BUFFER/RECEIVE_BUFFER` is occupied
pub fn register_device(context: *mut c_void, pcie_vid: u16, pcie_devid: u16) -> Result<(), ()> {
let buffer_send = [0; SEND_RECEIVE_BUFFER_LEN];
let buffer_receive = [0; SEND_RECEIVE_BUFFER_LEN];
let pcie_ids = PcieIdentifiers {
vid: pcie_vid,
devid: pcie_devid,
};
unsafe {
SEND_BUFFER.set(buffer_send).map_err(|e| {
error!("Failed to set send buffer: {e:?}");
()
})?;
RECEIVE_BUFFER.set(buffer_receive).map_err(|e| {
error!("Failed to set receive buffer: {e:?}");
()
})?;
PCIE_IDENTIFIERS.set(pcie_ids).map_err(|e| {
error!("Failed to set device PCIe Identifiers: {e:?}");
()
@@ -339,15 +211,11 @@ pub fn register_device(context: *mut c_void, pcie_vid: u16, pcie_devid: u16) ->
Some(doe_pci_cfg_send_message),
Some(doe_pci_cfg_receive_message),
);
libspdm_register_device_buffer_func(
io_buffers::libspdm_setup_io_buffers(
context,
SEND_RECEIVE_BUFFER_LEN as u32,
SEND_RECEIVE_BUFFER_LEN as u32,
Some(doe_pci_cfg_acquire_sender_buffer),
Some(doe_pci_cfg_release_sender_buffer),
Some(doe_pci_cfg_acquire_receiver_buffer),
Some(doe_pci_cfg_release_receiver_buffer),
);
SEND_RECEIVE_BUFFER_LEN,
SEND_RECEIVE_BUFFER_LEN,
)?;
}

Ok(())
125 changes: 125 additions & 0 deletions src/io_buffers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
use once_cell::sync::OnceCell;
use std::ffi::c_void;

static mut SEND_BUFFER: OnceCell<Vec<u8>> = OnceCell::new();
static mut RECEIVE_BUFFER: OnceCell<Vec<u8>> = OnceCell::new();

pub fn libspdm_setup_io_buffers(
context: *mut c_void,
send_recv_len: usize,
libsdpm_buff_len: usize,
) -> Result<(), ()> {
let result = std::panic::catch_unwind(|| {
let buffer_send = vec![0; send_recv_len];
let buffer_receive = vec![0; send_recv_len];
(buffer_send, buffer_receive)
});

match result {
Ok(buffers) => {
unsafe {
SEND_BUFFER.set(buffers.0).map_err(|_| {
error!("Failed to set send buffer");
()
})?;
RECEIVE_BUFFER.set(buffers.1).map_err(|_| {
error!("Failed to set receive buffer");
()
})?;
}

unsafe {
libspdm::libspdm_rs::libspdm_register_device_buffer_func(
context,
libsdpm_buff_len as u32,
libsdpm_buff_len as u32,
Some(acquire_sender_buffer),
Some(release_sender_buffer),
Some(acquire_receiver_buffer),
Some(release_receiver_buffer),
)
}
Ok(())
}
Err(_) => {
error!("Failed to allocate transport buffers");
Err(())
}
}
}

/// # Summary
///
/// A helper function to capture the SEND_BUFFER into `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `max_msg_size`: Returns the length of the sender buffer
/// * `msg_buf_ptr`: Returns a pointer to the sender buffer (mutable)
///
/// # Returns
///
/// (0) on success
#[no_mangle]
pub unsafe extern "C" fn acquire_sender_buffer(
_context: *mut c_void,
msg_buf_ptr: *mut *mut c_void,
) -> u32 {
if let Some(buffer) = SEND_BUFFER.get() {
let buf_ptr = buffer.as_ptr() as *mut c_void;
*msg_buf_ptr = buf_ptr;
return 0;
}
error!("Sender buffer is lost or not initialized");
return 1;
}

/// # Summary
///
/// A helper function to capture the RECEIVE_BUFFER into `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `max_msg_size`: Returns the length of the receiver buffer
/// * `msg_buf_ptr`: Returns a pointer to the receiver buffer (mutable)
///
/// # Returns
///
/// (0) on success
#[no_mangle]
pub unsafe extern "C" fn acquire_receiver_buffer(
_context: *mut c_void,
msg_buf_ptr: *mut *mut c_void,
) -> u32 {
if let Some(buffer) = RECEIVE_BUFFER.get() {
let buf_ptr = buffer.as_ptr() as *mut c_void;
*msg_buf_ptr = buf_ptr;
return 0;
}
error!("Receiver buffer is lost or not initialized");
return 1;
}

/// We are only passing a reference to heap allocated memory, no-op required
#[no_mangle]
pub unsafe extern "C" fn release_receiver_buffer(
_context: *mut c_void,
_msg_buf_ptr: *const c_void,
) {
}

/// We are only passing a reference to heap allocated memory, no-op required
#[no_mangle]
pub unsafe extern "C" fn release_sender_buffer(_context: *mut c_void, _msg_buf_ptr: *const c_void) {
}

/// # Summary
///
/// Take ownership of the IO buffer and drop them out of context allowing the
/// underlying memory to be freed.
pub unsafe fn libspdm_drop_io_buffers() {
if let Some(_) = SEND_BUFFER.take() {}
if let Some(_) = RECEIVE_BUFFER.take() {}
}
2 changes: 2 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@ pub static SOCKET_PATH: &str = "SPDM-Utils-loopback-socket";

mod cli_helpers;
mod doe_pci_cfg;
mod io_buffers;
mod qemu_server;
mod request;
mod socket_client;
@@ -890,6 +891,7 @@ async fn main() -> Result<(), ()> {
}
}
}
unsafe { io_buffers::libspdm_drop_io_buffers() }
Ok(())
}

142 changes: 5 additions & 137 deletions src/qemu_server.rs
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@
//! to implement and emulate an SPDM responder.
//!
use crate::io_buffers;
use crate::spdm::TransportLayer;
use crate::*;
use libspdm::spdm::LIBSPDM_MAX_SPDM_MSG_SIZE;
@@ -22,10 +23,6 @@ const SOCKET_SPDM_COMMAND_NORMAL: u32 = 0x01;

const SOCKET_TRANSPORT_TYPE_MCTP: u32 = 0x01;
const SOCKET_TRANSPORT_TYPE_PCI_DOE: u32 = 0x02;

static mut SEND_BUFFER: OnceCell<[u8; SEND_RECEIVE_BUFFER_LEN]> = OnceCell::new();
static mut RECEIVE_BUFFER: OnceCell<[u8; SEND_RECEIVE_BUFFER_LEN]> = OnceCell::new();

static mut CLIENT_CONNECTION: OnceCell<TcpStream> = OnceCell::new();

/// # Summary
@@ -326,119 +323,6 @@ unsafe extern "C" fn qemu_receive_message_mctp(
0
}

/// # Summary
///
/// A helper function to capture the SEND_BUFFER into `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `max_msg_size`: Returns the length of the sender buffer
/// * `msg_buf_ptr`: Returns a pointer to the sender buffer (mutable)
///
/// # Returns
///
/// (0) on success
///
/// # Panics
///
/// Panics if the SEND_BUFFER is not available
#[no_mangle]
unsafe extern "C" fn qemu_acquire_sender_buffer(
_context: *mut c_void,
msg_buf_ptr: *mut *mut c_void,
) -> u32 {
let mut buf = SEND_BUFFER.take().unwrap();
let buf_ptr = buf.as_mut_ptr() as *mut _ as *mut c_void;

*msg_buf_ptr = buf_ptr;

0
}

/// # Summary
///
/// A helper function to reset the SEND_BUFFER from `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `msg_buf_ptr`: A pointer representing the sender buffer.
///
/// # Returns
///
/// (0) on success
///
/// # Panics
///
/// Panics if the `msg_buf_ptr` is invalid or has less elements
/// than `SEND_RECEIVE_BUFFER_LEN`
#[no_mangle]
unsafe extern "C" fn qemu_release_sender_buffer(_context: *mut c_void, msg_buf_ptr: *const c_void) {
let message = msg_buf_ptr as *const u8;
let msg_buf = from_raw_parts(message, SEND_RECEIVE_BUFFER_LEN);

SEND_BUFFER.set(msg_buf.try_into().unwrap()).unwrap();
}

/// # Summary
///
/// A helper function to capture the RECEIVE_BUFFER into `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `max_msg_size`: Returns the length of the receiver buffer
/// * `msg_buf_ptr`: Returns a pointer to the receiver buffer (mutable)
///
/// # Returns
///
/// (0) on success
///
/// # Panics
///
/// Panics if the SEND_BUFFER is not available
#[no_mangle]
unsafe extern "C" fn qemu_acquire_receiver_buffer(
_context: *mut c_void,
msg_buf_ptr: *mut *mut c_void,
) -> u32 {
let mut buf = RECEIVE_BUFFER.take().unwrap();
let buf_ptr = buf.as_mut_ptr() as *mut _ as *mut c_void;

*msg_buf_ptr = buf_ptr;

0
}

/// # Summary
///
/// A helper function to reset the RECEIVE_BUFFER from `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `msg_buf_ptr`: A pointer representing the receiver buffer.
///
/// # Returns
///
/// (0) on success
///
/// # Panics
///
/// Panics if the `msg_buf_ptr` is invalid or has less elements
/// than `SEND_RECEIVE_BUFFER_LEN`
#[no_mangle]
unsafe extern "C" fn qemu_release_receiver_buffer(
_context: *mut c_void,
msg_buf_ptr: *const c_void,
) {
let message = msg_buf_ptr as *const u8;
let msg_buf = from_raw_parts(message, SEND_RECEIVE_BUFFER_LEN);

RECEIVE_BUFFER.set(msg_buf.try_into().unwrap()).unwrap();
}

/// # Summary
///
/// Registers the SPDM `context` for a `qemu_server` backend.
@@ -455,8 +339,6 @@ pub fn register_device(
port: u16,
transport: TransportLayer,
) -> Result<(), ()> {
let buffer_send = [0; SEND_RECEIVE_BUFFER_LEN];
let buffer_receive = [0; SEND_RECEIVE_BUFFER_LEN];
let ip = "127.0.0.1";
let addr = format!("{}:{}", ip, port);

@@ -496,15 +378,6 @@ pub fn register_device(
}

unsafe {
SEND_BUFFER.set(buffer_send).map_err(|e| {
error!("Failed to set send buffer: {e:?}");
()
})?;
RECEIVE_BUFFER.set(buffer_receive).map_err(|e| {
error!("Failed to receive buffer: {e:?}");
()
})?;

match transport {
TransportLayer::Doe => {
libspdm_register_device_io_func(
@@ -521,16 +394,11 @@ pub fn register_device(
);
}
}

libspdm_register_device_buffer_func(
io_buffers::libspdm_setup_io_buffers(
context,
SEND_RECEIVE_BUFFER_LEN as u32,
SEND_RECEIVE_BUFFER_LEN as u32,
Some(qemu_acquire_sender_buffer),
Some(qemu_release_sender_buffer),
Some(qemu_acquire_receiver_buffer),
Some(qemu_release_receiver_buffer),
);
SEND_RECEIVE_BUFFER_LEN,
SEND_RECEIVE_BUFFER_LEN,
)?;
}

Ok(())
137 changes: 4 additions & 133 deletions src/socket_client.rs
Original file line number Diff line number Diff line change
@@ -20,9 +20,6 @@ use std::slice::{from_raw_parts, from_raw_parts_mut};
use std::time::Duration;

const SEND_RECEIVE_BUFFER_LEN: usize = LIBSPDM_MAX_SPDM_MSG_SIZE as usize;
static mut SEND_BUFFER: OnceCell<[u8; SEND_RECEIVE_BUFFER_LEN]> = OnceCell::new();
static mut RECEIVE_BUFFER: OnceCell<[u8; SEND_RECEIVE_BUFFER_LEN]> = OnceCell::new();

static mut CLIENT_CONNECTION: OnceCell<UnixStream> = OnceCell::new();

/// # Summary
@@ -137,122 +134,6 @@ unsafe extern "C" fn sclient_receive_message(
0
}

/// # Summary
///
/// A helper function to capture the SEND_BUFFER into `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `max_msg_size`: Returns the length of the sender buffer
/// * `msg_buf_ptr`: Returns a pointer to the sender buffer (mutable)
///
/// # Returns
///
/// (0) on success
///
/// # Panics
///
/// Panics if the SEND_BUFFER is not available
#[no_mangle]
unsafe extern "C" fn sclient_acquire_sender_buffer(
_context: *mut c_void,
msg_buf_ptr: *mut *mut c_void,
) -> u32 {
let mut buf = SEND_BUFFER.take().unwrap();
let buf_ptr = buf.as_mut_ptr() as *mut _ as *mut c_void;

*msg_buf_ptr = buf_ptr;

0
}

/// # Summary
///
/// A helper function to reset the SEND_BUFFER from `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `msg_buf_ptr`: A pointer representing the sender buffer.
///
/// # Returns
///
/// (0) on success
///
/// # Panics
///
/// Panics if the `msg_buf_ptr` is invalid or has less elements
/// than `SEND_RECEIVE_BUFFER_LEN`
#[no_mangle]
unsafe extern "C" fn sclient_release_sender_buffer(
_context: *mut c_void,
msg_buf_ptr: *const c_void,
) {
let message = msg_buf_ptr as *const u8;
let msg_buf = from_raw_parts(message, SEND_RECEIVE_BUFFER_LEN);

SEND_BUFFER.set(msg_buf.try_into().unwrap()).unwrap();
}

/// # Summary
///
/// A helper function to capture the RECEIVE_BUFFER into `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `max_msg_size`: Returns the length of the receiver buffer
/// * `msg_buf_ptr`: Returns a pointer to the receiver buffer (mutable)
///
/// # Returns
///
/// (0) on success
///
/// # Panics
///
/// Panics if the SEND_BUFFER is not available
#[no_mangle]
unsafe extern "C" fn sclient_acquire_receiver_buffer(
_context: *mut c_void,
msg_buf_ptr: *mut *mut c_void,
) -> u32 {
let mut buf = RECEIVE_BUFFER.take().unwrap();
let buf_ptr = buf.as_mut_ptr() as *mut _ as *mut c_void;

*msg_buf_ptr = buf_ptr;

0
}

/// # Summary
///
/// A helper function to reset the RECEIVE_BUFFER from `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `msg_buf_ptr`: A pointer representing the receiver buffer.
///
/// # Returns
///
/// (0) on success
///
/// # Panics
///
/// Panics if the `msg_buf_ptr` is invalid or has less elements
/// than `SEND_RECEIVE_BUFFER_LEN`
#[no_mangle]
unsafe extern "C" fn sclient_release_receiver_buffer(
_context: *mut c_void,
msg_buf_ptr: *const c_void,
) {
let message = msg_buf_ptr as *const u8;
let msg_buf = from_raw_parts(message, SEND_RECEIVE_BUFFER_LEN);

RECEIVE_BUFFER.set(msg_buf.try_into().unwrap()).unwrap();
}

/// # Summary
///
/// Registers the SPDM `context` for a `socket_client` backend.
@@ -270,9 +151,6 @@ unsafe extern "C" fn sclient_release_receiver_buffer(
/// Panics if `SEND_BUFFER/RECEIVE_BUFFER` is occupied
/// Panics if the `socket_server` hasn't initialized the socket.
pub fn register_device(context: *mut c_void) -> Result<(), ()> {
let buffer_send = [0; SEND_RECEIVE_BUFFER_LEN];
let buffer_receive = [0; SEND_RECEIVE_BUFFER_LEN];

let socket = Path::new(SOCKET_PATH);

match UnixStream::connect(socket) {
@@ -292,23 +170,16 @@ pub fn register_device(context: *mut c_void) -> Result<(), ()> {
info!("Connected to server");

unsafe {
SEND_BUFFER.set(buffer_send).unwrap();
RECEIVE_BUFFER.set(buffer_receive).unwrap();

libspdm_register_device_io_func(
context,
Some(sclient_send_message),
Some(sclient_receive_message),
);
libspdm_register_device_buffer_func(
io_buffers::libspdm_setup_io_buffers(
context,
SEND_RECEIVE_BUFFER_LEN as u32,
SEND_RECEIVE_BUFFER_LEN as u32,
Some(sclient_acquire_sender_buffer),
Some(sclient_release_sender_buffer),
Some(sclient_acquire_receiver_buffer),
Some(sclient_release_receiver_buffer),
);
SEND_RECEIVE_BUFFER_LEN,
SEND_RECEIVE_BUFFER_LEN,
)?;
}

Ok(())
142 changes: 4 additions & 138 deletions src/socket_server.rs
Original file line number Diff line number Diff line change
@@ -21,9 +21,6 @@ use std::slice::{from_raw_parts, from_raw_parts_mut};
use std::time::Duration;

const SEND_RECEIVE_BUFFER_LEN: usize = LIBSPDM_MAX_SPDM_MSG_SIZE as usize;
static mut SEND_BUFFER: OnceCell<[u8; SEND_RECEIVE_BUFFER_LEN]> = OnceCell::new();
static mut RECEIVE_BUFFER: OnceCell<[u8; SEND_RECEIVE_BUFFER_LEN]> = OnceCell::new();

static mut CLIENT_CONNECTION: OnceCell<UnixStream> = OnceCell::new();
static mut SERVER_PERSIST: bool = false;

@@ -143,122 +140,6 @@ unsafe extern "C" fn sserver_receive_message(
0
}

/// # Summary
///
/// A helper function to capture the SEND_BUFFER into `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `max_msg_size`: Returns the length of the sender buffer
/// * `msg_buf_ptr`: Returns a pointer to the sender buffer (mutable)
///
/// # Returns
///
/// (0) on success
///
/// # Panics
///
/// Panics if the SEND_BUFFER is not available
#[no_mangle]
unsafe extern "C" fn sserver_acquire_sender_buffer(
_context: *mut c_void,
msg_buf_ptr: *mut *mut c_void,
) -> u32 {
let mut buf = SEND_BUFFER.take().unwrap();
let buf_ptr = buf.as_mut_ptr() as *mut _ as *mut c_void;

*msg_buf_ptr = buf_ptr;

0
}

/// # Summary
///
/// A helper function to reset the SEND_BUFFER from `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `msg_buf_ptr`: A pointer representing the sender buffer.
///
/// # Returns
///
/// (0) on success
///
/// # Panics
///
/// Panics if the `msg_buf_ptr` is invalid or has less elements
/// than `SEND_RECEIVE_BUFFER_LEN`
#[no_mangle]
unsafe extern "C" fn sserver_release_sender_buffer(
_context: *mut c_void,
msg_buf_ptr: *const c_void,
) {
let message = msg_buf_ptr as *const u8;
let msg_buf = from_raw_parts(message, SEND_RECEIVE_BUFFER_LEN);

SEND_BUFFER.set(msg_buf.try_into().unwrap()).unwrap();
}

/// # Summary
///
/// A helper function to capture the RECEIVE_BUFFER into `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `max_msg_size`: Returns the length of the receiver buffer
/// * `msg_buf_ptr`: Returns a pointer to the receiver buffer (mutable)
///
/// # Returns
///
/// (0) on success
///
/// # Panics
///
/// Panics if the SEND_BUFFER is not available
#[no_mangle]
unsafe extern "C" fn sserver_acquire_receiver_buffer(
_context: *mut c_void,
msg_buf_ptr: *mut *mut c_void,
) -> u32 {
let mut buf = RECEIVE_BUFFER.take().unwrap();
let buf_ptr = buf.as_mut_ptr() as *mut _ as *mut c_void;

*msg_buf_ptr = buf_ptr;

0
}

/// # Summary
///
/// A helper function to reset the RECEIVE_BUFFER from `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `msg_buf_ptr`: A pointer representing the receiver buffer.
///
/// # Returns
///
/// (0) on success
///
/// # Panics
///
/// Panics if the `msg_buf_ptr` is invalid or has less elements
/// than `SEND_RECEIVE_BUFFER_LEN`
#[no_mangle]
unsafe extern "C" fn sserver_release_receiver_buffer(
_context: *mut c_void,
msg_buf_ptr: *const c_void,
) {
let message = msg_buf_ptr as *const u8;
let msg_buf = from_raw_parts(message, SEND_RECEIVE_BUFFER_LEN);

RECEIVE_BUFFER.set(msg_buf.try_into().unwrap()).unwrap();
}

fn setup_socket_and_listen() -> Result<(), ()> {
let socket = Path::new(SOCKET_PATH);

@@ -321,36 +202,21 @@ fn setup_socket_and_listen() -> Result<(), ()> {
/// Panics if `SEND_BUFFER/RECEIVE_BUFFER` is occupied
/// Panics on errors based on socket setup.
pub fn register_device(context: *mut c_void, server_persist: bool) -> Result<(), ()> {
let buffer_send = [0; SEND_RECEIVE_BUFFER_LEN];
let buffer_receive = [0; SEND_RECEIVE_BUFFER_LEN];

setup_socket_and_listen()?;

unsafe {
SERVER_PERSIST = server_persist;
SEND_BUFFER.set(buffer_send).map_err(|e| {
error!("Failed to set send buffer: {e:?}");
()
})?;
RECEIVE_BUFFER.set(buffer_receive).map_err(|e| {
error!("Failed to set receive buffer: {e:?}");
()
})?;

libspdm_register_device_io_func(
context,
Some(sserver_send_message),
Some(sserver_receive_message),
);
libspdm_register_device_buffer_func(
io_buffers::libspdm_setup_io_buffers(
context,
SEND_RECEIVE_BUFFER_LEN as u32,
SEND_RECEIVE_BUFFER_LEN as u32,
Some(sserver_acquire_sender_buffer),
Some(sserver_release_sender_buffer),
Some(sserver_acquire_receiver_buffer),
Some(sserver_release_receiver_buffer),
);
SEND_RECEIVE_BUFFER_LEN,
SEND_RECEIVE_BUFFER_LEN,
)?;
}

Ok(())
140 changes: 1 addition & 139 deletions src/usb_i2c.rs
Original file line number Diff line number Diff line change
@@ -37,8 +37,6 @@ use std::time::Duration;
// We are using libspdm chunking, so let's use smaller transfer chunks at the hardware
// layer.
const SEND_RECEIVE_BUFFER_LEN: usize = 128;
static mut SEND_BUFFER: OnceCell<[u8; SEND_RECEIVE_BUFFER_LEN]> = OnceCell::new();
static mut RECEIVE_BUFFER: OnceCell<[u8; SEND_RECEIVE_BUFFER_LEN]> = OnceCell::new();

const MCTP_HEADER_LEN: usize = 10;
const LIBSPDM_BUFFER_LEN: usize = SEND_RECEIVE_BUFFER_LEN - MCTP_HEADER_LEN;
@@ -240,122 +238,6 @@ unsafe extern "C" fn usb_i2c_receive_message(
0
}

/// # Summary
///
/// A helper function to capture the SEND_BUFFER into `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `max_msg_size`: Returns the length of the sender buffer
/// * `msg_buf_ptr`: Returns a pointer to the sender buffer (mutable)
///
/// # Returns
///
/// (0) on success
///
/// # Panics
///
/// Panics if the SEND_BUFFER is not available
#[no_mangle]
unsafe extern "C" fn usb_i2c_acquire_sender_buffer(
_context: *mut c_void,
msg_buf_ptr: *mut *mut c_void,
) -> u32 {
let mut buf = SEND_BUFFER.take().unwrap();
let buf_ptr = buf.as_mut_ptr() as *mut _ as *mut c_void;

*msg_buf_ptr = buf_ptr;

0
}

/// # Summary
///
/// A helper function to reset the SEND_BUFFER from `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `msg_buf_ptr`: A pointer representing the sender buffer.
///
/// # Returns
///
/// (0) on success
///
/// # Panics
///
/// Panics if the `msg_buf_ptr` is invalid or has less elements
/// than `SEND_RECEIVE_BUFFER_LEN`
#[no_mangle]
unsafe extern "C" fn usb_i2c_release_sender_buffer(
_context: *mut c_void,
msg_buf_ptr: *const c_void,
) {
let message = msg_buf_ptr as *const u8;
let msg_buf = from_raw_parts(message, SEND_RECEIVE_BUFFER_LEN);

SEND_BUFFER.set(msg_buf.try_into().unwrap()).unwrap();
}

/// # Summary
///
/// A helper function to capture the RECEIVE_BUFFER into `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `max_msg_size`: Returns the length of the receiver buffer
/// * `msg_buf_ptr`: Returns a pointer to the receiver buffer (mutable)
///
/// # Returns
///
/// (0) on success
///
/// # Panics
///
/// Panics if the SEND_BUFFER is not available
#[no_mangle]
unsafe extern "C" fn usb_i2c_acquire_receiver_buffer(
_context: *mut c_void,
msg_buf_ptr: *mut *mut c_void,
) -> u32 {
let mut buf = RECEIVE_BUFFER.take().unwrap();
let buf_ptr = buf.as_mut_ptr() as *mut _ as *mut c_void;

*msg_buf_ptr = buf_ptr;

0
}

/// # Summary
///
/// A helper function to reset the RECEIVE_BUFFER from `msg_buf_ptr`
///
/// # Parameter
///
/// * `_context`: The SPDM context
/// * `msg_buf_ptr`: A pointer representing the receiver buffer.
///
/// # Returns
///
/// (0) on success
///
/// # Panics
///
/// Panics if the `msg_buf_ptr` is invalid or has less elements
/// than `SEND_RECEIVE_BUFFER_LEN`
#[no_mangle]
unsafe extern "C" fn usb_i2c_release_receiver_buffer(
_context: *mut c_void,
msg_buf_ptr: *const c_void,
) {
let message = msg_buf_ptr as *const u8;
let msg_buf = from_raw_parts(message, SEND_RECEIVE_BUFFER_LEN);

RECEIVE_BUFFER.set(msg_buf.try_into().unwrap()).unwrap();
}

/// # Summary
///
/// # Parameter
@@ -374,9 +256,6 @@ pub fn register_device(
usb_dev: Option<String>,
usb_baud: u32,
) -> Result<(), ()> {
let buffer_send = [0; SEND_RECEIVE_BUFFER_LEN];
let buffer_receive = [0; SEND_RECEIVE_BUFFER_LEN];

let udev = usb_dev.ok_or_else(|| {
error!("USB device path not specified");
()
@@ -421,15 +300,6 @@ pub fn register_device(
.replace(port);

unsafe {
SEND_BUFFER.set(buffer_send).map_err(|e| {
error!("Failed to set send buffer: {e:?}");
()
})?;
RECEIVE_BUFFER.set(buffer_receive).map_err(|e| {
error!("Failed to set receive buffer: {e:?}");
()
})?;

let _ = MCTPCONTEXT.set(libmctp::MCTPSMBusContext::new(
SOURCE_ID,
&MSG_TYPES,
@@ -441,15 +311,7 @@ pub fn register_device(
Some(usb_i2c_send_message),
Some(usb_i2c_receive_message),
);
libspdm_register_device_buffer_func(
context,
LIBSPDM_BUFFER_LEN as u32,
LIBSPDM_BUFFER_LEN as u32,
Some(usb_i2c_acquire_sender_buffer),
Some(usb_i2c_release_sender_buffer),
Some(usb_i2c_acquire_receiver_buffer),
Some(usb_i2c_release_receiver_buffer),
);
io_buffers::libspdm_setup_io_buffers(context, SEND_RECEIVE_BUFFER_LEN, LIBSPDM_BUFFER_LEN)?;
}

Ok(())

0 comments on commit 05a7aed

Please sign in to comment.