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