blob: 174fd2bfcbc2a486e4333c7b8ab7985d21b29bb1 [file] [log] [blame]
Zane Shelleya61f4c52019-08-01 13:58:49 -05001#pragma once
2
Zane Shelley3a02e242020-05-08 16:25:36 -05003#include <hei_signature.hpp>
Zane Shelley995be6c2021-02-24 15:48:55 -06004#include <util/hei_bit_string.hpp>
Zane Shelley3a02e242020-05-08 16:25:36 -05005
Zane Shelley47ca5c22021-06-22 11:44:02 -05006#include <algorithm>
Zane Shelleydae1af62021-01-14 11:00:46 -06007#include <map>
8#include <memory>
Zane Shelley3a02e242020-05-08 16:25:36 -05009#include <vector>
Zane Shelleya61f4c52019-08-01 13:58:49 -050010
11namespace libhei
12{
13
14/**
Zane Shelleyb406de42019-09-09 16:10:38 -050015 * @brief The main isolate() API is given a list of chips to analyze. This class
16 * will contain a list of all active hardware errors found on those
17 * chips, the contents of any registers associated with the active
18 * errors, and any other data that can be useful for debug.
Zane Shelleya61f4c52019-08-01 13:58:49 -050019 */
20class IsolationData
21{
Zane Shelley93b61ad2019-10-16 20:41:03 -050022 public: // Constructors, destructor, assignment, etc.
Zane Shelleyb406de42019-09-09 16:10:38 -050023 /** @brief Default constructor. */
24 IsolationData() = default;
Zane Shelley5a266612019-08-15 16:23:53 -050025
26 /** @brief Destructor. */
27 ~IsolationData() = default;
Zane Shelleya61f4c52019-08-01 13:58:49 -050028
29 /** @brief Copy constructor. */
Zane Shelleyfe27b652019-10-28 11:33:07 -050030 IsolationData(const IsolationData&) = default;
Zane Shelleya61f4c52019-08-01 13:58:49 -050031
32 /** @brief Assignment operator. */
Zane Shelleyfe27b652019-10-28 11:33:07 -050033 IsolationData& operator=(const IsolationData&) = default;
Zane Shelleya61f4c52019-08-01 13:58:49 -050034
Zane Shelleydae1af62021-01-14 11:00:46 -060035 public:
36 /** The data stored in each entry of the register dump. */
37 struct RegDumpEntry
38 {
39 RegDumpEntry(RegisterId_t i_regId, Instance_t i_regInst,
40 std::shared_ptr<BitStringBuffer> i_data) :
41 regId(i_regId),
42 regInst(i_regInst), data(i_data)
43 {}
44
45 RegisterId_t regId; ///< 3-byte register ID
46 Instance_t regInst; ///< 1-byte register instance
47 std::shared_ptr<BitStringBuffer> data; ///< register data
Zane Shelley47ca5c22021-06-22 11:44:02 -050048
49 bool operator==(const RegDumpEntry& r) const
50 {
51 return regId == r.regId && regInst == r.regInst && *data == *r.data;
52 }
Zane Shelleydae1af62021-01-14 11:00:46 -060053 };
54
Zane Shelley93b61ad2019-10-16 20:41:03 -050055 private: // Instance variables
Zane Shelley93b61ad2019-10-16 20:41:03 -050056 /** A list of all signatures found during isolation. */
57 std::vector<Signature> iv_sigLists;
Zane Shelleya61f4c52019-08-01 13:58:49 -050058
Zane Shelleydae1af62021-01-14 11:00:46 -060059 /**
60 * This intended to be a snapshot of the register values read from hardware
61 * as the isolator iterates the isolation tree. Therefore, it cannot share
62 * the values stored in the hardware register cache. Instead, it must be a
63 * copy of the data.
64 */
65 std::map<Chip, std::vector<RegDumpEntry>> iv_regDump;
Zane Shelley93b61ad2019-10-16 20:41:03 -050066
67 public: // Member functions
Zane Shelley93b61ad2019-10-16 20:41:03 -050068 /**
69 * @brief Adds a signature to the signature list.
70 * @param i_signature The target signature.
71 */
Zane Shelleyfe27b652019-10-28 11:33:07 -050072 void addSignature(const Signature& i_signature)
Zane Shelley93b61ad2019-10-16 20:41:03 -050073 {
Zane Shelley83da2452019-10-25 15:45:34 -050074 iv_sigLists.push_back(i_signature);
Zane Shelley93b61ad2019-10-16 20:41:03 -050075 }
76
Zane Shelleydae1af62021-01-14 11:00:46 -060077 /**
78 * @brief Adds the contents of a register to the register dump.
79 * @param i_chip The chip associated with this register.
80 * @param i_regId The register ID.
81 * @param i_regInst The register instance.
82 * @param i_data A BitString containing the contents of the register.
83 * Note that this function will make a copy of the data,
84 * which will be stored separately from the hardware
85 * register cache.
86 */
87 void addRegister(const Chip& i_chip, RegisterId_t i_regId,
88 Instance_t i_regInst, const BitString* i_data)
89 {
90 if (!i_data->isZero()) // Only add non-zero values to save space.
91 {
92 // Make a copy of the register value.
93 auto data = std::make_shared<BitStringBuffer>(*i_data);
94
Zane Shelley47ca5c22021-06-22 11:44:02 -050095 // We'll want to avoid adding duplicate data if possible.
96 if (iv_regDump.end() == iv_regDump.find(i_chip))
97 {
98 // The chip doesn't exist in the map. Therefore, the data
99 // doesn't currently exist. So, add it.
100 iv_regDump[i_chip].emplace_back(i_regId, i_regInst, data);
101 }
102 else
103 {
104 // Search this chip for the data.
105 RegDumpEntry entry{i_regId, i_regInst, data};
106 auto itr = std::find(iv_regDump[i_chip].begin(),
107 iv_regDump[i_chip].end(), entry);
108
109 if (iv_regDump[i_chip].end() == itr)
110 {
111 // The data doesn't currently exist. So, add it.
112 iv_regDump[i_chip].push_back(entry);
113 }
114 }
Zane Shelleydae1af62021-01-14 11:00:46 -0600115 }
116 }
117
Zane Shelley93b61ad2019-10-16 20:41:03 -0500118 /** @brief Allows access to the signature list. */
Zane Shelley2e38ae52020-11-05 22:21:30 -0600119 const std::vector<Signature>& getSignatureList() const
Zane Shelley93b61ad2019-10-16 20:41:03 -0500120 {
121 return iv_sigLists;
122 }
123
Zane Shelleydae1af62021-01-14 11:00:46 -0600124 /** @brief Allows access to the register dump. */
125 const std::map<Chip, std::vector<RegDumpEntry>>& getRegisterDump() const
126 {
127 return iv_regDump;
128 }
129
Zane Shelley93b61ad2019-10-16 20:41:03 -0500130 /** @brief Flushes the data to ensure a clean slate for isolation. */
131 void flush()
132 {
133 iv_sigLists.clear();
Zane Shelleydae1af62021-01-14 11:00:46 -0600134 iv_regDump.clear();
Zane Shelley93b61ad2019-10-16 20:41:03 -0500135 }
Zane Shelley5a266612019-08-15 16:23:53 -0500136
Zane Shelleya61f4c52019-08-01 13:58:49 -0500137}; // end class IsolationData
138
139} // end namespace libhei