1 #include <fcntl.h> 2 #include <libpdbg.h> 3 4 #include <hei_main.hpp> 5 #include <test/sim-hw-access.hpp> 6 #include <util/pdbg.hpp> 7 #include <util/trace.hpp> 8 9 #include <limits> 10 #include <vector> 11 12 #include "gtest/gtest.h" 13 14 TEST(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 37 TEST(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 59 TEST(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 88 TEST(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 } 113 114 TEST(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 133 TEST(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 } 168 169 TEST(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 204 TEST(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 } 237 238 TEST(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()); 249 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 */ 287 } 288