blob: e544b6e538aefa126468aee9f149690720925eac [file] [log] [blame]
Zane Shelley979e2872021-09-20 22:46:06 -05001#include <analyzer/service_data.hpp>
2
3namespace analyzer
4{
5
Zane Shelley37acb282022-01-10 16:05:22 -06006//------------------------------------------------------------------------------
7
8void ServiceData::calloutTarget(pdbg_target* i_target,
9 const callout::Priority& i_priority,
10 bool i_guard)
11{
12 // Add the target to the callout list.
13 addTargetCallout(i_target, i_priority, i_guard);
14
15 // Add the callout FFDC.
16 nlohmann::json ffdc;
17 ffdc["Callout Type"] = "Hardware Callout";
18 ffdc["Target"] = util::pdbg::getPhysDevPath(i_target);
19 ffdc["Priority"] = i_priority.getRegistryString();
20 ffdc["Guard"] = i_guard;
21 addCalloutFFDC(ffdc);
22}
23
24//------------------------------------------------------------------------------
25
26void ServiceData::calloutConnected(pdbg_target* i_rxTarget,
27 const callout::BusType& i_busType,
28 const callout::Priority& i_priority,
29 bool i_guard)
30{
31 // Get the endpoint target for the transfer side of the bus.
32 auto txTarget = util::pdbg::getConnectedTarget(i_rxTarget, i_busType);
33
34 // Callout the TX endpoint.
35 addTargetCallout(txTarget, i_priority, i_guard);
36
37 // Add the callout FFDC.
38 nlohmann::json ffdc;
39 ffdc["Callout Type"] = "Connected Callout";
40 ffdc["Bus Type"] = i_busType.getString();
41 ffdc["RX Target"] = util::pdbg::getPhysDevPath(i_rxTarget);
42 ffdc["TX Target"] = util::pdbg::getPhysDevPath(txTarget);
43 ffdc["Priority"] = i_priority.getRegistryString();
44 ffdc["Guard"] = i_guard;
45 addCalloutFFDC(ffdc);
46}
47
48//------------------------------------------------------------------------------
49
50void ServiceData::calloutBus(pdbg_target* i_rxTarget,
51 const callout::BusType& i_busType,
52 const callout::Priority& i_priority, bool i_guard)
53{
54 // Get the endpoint target for the transfer side of the bus.
55 auto txTarget = util::pdbg::getConnectedTarget(i_rxTarget, i_busType);
56
57 // Callout the RX endpoint.
58 addTargetCallout(i_rxTarget, i_priority, i_guard);
59
60 // Callout the TX endpoint.
61 addTargetCallout(txTarget, i_priority, i_guard);
62
63 // Callout everything else in between.
64 // TODO: For P10 (OMI bus and XBUS), the callout is simply the backplane.
65 addBackplaneCallout(i_priority);
66
67 // Add the callout FFDC.
68 nlohmann::json ffdc;
69 ffdc["Callout Type"] = "Bus Callout";
70 ffdc["Bus Type"] = i_busType.getString();
71 ffdc["RX Target"] = util::pdbg::getPhysDevPath(i_rxTarget);
72 ffdc["TX Target"] = util::pdbg::getPhysDevPath(txTarget);
73 ffdc["Priority"] = i_priority.getRegistryString();
74 ffdc["Guard"] = i_guard;
75 addCalloutFFDC(ffdc);
76}
77
78//------------------------------------------------------------------------------
79
80void ServiceData::calloutClock(const callout::ClockType& i_clockType,
81 const callout::Priority& i_priority, bool)
82{
83 // Callout the clock target.
84 // TODO: For P10, the callout is simply the backplane. Also, there are no
85 // clock targets in the device tree. So at the moment there is no
86 // guard support for clock targets.
87 addBackplaneCallout(i_priority);
88
89 // Add the callout FFDC.
90 // TODO: Add the target and guard type if guard is ever supported.
91 nlohmann::json ffdc;
92 ffdc["Callout Type"] = "Clock Callout";
93 ffdc["Clock Type"] = i_clockType.getString();
94 ffdc["Priority"] = i_priority.getRegistryString();
95 addCalloutFFDC(ffdc);
96}
97
98//------------------------------------------------------------------------------
99
100void ServiceData::calloutProcedure(const callout::Procedure& i_procedure,
101 const callout::Priority& i_priority)
102{
103 // Add the actual callout to the service data.
104 nlohmann::json callout;
105 callout["Procedure"] = i_procedure.getString();
106 callout["Priority"] = i_priority.getUserDataString();
107 addCallout(callout);
108
109 // Add the callout FFDC.
110 nlohmann::json ffdc;
111 ffdc["Callout Type"] = "Procedure Callout";
112 ffdc["Procedure"] = i_procedure.getString();
113 ffdc["Priority"] = i_priority.getRegistryString();
114 addCalloutFFDC(ffdc);
115}
116
117//------------------------------------------------------------------------------
118
Zane Shelley979e2872021-09-20 22:46:06 -0500119void ServiceData::addCallout(const nlohmann::json& i_callout)
120{
121 // The new callout is either a hardware callout with a location code or a
122 // procedure callout.
123
124 std::string type{};
125 if (i_callout.contains("LocationCode"))
126 {
127 type = "LocationCode";
128 }
129 else if (i_callout.contains("Procedure"))
130 {
131 type = "Procedure";
132 }
133 else
134 {
135 throw std::logic_error("Unsupported callout: " + i_callout.dump());
136 }
137
138 // A map to determine the priority order. All of the medium priorities,
139 // including the medium group priorities, are all the same level.
140 static const std::map<std::string, unsigned int> m = {
141 {"H", 3}, {"M", 2}, {"A", 2}, {"B", 2}, {"C", 2}, {"L", 1},
142 };
143
144 bool addCallout = true;
145
146 for (auto& c : iv_calloutList)
147 {
148 if (c.contains(type) && (c.at(type) == i_callout.at(type)))
149 {
150 // The new callout already exists. Don't add a new callout.
151 addCallout = false;
152
153 if (m.at(c.at("Priority")) < m.at(i_callout.at("Priority")))
154 {
155 // The new callout has a higher priority, update it.
156 c["Priority"] = i_callout.at("Priority");
157 }
158 }
159 }
160
161 if (addCallout)
162 {
163 iv_calloutList.push_back(i_callout);
164 }
165}
166
Zane Shelley37acb282022-01-10 16:05:22 -0600167//------------------------------------------------------------------------------
168
169void ServiceData::addTargetCallout(pdbg_target* i_target,
170 const callout::Priority& i_priority,
171 bool i_guard)
172{
173 nlohmann::json callout;
174
175 callout["LocationCode"] = util::pdbg::getLocationCode(i_target);
176 callout["Priority"] = i_priority.getUserDataString();
177 callout["Deconfigured"] = false;
178 callout["Guarded"] = false; // default
179
180 // Check if guard info should be added.
181 if (i_guard)
182 {
183 auto guardType = queryGuardPolicy();
184
185 if (!(callout::GuardType::NONE == guardType))
186 {
187 callout["Guarded"] = true;
188 callout["EntityPath"] = util::pdbg::getPhysBinPath(i_target);
189 callout["GuardType"] = guardType.getString();
190 }
191 }
192
193 addCallout(callout);
194}
195
196//------------------------------------------------------------------------------
197
198void ServiceData::addBackplaneCallout(const callout::Priority& i_priority)
199{
200 // TODO: There isn't a device tree object for this. So will need to hardcode
201 // the location code for now. In the future, we will need a mechanism
202 // to make this data driven.
203
204 nlohmann::json callout;
205
206 callout["LocationCode"] = "P0";
207 callout["Priority"] = i_priority.getUserDataString();
208 callout["Deconfigured"] = false;
209 callout["Guarded"] = false;
210
211 addCallout(callout);
212}
213
214//------------------------------------------------------------------------------
215
Zane Shelley979e2872021-09-20 22:46:06 -0500216} // namespace analyzer