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:%08x Data:%016" PRIx64 " Proc:00000000", 63 l_scomAddr1, l_scomData1); 64 trace::inf("HostBoot Reg:%08x Data:%016" PRIx64 " Proc:00000000", 65 l_scomAddr2, l_scomData2); 66 } 67 68 return; 69 70 } // end addHbStatusRegs 71 72 /** @brief Check for recoverable errors present */ 73 bool recoverableErrors() 74 { 75 bool recoverableErrors = false; // assume no recoverable attentions 76 77 pdbg_target* target; 78 pdbg_for_each_class_target("proc", target) 79 { 80 if (PDBG_TARGET_ENABLED == pdbg_target_probe(target)) 81 { 82 auto proc = pdbg_target_index(target); // get processor number 83 84 // Use PIB target to determine if a processor is enabled 85 char path[16]; 86 sprintf(path, "/proc%d/pib", proc); 87 pdbg_target* pibTarget = pdbg_target_from_path(nullptr, path); 88 89 // sanity check 90 if (nullptr == pibTarget) 91 { 92 trace::inf("pib path or target not found"); 93 continue; 94 } 95 96 // check if pib target is enabled - indicates proc is enabled 97 if (PDBG_TARGET_ENABLED == pdbg_target_probe(pibTarget)) 98 { 99 // The processor FSI target is required for CFAM read 100 sprintf(path, "/proc%d/fsi", proc); 101 pdbg_target* fsiTarget = pdbg_target_from_path(nullptr, path); 102 103 // sanity check 104 if (nullptr == fsiTarget) 105 { 106 trace::inf("fsi path or target not found"); 107 continue; 108 } 109 110 uint32_t isr_val = 0xffffffff; // invalid isr value 111 112 // get active attentions on processor 113 if (RC_SUCCESS != fsi_read(fsiTarget, 0x1007, &isr_val)) 114 { 115 // log cfam read error 116 trace::err("cfam read 0x1007 FAILED"); 117 eventAttentionFail((int)AttnSection::attnHandler | 118 ATTN_PDBG_CFAM); 119 } 120 // check for invalid/stale value 121 else if (0xffffffff == isr_val) 122 { 123 trace::err("cfam read 0x1007 INVALID"); 124 continue; 125 } 126 // check recoverable error status bit 127 else if (0 != (isr_val & RECOVERABLE_ATTN)) 128 { 129 recoverableErrors = true; 130 break; 131 } 132 } // fsi target enabled 133 } // pib target enabled 134 } // next processor 135 136 return recoverableErrors; 137 } 138 139 /** @brief timesec less-than-equal-to compare */ 140 bool operator<=(const timespec& lhs, const timespec& rhs) 141 { 142 if (lhs.tv_sec == rhs.tv_sec) 143 return lhs.tv_nsec <= rhs.tv_nsec; 144 else 145 return lhs.tv_sec <= rhs.tv_sec; 146 } 147 148 /** @brief sleep for n-seconds */ 149 void sleepSeconds(const unsigned int seconds) 150 { 151 auto count = seconds; 152 struct timespec requested, remaining; 153 154 while (0 < count) 155 { 156 requested.tv_sec = 1; 157 requested.tv_nsec = 0; 158 remaining = requested; 159 160 while (-1 == nanosleep(&requested, &remaining)) 161 { 162 // if not changing or implausible then abort 163 if (requested <= remaining) 164 { 165 break; 166 } 167 168 // back to sleep 169 requested = remaining; 170 } 171 count--; 172 } 173 } 174 175 } // namespace attn 176