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