blob: 03c80371e6230d3218a0d32ec43f5dd3d2c5a0e4 [file] [log] [blame]
Zane Shelley171a2e02020-11-13 13:56:13 -06001#include <assert.h>
2
Zane Shelley7ae9c8c2020-12-02 20:10:31 -06003#include <hei_main.hpp>
Zane Shelleyf4bd5ff2020-11-05 22:26:04 -06004#include <util/pdbg.hpp>
Zane Shelley171a2e02020-11-13 13:56:13 -06005#include <util/trace.hpp>
Zane Shelleyf4bd5ff2020-11-05 22:26:04 -06006
Zane Shelley3a851082021-03-23 16:45:28 -05007#ifdef CONFIG_PHAL_API
8#include <attribute_info.H>
9#endif
10
Zane Shelleyf4bd5ff2020-11-05 22:26:04 -060011namespace util
12{
13
14namespace pdbg
15{
16
17//------------------------------------------------------------------------------
18
Zane Shelleya0299852020-11-13 13:38:04 -060019pdbg_target* getTrgt(const libhei::Chip& i_chip)
20{
21 return (pdbg_target*)i_chip.getChip();
22}
23
24//------------------------------------------------------------------------------
25
26const char* getPath(pdbg_target* i_trgt)
27{
28 return pdbg_target_path(i_trgt);
29}
30
Zane Shelleyf4bd5ff2020-11-05 22:26:04 -060031const char* getPath(const libhei::Chip& i_chip)
32{
Zane Shelleya0299852020-11-13 13:38:04 -060033 return getPath(getTrgt(i_chip));
34}
35
36//------------------------------------------------------------------------------
37
38uint32_t getChipPos(pdbg_target* i_trgt)
39{
40 uint32_t attr = 0;
41 pdbg_target_get_attribute(i_trgt, "ATTR_FAPI_POS", 4, 1, &attr);
42 return attr;
43}
44
45uint32_t getChipPos(const libhei::Chip& i_chip)
46{
47 return getChipPos(getTrgt(i_chip));
48}
49
50//------------------------------------------------------------------------------
51
52uint8_t getTrgtType(pdbg_target* i_trgt)
53{
54 uint8_t attr = 0;
55 pdbg_target_get_attribute(i_trgt, "ATTR_TYPE", 1, 1, &attr);
56 return attr;
57}
58
59uint8_t getTrgtType(const libhei::Chip& i_chip)
60{
61 return getTrgtType(getTrgt(i_chip));
Zane Shelleyf4bd5ff2020-11-05 22:26:04 -060062}
63
64//------------------------------------------------------------------------------
65
Zane Shelley171a2e02020-11-13 13:56:13 -060066pdbg_target* getPibTrgt(pdbg_target* i_procTrgt)
67{
68 // The input target must be a processor.
Zane Shelley35171d92020-12-03 13:31:13 -060069 assert(TYPE_PROC == getTrgtType(i_procTrgt));
Zane Shelley171a2e02020-11-13 13:56:13 -060070
71 // Get the pib path.
72 char path[16];
73 sprintf(path, "/proc%d/pib", pdbg_target_index(i_procTrgt));
74
75 // Return the pib target.
76 pdbg_target* pibTrgt = pdbg_target_from_path(nullptr, path);
77 assert(nullptr != pibTrgt);
78
79 return pibTrgt;
80}
81
82//------------------------------------------------------------------------------
83
Zane Shelleyff76b6b2020-11-18 13:54:26 -060084pdbg_target* getFsiTrgt(pdbg_target* i_procTrgt)
85{
86 // The input target must be a processor.
Zane Shelley35171d92020-12-03 13:31:13 -060087 assert(TYPE_PROC == getTrgtType(i_procTrgt));
Zane Shelleyff76b6b2020-11-18 13:54:26 -060088
89 // Get the fsi path.
90 char path[16];
91 sprintf(path, "/proc%d/fsi", pdbg_target_index(i_procTrgt));
92
93 // Return the fsi target.
94 pdbg_target* fsiTrgt = pdbg_target_from_path(nullptr, path);
95 assert(nullptr != fsiTrgt);
96
97 return fsiTrgt;
98}
99
100//------------------------------------------------------------------------------
101
Zane Shelley35171d92020-12-03 13:31:13 -0600102int getCfam(pdbg_target* i_trgt, uint32_t i_addr, uint32_t& o_val)
103{
104 // Only processor targets are supported.
105 assert(TYPE_PROC == getTrgtType(i_trgt));
106
107 auto fsiTrgt = util::pdbg::getFsiTrgt(i_trgt);
108
109 int rc = fsi_read(fsiTrgt, i_addr, &o_val);
110
111 if (0 != rc)
112 {
113 trace::err("fsi_read failure: trgt=%s addr=0x%08x",
114 util::pdbg::getPath(fsiTrgt), i_addr);
115 }
116
117 return rc;
118}
119
120//------------------------------------------------------------------------------
121
122// IMPORTANT:
123// The ATTR_CHIP_ID attribute will be synced from Hostboot to the BMC at some
124// point during the IPL. It is possible that this information is needed before
125// the sync occurs, in which case the value will return 0.
Zane Shelley171a2e02020-11-13 13:56:13 -0600126uint32_t __getChipId(pdbg_target* i_trgt)
127{
128 uint32_t attr = 0;
129 pdbg_target_get_attribute(i_trgt, "ATTR_CHIP_ID", 4, 1, &attr);
130 return attr;
131}
132
Zane Shelley35171d92020-12-03 13:31:13 -0600133// IMPORTANT:
134// The ATTR_EC attribute will be synced from Hostboot to the BMC at some point
135// during the IPL. It is possible that this information is needed before the
136// sync occurs, in which case the value will return 0.
Zane Shelley171a2e02020-11-13 13:56:13 -0600137uint8_t __getChipEc(pdbg_target* i_trgt)
138{
139 uint8_t attr = 0;
140 pdbg_target_get_attribute(i_trgt, "ATTR_EC", 1, 1, &attr);
141 return attr;
142}
143
144uint32_t __getChipIdEc(pdbg_target* i_trgt)
145{
Zane Shelley35171d92020-12-03 13:31:13 -0600146 auto chipId = __getChipId(i_trgt);
147 auto chipEc = __getChipEc(i_trgt);
148
149 if (((0 == chipId) || (0 == chipEc)) && (TYPE_PROC == getTrgtType(i_trgt)))
150 {
151 // There is a special case where the model/level attributes have not
152 // been initialized in the devtree. This is possible on the epoch IPL
153 // where an attention occurs before Hostboot is able to update the
154 // devtree information on the BMC. It may is still possible to get this
155 // information from chips with CFAM access (i.e. a processor) via the
156 // CFAM chip ID register.
157
158 uint32_t val = 0;
159 if (0 == getCfam(i_trgt, 0x100a, val))
160 {
161 chipId = ((val & 0x0F0FF000) >> 12);
162 chipEc = ((val & 0xF0000000) >> 24) | ((val & 0x00F00000) >> 20);
163 }
164 }
165
166 return ((chipId & 0xffff) << 16) | (chipEc & 0xff);
Zane Shelley171a2e02020-11-13 13:56:13 -0600167}
168
169void __addChip(std::vector<libhei::Chip>& o_chips, pdbg_target* i_trgt,
170 libhei::ChipType_t i_type)
171{
172 // Trace each chip for debug. It is important to show the type just in case
173 // the model/EC does not exist. See note below.
174 trace::inf("Chip found: type=0x%08" PRIx32 " chip=%s", i_type,
175 getPath(i_trgt));
176
177 if (0 == i_type)
178 {
Zane Shelley35171d92020-12-03 13:31:13 -0600179 // This is a special case. See the details in __getChipIdEC(). There is
180 // nothing more we can do with this chip since we don't know what it is.
181 // So ignore the chip for now.
Zane Shelley171a2e02020-11-13 13:56:13 -0600182 }
183 else
184 {
185 o_chips.emplace_back(i_trgt, i_type);
186 }
187}
188
189void getActiveChips(std::vector<libhei::Chip>& o_chips)
190{
191 o_chips.clear();
192
193 // Iterate each processor.
194 pdbg_target* procTrgt;
195 pdbg_for_each_class_target("proc", procTrgt)
196 {
197 // We cannot use the proc target to determine if the chip is active.
198 // There is some design limitation in pdbg that requires the proc
199 // targets to always be active. Instead, we must get the associated pib
200 // target and check if it is active.
201
202 // Active processors only.
203 if (PDBG_TARGET_ENABLED != pdbg_target_probe(getPibTrgt(procTrgt)))
204 continue;
205
206 // Add the processor to the list.
207 __addChip(o_chips, procTrgt, __getChipIdEc(procTrgt));
208
209 // Iterate the connected OCMBs, if they exist.
210 pdbg_target* ocmbTrgt;
211 pdbg_for_each_target("ocmb", procTrgt, ocmbTrgt)
212 {
213 // Active OCMBs only.
214 if (PDBG_TARGET_ENABLED != pdbg_target_probe(ocmbTrgt))
215 continue;
216
217 // Add the OCMB to the list.
218 __addChip(o_chips, ocmbTrgt, __getChipIdEc(ocmbTrgt));
219 }
220 }
221}
222
223//------------------------------------------------------------------------------
224
Zane Shelley7ae9c8c2020-12-02 20:10:31 -0600225bool queryHardwareAnalysisSupported()
226{
227 // Hardware analysis is only supported on P10 systems and up.
Zane Shelley5183af32020-12-07 14:49:03 -0600228 return (PDBG_PROC_P9 < pdbg_get_proc());
Zane Shelley7ae9c8c2020-12-02 20:10:31 -0600229}
230
231//------------------------------------------------------------------------------
232
Zane Shelley3a851082021-03-23 16:45:28 -0500233std::string getLocationCode(pdbg_target* trgt)
234{
235 if (nullptr == trgt)
236 {
237 // Either the path is wrong or the attribute doesn't exist.
238 return std::string{};
239 }
240
241#ifdef CONFIG_PHAL_API
242
243 ATTR_LOCATION_CODE_Type val;
244 if (DT_GET_PROP(ATTR_LOCATION_CODE, trgt, val))
245 {
246 // Get the immediate parent in the devtree path and try again.
247 return getLocationCode(pdbg_target_parent(nullptr, trgt));
248 }
249
250 // Attribute found.
251 return std::string{val};
252
253#else
254
255 return std::string{getPath(trgt)};
256
257#endif
258}
259
260//------------------------------------------------------------------------------
261
262std::string getPhysDevPath(pdbg_target* trgt)
263{
264 if (nullptr == trgt)
265 {
266 // Either the path is wrong or the attribute doesn't exist.
267 return std::string{};
268 }
269
270#ifdef CONFIG_PHAL_API
271
272 ATTR_PHYS_DEV_PATH_Type val;
273 if (DT_GET_PROP(ATTR_PHYS_DEV_PATH, trgt, val))
274 {
275 // Get the immediate parent in the devtree path and try again.
276 return getPhysDevPath(pdbg_target_parent(nullptr, trgt));
277 }
278
279 // Attribute found.
280 return std::string{val};
281
282#else
283
284 return std::string{getPath(trgt)};
285
286#endif
287}
288
289//------------------------------------------------------------------------------
290
Zane Shelleyf4bd5ff2020-11-05 22:26:04 -0600291} // namespace pdbg
292
293} // namespace util