blob: 3183216456755645c2a375f8d7d86aaabc73f452 [file] [log] [blame]
Zane Shelley15527a42021-12-16 21:43:13 -06001#include <analyzer/plugins/plugin.hpp>
Zane Shelley0b8368c2021-03-18 17:33:41 -05002#include <analyzer/resolution.hpp>
Zane Shelley236bb732021-03-24 17:07:46 -05003#include <util/pdbg.hpp>
4#include <util/trace.hpp>
Zane Shelley0b8368c2021-03-18 17:33:41 -05005
6namespace analyzer
7{
8
Zane Shelley2d114322021-08-25 17:06:12 -05009//------------------------------------------------------------------------------
10
Zane Shelley96d54862021-09-17 11:16:12 -050011// Helper function to get the root cause chip target from the service data.
12pdbg_target* __getRootCauseChipTarget(const ServiceData& i_sd)
Zane Shelley0b8368c2021-03-18 17:33:41 -050013{
Zane Shelley96d54862021-09-17 11:16:12 -050014 auto target = util::pdbg::getTrgt(i_sd.getRootCause().getChip());
15 assert(nullptr != target); // This would be a really bad bug.
16 return target;
17}
Zane Shelley236bb732021-03-24 17:07:46 -050018
Zane Shelley96d54862021-09-17 11:16:12 -050019//------------------------------------------------------------------------------
20
21// Helper function to get a unit target from the given unit path, which is a
22// devtree path relative the the containing chip. An empty string indicates the
23// chip target should be returned.
24pdbg_target* __getUnitTarget(pdbg_target* i_chipTarget,
25 const std::string& i_unitPath)
26{
27 assert(nullptr != i_chipTarget);
28
29 auto target = i_chipTarget; // default, if i_unitPath is empty
30
31 if (!i_unitPath.empty())
Zane Shelley236bb732021-03-24 17:07:46 -050032 {
Zane Shelley96d54862021-09-17 11:16:12 -050033 auto path = std::string{util::pdbg::getPath(target)} + "/" + i_unitPath;
34
35 target = util::pdbg::getTrgt(path);
36 if (nullptr == target)
Zane Shelley236bb732021-03-24 17:07:46 -050037 {
Zane Shelley96d54862021-09-17 11:16:12 -050038 // Likely a bug the RAS data files.
39 throw std::logic_error("Unable to find target for " + path);
Zane Shelley236bb732021-03-24 17:07:46 -050040 }
41 }
42
Zane Shelley96d54862021-09-17 11:16:12 -050043 return target;
44}
45
46//------------------------------------------------------------------------------
47
Zane Shelley5d63cef2021-09-17 18:10:17 -050048// Helper function to get the connected target on the other side of the
49// given bus.
50pdbg_target* __getConnectedTarget(pdbg_target* i_rxTarget,
51 const callout::BusType& i_busType)
52{
53 assert(nullptr != i_rxTarget);
54
55 pdbg_target* txTarget = nullptr;
56
57 auto rxType = util::pdbg::getTrgtType(i_rxTarget);
58 std::string rxPath = util::pdbg::getPath(i_rxTarget);
59
60 if (callout::BusType::SMP_BUS == i_busType &&
61 util::pdbg::TYPE_IOLINK == rxType)
62 {
63 // TODO: Will need to reference some sort of data that can tell us how
64 // the processors are connected in the system. For now, return the
65 // RX target to avoid returning a nullptr.
66 trace::inf("No support to get peer target on SMP bus");
67 txTarget = i_rxTarget;
68 }
Zane Shelleybe619c02021-09-30 17:56:42 -050069 else if (callout::BusType::SMP_BUS == i_busType &&
70 util::pdbg::TYPE_IOHS == rxType)
71 {
72 // TODO: Will need to reference some sort of data that can tell us how
73 // the processors are connected in the system. For now, return the
74 // RX target to avoid returning a nullptr.
75 trace::inf("No support to get peer target on SMP bus");
76 txTarget = i_rxTarget;
77 }
Zane Shelley5d63cef2021-09-17 18:10:17 -050078 else if (callout::BusType::OMI_BUS == i_busType &&
79 util::pdbg::TYPE_OMI == rxType)
80 {
81 // This is a bit clunky. The pdbg APIs only give us the ability to
82 // iterate over the children instead of just returning a list. So we'll
83 // push all the children to a list and go from there.
84 std::vector<pdbg_target*> childList;
85
86 pdbg_target* childTarget = nullptr;
87 pdbg_for_each_target("ocmb", i_rxTarget, childTarget)
88 {
89 if (nullptr != childTarget)
90 {
91 childList.push_back(childTarget);
92 }
93 }
94
95 // We know there should only be one OCMB per OMI.
96 if (1 != childList.size())
97 {
98 throw std::logic_error("Invalid child list size for " + rxPath);
99 }
100
101 // Get the connected target.
102 txTarget = childList.front();
103 }
104 else if (callout::BusType::OMI_BUS == i_busType &&
105 util::pdbg::TYPE_OCMB == rxType)
106 {
107 txTarget = pdbg_target_parent("omi", i_rxTarget);
108 if (nullptr == txTarget)
109 {
110 throw std::logic_error("No parent OMI found for " + rxPath);
111 }
112 }
113 else
114 {
115 // This would be a code bug.
116 throw std::logic_error("Unsupported config: i_rxTarget=" + rxPath +
117 " i_busType=" + i_busType.getString());
118 }
119
120 assert(nullptr != txTarget); // just in case we missed something above
121
122 return txTarget;
123}
124
125//------------------------------------------------------------------------------
126
Zane Shelley9a738f72021-11-03 20:45:30 -0500127void __calloutTarget(ServiceData& io_sd, pdbg_target* i_target,
128 const callout::Priority& i_priority, bool i_guard)
129{
130 nlohmann::json callout;
131 callout["LocationCode"] = util::pdbg::getLocationCode(i_target);
132 callout["Priority"] = i_priority.getUserDataString();
133 callout["Deconfigured"] = false;
Zane Shelleybf3326f2021-11-12 13:41:39 -0600134 callout["Guarded"] = false; // default
135
136 // Check if guard info should be added.
137 if (i_guard)
138 {
139 auto guardType = io_sd.queryGuardPolicy();
140
141 if (!(callout::GuardType::NONE == guardType))
142 {
143 callout["Guarded"] = true;
144 callout["EntityPath"] = util::pdbg::getPhysBinPath(i_target);
145 callout["GuardType"] = guardType.getString();
146 }
147 }
148
Zane Shelley9a738f72021-11-03 20:45:30 -0500149 io_sd.addCallout(callout);
150}
151
152//------------------------------------------------------------------------------
153
Zane Shelley1eff9452021-11-03 13:59:54 -0500154void __calloutBackplane(ServiceData& io_sd, const callout::Priority& i_priority)
155{
156 // TODO: There isn't a device tree object for this. So will need to hardcode
157 // the location code for now. In the future, we will need a mechanism
158 // to make this data driven.
159
160 nlohmann::json callout;
161 callout["LocationCode"] = "P0";
162 callout["Priority"] = i_priority.getUserDataString();
163 callout["Deconfigured"] = false;
164 callout["Guarded"] = false;
165 io_sd.addCallout(callout);
166}
167
168//------------------------------------------------------------------------------
169
Zane Shelley96d54862021-09-17 11:16:12 -0500170void HardwareCalloutResolution::resolve(ServiceData& io_sd) const
171{
172 // Get the target for the hardware callout.
173 auto target = __getUnitTarget(__getRootCauseChipTarget(io_sd), iv_unitPath);
174
Zane Shelleyc85716c2021-08-17 10:54:06 -0500175 // Add the actual callout to the service data.
Zane Shelley9a738f72021-11-03 20:45:30 -0500176 __calloutTarget(io_sd, target, iv_priority, iv_guard);
Zane Shelley236bb732021-03-24 17:07:46 -0500177
Zane Shelley2d114322021-08-25 17:06:12 -0500178 // Add the callout FFDC to the service data.
179 nlohmann::json ffdc;
180 ffdc["Callout Type"] = "Hardware Callout";
Zane Shelleya00426f2021-11-04 10:50:50 -0500181 ffdc["Target"] = util::pdbg::getPhysDevPath(target);
Zane Shelley2d114322021-08-25 17:06:12 -0500182 ffdc["Priority"] = iv_priority.getRegistryString();
Zane Shelleya00426f2021-11-04 10:50:50 -0500183 ffdc["Guard"] = iv_guard;
Zane Shelley2d114322021-08-25 17:06:12 -0500184 io_sd.addCalloutFFDC(ffdc);
Zane Shelley0b8368c2021-03-18 17:33:41 -0500185}
186
Zane Shelleyc85716c2021-08-17 10:54:06 -0500187//------------------------------------------------------------------------------
188
Zane Shelley5d63cef2021-09-17 18:10:17 -0500189void ConnectedCalloutResolution::resolve(ServiceData& io_sd) const
190{
191 // Get the chip target from the root cause signature.
192 auto chipTarget = __getRootCauseChipTarget(io_sd);
193
194 // Get the endpoint target for the receiving side of the bus.
195 auto rxTarget = __getUnitTarget(chipTarget, iv_unitPath);
196
197 // Get the endpoint target for the transfer side of the bus.
198 auto txTarget = __getConnectedTarget(rxTarget, iv_busType);
199
200 // Callout the TX endpoint.
Zane Shelley9a738f72021-11-03 20:45:30 -0500201 __calloutTarget(io_sd, txTarget, iv_priority, iv_guard);
Zane Shelley5d63cef2021-09-17 18:10:17 -0500202
Zane Shelley5d63cef2021-09-17 18:10:17 -0500203 // Add the callout FFDC to the service data.
204 nlohmann::json ffdc;
205 ffdc["Callout Type"] = "Connected Callout";
206 ffdc["Bus Type"] = iv_busType.getString();
207 ffdc["Target"] = util::pdbg::getPhysDevPath(txTarget);
208 ffdc["Priority"] = iv_priority.getRegistryString();
Zane Shelleya00426f2021-11-04 10:50:50 -0500209 ffdc["Guard"] = iv_guard;
Zane Shelley5d63cef2021-09-17 18:10:17 -0500210 io_sd.addCalloutFFDC(ffdc);
211}
212
213//------------------------------------------------------------------------------
214
Zane Shelley4757a7b2021-09-20 22:23:38 -0500215void BusCalloutResolution::resolve(ServiceData& io_sd) const
216{
217 // Get the chip target from the root cause signature.
218 auto chipTarget = __getRootCauseChipTarget(io_sd);
219
220 // Get the endpoint target for the receiving side of the bus.
221 auto rxTarget = __getUnitTarget(chipTarget, iv_unitPath);
222
223 // Get the endpoint target for the transfer side of the bus.
224 auto txTarget = __getConnectedTarget(rxTarget, iv_busType);
225
226 // Callout the RX endpoint.
Zane Shelley9a738f72021-11-03 20:45:30 -0500227 __calloutTarget(io_sd, rxTarget, iv_priority, iv_guard);
Zane Shelley4757a7b2021-09-20 22:23:38 -0500228
229 // Callout the TX endpoint.
Zane Shelley9a738f72021-11-03 20:45:30 -0500230 __calloutTarget(io_sd, txTarget, iv_priority, iv_guard);
Zane Shelley4757a7b2021-09-20 22:23:38 -0500231
232 // Callout everything else in between.
233 // TODO: For P10 (OMI bus and XBUS), the callout is simply the backplane.
Zane Shelley1eff9452021-11-03 13:59:54 -0500234 __calloutBackplane(io_sd, iv_priority);
Zane Shelley4757a7b2021-09-20 22:23:38 -0500235
Zane Shelley4757a7b2021-09-20 22:23:38 -0500236 // Add the callout FFDC to the service data.
237 nlohmann::json ffdc;
238 ffdc["Callout Type"] = "Bus Callout";
239 ffdc["Bus Type"] = iv_busType.getString();
240 ffdc["RX Target"] = util::pdbg::getPhysDevPath(rxTarget);
241 ffdc["TX Target"] = util::pdbg::getPhysDevPath(txTarget);
242 ffdc["Priority"] = iv_priority.getRegistryString();
Zane Shelleya00426f2021-11-04 10:50:50 -0500243 ffdc["Guard"] = iv_guard;
Zane Shelley4757a7b2021-09-20 22:23:38 -0500244 io_sd.addCalloutFFDC(ffdc);
245}
246
247//------------------------------------------------------------------------------
248
Zane Shelley84721d92021-09-08 13:30:27 -0500249void ClockCalloutResolution::resolve(ServiceData& io_sd) const
250{
Zane Shelley1eff9452021-11-03 13:59:54 -0500251 // Callout the clock target.
252 // TODO: For P10, the callout is simply the backplane. Also, there are no
253 // clock targets in the device tree. So at the moment there is no
254 // guard support for clock targets.
255 __calloutBackplane(io_sd, iv_priority);
Zane Shelley84721d92021-09-08 13:30:27 -0500256
257 // Add the callout FFDC to the service data.
Zane Shelley1eff9452021-11-03 13:59:54 -0500258 // TODO: Add the target and guard type if guard is ever supported.
Zane Shelley84721d92021-09-08 13:30:27 -0500259 nlohmann::json ffdc;
260 ffdc["Callout Type"] = "Clock Callout";
261 ffdc["Clock Type"] = iv_clockType.getString();
Zane Shelley84721d92021-09-08 13:30:27 -0500262 ffdc["Priority"] = iv_priority.getRegistryString();
Zane Shelley84721d92021-09-08 13:30:27 -0500263 io_sd.addCalloutFFDC(ffdc);
264}
265
266//------------------------------------------------------------------------------
267
Zane Shelleyc85716c2021-08-17 10:54:06 -0500268void ProcedureCalloutResolution::resolve(ServiceData& io_sd) const
269{
270 // Add the actual callout to the service data.
271 nlohmann::json callout;
272 callout["Procedure"] = iv_procedure.getString();
273 callout["Priority"] = iv_priority.getUserDataString();
274 io_sd.addCallout(callout);
Zane Shelley2d114322021-08-25 17:06:12 -0500275
276 // Add the callout FFDC to the service data.
277 nlohmann::json ffdc;
278 ffdc["Callout Type"] = "Procedure Callout";
279 ffdc["Procedure"] = iv_procedure.getString();
280 ffdc["Priority"] = iv_priority.getRegistryString();
281 io_sd.addCalloutFFDC(ffdc);
Zane Shelleyc85716c2021-08-17 10:54:06 -0500282}
283
284//------------------------------------------------------------------------------
285
Zane Shelley15527a42021-12-16 21:43:13 -0600286void PluginResolution::resolve(ServiceData& io_sd) const
Zane Shelleye13a9f92021-12-16 21:19:11 -0600287{
Zane Shelley15527a42021-12-16 21:43:13 -0600288 // Get the plugin function and call it.
289
290 auto chip = io_sd.getRootCause().getChip();
291
292 auto func = PluginMap::getSingleton().get(chip.getType(), iv_name);
293
294 func(iv_instance, chip, io_sd);
Zane Shelleye13a9f92021-12-16 21:19:11 -0600295}
296
297//------------------------------------------------------------------------------
298
Zane Shelley0b8368c2021-03-18 17:33:41 -0500299} // namespace analyzer