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