blob: d9749dbb342d8028f19f8df280d17076257f3d47 [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
Jayanth Othayoth25e39c82021-07-12 01:00:17 -05007#include "extensions/phal/common_utils.hpp"
Jayanth Othayoth6552de02021-07-12 00:55:57 -05008#include "extensions/phal/phal_error.hpp"
Chirag Sharmaa2576932020-12-05 23:17:41 -06009
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
Jayanth Othayoth2de8c8d2021-07-16 06:40:33 -050032 setDevtreeEnv();
Jayanth Othayoth583a9ed2021-06-29 05:42:45 -050033
Chirag Sharmaa2576932020-12-05 23:17:41 -060034 if (!pdbg_targets_init(NULL))
35 {
36 log<level::ERR>("pdbg_targets_init failed");
37 throw std::runtime_error("pdbg target initialization failed");
38 }
39
40 if (libekb_init())
41 {
42 log<level::ERR>("libekb_init failed");
43 throw std::runtime_error("libekb initialization failed");
44 }
45
46 if (ipl_init(mode) != 0)
47 {
48 log<level::ERR>("ipl_init failed");
49 throw std::runtime_error("libipl initialization failed");
50 }
51}
52
Andrew Geissler5c3f9252021-06-10 10:53:05 -050053bool isPrimaryProc(struct pdbg_target* procTarget)
54{
55 ATTR_PROC_MASTER_TYPE_Type type;
56
57 // Get processor type (Primary or Secondary)
58 if (DT_GET_PROP(ATTR_PROC_MASTER_TYPE, procTarget, type))
59 {
60 log<level::ERR>("Attribute [ATTR_PROC_MASTER_TYPE] get failed");
61 throw std::runtime_error(
62 "Attribute [ATTR_PROC_MASTER_TYPE] get failed");
63 }
64
65 /* Attribute value 0 corresponds to primary processor */
66 if (type == ENUM_ATTR_PROC_MASTER_TYPE_ACTING_MASTER)
67 {
68 return true;
69 }
70 else
71 {
72 return false;
73 }
74}
75
Andrew Geissleraf48bed2021-06-24 10:01:35 -050076pdbg_target* getFsiTarget(struct pdbg_target* procTarget)
Andrew Geissler65c01012021-06-15 14:03:34 -050077{
Andrew Geissler65c01012021-06-15 14:03:34 -050078
Andrew Geissleraf48bed2021-06-24 10:01:35 -050079 struct pdbg_target* fsiTarget = nullptr;
80 pdbg_for_each_target("fsi", procTarget, fsiTarget)
Andrew Geissler65c01012021-06-15 14:03:34 -050081 {
Andrew Geissleraf48bed2021-06-24 10:01:35 -050082 // grab first one we find
83 break;
84 }
85 if (!fsiTarget)
86 {
87 log<level::ERR>(
88 "fsi path of target not found",
89 entry("PROC_TARGET_PATH=%s", pdbg_target_path(procTarget)));
90 return nullptr;
Andrew Geissler65c01012021-06-15 14:03:34 -050091 }
92
Andrew Geissleraf48bed2021-06-24 10:01:35 -050093 return fsiTarget;
94}
95
96uint32_t probeTarget(struct pdbg_target* procTarget)
97{
98 struct pdbg_target* pibTarget = nullptr;
99 pdbg_for_each_target("pib", procTarget, pibTarget)
100 {
101 // grab first one we find
102 break;
103 }
104 if (!pibTarget)
105 {
106 log<level::ERR>(
107 "pib path of target not found",
108 entry("PROC_TARGET_PATH=%s", pdbg_target_path(procTarget)));
109 return -1;
110 }
Andrew Geissler65c01012021-06-15 14:03:34 -0500111 // probe PIB and ensure it's enabled
112 if (PDBG_TARGET_ENABLED != pdbg_target_probe(pibTarget))
113 {
Andrew Geissleraf48bed2021-06-24 10:01:35 -0500114 log<level::ERR>(
115 "probe on pib target failed",
116 entry("PIB_TARGET_PATH=%s", pdbg_target_path(pibTarget)));
Andrew Geissler65c01012021-06-15 14:03:34 -0500117 return -1;
118 }
Andrew Geissleraf48bed2021-06-24 10:01:35 -0500119 return 0;
120}
Andrew Geissler65c01012021-06-15 14:03:34 -0500121
Andrew Geissleraf48bed2021-06-24 10:01:35 -0500122uint32_t getCFAM(struct pdbg_target* procTarget, const uint32_t reg,
123 uint32_t& val)
124{
125
126 pdbg_target* fsiTarget = getFsiTarget(procTarget);
Andrew Geissler65c01012021-06-15 14:03:34 -0500127 if (nullptr == fsiTarget)
128 {
Andrew Geissleraf48bed2021-06-24 10:01:35 -0500129 log<level::ERR>("getCFAM: fsi path or target not found");
Andrew Geissler65c01012021-06-15 14:03:34 -0500130 return -1;
131 }
132
Andrew Geissleraf48bed2021-06-24 10:01:35 -0500133 auto rc = probeTarget(procTarget);
Andrew Geissler65c01012021-06-15 14:03:34 -0500134 if (rc)
135 {
Andrew Geissleraf48bed2021-06-24 10:01:35 -0500136 // probe function logged details to journal
137 return rc;
138 }
139
140 rc = fsi_read(fsiTarget, reg, &val);
141 if (rc)
142 {
143 log<level::ERR>(
144 "failed to read input cfam", entry("RC=%u", rc),
145 entry("CFAM=0x%X", reg),
146 entry("FSI_TARGET_PATH=%s", pdbg_target_path(fsiTarget)));
147 return rc;
148 }
149 return 0;
150}
151
152uint32_t putCFAM(struct pdbg_target* procTarget, const uint32_t reg,
153 const uint32_t val)
154{
155 pdbg_target* fsiTarget = getFsiTarget(procTarget);
156 if (nullptr == fsiTarget)
157 {
158 log<level::ERR>("putCFAM: fsi path or target not found");
159 return -1;
160 }
161
162 auto rc = probeTarget(procTarget);
163 if (rc)
164 {
165 // probe function logged details to journal
166 return rc;
167 }
168
169 rc = fsi_write(fsiTarget, reg, val);
170 if (rc)
171 {
172 log<level::ERR>(
173 "failed to write input cfam", entry("RC=%u", rc),
174 entry("CFAM=0x%X", reg),
175 entry("FSI_TARGET_PATH=%s", pdbg_target_path(fsiTarget)));
Andrew Geissler65c01012021-06-15 14:03:34 -0500176 return rc;
177 }
178 return 0;
179}
180
Jayanth Othayoth2de8c8d2021-07-16 06:40:33 -0500181void setDevtreeEnv()
182{
183 // PDBG_DTB environment variable set to CEC device tree path
184 static constexpr auto PDBG_DTB_PATH =
185 "/var/lib/phosphor-software-manager/pnor/rw/DEVTREE";
186
187 if (setenv("PDBG_DTB", PDBG_DTB_PATH, 1))
188 {
189 log<level::ERR>(
190 fmt::format("Failed to set PDBG_DTB: ({})", strerror(errno))
191 .c_str());
192 throw std::runtime_error("Failed to set PDBG_DTB");
193 }
194}
195
Chirag Sharmaa2576932020-12-05 23:17:41 -0600196} // namespace phal
197} // namespace openpower