1use std::fmt::Display;
5
6use luwen_def::Arch;
7use thiserror::Error;
8
9use crate::arc_msg::ArcMsgError;
10
11#[derive(Debug)]
12pub struct BtWrapper(pub std::backtrace::Backtrace);
13
14impl BtWrapper {
15 #[inline(always)]
16 pub fn capture() -> Self {
17 Self(std::backtrace::Backtrace::capture())
18 }
19}
20
21impl Display for BtWrapper {
22 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23 if let std::backtrace::BacktraceStatus::Captured = self.0.status() {
24 self.0.fmt(f)?;
25 }
26 Ok(())
27 }
28}
29
30#[derive(Clone, Error, Debug)]
31pub enum ArcReadyError {
32 #[error("scratch register access failed")]
33 NoAccess,
34 #[error("ARC watchdog has triggered")]
35 WatchdogTriggered,
36 #[error("ARC FW has not yet booted")]
37 BootIncomplete,
38 #[error("ARC FW encountered an error during boot")]
39 BootError,
40 #[error("ARC is asleep")]
41 Asleep,
42 #[error("there is an outstanding PCIE DMA request")]
43 OutstandingPcieDMA,
44 #[error("another message is queued (0x{0:02x})")]
45 MessageQueued(u32),
46 #[error("another message is being processed (0x{0:02x})")]
47 HandlingMessage(u32),
48 #[error("post code 0x{0:08x} indicates that you are running old fw... or that you aren't running any")]
49 OldPostCode(u32),
50}
51
52#[derive(Error, Debug)]
53pub enum PlatformError {
54 #[error("Tried to initialize chip with the wrong architecture, expected {expected:?} but got {actual:?}\n{backtrace}")]
55 WrongChipArch {
56 actual: Arch,
57 expected: Arch,
58 backtrace: BtWrapper,
59 },
60
61 #[error("Tried to initialize chip with the wrong architecture, expected one of {expected:?} but got {actual:?}\n{backtrace}")]
62 WrongChipArchs {
63 actual: Arch,
64 expected: Vec<Arch>,
65 backtrace: BtWrapper,
66 },
67
68 #[error("Unsupported fw version, got {} but required {required:x}", version.map(|v| format!("{v:x}")).unwrap_or("<unknown version>".to_string()))]
69 UnsupportedFwVersion { version: Option<u32>, required: u32 },
70
71 #[error("It is not currently safe to communicate with ARC because, {0}\n{1}")]
72 ArcNotReady(ArcReadyError, BtWrapper),
73
74 #[error(transparent)]
75 ArcMsgError(#[from] ArcMsgError),
76
77 #[error(transparent)]
78 MessageError(#[from] crate::chip::MessageError),
79
80 #[error("Ethernet training not complete on {} ports", .0.iter().copied().filter(|v| *v).count())]
81 EthernetTrainingNotComplete(Vec<bool>),
82
83 #[error(transparent)]
84 AxiError(#[from] crate::chip::AxiError),
85
86 #[error("{0}\n{1}")]
87 Generic(String, BtWrapper),
88
89 #[error("{0}\n{1}")]
90 GenericError(Box<dyn std::error::Error>, BtWrapper),
91}
92
93impl From<Box<dyn std::error::Error>> for PlatformError {
94 #[inline]
95 fn from(e: Box<dyn std::error::Error>) -> Self {
96 Self::GenericError(e, BtWrapper::capture())
97 }
98}
99
100impl From<String> for PlatformError {
101 #[inline]
102 fn from(e: String) -> Self {
103 Self::Generic(e, BtWrapper::capture())
104 }
105}