1 #include <libpdbg.h> 2 3 #include <attn/attn_common.hpp> 4 #include <attn/attn_handler.hpp> 5 #include <attn/attn_logging.hpp> 6 #include <sdbusplus/bus.hpp> 7 #include <util/pdbg.hpp> 8 #include <util/trace.hpp> 9 10 #include <iomanip> 11 #include <iostream> 12 #include <map> 13 14 namespace attn 15 { 16 17 /** @brief Traces some regs for hostboot */ 18 void addHbStatusRegs() 19 { 20 // Only do this for P10 systems 21 if (util::pdbg::queryHardwareAnalysisSupported()) 22 { 23 // We only need this for PRIMARY processor 24 pdbg_target* pibTarget = pdbg_target_from_path(nullptr, "/proc0/pib"); 25 pdbg_target* fsiTarget = pdbg_target_from_path(nullptr, "/proc0/fsi"); 26 27 uint32_t l_cfamData = 0xFFFFFFFF; 28 uint64_t l_scomData1 = 0xFFFFFFFFFFFFFFFFull; 29 uint64_t l_scomData2 = 0xFFFFFFFFFFFFFFFFull; 30 uint32_t l_cfamAddr = 0x283C; 31 uint64_t l_scomAddr1 = 0x4602F489; 32 uint64_t l_scomAddr2 = 0x4602F487; 33 34 if ((nullptr != fsiTarget) && (nullptr != pibTarget)) 35 { 36 // get first debug reg (CFAM) 37 if (RC_SUCCESS != fsi_read(fsiTarget, l_cfamAddr, &l_cfamData)) 38 { 39 trace::err("cfam read error: 0x%08x", l_cfamAddr); 40 l_cfamData = 0xFFFFFFFF; 41 } 42 43 // Get SCOM regs next (just 2 of them) 44 if (RC_SUCCESS != pib_read(pibTarget, l_scomAddr1, &l_scomData1)) 45 { 46 trace::err("scom read error: 0x%016" PRIx64 "", l_scomAddr1); 47 l_scomData1 = 0xFFFFFFFFFFFFFFFFull; 48 } 49 50 if (RC_SUCCESS != pib_read(pibTarget, l_scomAddr2, &l_scomData2)) 51 { 52 trace::err("scom read error: 0x%016" PRIx64 "", l_scomAddr2); 53 l_scomData2 = 0xFFFFFFFFFFFFFFFFull; 54 } 55 } 56 57 // Trace out the results here of all 3 regs 58 // (Format should resemble FSP: HostBoot Reg:0000283C Data:AA801504 59 // 00000000 Proc:00050001 ) 60 trace::inf("HostBoot Reg:%08x Data:%08x Proc:00000000", l_cfamAddr, 61 l_cfamData); 62 trace::inf("HostBoot Reg:%08" PRIx64 " Data:%016" PRIx64 63 " Proc:00000000", 64 l_scomAddr1, l_scomData1); 65 trace::inf("HostBoot Reg:%08" PRIx64 " Data:%016" PRIx64 66 " Proc:00000000", 67 l_scomAddr2, l_scomData2); 68 } 69 70 return; 71 72 } // end addHbStatusRegs 73 74 /** @brief Check for recoverable errors present */ 75 bool recoverableErrors() 76 { 77 bool recoverableErrors = false; // assume no recoverable attentions 78 79 pdbg_target* target; 80 pdbg_for_each_class_target("proc", target) 81 { 82 if (PDBG_TARGET_ENABLED == pdbg_target_probe(target)) 83 { 84 auto proc = pdbg_target_index(target); // get processor number 85 86 // Use PIB target to determine if a processor is enabled 87 char path[16]; 88 sprintf(path, "/proc%d/pib", proc); 89 pdbg_target* pibTarget = pdbg_target_from_path(nullptr, path); 90 91 // sanity check 92 if (nullptr == pibTarget) 93 { 94 trace::inf("pib path or target not found"); 95 continue; 96 } 97 98 // check if pib target is enabled - indicates proc is enabled 99 if (PDBG_TARGET_ENABLED == pdbg_target_probe(pibTarget)) 100 { 101 // The processor FSI target is required for CFAM read 102 sprintf(path, "/proc%d/fsi", proc); 103 pdbg_target* fsiTarget = pdbg_target_from_path(nullptr, path); 104 105 // sanity check 106 if (nullptr == fsiTarget) 107 { 108 trace::inf("fsi path or target not found"); 109 continue; 110 } 111 112 uint32_t isr_val = 0xffffffff; // invalid isr value 113 114 // get active attentions on processor 115 if (RC_SUCCESS != fsi_read(fsiTarget, 0x1007, &isr_val)) 116 { 117 // log cfam read error 118 trace::err("cfam read 0x1007 FAILED"); 119 eventAttentionFail((int)AttnSection::attnHandler | 120 ATTN_PDBG_CFAM); 121 } 122 // check for invalid/stale value 123 else if (0xffffffff == isr_val) 124 { 125 trace::err("cfam read 0x1007 INVALID"); 126 continue; 127 } 128 // check recoverable error status bit 129 else if (0 != (isr_val & RECOVERABLE_ATTN)) 130 { 131 recoverableErrors = true; 132 break; 133 } 134 } // fsi target enabled 135 } // pib target enabled 136 } // next processor 137 138 return recoverableErrors; 139 } 140 141 /** @brief timesec less-than-equal-to compare */ 142 bool operator<=(const timespec& lhs, const timespec& rhs) 143 { 144 if (lhs.tv_sec == rhs.tv_sec) 145 return lhs.tv_nsec <= rhs.tv_nsec; 146 else 147 return lhs.tv_sec <= rhs.tv_sec; 148 } 149 150 /** @brief sleep for n-seconds */ 151 void sleepSeconds(const unsigned int seconds) 152 { 153 auto count = seconds; 154 struct timespec requested, remaining; 155 156 while (0 < count) 157 { 158 requested.tv_sec = 1; 159 requested.tv_nsec = 0; 160 remaining = requested; 161 162 while (-1 == nanosleep(&requested, &remaining)) 163 { 164 // if not changing or implausible then abort 165 if (requested <= remaining) 166 { 167 break; 168 } 169 170 // back to sleep 171 requested = remaining; 172 } 173 count--; 174 } 175 } 176 177 } // namespace attn 178