blob: 83d3f89f92343f6cd992a574f7c2f59a6fccdbf5 [file] [log] [blame]
austinfcui35257fd2021-12-09 17:56:00 -06001#include <fcntl.h>
austinfcuie81eb152022-04-19 10:56:32 -05002#include <libpdbg.h>
austinfcui35257fd2021-12-09 17:56:00 -06003
austinfcuie81eb152022-04-19 10:56:32 -05004#include <hei_main.hpp>
Zane Shelleyc7026262022-02-22 16:37:36 -06005#include <test/sim-hw-access.hpp>
austinfcui35257fd2021-12-09 17:56:00 -06006#include <util/pdbg.hpp>
7#include <util/trace.hpp>
8
9#include <limits>
austinfcuie81eb152022-04-19 10:56:32 -050010#include <vector>
austinfcui35257fd2021-12-09 17:56:00 -060011
12#include "gtest/gtest.h"
13
14TEST(PDBG, PdbgDtsTest1)
15{
16 const char* perv1_fapi_pos_path = "/proc0/pib/perv1";
17 const char* perv12_fapi_pos_path = "/proc0/pib/perv12";
18 const uint32_t perv1_fapi_pos = 1;
19 const uint32_t perv12_fapi_pos = 12;
20
21 pdbg_targets_init(nullptr);
22
23 trace::inf("retrieving fapi pos.");
24 uint32_t attr = std::numeric_limits<uint32_t>::max();
25 pdbg_target* trgt = pdbg_target_from_path(nullptr, perv1_fapi_pos_path);
26 pdbg_target_get_attribute(trgt, "ATTR_FAPI_POS", 4, 1, &attr);
27 trace::inf("perv1 fapi pos in DTS: %u", attr);
28 EXPECT_EQ(attr, perv1_fapi_pos);
29
30 attr = std::numeric_limits<uint32_t>::max();
31 trgt = pdbg_target_from_path(nullptr, perv12_fapi_pos_path);
32 pdbg_target_get_attribute(trgt, "ATTR_FAPI_POS", 4, 1, &attr);
33 trace::inf("perv12 fapi pos in DTS: %u", attr);
34 EXPECT_EQ(attr, perv12_fapi_pos);
35}
36
37TEST(PDBG, PdbgDtsTest2)
38{
39 const char* dimm0_path =
40 "/proc0/pib/perv12/mc0/mi0/mcc0/omi0/ocmb0/mem_port0/dimm0";
41 const uint32_t index = 0;
42 const uint32_t fapi_pos = 0;
43
44 pdbg_targets_init(nullptr);
45
46 trace::inf("retrieving fapi pos.");
47 uint32_t attr = std::numeric_limits<uint32_t>::max();
48 pdbg_target* trgt = pdbg_target_from_path(nullptr, dimm0_path);
49 pdbg_target_get_attribute(trgt, "index", 4, 1, &attr);
50 trace::inf("index in DTS: %u", attr);
51 EXPECT_EQ(attr, index);
52
53 attr = std::numeric_limits<uint32_t>::max();
54 pdbg_target_get_attribute(trgt, "ATTR_FAPI_POS", 4, 1, &attr);
55 trace::inf("fapi pos in DTS: %u", attr);
56 EXPECT_EQ(attr, fapi_pos);
57}
58
59TEST(PDBG, PdbgDtsTest3)
60{
61 const uint32_t chipId = 0; // ID for proc0.
62 const uint32_t fapiPos = 0; // FAPI Position for proc0.
63
64 pdbg_targets_init(nullptr);
65
66 // Iterate each processor.
67 pdbg_target* procTrgt;
68 pdbg_for_each_class_target("/proc0", procTrgt)
69 {
70 // Active processors only.
71 if (PDBG_TARGET_ENABLED !=
72 pdbg_target_probe(util::pdbg::getPibTrgt(procTrgt)))
73 continue;
74
75 // Process the PROC target.
76 uint32_t attr = std::numeric_limits<uint32_t>::max();
77 pdbg_target_get_attribute(procTrgt, "ATTR_CHIP_ID", 4, 1, &attr);
78 trace::inf("Chip ID: %u", attr);
79 EXPECT_EQ(attr, chipId);
80
81 attr = std::numeric_limits<uint32_t>::max();
82 pdbg_target_get_attribute(procTrgt, "ATTR_FAPI_POS", 4, 1, &attr);
83 trace::inf("ATTR_FAPI_POS: %u", attr);
84 EXPECT_EQ(attr, fapiPos);
85 }
86}
87
88TEST(PDBG, PdbgDtsTest4)
89{
90 const uint32_t index = 1;
91 const uint32_t fapi_pos = 1;
92 const char* perv1_path = "/proc0/pib/perv1";
93
94 pdbg_targets_init(nullptr);
95
96 // Iterate each processor.
97 pdbg_target* trgt;
98 uint32_t attr;
99
100 pdbg_for_each_class_target(perv1_path, trgt)
101 {
102 attr = std::numeric_limits<uint32_t>::max();
103 pdbg_target_get_attribute(trgt, "index", 4, 1, &attr);
104 trace::inf("index in DTS: %u", attr);
105 EXPECT_EQ(attr, index);
106
107 attr = std::numeric_limits<uint32_t>::max();
108 pdbg_target_get_attribute(trgt, "ATTR_FAPI_POS", 4, 1, &attr);
109 trace::inf("fapi pos in DTS: %u", attr);
110 EXPECT_EQ(attr, fapi_pos);
111 }
112}
Zane Shelley2a394cb2022-02-17 22:01:39 -0600113
114TEST(util_pdbg, getParentChip)
115{
116 using namespace util::pdbg;
117 pdbg_targets_init(nullptr);
118
119 auto procChip = getTrgt("/proc0");
120 auto omiUnit = getTrgt("/proc0/pib/perv13/mc1/mi0/mcc0/omi1");
121
122 EXPECT_EQ(procChip, getParentChip(procChip)); // get self
123 EXPECT_EQ(procChip, getParentChip(omiUnit)); // get unit
124
125 auto ocmbChip = getTrgt("/proc0/pib/perv13/mc1/mi0/mcc0/omi1/ocmb0");
126 auto memPortUnit =
127 getTrgt("/proc0/pib/perv13/mc1/mi0/mcc0/omi1/ocmb0/mem_port0");
128
129 EXPECT_EQ(ocmbChip, getParentChip(ocmbChip)); // get self
130 EXPECT_EQ(ocmbChip, getParentChip(memPortUnit)); // get unit
131}
132
133TEST(util_pdbg, getChipUnit)
134{
135 using namespace util::pdbg;
136 pdbg_targets_init(nullptr);
137
138 auto procChip = getTrgt("/proc0");
139 auto omiUnit = getTrgt("/proc0/pib/perv13/mc1/mi0/mcc0/omi1");
140 auto omiUnitPos = 5;
141
142 // Get the unit and verify.
143 EXPECT_EQ(omiUnit, getChipUnit(procChip, TYPE_OMI, omiUnitPos));
144
145 // Expect an exception when passing a unit instead of a chip.
146 EXPECT_THROW(getChipUnit(omiUnit, TYPE_OMI, omiUnitPos), std::logic_error);
147
148 // Expect an exception when passing a chip type.
149 EXPECT_THROW(getChipUnit(procChip, TYPE_PROC, omiUnitPos),
150 std::out_of_range);
151
152 // Expect an exception when passing a unit type not on the target chip.
153 EXPECT_THROW(getChipUnit(procChip, TYPE_MEM_PORT, omiUnitPos),
154 std::out_of_range);
155
156 // Expect a nullptr if the target is not found.
157 EXPECT_EQ(nullptr, getChipUnit(procChip, TYPE_OMI, 100));
158
159 auto ocmbChip = getTrgt("/proc0/pib/perv13/mc1/mi0/mcc0/omi1/ocmb0");
160 auto memPortUnit =
161 getTrgt("/proc0/pib/perv13/mc1/mi0/mcc0/omi1/ocmb0/mem_port0");
162 auto memPortUnitPos = 0;
163
164 // Get the unit and verify.
165 EXPECT_EQ(memPortUnit,
166 getChipUnit(ocmbChip, TYPE_MEM_PORT, memPortUnitPos));
167}
Zane Shelleyc7026262022-02-22 16:37:36 -0600168
169TEST(util_pdbg, getScom)
170{
171 using namespace util::pdbg;
172 pdbg_targets_init(nullptr);
173
174 auto procChip = getTrgt("/proc0");
175 auto ocmbChip = getTrgt("/proc0/pib/perv13/mc1/mi0/mcc0/omi1/ocmb0");
176 auto omiUnit = getTrgt("/proc0/pib/perv13/mc1/mi0/mcc0/omi1");
177
178 sim::ScomAccess& scom = sim::ScomAccess::getSingleton();
179 scom.flush();
180 scom.add(procChip, 0x11111111, 0x0011223344556677);
181 scom.error(ocmbChip, 0x22222222);
182
183 int rc = 0;
184 uint64_t val = 0;
185
186 // Test good path.
187 rc = getScom(procChip, 0x11111111, val);
188 EXPECT_EQ(0, rc);
189 EXPECT_EQ(0x0011223344556677, val);
190
191 // Test address that has not been added to ScomAccess.
192 rc = getScom(procChip, 0x33333333, val);
193 EXPECT_EQ(0, rc);
194 EXPECT_EQ(0, val);
195
196 // Test SCOM error.
197 rc = getScom(ocmbChip, 0x22222222, val);
198 EXPECT_EQ(1, rc);
199
200 // Test non-chip target.
201 EXPECT_DEATH({ getScom(omiUnit, 0x11111111, val); }, "");
202}
203
204TEST(util_pdbg, getCfam)
205{
206 using namespace util::pdbg;
207 pdbg_targets_init(nullptr);
208
209 auto procChip = getTrgt("/proc0");
210 auto omiUnit = getTrgt("/proc0/pib/perv13/mc1/mi0/mcc0/omi1");
211
212 sim::CfamAccess& cfam = sim::CfamAccess::getSingleton();
213 cfam.flush();
214 cfam.add(procChip, 0x11111111, 0x00112233);
215 cfam.error(procChip, 0x22222222);
216
217 int rc = 0;
218 uint32_t val = 0;
219
220 // Test good path.
221 rc = getCfam(procChip, 0x11111111, val);
222 EXPECT_EQ(0, rc);
223 EXPECT_EQ(0x00112233, val);
224
225 // Test address that has not been added to CfamAccess.
226 rc = getCfam(procChip, 0x33333333, val);
227 EXPECT_EQ(0, rc);
228 EXPECT_EQ(0, val);
229
230 // Test CFAM error.
231 rc = getCfam(procChip, 0x22222222, val);
232 EXPECT_EQ(1, rc);
233
234 // Test non-chip target.
235 EXPECT_DEATH({ getCfam(omiUnit, 0x11111111, val); }, "");
236}
austinfcuie81eb152022-04-19 10:56:32 -0500237
238TEST(util_pdbg, getActiveChips)
239{
240 using namespace util::pdbg;
241 using namespace libhei;
242 pdbg_targets_init(nullptr);
243
244 std::vector<libhei::Chip> chips;
245 getActiveChips(chips);
246
247 trace::inf("chips size: %u", chips.size());
248 EXPECT_EQ(2, chips.size());
Zane Shelleycd6373d2022-05-12 16:49:56 -0500249
250 /* TODO: There is an issue with the getActiveChips() function that only
251 * seems to exist in simulation. For some reason, the OCMBs do not
252 * show up as PDBG_TARGET_ENABLED. If we remove that check, this test
253 * case works as expected. However, we don't want to do that in
254 * production code. Instead, we'll need to determine why the OCMBs
255 * are not enabled in CI test and then reenable this test case.
256 auto proc0 = getTrgt("/proc0");
257 auto proc1 = getTrgt("/proc1");
258
259 sim::ScomAccess& scom = sim::ScomAccess::getSingleton();
260 scom.flush();
261
262 // Mask off proc0 mcc0 channel 1. The connected OCMB should be removed from
263 // the list.
264 scom.add(proc0, 0x0C010D03, 0x0f00000000000000);
265
266 // Mask off one or two attentions, but not all, on proc0 mcc2. None of the
267 // connected OCMBs should be removed from the list.
268 scom.add(proc0, 0x0D010D03, 0xA500000000000000);
269
270 // Mask off proc1 mcc7 channel 0. The connected OCMB should be removed from
271 // the list.
272 scom.add(proc1, 0x0F010D43, 0xf000000000000000);
273
274 // Mask off proc1 mcc5 channels 0 and 1. Both the connected OCMBs should be
275 // removed from the list.
276 scom.add(proc1, 0x0E010D43, 0xff00000000000000);
277
278 std::vector<libhei::Chip> chips;
279 getActiveChips(chips);
280
281 // In total there should be 14 chips with 2 processors, 7 OCMBs on proc0,
282 // and 5 OCMBs on proc1.
283
284 trace::inf("chips size: %u", chips.size());
285 EXPECT_EQ(14, chips.size());
286 */
austinfcuie81eb152022-04-19 10:56:32 -0500287}