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