xref: /openbmc/openpower-hw-diags/util/pdbg.cpp (revision ff76b6b4)
1 #include <assert.h>
2 
3 #include <util/pdbg.hpp>
4 #include <util/trace.hpp>
5 
6 namespace util
7 {
8 
9 namespace pdbg
10 {
11 
12 //------------------------------------------------------------------------------
13 
14 pdbg_target* getTrgt(const libhei::Chip& i_chip)
15 {
16     return (pdbg_target*)i_chip.getChip();
17 }
18 
19 //------------------------------------------------------------------------------
20 
21 const char* getPath(pdbg_target* i_trgt)
22 {
23     return pdbg_target_path(i_trgt);
24 }
25 
26 const char* getPath(const libhei::Chip& i_chip)
27 {
28     return getPath(getTrgt(i_chip));
29 }
30 
31 //------------------------------------------------------------------------------
32 
33 uint32_t getChipPos(pdbg_target* i_trgt)
34 {
35     uint32_t attr = 0;
36     pdbg_target_get_attribute(i_trgt, "ATTR_FAPI_POS", 4, 1, &attr);
37     return attr;
38 }
39 
40 uint32_t getChipPos(const libhei::Chip& i_chip)
41 {
42     return getChipPos(getTrgt(i_chip));
43 }
44 
45 //------------------------------------------------------------------------------
46 
47 uint8_t getTrgtType(pdbg_target* i_trgt)
48 {
49     uint8_t attr = 0;
50     pdbg_target_get_attribute(i_trgt, "ATTR_TYPE", 1, 1, &attr);
51     return attr;
52 }
53 
54 uint8_t getTrgtType(const libhei::Chip& i_chip)
55 {
56     return getTrgtType(getTrgt(i_chip));
57 }
58 
59 //------------------------------------------------------------------------------
60 
61 pdbg_target* getPibTrgt(pdbg_target* i_procTrgt)
62 {
63     // The input target must be a processor.
64     assert(0x05 == getTrgtType(i_procTrgt));
65 
66     // Get the pib path.
67     char path[16];
68     sprintf(path, "/proc%d/pib", pdbg_target_index(i_procTrgt));
69 
70     // Return the pib target.
71     pdbg_target* pibTrgt = pdbg_target_from_path(nullptr, path);
72     assert(nullptr != pibTrgt);
73 
74     return pibTrgt;
75 }
76 
77 //------------------------------------------------------------------------------
78 
79 pdbg_target* getFsiTrgt(pdbg_target* i_procTrgt)
80 {
81     // The input target must be a processor.
82     assert(0x05 == getTrgtType(i_procTrgt));
83 
84     // Get the fsi path.
85     char path[16];
86     sprintf(path, "/proc%d/fsi", pdbg_target_index(i_procTrgt));
87 
88     // Return the fsi target.
89     pdbg_target* fsiTrgt = pdbg_target_from_path(nullptr, path);
90     assert(nullptr != fsiTrgt);
91 
92     return fsiTrgt;
93 }
94 
95 //------------------------------------------------------------------------------
96 
97 uint32_t __getChipId(pdbg_target* i_trgt)
98 {
99     uint32_t attr = 0;
100     pdbg_target_get_attribute(i_trgt, "ATTR_CHIP_ID", 4, 1, &attr);
101     return attr;
102 }
103 
104 uint8_t __getChipEc(pdbg_target* i_trgt)
105 {
106     uint8_t attr = 0;
107     pdbg_target_get_attribute(i_trgt, "ATTR_EC", 1, 1, &attr);
108     return attr;
109 }
110 
111 uint32_t __getChipIdEc(pdbg_target* i_trgt)
112 {
113     return ((__getChipId(i_trgt) & 0xffff) << 16) | __getChipEc(i_trgt);
114 }
115 
116 void __addChip(std::vector<libhei::Chip>& o_chips, pdbg_target* i_trgt,
117                libhei::ChipType_t i_type)
118 {
119     // Trace each chip for debug. It is important to show the type just in case
120     // the model/EC does not exist. See note below.
121     trace::inf("Chip found: type=0x%08" PRIx32 " chip=%s", i_type,
122                getPath(i_trgt));
123 
124     if (0 == i_type)
125     {
126         // There is a special case where the model/level attributes have not
127         // been initialized in the devtree. This is possible on the epoch IPL
128         // where an attention occurs before Hostboot is able to update the
129         // devtree information on the BMC. For now, just ignore the chip.
130     }
131     else
132     {
133         o_chips.emplace_back(i_trgt, i_type);
134     }
135 }
136 
137 void getActiveChips(std::vector<libhei::Chip>& o_chips)
138 {
139     o_chips.clear();
140 
141     // Iterate each processor.
142     pdbg_target* procTrgt;
143     pdbg_for_each_class_target("proc", procTrgt)
144     {
145         // We cannot use the proc target to determine if the chip is active.
146         // There is some design limitation in pdbg that requires the proc
147         // targets to always be active. Instead, we must get the associated pib
148         // target and check if it is active.
149 
150         // Active processors only.
151         if (PDBG_TARGET_ENABLED != pdbg_target_probe(getPibTrgt(procTrgt)))
152             continue;
153 
154         // Add the processor to the list.
155         __addChip(o_chips, procTrgt, __getChipIdEc(procTrgt));
156 
157         // Iterate the connected OCMBs, if they exist.
158         pdbg_target* ocmbTrgt;
159         pdbg_for_each_target("ocmb", procTrgt, ocmbTrgt)
160         {
161             // Active OCMBs only.
162             if (PDBG_TARGET_ENABLED != pdbg_target_probe(ocmbTrgt))
163                 continue;
164 
165             // Add the OCMB to the list.
166             __addChip(o_chips, ocmbTrgt, __getChipIdEc(ocmbTrgt));
167         }
168     }
169 }
170 
171 //------------------------------------------------------------------------------
172 
173 } // namespace pdbg
174 
175 } // namespace util
176