blob: 86a10e1cfeb3b3ee693eb8c35c8060735e27fa0b [file] [log] [blame]
Zane Shelley0b8368c2021-03-18 17:33:41 -05001#include <analyzer/resolution.hpp>
Zane Shelley236bb732021-03-24 17:07:46 -05002#include <util/pdbg.hpp>
3#include <util/trace.hpp>
Zane Shelley0b8368c2021-03-18 17:33:41 -05004
5namespace analyzer
6{
7
Zane Shelley2d114322021-08-25 17:06:12 -05008//------------------------------------------------------------------------------
9
Zane Shelley96d54862021-09-17 11:16:12 -050010// Helper function to get the root cause chip target from the service data.
11pdbg_target* __getRootCauseChipTarget(const ServiceData& i_sd)
Zane Shelley0b8368c2021-03-18 17:33:41 -050012{
Zane Shelley96d54862021-09-17 11:16:12 -050013 auto target = util::pdbg::getTrgt(i_sd.getRootCause().getChip());
14 assert(nullptr != target); // This would be a really bad bug.
15 return target;
16}
Zane Shelley236bb732021-03-24 17:07:46 -050017
Zane Shelley96d54862021-09-17 11:16:12 -050018//------------------------------------------------------------------------------
19
20// Helper function to get a unit target from the given unit path, which is a
21// devtree path relative the the containing chip. An empty string indicates the
22// chip target should be returned.
23pdbg_target* __getUnitTarget(pdbg_target* i_chipTarget,
24 const std::string& i_unitPath)
25{
26 assert(nullptr != i_chipTarget);
27
28 auto target = i_chipTarget; // default, if i_unitPath is empty
29
30 if (!i_unitPath.empty())
Zane Shelley236bb732021-03-24 17:07:46 -050031 {
Zane Shelley96d54862021-09-17 11:16:12 -050032 auto path = std::string{util::pdbg::getPath(target)} + "/" + i_unitPath;
33
34 target = util::pdbg::getTrgt(path);
35 if (nullptr == target)
Zane Shelley236bb732021-03-24 17:07:46 -050036 {
Zane Shelley96d54862021-09-17 11:16:12 -050037 // Likely a bug the RAS data files.
38 throw std::logic_error("Unable to find target for " + path);
Zane Shelley236bb732021-03-24 17:07:46 -050039 }
40 }
41
Zane Shelley96d54862021-09-17 11:16:12 -050042 return target;
43}
44
45//------------------------------------------------------------------------------
46
Zane Shelley5d63cef2021-09-17 18:10:17 -050047// Helper function to get the connected target on the other side of the
48// given bus.
49pdbg_target* __getConnectedTarget(pdbg_target* i_rxTarget,
50 const callout::BusType& i_busType)
51{
52 assert(nullptr != i_rxTarget);
53
54 pdbg_target* txTarget = nullptr;
55
56 auto rxType = util::pdbg::getTrgtType(i_rxTarget);
57 std::string rxPath = util::pdbg::getPath(i_rxTarget);
58
59 if (callout::BusType::SMP_BUS == i_busType &&
60 util::pdbg::TYPE_IOLINK == rxType)
61 {
62 // TODO: Will need to reference some sort of data that can tell us how
63 // the processors are connected in the system. For now, return the
64 // RX target to avoid returning a nullptr.
65 trace::inf("No support to get peer target on SMP bus");
66 txTarget = i_rxTarget;
67 }
68 else if (callout::BusType::OMI_BUS == i_busType &&
69 util::pdbg::TYPE_OMI == rxType)
70 {
71 // This is a bit clunky. The pdbg APIs only give us the ability to
72 // iterate over the children instead of just returning a list. So we'll
73 // push all the children to a list and go from there.
74 std::vector<pdbg_target*> childList;
75
76 pdbg_target* childTarget = nullptr;
77 pdbg_for_each_target("ocmb", i_rxTarget, childTarget)
78 {
79 if (nullptr != childTarget)
80 {
81 childList.push_back(childTarget);
82 }
83 }
84
85 // We know there should only be one OCMB per OMI.
86 if (1 != childList.size())
87 {
88 throw std::logic_error("Invalid child list size for " + rxPath);
89 }
90
91 // Get the connected target.
92 txTarget = childList.front();
93 }
94 else if (callout::BusType::OMI_BUS == i_busType &&
95 util::pdbg::TYPE_OCMB == rxType)
96 {
97 txTarget = pdbg_target_parent("omi", i_rxTarget);
98 if (nullptr == txTarget)
99 {
100 throw std::logic_error("No parent OMI found for " + rxPath);
101 }
102 }
103 else
104 {
105 // This would be a code bug.
106 throw std::logic_error("Unsupported config: i_rxTarget=" + rxPath +
107 " i_busType=" + i_busType.getString());
108 }
109
110 assert(nullptr != txTarget); // just in case we missed something above
111
112 return txTarget;
113}
114
115//------------------------------------------------------------------------------
116
Zane Shelley96d54862021-09-17 11:16:12 -0500117void HardwareCalloutResolution::resolve(ServiceData& io_sd) const
118{
119 // Get the target for the hardware callout.
120 auto target = __getUnitTarget(__getRootCauseChipTarget(io_sd), iv_unitPath);
121
Zane Shelley95135822021-08-23 09:00:05 -0500122 // Get the location code and entity path for this target.
Zane Shelley96d54862021-09-17 11:16:12 -0500123 auto locCode = util::pdbg::getLocationCode(target);
124 auto entityPath = util::pdbg::getPhysDevPath(target);
Zane Shelleyc85716c2021-08-17 10:54:06 -0500125
126 // Add the actual callout to the service data.
127 nlohmann::json callout;
128 callout["LocationCode"] = locCode;
129 callout["Priority"] = iv_priority.getUserDataString();
130 io_sd.addCallout(callout);
Zane Shelley236bb732021-03-24 17:07:46 -0500131
Zane Shelley95135822021-08-23 09:00:05 -0500132 // Add the guard info to the service data.
Zane Shelley2d114322021-08-25 17:06:12 -0500133 Guard guard = io_sd.addGuard(entityPath, iv_guard);
134
135 // Add the callout FFDC to the service data.
136 nlohmann::json ffdc;
137 ffdc["Callout Type"] = "Hardware Callout";
138 ffdc["Target"] = entityPath;
139 ffdc["Priority"] = iv_priority.getRegistryString();
140 ffdc["Guard Type"] = guard.getString();
141 io_sd.addCalloutFFDC(ffdc);
Zane Shelley0b8368c2021-03-18 17:33:41 -0500142}
143
Zane Shelleyc85716c2021-08-17 10:54:06 -0500144//------------------------------------------------------------------------------
145
Zane Shelley5d63cef2021-09-17 18:10:17 -0500146void ConnectedCalloutResolution::resolve(ServiceData& io_sd) const
147{
148 // Get the chip target from the root cause signature.
149 auto chipTarget = __getRootCauseChipTarget(io_sd);
150
151 // Get the endpoint target for the receiving side of the bus.
152 auto rxTarget = __getUnitTarget(chipTarget, iv_unitPath);
153
154 // Get the endpoint target for the transfer side of the bus.
155 auto txTarget = __getConnectedTarget(rxTarget, iv_busType);
156
157 // Callout the TX endpoint.
158 nlohmann::json txCallout;
159 txCallout["LocationCode"] = util::pdbg::getLocationCode(txTarget);
160 txCallout["Priority"] = iv_priority.getUserDataString();
161 io_sd.addCallout(txCallout);
162
163 // Guard the TX endpoint.
164 Guard txGuard =
165 io_sd.addGuard(util::pdbg::getPhysDevPath(txTarget), iv_guard);
166
167 // Add the callout FFDC to the service data.
168 nlohmann::json ffdc;
169 ffdc["Callout Type"] = "Connected Callout";
170 ffdc["Bus Type"] = iv_busType.getString();
171 ffdc["Target"] = util::pdbg::getPhysDevPath(txTarget);
172 ffdc["Priority"] = iv_priority.getRegistryString();
173 ffdc["Guard Type"] = txGuard.getString();
174 io_sd.addCalloutFFDC(ffdc);
175}
176
177//------------------------------------------------------------------------------
178
Zane Shelley4757a7b2021-09-20 22:23:38 -0500179void BusCalloutResolution::resolve(ServiceData& io_sd) const
180{
181 // Get the chip target from the root cause signature.
182 auto chipTarget = __getRootCauseChipTarget(io_sd);
183
184 // Get the endpoint target for the receiving side of the bus.
185 auto rxTarget = __getUnitTarget(chipTarget, iv_unitPath);
186
187 // Get the endpoint target for the transfer side of the bus.
188 auto txTarget = __getConnectedTarget(rxTarget, iv_busType);
189
190 // Callout the RX endpoint.
191 nlohmann::json rxCallout;
192 rxCallout["LocationCode"] = util::pdbg::getLocationCode(rxTarget);
193 rxCallout["Priority"] = iv_priority.getUserDataString();
194 io_sd.addCallout(rxCallout);
195
196 // Callout the TX endpoint.
197 nlohmann::json txCallout;
198 txCallout["LocationCode"] = util::pdbg::getLocationCode(txTarget);
199 txCallout["Priority"] = iv_priority.getUserDataString();
200 io_sd.addCallout(txCallout);
201
202 // Callout everything else in between.
203 // TODO: For P10 (OMI bus and XBUS), the callout is simply the backplane.
204 // There isn't a devtree object for this, yet. So will need to
205 // hardcode the location code for now. In the future, we will need a
206 // mechanism to make this data driven.
207 nlohmann::json bpCallout;
208 bpCallout["LocationCode"] = "P0";
209 bpCallout["Priority"] = iv_priority.getUserDataString();
210 io_sd.addCallout(bpCallout);
211
212 // Guard the RX endpoint.
213 Guard guard =
214 io_sd.addGuard(util::pdbg::getPhysDevPath(rxTarget), iv_guard);
215
216 // Guard the TX endpoint.
217 // No need to check return because it is the same as RX target.
218 io_sd.addGuard(util::pdbg::getPhysDevPath(txTarget), iv_guard);
219
220 // TODO: Currently no guard for "everything else in between".
221
222 // Add the callout FFDC to the service data.
223 nlohmann::json ffdc;
224 ffdc["Callout Type"] = "Bus Callout";
225 ffdc["Bus Type"] = iv_busType.getString();
226 ffdc["RX Target"] = util::pdbg::getPhysDevPath(rxTarget);
227 ffdc["TX Target"] = util::pdbg::getPhysDevPath(txTarget);
228 ffdc["Priority"] = iv_priority.getRegistryString();
229 ffdc["Guard Type"] = guard.getString();
230 io_sd.addCalloutFFDC(ffdc);
231}
232
233//------------------------------------------------------------------------------
234
Zane Shelley84721d92021-09-08 13:30:27 -0500235void ClockCalloutResolution::resolve(ServiceData& io_sd) const
236{
237 // Add the callout to the service data.
238 // TODO: For P10, the callout is simply the backplane. There isn't a devtree
239 // object for this, yet. So will need to hardcode the location code
240 // for now. In the future, we will need a mechanism to make this data
241 // driven.
242 nlohmann::json callout;
243 callout["LocationCode"] = "P0";
244 callout["Priority"] = iv_priority.getUserDataString();
245 io_sd.addCallout(callout);
246
247 // Add the guard info to the service data.
248 // TODO: Still waiting for clock targets to be defined in the device tree.
249 // For get the processor path for the FFDC.
250 // static const std::map<callout::ClockType, std::string> m = {
251 // {callout::ClockType::OSC_REF_CLOCK_0, ""},
252 // {callout::ClockType::OSC_REF_CLOCK_1, ""},
253 // };
254 // auto target = std::string{util::pdbg::getPath(m.at(iv_clockType))};
255 // auto guardPath = util::pdbg::getPhysDevPath(target);
256 // Guard guard = io_sd.addGuard(guardPath, iv_guard);
Zane Shelley96d54862021-09-17 11:16:12 -0500257 auto target = __getRootCauseChipTarget(io_sd);
Zane Shelley84721d92021-09-08 13:30:27 -0500258 auto guardPath = util::pdbg::getPhysDevPath(target);
259
260 // Add the callout FFDC to the service data.
261 nlohmann::json ffdc;
262 ffdc["Callout Type"] = "Clock Callout";
263 ffdc["Clock Type"] = iv_clockType.getString();
264 ffdc["Target"] = guardPath;
265 ffdc["Priority"] = iv_priority.getRegistryString();
266 ffdc["Guard Type"] = ""; // TODO: guard.getString();
267 io_sd.addCalloutFFDC(ffdc);
268}
269
270//------------------------------------------------------------------------------
271
Zane Shelleyc85716c2021-08-17 10:54:06 -0500272void ProcedureCalloutResolution::resolve(ServiceData& io_sd) const
273{
274 // Add the actual callout to the service data.
275 nlohmann::json callout;
276 callout["Procedure"] = iv_procedure.getString();
277 callout["Priority"] = iv_priority.getUserDataString();
278 io_sd.addCallout(callout);
Zane Shelley2d114322021-08-25 17:06:12 -0500279
280 // Add the callout FFDC to the service data.
281 nlohmann::json ffdc;
282 ffdc["Callout Type"] = "Procedure Callout";
283 ffdc["Procedure"] = iv_procedure.getString();
284 ffdc["Priority"] = iv_priority.getRegistryString();
285 io_sd.addCalloutFFDC(ffdc);
Zane Shelleyc85716c2021-08-17 10:54:06 -0500286}
287
288//------------------------------------------------------------------------------
289
Zane Shelley0b8368c2021-03-18 17:33:41 -0500290} // namespace analyzer