diff --git a/Cargo.lock b/Cargo.lock index ae1715d05..3a3162629 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2231,6 +2231,7 @@ dependencies = [ "drv-sidecar-mainboard-controller", "drv-sidecar-seq-api", "drv-stm32xx-sys-api", + "ereports", "fixedstr", "hubpack", "idol", diff --git a/build/xtask/src/dist.rs b/build/xtask/src/dist.rs index cfd9f47df..77f6c59e3 100644 --- a/build/xtask/src/dist.rs +++ b/build/xtask/src/dist.rs @@ -2004,6 +2004,7 @@ fn build( -C link-arg=-z -C link-arg=max-page-size=0x20 \ -C llvm-args=--enable-machine-outliner=never \ -Z emit-stack-sizes \ + -Z macro-backtrace \ -C overflow-checks=y \ -C metadata={} \ {} diff --git a/drv/sidecar-seq-server/Cargo.toml b/drv/sidecar-seq-server/Cargo.toml index 356e21aa3..712177c98 100644 --- a/drv/sidecar-seq-server/Cargo.toml +++ b/drv/sidecar-seq-server/Cargo.toml @@ -23,6 +23,7 @@ drv-sidecar-front-io = { path = "../sidecar-front-io", features = ["controller", drv-sidecar-mainboard-controller = { path = "../sidecar-mainboard-controller", features = ["bitstream"] } drv-sidecar-seq-api = { path = "../sidecar-seq-api" } drv-stm32xx-sys-api = { path = "../stm32xx-sys-api", features = ["family-stm32h7"] } +ereports = { path = "../../lib/ereports", features = ["ereporter-macro"] } ringbuf = { path = "../../lib/ringbuf" } userlib = { path = "../../sys/userlib", features = ["panic-messages"] } task-packrat-api = { path = "../../task/packrat-api", features = ["microcbor"] } diff --git a/drv/sidecar-seq-server/src/main.rs b/drv/sidecar-seq-server/src/main.rs index 497ac4078..bb8e5bda5 100644 --- a/drv/sidecar-seq-server/src/main.rs +++ b/drv/sidecar-seq-server/src/main.rs @@ -9,6 +9,7 @@ use crate::clock_generator::ClockGenerator; use crate::front_io::FrontIOBoard; +use crate::i2c_config::MAX_COMPONENT_ID_LEN as REFDES_LEN; use crate::tofino::Tofino; use core::convert::Infallible; use drv_fpga_api::{DeviceState, FpgaError, WriteOp}; @@ -127,26 +128,6 @@ const NO_PCIE_LIMIT: u8 = 120; // QSFP_2_SP_A2_PG const POWER_GOOD: sys_api::PinSet = sys_api::Port::F.pin(12); -const EREPORT_BUF_LEN: usize = microcbor::max_cbor_len_for!( - task_packrat_api::Ereport -); - -#[derive(microcbor::Encode)] -pub enum EreportClass { - #[cbor(rename = "hw.pwr.bmr491.mitfail")] - Bmr491MitigationFailure, -} - -#[derive(microcbor::EncodeFields)] -pub(crate) enum EreportKind { - Bmr491MitigationFailure { - refdes: FixedStr<'static, { crate::i2c_config::MAX_COMPONENT_ID_LEN }>, - failures: u32, - last_cause: drv_i2c_devices::bmr491::MitigationFailureKind, - succeeded: bool, - }, -} - #[derive(Copy, Clone, PartialEq)] enum TofinoStateDetails { A0 { @@ -918,12 +899,7 @@ fn main() -> ! { let fan_modules = FanModules::new(MAINBOARD.get_task_id()); let packrat = Packrat::from(PACKRAT.get_task_id()); - let ereport_buf = { - use static_cell::ClaimOnceCell; - static EREPORT_BUF: ClaimOnceCell<[u8; EREPORT_BUF_LEN]> = - ClaimOnceCell::new([0; EREPORT_BUF_LEN]); - EREPORT_BUF.claim() - }; + let mut ereporter = Ereporter::claim_static_resources(packrat.clone()); // Apply the configuration mitigation on the BMR491, if required. This is an // external device access and may fail. We'll attempt it thrice and then @@ -945,18 +921,15 @@ fn main() -> ! { }; if let Some(last_cause) = last_cause { - // Report the failure even if we eventually succeeded. - try_send_ereport( - &packrat, - &mut ereport_buf[..], - EreportClass::Bmr491MitigationFailure, - EreportKind::Bmr491MitigationFailure { - refdes: FixedStr::from_str(dev.component_id()), - failures, - last_cause, - succeeded, - }, - ); + let ereport = ereports::pwr::Bmr491MitigationFailure { + refdes: FixedStr::<{ REFDES_LEN }>::from_str( + dev.component_id(), + ), + failures, + last_cause, + succeeded, + }; + let _ = ereporter.deliver_ereport(&ereport); } } @@ -1173,28 +1146,11 @@ fn main() -> ! { } } -fn try_send_ereport( - packrat: &task_packrat_api::Packrat, - ereport_buf: &mut [u8], - class: EreportClass, - report: EreportKind, -) { - let eresult = packrat.deliver_microcbor_ereport( - &task_packrat_api::Ereport { - class, - version: 0, - report, - }, - ereport_buf, - ); - match eresult { - Ok((len, _ena)) => ringbuf_entry!(Trace::EreportSent(len)), - Err(task_packrat_api::EreportEncodeError::Packrat { len, err }) => { - ringbuf_entry!(Trace::EreportLost(len, err)) - } - Err(task_packrat_api::EreportEncodeError::Encoder(_)) => { - ringbuf_entry!(Trace::EreportTooBig) - } +ereports::declare_ereporter! { + pub(crate) struct Ereporter { + Bmr491MitigationFailure( + ereports::pwr::Bmr491MitigationFailure<{ REFDES_LEN }> + ), } } diff --git a/lib/ereports/src/lib.rs b/lib/ereports/src/lib.rs index 9d7591470..11aa2e89e 100644 --- a/lib/ereports/src/lib.rs +++ b/lib/ereports/src/lib.rs @@ -143,6 +143,9 @@ macro_rules! declare_ereporter { $v use [< $Ereporter:snake >]::$Trait; $v mod [< $Ereporter:snake >] { use super::*; + // the #[derive(Counters)] proc macro requires `counters` to be + // in scope under its own name. + use $crate::__macro_support::counters; pub(super) trait $Trait: $crate::microcbor::StaticCborLen + sealed::Sealed { fn class(&self) -> EreportClass;