blob: 6f2995ef7cd6ce9a15942c54d71fd7feaed68cd4 [file] [log] [blame]
Chirag Sharmaa2576932020-12-05 23:17:41 -06001extern "C"
2{
3#include <libpdbg.h>
4}
Andrew Geissler5c3f9252021-06-10 10:53:05 -05005#include "attributes_info.H"
Chirag Sharmaa2576932020-12-05 23:17:41 -06006
7#include "phalerror/phal_error.hpp"
8#include "procedures/phal/common_utils.hpp"
9
Jayanth Othayoth583a9ed2021-06-29 05:42:45 -050010#include <fmt/format.h>
Chirag Sharmaa2576932020-12-05 23:17:41 -060011#include <libekb.H>
12
13#include <phosphor-logging/log.hpp>
14
15namespace openpower
16{
17namespace phal
18{
19
20using namespace phosphor::logging;
21
22void phal_init(enum ipl_mode mode)
23{
24 // TODO: Setting boot error callback should not be in common code
25 // because, we wont get proper reason in PEL for failure.
26 // So, need to make code like caller of this function pass error
27 // handling callback.
28 // add callback methods for debug traces and for boot failures
29 openpower::pel::addBootErrorCallbacks();
30
Jayanth Othayoth583a9ed2021-06-29 05:42:45 -050031 // PDBG_DTB environment variable set to CEC device tree path
32 static constexpr auto PDBG_DTB_PATH =
33 "/var/lib/phosphor-software-manager/pnor/rw/DEVTREE";
34
35 if (setenv("PDBG_DTB", PDBG_DTB_PATH, 1))
36 {
37 log<level::ERR>(
38 fmt::format("Failed to set PDBG_DTB: ({})", strerror(errno))
39 .c_str());
40 throw std::runtime_error("Failed to set PDBG_DTB");
41 }
42
Chirag Sharmaa2576932020-12-05 23:17:41 -060043 if (!pdbg_targets_init(NULL))
44 {
45 log<level::ERR>("pdbg_targets_init failed");
46 throw std::runtime_error("pdbg target initialization failed");
47 }
48
49 if (libekb_init())
50 {
51 log<level::ERR>("libekb_init failed");
52 throw std::runtime_error("libekb initialization failed");
53 }
54
55 if (ipl_init(mode) != 0)
56 {
57 log<level::ERR>("ipl_init failed");
58 throw std::runtime_error("libipl initialization failed");
59 }
60}
61
Andrew Geissler5c3f9252021-06-10 10:53:05 -050062bool isPrimaryProc(struct pdbg_target* procTarget)
63{
64 ATTR_PROC_MASTER_TYPE_Type type;
65
66 // Get processor type (Primary or Secondary)
67 if (DT_GET_PROP(ATTR_PROC_MASTER_TYPE, procTarget, type))
68 {
69 log<level::ERR>("Attribute [ATTR_PROC_MASTER_TYPE] get failed");
70 throw std::runtime_error(
71 "Attribute [ATTR_PROC_MASTER_TYPE] get failed");
72 }
73
74 /* Attribute value 0 corresponds to primary processor */
75 if (type == ENUM_ATTR_PROC_MASTER_TYPE_ACTING_MASTER)
76 {
77 return true;
78 }
79 else
80 {
81 return false;
82 }
83}
84
Andrew Geissleraf48bed2021-06-24 10:01:35 -050085pdbg_target* getFsiTarget(struct pdbg_target* procTarget)
Andrew Geissler65c01012021-06-15 14:03:34 -050086{
Andrew Geissler65c01012021-06-15 14:03:34 -050087
Andrew Geissleraf48bed2021-06-24 10:01:35 -050088 struct pdbg_target* fsiTarget = nullptr;
89 pdbg_for_each_target("fsi", procTarget, fsiTarget)
Andrew Geissler65c01012021-06-15 14:03:34 -050090 {
Andrew Geissleraf48bed2021-06-24 10:01:35 -050091 // grab first one we find
92 break;
93 }
94 if (!fsiTarget)
95 {
96 log<level::ERR>(
97 "fsi path of target not found",
98 entry("PROC_TARGET_PATH=%s", pdbg_target_path(procTarget)));
99 return nullptr;
Andrew Geissler65c01012021-06-15 14:03:34 -0500100 }
101
Andrew Geissleraf48bed2021-06-24 10:01:35 -0500102 return fsiTarget;
103}
104
105uint32_t probeTarget(struct pdbg_target* procTarget)
106{
107 struct pdbg_target* pibTarget = nullptr;
108 pdbg_for_each_target("pib", procTarget, pibTarget)
109 {
110 // grab first one we find
111 break;
112 }
113 if (!pibTarget)
114 {
115 log<level::ERR>(
116 "pib path of target not found",
117 entry("PROC_TARGET_PATH=%s", pdbg_target_path(procTarget)));
118 return -1;
119 }
Andrew Geissler65c01012021-06-15 14:03:34 -0500120 // probe PIB and ensure it's enabled
121 if (PDBG_TARGET_ENABLED != pdbg_target_probe(pibTarget))
122 {
Andrew Geissleraf48bed2021-06-24 10:01:35 -0500123 log<level::ERR>(
124 "probe on pib target failed",
125 entry("PIB_TARGET_PATH=%s", pdbg_target_path(pibTarget)));
Andrew Geissler65c01012021-06-15 14:03:34 -0500126 return -1;
127 }
Andrew Geissleraf48bed2021-06-24 10:01:35 -0500128 return 0;
129}
Andrew Geissler65c01012021-06-15 14:03:34 -0500130
Andrew Geissleraf48bed2021-06-24 10:01:35 -0500131uint32_t getCFAM(struct pdbg_target* procTarget, const uint32_t reg,
132 uint32_t& val)
133{
134
135 pdbg_target* fsiTarget = getFsiTarget(procTarget);
Andrew Geissler65c01012021-06-15 14:03:34 -0500136 if (nullptr == fsiTarget)
137 {
Andrew Geissleraf48bed2021-06-24 10:01:35 -0500138 log<level::ERR>("getCFAM: fsi path or target not found");
Andrew Geissler65c01012021-06-15 14:03:34 -0500139 return -1;
140 }
141
Andrew Geissleraf48bed2021-06-24 10:01:35 -0500142 auto rc = probeTarget(procTarget);
Andrew Geissler65c01012021-06-15 14:03:34 -0500143 if (rc)
144 {
Andrew Geissleraf48bed2021-06-24 10:01:35 -0500145 // probe function logged details to journal
146 return rc;
147 }
148
149 rc = fsi_read(fsiTarget, reg, &val);
150 if (rc)
151 {
152 log<level::ERR>(
153 "failed to read input cfam", entry("RC=%u", rc),
154 entry("CFAM=0x%X", reg),
155 entry("FSI_TARGET_PATH=%s", pdbg_target_path(fsiTarget)));
156 return rc;
157 }
158 return 0;
159}
160
161uint32_t putCFAM(struct pdbg_target* procTarget, const uint32_t reg,
162 const uint32_t val)
163{
164 pdbg_target* fsiTarget = getFsiTarget(procTarget);
165 if (nullptr == fsiTarget)
166 {
167 log<level::ERR>("putCFAM: fsi path or target not found");
168 return -1;
169 }
170
171 auto rc = probeTarget(procTarget);
172 if (rc)
173 {
174 // probe function logged details to journal
175 return rc;
176 }
177
178 rc = fsi_write(fsiTarget, reg, val);
179 if (rc)
180 {
181 log<level::ERR>(
182 "failed to write input cfam", entry("RC=%u", rc),
183 entry("CFAM=0x%X", reg),
184 entry("FSI_TARGET_PATH=%s", pdbg_target_path(fsiTarget)));
Andrew Geissler65c01012021-06-15 14:03:34 -0500185 return rc;
186 }
187 return 0;
188}
189
Chirag Sharmaa2576932020-12-05 23:17:41 -0600190} // namespace phal
191} // namespace openpower