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