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