Skip to main content

intel_crashlog/analysis/
tag.rs

1// Copyright (C) 2026 Intel Corporation
2// SPDX-License-Identifier: MIT
3
4use super::Analyzer;
5use super::agent::CrashLogAgentStatus;
6use super::reason::CrashLogReason;
7use super::reset::ResetKind;
8use super::xq::TransactionQueueState;
9#[cfg(not(feature = "std"))]
10use alloc::{fmt, string::String};
11#[cfg(not(feature = "std"))]
12use core::cmp::Ordering;
13#[cfg(feature = "std")]
14use std::cmp::Ordering;
15#[cfg(feature = "std")]
16use std::fmt;
17
18/// Triage tag identifying a specific crash log issue or finding.
19///
20/// Tags represent decoded and classified information from crash log records.
21/// Each variant corresponds to a different category of system failure or
22/// diagnostic event.
23///
24/// # Display Format
25///
26/// Tags implement [`Display`](fmt::Display) with a hierarchical dot-notation format
27/// for easy parsing and filtering:
28///
29/// - `RESET_CAUSE.{kind}.{cause}` - System reset events
30/// - `CRASHLOG_REASON.{record}.{reason}` - Crash Log trigger reasons
31/// - `CORE_TIMEOUT.{transaction_queue}` - Core timeout
32/// - `MCA.BANK{n}.{mcacod}.{mscod}` - Machine Check Architecture events
33#[derive(Clone, PartialEq, Eq)]
34pub enum Tag {
35    /// Cause of the latest reset.
36    ResetCause { kind: ResetKind, cause: String },
37    /// Defines why the Crash Log collection was triggered.
38    CrashLogReason {
39        record: String,
40        reason: CrashLogReason,
41    },
42    /// Core timeout has occurred.
43    CoreTimeout {
44        transaction_queue: TransactionQueueState,
45    },
46    /// Machine Check Architecture (MCA) error has occurred.
47    MachineCheck {
48        bank: usize,
49        mscod: String,
50        mcacod: String,
51    },
52    CrashLogAgentError {
53        status: CrashLogAgentStatus,
54        instruction_pointer: u32,
55    },
56}
57
58#[derive(Clone, PartialEq, Eq)]
59pub(super) struct TriageTag {
60    priority: i32,
61    pub tag: Tag,
62}
63
64impl Ord for TriageTag {
65    fn cmp(&self, other: &Self) -> Ordering {
66        self.priority.cmp(&other.priority)
67    }
68}
69
70impl PartialOrd for TriageTag {
71    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
72        Some(self.cmp(other))
73    }
74}
75
76impl fmt::Display for Tag {
77    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78        match self {
79            Self::ResetCause { kind, cause } => write!(f, "RESET_CAUSE.{kind}.{cause}"),
80            Self::CrashLogReason { record, reason } => {
81                write!(f, "CRASHLOG_REASON.{record}.{reason}")
82            }
83            Self::CoreTimeout { transaction_queue } => {
84                write!(f, "CORE_TIMEOUT.{transaction_queue}")
85            }
86            Self::MachineCheck {
87                bank,
88                mscod,
89                mcacod,
90            } => {
91                write!(f, "MCA.BANK{bank}.{mcacod}.{mscod}")
92            }
93            Self::CrashLogAgentError {
94                status,
95                instruction_pointer,
96            } => {
97                write!(
98                    f,
99                    "CRASHLOG_AGENT_ERROR.{status}.IP_{instruction_pointer:X}H"
100                )
101            }
102        }
103    }
104}
105
106impl Analyzer<'_> {
107    pub(super) fn tag(&mut self, tag: Tag) {
108        self.tag_with_priority(0, tag);
109    }
110
111    pub(super) fn tag_with_priority(&mut self, priority: i32, tag: Tag) {
112        self.tags.push(TriageTag { priority, tag });
113    }
114}