blob: 1ba5df4390119723bc7cf09a6b254f9e7ca52f0a [file] [log] [blame]
Ben Tynerbcf65a82020-12-01 08:46:36 -06001#include <libpdbg.h>
2
3#include <attn/attn_common.hpp>
Ben Tyner135793a2021-10-27 09:18:41 -05004#include <attn/attn_handler.hpp>
Ben Tynerb8335562021-07-16 12:43:52 -05005#include <attn/attn_logging.hpp>
Ben Tynerbcf65a82020-12-01 08:46:36 -06006#include <sdbusplus/bus.hpp>
Ben Tynerb8335562021-07-16 12:43:52 -05007#include <util/pdbg.hpp>
austinfcuibfa831a2022-01-26 15:37:07 -06008#include <util/trace.hpp>
Ben Tynerbcf65a82020-12-01 08:46:36 -06009
Ben Tynerb8335562021-07-16 12:43:52 -050010#include <iomanip>
11#include <iostream>
Ben Tynerbcf65a82020-12-01 08:46:36 -060012#include <map>
13
14namespace attn
15{
16
Ben Tynerb8335562021-07-16 12:43:52 -050017/** @brief Traces some regs for hostboot */
18void 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 {
austinfcuibfa831a2022-01-26 15:37:07 -060039 trace::err("cfam read error: 0x%08x", l_cfamAddr);
Ben Tynerb8335562021-07-16 12:43:52 -050040 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 {
austinfcuibfa831a2022-01-26 15:37:07 -060046 trace::err("scom read error: 0x%016" PRIx64 "", l_scomAddr1);
Ben Tynerb8335562021-07-16 12:43:52 -050047 l_scomData1 = 0xFFFFFFFFFFFFFFFFull;
48 }
49
50 if (RC_SUCCESS != pib_read(pibTarget, l_scomAddr2, &l_scomData2))
51 {
austinfcuibfa831a2022-01-26 15:37:07 -060052 trace::err("scom read error: 0x%016" PRIx64 "", l_scomAddr2);
Ben Tynerb8335562021-07-16 12:43:52 -050053 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 )
austinfcuibfa831a2022-01-26 15:37:07 -060060 trace::inf("HostBoot Reg:%08x Data:%08x Proc:00000000", l_cfamAddr,
61 l_cfamData);
Zane Shelleyebddb422022-03-22 17:17:23 -050062 trace::inf("HostBoot Reg:%08" PRIx64 " Data:%016" PRIx64
63 " Proc:00000000",
austinfcuibfa831a2022-01-26 15:37:07 -060064 l_scomAddr1, l_scomData1);
Zane Shelleyebddb422022-03-22 17:17:23 -050065 trace::inf("HostBoot Reg:%08" PRIx64 " Data:%016" PRIx64
66 " Proc:00000000",
austinfcuibfa831a2022-01-26 15:37:07 -060067 l_scomAddr2, l_scomData2);
Ben Tynerb8335562021-07-16 12:43:52 -050068 }
69
70 return;
71
72} // end addHbStatusRegs
73
Ben Tyner21cc6272022-10-05 18:26:36 -050074/** @brief Capture some scratch registers for PRD */
75void addPrdScratchRegs(std::vector<util::FFDCFile>& o_files)
76{
77 // Get primary processor FSI target for CFAM reads
78 pdbg_target* fsiTarget = pdbg_target_from_path(nullptr, "/proc0/fsi");
79
80 if (nullptr == fsiTarget)
81 {
82 trace::err("error getting scratch register target");
83 }
84 else
85 {
86 uint32_t chipId = 0;
87 uint32_t signatureId = 0;
88
89 // get scratch register 9 (CFAM)
90 if (RC_SUCCESS != fsi_read(fsiTarget, 0x2980, &chipId))
91 {
92 trace::err("error reading scratch register 9");
93 chipId = 0;
94 }
95
96 // get scratch register 10 (CFAM)
97 if (RC_SUCCESS != fsi_read(fsiTarget, 0x2981, &signatureId))
98 {
99 trace::err("error reading scratch register 10");
100 signatureId = 0;
101 }
102
103 // Add data to traces and create user data section
104 if (0 != chipId || 0 != signatureId)
105 {
106 // trace scratch register data
107 trace::inf("PRD scratch Proc0, Chip ID: %08x, Signature ID: %08x",
108 chipId, signatureId);
109
110 // create ffdc data for user data section
111 try
112 {
113 util::FFDCFile file{util::FFDCFormat::Text};
114 int fd = file.getFileDescriptor();
115 char buffer[150];
116 int len = sprintf(buffer,
117 "Scratch Register Error Signature\n"
118 "Processor : 0\n"
119 "Chip ID : %08x\n"
120 "Signature ID : %08x\n",
121 chipId, signatureId);
122 if (write(fd, buffer, len) < 0)
123 {
124 trace::err("error writing scratch register user data");
125 }
126 else
127 {
128 o_files.push_back(std::move(file));
129 }
130 }
131 catch (const std::exception& e)
132 {
133 trace::err(
134 "exception when creating scratch register user data");
135 trace::inf(e.what());
136 }
137 }
138 }
139
140 return;
141}
142
Ben Tyner135793a2021-10-27 09:18:41 -0500143/** @brief Check for recoverable errors present */
144bool recoverableErrors()
145{
146 bool recoverableErrors = false; // assume no recoverable attentions
147
148 pdbg_target* target;
149 pdbg_for_each_class_target("proc", target)
150 {
151 if (PDBG_TARGET_ENABLED == pdbg_target_probe(target))
152 {
153 auto proc = pdbg_target_index(target); // get processor number
154
155 // Use PIB target to determine if a processor is enabled
156 char path[16];
157 sprintf(path, "/proc%d/pib", proc);
158 pdbg_target* pibTarget = pdbg_target_from_path(nullptr, path);
159
160 // sanity check
161 if (nullptr == pibTarget)
162 {
austinfcuibfa831a2022-01-26 15:37:07 -0600163 trace::inf("pib path or target not found");
Ben Tyner135793a2021-10-27 09:18:41 -0500164 continue;
165 }
166
167 // check if pib target is enabled - indicates proc is enabled
168 if (PDBG_TARGET_ENABLED == pdbg_target_probe(pibTarget))
169 {
170 // The processor FSI target is required for CFAM read
171 sprintf(path, "/proc%d/fsi", proc);
172 pdbg_target* fsiTarget = pdbg_target_from_path(nullptr, path);
173
174 // sanity check
175 if (nullptr == fsiTarget)
176 {
austinfcuibfa831a2022-01-26 15:37:07 -0600177 trace::inf("fsi path or target not found");
Ben Tyner135793a2021-10-27 09:18:41 -0500178 continue;
179 }
180
181 uint32_t isr_val = 0xffffffff; // invalid isr value
182
183 // get active attentions on processor
184 if (RC_SUCCESS != fsi_read(fsiTarget, 0x1007, &isr_val))
185 {
186 // log cfam read error
austinfcuibfa831a2022-01-26 15:37:07 -0600187 trace::err("cfam read 0x1007 FAILED");
Ben Tyner135793a2021-10-27 09:18:41 -0500188 eventAttentionFail((int)AttnSection::attnHandler |
189 ATTN_PDBG_CFAM);
190 }
191 // check for invalid/stale value
192 else if (0xffffffff == isr_val)
193 {
austinfcuibfa831a2022-01-26 15:37:07 -0600194 trace::err("cfam read 0x1007 INVALID");
Ben Tyner135793a2021-10-27 09:18:41 -0500195 continue;
196 }
197 // check recoverable error status bit
198 else if (0 != (isr_val & RECOVERABLE_ATTN))
199 {
200 recoverableErrors = true;
201 break;
202 }
203 } // fsi target enabled
204 } // pib target enabled
205 } // next processor
206
207 return recoverableErrors;
208}
209
Ben Tyner07ebb9b2021-12-01 12:16:24 -0600210/** @brief timesec less-than-equal-to compare */
211bool operator<=(const timespec& lhs, const timespec& rhs)
212{
213 if (lhs.tv_sec == rhs.tv_sec)
214 return lhs.tv_nsec <= rhs.tv_nsec;
215 else
216 return lhs.tv_sec <= rhs.tv_sec;
217}
218
219/** @brief sleep for n-seconds */
220void sleepSeconds(const unsigned int seconds)
221{
222 auto count = seconds;
223 struct timespec requested, remaining;
224
225 while (0 < count)
226 {
227 requested.tv_sec = 1;
228 requested.tv_nsec = 0;
229 remaining = requested;
230
231 while (-1 == nanosleep(&requested, &remaining))
232 {
233 // if not changing or implausible then abort
234 if (requested <= remaining)
235 {
236 break;
237 }
238
239 // back to sleep
240 requested = remaining;
241 }
242 count--;
243 }
244}
245
Ben Tynerbcf65a82020-12-01 08:46:36 -0600246} // namespace attn