1 extern "C"
2 {
3 #include <libpdbg.h>
4 }
5
6 #include "config.h"
7
8 #include "extensions/phal/pdbg_utils.hpp"
9 #include "extensions/phal/phal_error.hpp"
10
11 #include <phosphor-logging/log.hpp>
12
13 #include <format>
14
15 namespace openpower
16 {
17 namespace phal
18 {
19
20 using namespace phosphor::logging;
21
getFsiTarget(struct pdbg_target * procTarget)22 pdbg_target* getFsiTarget(struct pdbg_target* procTarget)
23 {
24 struct pdbg_target* fsiTarget = nullptr;
25 pdbg_for_each_target("fsi", procTarget, fsiTarget)
26 {
27 // grab first one we find
28 break;
29 }
30 if (!fsiTarget)
31 {
32 log<level::ERR>(
33 "fsi path of target not found",
34 entry("PROC_TARGET_PATH=%s", pdbg_target_path(procTarget)));
35 return nullptr;
36 }
37
38 return fsiTarget;
39 }
40
probeTarget(struct pdbg_target * procTarget)41 uint32_t probeTarget(struct pdbg_target* procTarget)
42 {
43 struct pdbg_target* pibTarget = nullptr;
44 pdbg_for_each_target("pib", procTarget, pibTarget)
45 {
46 // grab first one we find
47 break;
48 }
49 if (!pibTarget)
50 {
51 log<level::ERR>(
52 "pib path of target not found",
53 entry("PROC_TARGET_PATH=%s", pdbg_target_path(procTarget)));
54 return -1;
55 }
56 // probe PIB and ensure it's enabled
57 if (PDBG_TARGET_ENABLED != pdbg_target_probe(pibTarget))
58 {
59 log<level::ERR>(
60 "probe on pib target failed",
61 entry("PIB_TARGET_PATH=%s", pdbg_target_path(pibTarget)));
62 return -1;
63 }
64 return 0;
65 }
66
getCFAM(struct pdbg_target * procTarget,const uint32_t reg,uint32_t & val)67 uint32_t getCFAM(struct pdbg_target* procTarget, const uint32_t reg,
68 uint32_t& val)
69 {
70 pdbg_target* fsiTarget = getFsiTarget(procTarget);
71 if (nullptr == fsiTarget)
72 {
73 log<level::ERR>("getCFAM: fsi path or target not found");
74 return -1;
75 }
76
77 auto rc = probeTarget(procTarget);
78 if (rc)
79 {
80 // probe function logged details to journal
81 return rc;
82 }
83
84 rc = fsi_read(fsiTarget, reg, &val);
85 if (rc)
86 {
87 log<level::ERR>(
88 "failed to read input cfam", entry("RC=%u", rc),
89 entry("CFAM=0x%X", reg),
90 entry("FSI_TARGET_PATH=%s", pdbg_target_path(fsiTarget)));
91 return rc;
92 }
93 return 0;
94 }
95
putCFAM(struct pdbg_target * procTarget,const uint32_t reg,const uint32_t val)96 uint32_t putCFAM(struct pdbg_target* procTarget, const uint32_t reg,
97 const uint32_t val)
98 {
99 pdbg_target* fsiTarget = getFsiTarget(procTarget);
100 if (nullptr == fsiTarget)
101 {
102 log<level::ERR>("putCFAM: fsi path or target not found");
103 return -1;
104 }
105
106 auto rc = probeTarget(procTarget);
107 if (rc)
108 {
109 // probe function logged details to journal
110 return rc;
111 }
112
113 rc = fsi_write(fsiTarget, reg, val);
114 if (rc)
115 {
116 log<level::ERR>(
117 "failed to write input cfam", entry("RC=%u", rc),
118 entry("CFAM=0x%X", reg),
119 entry("FSI_TARGET_PATH=%s", pdbg_target_path(fsiTarget)));
120 return rc;
121 }
122 return 0;
123 }
124
setDevtreeEnv()125 void setDevtreeEnv()
126 {
127 // PDBG_DTB environment variable set to CEC device tree path
128 if (setenv("PDBG_DTB", CEC_DEVTREE_RW_PATH, 1))
129 {
130 log<level::ERR>(
131 std::format("Failed to set PDBG_DTB: ({})", strerror(errno))
132 .c_str());
133 throw std::runtime_error("Failed to set PDBG_DTB");
134 }
135 }
136
setPdataInfoDBEnv()137 void setPdataInfoDBEnv()
138 {
139 // PDATA_INFODB environment variable set to attributes tool infodb path
140 static constexpr auto PDATA_INFODB_PATH =
141 "/usr/share/pdata/attributes_info.db";
142
143 if (setenv("PDATA_INFODB", PDATA_INFODB_PATH, 1))
144 {
145 log<level::ERR>(
146 std::format("Failed to set PDATA_INFODB: ({})", strerror(errno))
147 .c_str());
148 throw std::runtime_error("Failed to set PDATA_INFODB");
149 }
150 }
151
152 } // namespace phal
153 } // namespace openpower
154