stm32/ipcc: refactor tl_mbox

This commit is contained in:
xoviat 2023-05-27 15:05:23 -05:00
parent 7e501855fc
commit 37e104a6b3
7 changed files with 51 additions and 45 deletions

View file

@ -1,5 +1,3 @@
use core::mem::MaybeUninit;
use embassy_futures::block_on; use embassy_futures::block_on;
use super::cmd::CmdSerial; use super::cmd::CmdSerial;
@ -10,17 +8,17 @@ use super::{
channels, BleTable, BLE_CMD_BUFFER, CS_BUFFER, EVT_QUEUE, HCI_ACL_DATA_BUFFER, TL_BLE_TABLE, TL_CHANNEL, channels, BleTable, BLE_CMD_BUFFER, CS_BUFFER, EVT_QUEUE, HCI_ACL_DATA_BUFFER, TL_BLE_TABLE, TL_CHANNEL,
TL_REF_TABLE, TL_REF_TABLE,
}; };
use crate::ipcc::Ipcc;
use crate::tl_mbox::cmd::CmdPacket; use crate::tl_mbox::cmd::CmdPacket;
use crate::tl_mbox::ipcc::Ipcc;
pub struct Ble; pub struct Ble;
impl Ble { impl Ble {
pub(crate) fn new() -> Self { pub fn enable() {
unsafe { unsafe {
LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr()); LinkedListNode::init_head(EVT_QUEUE.as_mut_ptr());
TL_BLE_TABLE = MaybeUninit::new(BleTable { TL_BLE_TABLE.as_mut_ptr().write_volatile(BleTable {
pcmd_buffer: BLE_CMD_BUFFER.as_mut_ptr().cast(), pcmd_buffer: BLE_CMD_BUFFER.as_mut_ptr().cast(),
pcs_buffer: CS_BUFFER.as_mut_ptr().cast(), pcs_buffer: CS_BUFFER.as_mut_ptr().cast(),
pevt_queue: EVT_QUEUE.as_ptr().cast(), pevt_queue: EVT_QUEUE.as_ptr().cast(),
@ -29,11 +27,9 @@ impl Ble {
} }
Ipcc::c1_set_rx_channel(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, true); Ipcc::c1_set_rx_channel(channels::cpu2::IPCC_BLE_EVENT_CHANNEL, true);
Ble
} }
pub(crate) fn evt_handler() { pub fn evt_handler() {
unsafe { unsafe {
let mut node_ptr = core::ptr::null_mut(); let mut node_ptr = core::ptr::null_mut();
let node_ptr_ptr: *mut _ = &mut node_ptr; let node_ptr_ptr: *mut _ = &mut node_ptr;
@ -51,7 +47,7 @@ impl Ble {
Ipcc::c1_clear_flag_channel(channels::cpu2::IPCC_BLE_EVENT_CHANNEL); Ipcc::c1_clear_flag_channel(channels::cpu2::IPCC_BLE_EVENT_CHANNEL);
} }
pub(crate) fn send_cmd(buf: &[u8]) { pub fn send_cmd(buf: &[u8]) {
unsafe { unsafe {
let pcmd_buffer: *mut CmdPacket = (*TL_REF_TABLE.assume_init().ble_table).pcmd_buffer; let pcmd_buffer: *mut CmdPacket = (*TL_REF_TABLE.assume_init().ble_table).pcmd_buffer;
let pcmd_serial: *mut CmdSerial = &mut (*pcmd_buffer).cmd_serial; let pcmd_serial: *mut CmdSerial = &mut (*pcmd_buffer).cmd_serial;

View file

@ -50,7 +50,7 @@
//! //!
pub mod cpu1 { pub mod cpu1 {
use crate::ipcc::IpccChannel; use crate::tl_mbox::ipcc::IpccChannel;
// Not used currently but reserved // Not used currently but reserved
pub const IPCC_BLE_CMD_CHANNEL: IpccChannel = IpccChannel::Channel1; pub const IPCC_BLE_CMD_CHANNEL: IpccChannel = IpccChannel::Channel1;
@ -75,7 +75,7 @@ pub mod cpu1 {
} }
pub mod cpu2 { pub mod cpu2 {
use crate::ipcc::IpccChannel; use crate::tl_mbox::ipcc::IpccChannel;
pub const IPCC_BLE_EVENT_CHANNEL: IpccChannel = IpccChannel::Channel1; pub const IPCC_BLE_EVENT_CHANNEL: IpccChannel = IpccChannel::Channel1;
pub const IPCC_SYSTEM_EVENT_CHANNEL: IpccChannel = IpccChannel::Channel2; pub const IPCC_SYSTEM_EVENT_CHANNEL: IpccChannel = IpccChannel::Channel2;

View file

@ -3,7 +3,7 @@ use core::mem::MaybeUninit;
use super::cmd::{AclDataPacket, AclDataSerial}; use super::cmd::{AclDataPacket, AclDataSerial};
use super::consts::TlPacketType; use super::consts::TlPacketType;
use super::{PacketHeader, TL_EVT_HEADER_SIZE}; use super::{PacketHeader, TL_EVT_HEADER_SIZE};
use crate::tl_mbox::mm; use crate::tl_mbox::mm::MemoryManager;
/// the payload of [`Evt`] for a command status event /// the payload of [`Evt`] for a command status event
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
@ -131,6 +131,6 @@ impl EvtBox {
impl Drop for EvtBox { impl Drop for EvtBox {
fn drop(&mut self) { fn drop(&mut self) {
mm::MemoryManager::evt_drop(self.ptr); MemoryManager::evt_drop(self.ptr);
} }
} }

View file

@ -1,22 +1,20 @@
use core::mem::MaybeUninit;
use super::evt::EvtPacket; use super::evt::EvtPacket;
use super::unsafe_linked_list::LinkedListNode; use super::unsafe_linked_list::LinkedListNode;
use super::{ use super::{
channels, MemManagerTable, BLE_SPARE_EVT_BUF, EVT_POOL, FREE_BUFF_QUEUE, LOCAL_FREE_BUF_QUEUE, POOL_SIZE, channels, MemManagerTable, BLE_SPARE_EVT_BUF, EVT_POOL, FREE_BUFF_QUEUE, LOCAL_FREE_BUF_QUEUE, POOL_SIZE,
SYS_SPARE_EVT_BUF, TL_MEM_MANAGER_TABLE, TL_REF_TABLE, SYS_SPARE_EVT_BUF, TL_MEM_MANAGER_TABLE, TL_REF_TABLE,
}; };
use crate::ipcc::Ipcc; use crate::tl_mbox::ipcc::Ipcc;
pub struct MemoryManager; pub struct MemoryManager;
impl MemoryManager { impl MemoryManager {
pub fn new() -> Self { pub fn enable() {
unsafe { unsafe {
LinkedListNode::init_head(FREE_BUFF_QUEUE.as_mut_ptr()); LinkedListNode::init_head(FREE_BUFF_QUEUE.as_mut_ptr());
LinkedListNode::init_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr()); LinkedListNode::init_head(LOCAL_FREE_BUF_QUEUE.as_mut_ptr());
TL_MEM_MANAGER_TABLE = MaybeUninit::new(MemManagerTable { TL_MEM_MANAGER_TABLE.as_mut_ptr().write_volatile(MemManagerTable {
spare_ble_buffer: BLE_SPARE_EVT_BUF.as_ptr().cast(), spare_ble_buffer: BLE_SPARE_EVT_BUF.as_ptr().cast(),
spare_sys_buffer: SYS_SPARE_EVT_BUF.as_ptr().cast(), spare_sys_buffer: SYS_SPARE_EVT_BUF.as_ptr().cast(),
ble_pool: EVT_POOL.as_ptr().cast(), ble_pool: EVT_POOL.as_ptr().cast(),
@ -26,8 +24,6 @@ impl MemoryManager {
traces_pool_size: 0, traces_pool_size: 0,
}); });
} }
MemoryManager
} }
pub fn evt_handler() { pub fn evt_handler() {

View file

@ -1,7 +1,9 @@
use core::mem::MaybeUninit; use core::mem::MaybeUninit;
use atomic_polyfill::{compiler_fence, Ordering};
use bit_field::BitField; use bit_field::BitField;
use embassy_cortex_m::interrupt::{Interrupt, InterruptExt}; use embassy_cortex_m::interrupt::{Interrupt, InterruptExt};
use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_sync::channel::Channel; use embassy_sync::channel::Channel;
@ -13,13 +15,16 @@ use self::shci::{shci_ble_init, ShciBleInitCmdParam};
use self::sys::Sys; use self::sys::Sys;
use self::unsafe_linked_list::LinkedListNode; use self::unsafe_linked_list::LinkedListNode;
use crate::interrupt; use crate::interrupt;
use crate::ipcc::{Config, Ipcc}; use crate::peripherals::IPCC;
pub use crate::tl_mbox::ipcc::Config;
use crate::tl_mbox::ipcc::Ipcc;
mod ble; mod ble;
mod channels; mod channels;
mod cmd; mod cmd;
mod consts; mod consts;
mod evt; mod evt;
mod ipcc;
mod mm; mod mm;
mod shci; mod shci;
mod sys; mod sys;
@ -60,6 +65,8 @@ pub struct ReceiveInterruptHandler {}
impl interrupt::Handler<interrupt::IPCC_C1_RX> for ReceiveInterruptHandler { impl interrupt::Handler<interrupt::IPCC_C1_RX> for ReceiveInterruptHandler {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
// info!("ipcc rx interrupt");
if Ipcc::is_rx_pending(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL) { if Ipcc::is_rx_pending(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL) {
sys::Sys::evt_handler(); sys::Sys::evt_handler();
} else if Ipcc::is_rx_pending(channels::cpu2::IPCC_BLE_EVENT_CHANNEL) { } else if Ipcc::is_rx_pending(channels::cpu2::IPCC_BLE_EVENT_CHANNEL) {
@ -74,6 +81,8 @@ pub struct TransmitInterruptHandler {}
impl interrupt::Handler<interrupt::IPCC_C1_TX> for TransmitInterruptHandler { impl interrupt::Handler<interrupt::IPCC_C1_TX> for TransmitInterruptHandler {
unsafe fn on_interrupt() { unsafe fn on_interrupt() {
// info!("ipcc tx interrupt");
if Ipcc::is_tx_pending(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL) { if Ipcc::is_tx_pending(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL) {
// TODO: handle this case // TODO: handle this case
let _ = sys::Sys::cmd_evt_handler(); let _ = sys::Sys::cmd_evt_handler();
@ -307,21 +316,24 @@ static mut HCI_ACL_DATA_BUFFER: MaybeUninit<[u8; TL_PACKET_HEADER_SIZE + 5 + 251
// TODO: get a better size, this is a placeholder // TODO: get a better size, this is a placeholder
pub(crate) static TL_CHANNEL: Channel<CriticalSectionRawMutex, EvtBox, 5> = Channel::new(); pub(crate) static TL_CHANNEL: Channel<CriticalSectionRawMutex, EvtBox, 5> = Channel::new();
pub struct TlMbox { pub struct TlMbox<'d> {
_sys: Sys, _ipcc: PeripheralRef<'d, IPCC>,
_ble: Ble,
_mm: MemoryManager,
} }
impl TlMbox { impl<'d> TlMbox<'d> {
/// initializes low-level transport between CPU1 and BLE stack on CPU2 /// initializes low-level transport between CPU1 and BLE stack on CPU2
pub fn init( pub fn new(
ipcc: impl Peripheral<P = IPCC> + 'd,
_irqs: impl interrupt::Binding<interrupt::IPCC_C1_RX, ReceiveInterruptHandler> _irqs: impl interrupt::Binding<interrupt::IPCC_C1_RX, ReceiveInterruptHandler>
+ interrupt::Binding<interrupt::IPCC_C1_TX, TransmitInterruptHandler>, + interrupt::Binding<interrupt::IPCC_C1_TX, TransmitInterruptHandler>,
config: Config, config: Config,
) -> TlMbox { ) -> Self {
into_ref!(ipcc);
unsafe { unsafe {
TL_REF_TABLE = MaybeUninit::new(RefTable { compiler_fence(Ordering::AcqRel);
TL_REF_TABLE.as_mut_ptr().write_volatile(RefTable {
device_info_table: TL_DEVICE_INFO_TABLE.as_ptr(), device_info_table: TL_DEVICE_INFO_TABLE.as_ptr(),
ble_table: TL_BLE_TABLE.as_ptr(), ble_table: TL_BLE_TABLE.as_ptr(),
thread_table: TL_THREAD_TABLE.as_ptr(), thread_table: TL_THREAD_TABLE.as_ptr(),
@ -334,6 +346,10 @@ impl TlMbox {
ble_lld_table: TL_BLE_LLD_TABLE.as_ptr(), ble_lld_table: TL_BLE_LLD_TABLE.as_ptr(),
}); });
// info!("TL_REF_TABLE addr: {:x}", TL_REF_TABLE.as_ptr() as usize);
compiler_fence(Ordering::AcqRel);
TL_SYS_TABLE = MaybeUninit::zeroed(); TL_SYS_TABLE = MaybeUninit::zeroed();
TL_DEVICE_INFO_TABLE = MaybeUninit::zeroed(); TL_DEVICE_INFO_TABLE = MaybeUninit::zeroed();
TL_BLE_TABLE = MaybeUninit::zeroed(); TL_BLE_TABLE = MaybeUninit::zeroed();
@ -352,13 +368,15 @@ impl TlMbox {
CS_BUFFER = MaybeUninit::zeroed(); CS_BUFFER = MaybeUninit::zeroed();
BLE_CMD_BUFFER = MaybeUninit::zeroed(); BLE_CMD_BUFFER = MaybeUninit::zeroed();
HCI_ACL_DATA_BUFFER = MaybeUninit::zeroed(); HCI_ACL_DATA_BUFFER = MaybeUninit::zeroed();
compiler_fence(Ordering::AcqRel);
} }
Ipcc::init(config); Ipcc::enable(config);
let _sys = Sys::new(); Sys::enable();
let _ble = Ble::new(); Ble::enable();
let _mm = MemoryManager::new(); MemoryManager::enable();
// enable interrupts // enable interrupts
unsafe { crate::interrupt::IPCC_C1_RX::steal() }.unpend(); unsafe { crate::interrupt::IPCC_C1_RX::steal() }.unpend();
@ -367,7 +385,7 @@ impl TlMbox {
unsafe { crate::interrupt::IPCC_C1_RX::steal() }.enable(); unsafe { crate::interrupt::IPCC_C1_RX::steal() }.enable();
unsafe { crate::interrupt::IPCC_C1_TX::steal() }.enable(); unsafe { crate::interrupt::IPCC_C1_TX::steal() }.enable();
TlMbox { _sys, _ble, _mm } Self { _ipcc: ipcc }
} }
pub fn wireless_fw_info(&self) -> Option<WirelessFwInfoTable> { pub fn wireless_fw_info(&self) -> Option<WirelessFwInfoTable> {

View file

@ -3,7 +3,7 @@
use super::cmd::CmdPacket; use super::cmd::CmdPacket;
use super::consts::TlPacketType; use super::consts::TlPacketType;
use super::{channels, TL_CS_EVT_SIZE, TL_EVT_HEADER_SIZE, TL_PACKET_HEADER_SIZE, TL_SYS_TABLE}; use super::{channels, TL_CS_EVT_SIZE, TL_EVT_HEADER_SIZE, TL_PACKET_HEADER_SIZE, TL_SYS_TABLE};
use crate::ipcc::Ipcc; use crate::tl_mbox::ipcc::Ipcc;
const SCHI_OPCODE_BLE_INIT: u16 = 0xfc66; const SCHI_OPCODE_BLE_INIT: u16 = 0xfc66;
pub const TL_BLE_EVT_CS_PACKET_SIZE: usize = TL_EVT_HEADER_SIZE + TL_CS_EVT_SIZE; pub const TL_BLE_EVT_CS_PACKET_SIZE: usize = TL_EVT_HEADER_SIZE + TL_CS_EVT_SIZE;

View file

@ -1,5 +1,3 @@
use core::mem::MaybeUninit;
use embassy_futures::block_on; use embassy_futures::block_on;
use super::cmd::{CmdPacket, CmdSerial}; use super::cmd::{CmdPacket, CmdSerial};
@ -7,27 +5,25 @@ use super::consts::TlPacketType;
use super::evt::{CcEvt, EvtBox, EvtSerial}; use super::evt::{CcEvt, EvtBox, EvtSerial};
use super::unsafe_linked_list::LinkedListNode; use super::unsafe_linked_list::LinkedListNode;
use super::{channels, SysTable, SYSTEM_EVT_QUEUE, SYS_CMD_BUF, TL_CHANNEL, TL_REF_TABLE, TL_SYS_TABLE}; use super::{channels, SysTable, SYSTEM_EVT_QUEUE, SYS_CMD_BUF, TL_CHANNEL, TL_REF_TABLE, TL_SYS_TABLE};
use crate::ipcc::Ipcc; use crate::tl_mbox::ipcc::Ipcc;
pub struct Sys; pub struct Sys;
impl Sys { impl Sys {
pub(crate) fn new() -> Self { pub fn enable() {
unsafe { unsafe {
LinkedListNode::init_head(SYSTEM_EVT_QUEUE.as_mut_ptr()); LinkedListNode::init_head(SYSTEM_EVT_QUEUE.as_mut_ptr());
TL_SYS_TABLE = MaybeUninit::new(SysTable { TL_SYS_TABLE.as_mut_ptr().write_volatile(SysTable {
pcmd_buffer: SYS_CMD_BUF.as_mut_ptr(), pcmd_buffer: SYS_CMD_BUF.as_mut_ptr(),
sys_queue: SYSTEM_EVT_QUEUE.as_ptr(), sys_queue: SYSTEM_EVT_QUEUE.as_ptr(),
}); });
} }
Ipcc::c1_set_rx_channel(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL, true); Ipcc::c1_set_rx_channel(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL, true);
Sys
} }
pub(crate) fn evt_handler() { pub fn evt_handler() {
unsafe { unsafe {
let mut node_ptr = core::ptr::null_mut(); let mut node_ptr = core::ptr::null_mut();
let node_ptr_ptr: *mut _ = &mut node_ptr; let node_ptr_ptr: *mut _ = &mut node_ptr;
@ -46,7 +42,7 @@ impl Sys {
Ipcc::c1_clear_flag_channel(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL); Ipcc::c1_clear_flag_channel(channels::cpu2::IPCC_SYSTEM_EVENT_CHANNEL);
} }
pub(crate) fn cmd_evt_handler() -> CcEvt { pub fn cmd_evt_handler() -> CcEvt {
Ipcc::c1_set_tx_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, false); Ipcc::c1_set_tx_channel(channels::cpu1::IPCC_SYSTEM_CMD_RSP_CHANNEL, false);
// ST's command response data structure is really convoluted. // ST's command response data structure is really convoluted.
@ -68,7 +64,7 @@ impl Sys {
} }
#[allow(dead_code)] #[allow(dead_code)]
pub(crate) fn send_cmd(buf: &[u8]) { pub fn send_cmd(buf: &[u8]) {
unsafe { unsafe {
// TODO: check this // TODO: check this
let cmd_buffer = &mut *(*TL_REF_TABLE.assume_init().sys_table).pcmd_buffer; let cmd_buffer = &mut *(*TL_REF_TABLE.assume_init().sys_table).pcmd_buffer;