1324234b4SBen Tyner #include <util/dbus.hpp>
2324234b4SBen Tyner #include <util/trace.hpp>
3fe2c50d7SBen Tyner #include <xyz/openbmc_project/State/Boot/Progress/server.hpp>
4324234b4SBen Tyner
5710101c0SPatrick Williams #include <format>
6710101c0SPatrick Williams
7324234b4SBen Tyner namespace util
8324234b4SBen Tyner {
9324234b4SBen Tyner namespace dbus
10324234b4SBen Tyner {
11324234b4SBen Tyner //------------------------------------------------------------------------------
12324234b4SBen Tyner
13324234b4SBen Tyner constexpr auto objectMapperService = "xyz.openbmc_project.ObjectMapper";
14324234b4SBen Tyner constexpr auto objectMapperPath = "/xyz/openbmc_project/object_mapper";
15324234b4SBen Tyner constexpr auto objectMapperInterface = "xyz.openbmc_project.ObjectMapper";
16324234b4SBen Tyner
1788b10093SBen Tyner constexpr uint8_t terminusIdZero = 0;
1888b10093SBen Tyner
19324234b4SBen Tyner /** @brief Find the path and service that implements the given interface */
find(const std::string & i_interface,std::string & o_path,std::string & o_service)20324234b4SBen Tyner int find(const std::string& i_interface, std::string& o_path,
21324234b4SBen Tyner std::string& o_service)
22324234b4SBen Tyner {
23324234b4SBen Tyner int rc = 1; // assume not success
24324234b4SBen Tyner
25324234b4SBen Tyner auto bus = sdbusplus::bus::new_default();
26324234b4SBen Tyner
27324234b4SBen Tyner try
28324234b4SBen Tyner {
29659e65cfSBen Tyner constexpr auto function = "GetSubTree";
30659e65cfSBen Tyner
31324234b4SBen Tyner auto method = bus.new_method_call(objectMapperService, objectMapperPath,
32324234b4SBen Tyner objectMapperInterface, function);
33324234b4SBen Tyner
34324234b4SBen Tyner // Search the entire dbus tree for the specified interface
35324234b4SBen Tyner method.append(std::string{"/"}, 0,
36324234b4SBen Tyner std::vector<std::string>{i_interface});
37324234b4SBen Tyner
38324234b4SBen Tyner auto reply = bus.call(method);
39324234b4SBen Tyner
40324234b4SBen Tyner DBusSubTree response;
41324234b4SBen Tyner reply.read(response);
42324234b4SBen Tyner
43324234b4SBen Tyner if (!response.empty())
44324234b4SBen Tyner {
45324234b4SBen Tyner // Response is a map of object paths to a map of service, interfaces
46324234b4SBen Tyner auto object = *(response.begin());
47324234b4SBen Tyner o_path = object.first; // return path
48324234b4SBen Tyner o_service = object.second.begin()->first; // return service
49324234b4SBen Tyner
50324234b4SBen Tyner rc = 0; // success
51324234b4SBen Tyner }
52324234b4SBen Tyner }
53324234b4SBen Tyner catch (const sdbusplus::exception::SdBusError& e)
54324234b4SBen Tyner {
55324234b4SBen Tyner trace::err("util::dbus::find exception");
56324234b4SBen Tyner std::string traceMsg = std::string(e.what());
57324234b4SBen Tyner trace::err(traceMsg.c_str());
58324234b4SBen Tyner }
59324234b4SBen Tyner
60324234b4SBen Tyner return rc;
61324234b4SBen Tyner }
62324234b4SBen Tyner
63324234b4SBen Tyner /** @brief Find the service that implements the given object and interface */
findService(const std::string & i_interface,const std::string & i_path,std::string & o_service)64324234b4SBen Tyner int findService(const std::string& i_interface, const std::string& i_path,
65324234b4SBen Tyner std::string& o_service)
66324234b4SBen Tyner {
67324234b4SBen Tyner int rc = 1; // assume not success
68324234b4SBen Tyner
69324234b4SBen Tyner auto bus = sdbusplus::bus::new_default();
70324234b4SBen Tyner
71324234b4SBen Tyner try
72324234b4SBen Tyner {
73659e65cfSBen Tyner constexpr auto function = "GetObject";
74659e65cfSBen Tyner
75324234b4SBen Tyner auto method = bus.new_method_call(objectMapperService, objectMapperPath,
76324234b4SBen Tyner objectMapperInterface, function);
77324234b4SBen Tyner
78324234b4SBen Tyner // Find services that implement the object path, constrain the search
79324234b4SBen Tyner // to the given interface.
80324234b4SBen Tyner method.append(i_path, std::vector<std::string>{i_interface});
81324234b4SBen Tyner
82324234b4SBen Tyner auto reply = bus.call(method);
83324234b4SBen Tyner
84324234b4SBen Tyner // response is a map of service names to their interfaces
85324234b4SBen Tyner std::map<DBusService, DBusInterfaceList> response;
86324234b4SBen Tyner reply.read(response);
87324234b4SBen Tyner
88324234b4SBen Tyner if (!response.empty())
89324234b4SBen Tyner {
90324234b4SBen Tyner // return the service
91324234b4SBen Tyner o_service = response.begin()->first;
92324234b4SBen Tyner
93324234b4SBen Tyner rc = 0; // success
94324234b4SBen Tyner }
95324234b4SBen Tyner }
96324234b4SBen Tyner catch (const sdbusplus::exception::SdBusError& e)
97324234b4SBen Tyner {
98324234b4SBen Tyner trace::err("util::dbus::map exception");
99324234b4SBen Tyner std::string traceMsg = std::string(e.what());
100324234b4SBen Tyner trace::err(traceMsg.c_str());
101324234b4SBen Tyner }
102324234b4SBen Tyner
103324234b4SBen Tyner return rc;
104324234b4SBen Tyner }
105324234b4SBen Tyner
106324234b4SBen Tyner /** @brief Read a property from a dbus object interface */
getProperty(const std::string & i_interface,const std::string & i_path,const std::string & i_service,const std::string & i_property,DBusValue & o_response)107324234b4SBen Tyner int getProperty(const std::string& i_interface, const std::string& i_path,
108324234b4SBen Tyner const std::string& i_service, const std::string& i_property,
109324234b4SBen Tyner DBusValue& o_response)
110324234b4SBen Tyner {
111324234b4SBen Tyner int rc = 1; // assume not success
112324234b4SBen Tyner
113324234b4SBen Tyner auto bus = sdbusplus::bus::new_default();
114324234b4SBen Tyner
115659e65cfSBen Tyner try
116659e65cfSBen Tyner {
117324234b4SBen Tyner constexpr auto interface = "org.freedesktop.DBus.Properties";
118324234b4SBen Tyner constexpr auto function = "Get";
119324234b4SBen Tyner
120324234b4SBen Tyner // calling the get property method
121324234b4SBen Tyner auto method = bus.new_method_call(i_service.c_str(), i_path.c_str(),
122324234b4SBen Tyner interface, function);
123324234b4SBen Tyner
124324234b4SBen Tyner method.append(i_interface, i_property);
125324234b4SBen Tyner auto reply = bus.call(method);
126324234b4SBen Tyner
127324234b4SBen Tyner // returning the property value
128324234b4SBen Tyner reply.read(o_response);
129324234b4SBen Tyner
130324234b4SBen Tyner rc = 0; // success
131324234b4SBen Tyner }
132324234b4SBen Tyner catch (const sdbusplus::exception::SdBusError& e)
133324234b4SBen Tyner {
134324234b4SBen Tyner trace::err("util::dbus::getProperty exception");
135324234b4SBen Tyner std::string traceMsg = std::string(e.what());
136324234b4SBen Tyner trace::err(traceMsg.c_str());
137324234b4SBen Tyner }
138324234b4SBen Tyner
139324234b4SBen Tyner return rc;
140324234b4SBen Tyner }
141324234b4SBen Tyner
142324234b4SBen Tyner /** @brief Get the IBM compatible names defined for this system */
systemNames()143324234b4SBen Tyner std::vector<std::string> systemNames()
144324234b4SBen Tyner {
145324234b4SBen Tyner std::vector<std::string> names;
146324234b4SBen Tyner
147324234b4SBen Tyner constexpr auto interface =
148324234b4SBen Tyner "xyz.openbmc_project.Configuration.IBMCompatibleSystem";
149324234b4SBen Tyner
150324234b4SBen Tyner DBusService service;
151324234b4SBen Tyner DBusPath path;
152324234b4SBen Tyner
153324234b4SBen Tyner // find a dbus object and path that implements the interface
154324234b4SBen Tyner if (0 == find(interface, path, service))
155324234b4SBen Tyner {
156324234b4SBen Tyner DBusValue value;
157324234b4SBen Tyner
158324234b4SBen Tyner // compatible system names are implemented as a property
159324234b4SBen Tyner constexpr auto property = "Names";
160324234b4SBen Tyner
161324234b4SBen Tyner if (0 == getProperty(interface, path, service, property, value))
162324234b4SBen Tyner {
163324234b4SBen Tyner // return value is a variant, names are in the vector
164324234b4SBen Tyner names = std::get<std::vector<std::string>>(value);
165324234b4SBen Tyner }
166324234b4SBen Tyner }
167324234b4SBen Tyner
168324234b4SBen Tyner return names;
169324234b4SBen Tyner }
170324234b4SBen Tyner
1719306716dSBen Tyner /** @brief Transition the host state */
transitionHost(const HostState i_hostState)1729306716dSBen Tyner void transitionHost(const HostState i_hostState)
1739306716dSBen Tyner {
1749306716dSBen Tyner try
1759306716dSBen Tyner {
1769306716dSBen Tyner // We will be transitioning host by starting appropriate dbus target
1779306716dSBen Tyner std::string target = "obmc-host-quiesce@0.target"; // quiesce is default
1789306716dSBen Tyner
1799306716dSBen Tyner // crash (mpipl) mode state requested
1809306716dSBen Tyner if (HostState::Crash == i_hostState)
1819306716dSBen Tyner {
1829306716dSBen Tyner target = "obmc-host-crash@0.target";
1839306716dSBen Tyner }
1849306716dSBen Tyner
1851ff926e0SAndrew Geissler // If the system is powering off for any reason (ex. we hit a PHYP TI
1861ff926e0SAndrew Geissler // in the graceful power off path), then we want to call the immediate
1871ff926e0SAndrew Geissler // power off target
1881ff926e0SAndrew Geissler if (hostRunningState() == HostRunningState::Stopping)
1891ff926e0SAndrew Geissler {
1901ff926e0SAndrew Geissler trace::inf("system is powering off so no dump will be requested");
1911ff926e0SAndrew Geissler target = "obmc-chassis-hard-poweroff@0.target";
1921ff926e0SAndrew Geissler }
1931ff926e0SAndrew Geissler
1949306716dSBen Tyner auto bus = sdbusplus::bus::new_system();
1959306716dSBen Tyner auto method = bus.new_method_call(
1969306716dSBen Tyner "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
1979306716dSBen Tyner "org.freedesktop.systemd1.Manager", "StartUnit");
1989306716dSBen Tyner
1999306716dSBen Tyner method.append(target); // target unit to start
2009306716dSBen Tyner method.append("replace"); // mode = replace conflicting queued jobs
2019306716dSBen Tyner
2029306716dSBen Tyner bus.call_noreply(method); // start the service
2039306716dSBen Tyner }
2049306716dSBen Tyner catch (const sdbusplus::exception::SdBusError& e)
2059306716dSBen Tyner {
2069306716dSBen Tyner trace::err("util::dbus::transitionHost exception");
2079306716dSBen Tyner std::string traceMsg = std::string(e.what());
2089306716dSBen Tyner trace::err(traceMsg.c_str());
2099306716dSBen Tyner }
2109306716dSBen Tyner }
2119306716dSBen Tyner
21239fcf65dSBen Tyner /** @brief Read state of autoRebootEnabled property via dbus */
autoRebootEnabled()213ffb4867fSBen Tyner bool autoRebootEnabled()
214ffb4867fSBen Tyner {
21539fcf65dSBen Tyner // Assume true in case autoRebootEnbabled property is not available
21639fcf65dSBen Tyner bool autoReboot = true;
217ffb4867fSBen Tyner
218ffb4867fSBen Tyner constexpr auto interface = "xyz.openbmc_project.Control.Boot.RebootPolicy";
219ffb4867fSBen Tyner
22039fcf65dSBen Tyner DBusService service; // will find this
22139fcf65dSBen Tyner DBusPath path; // will find this
222ffb4867fSBen Tyner
223ffb4867fSBen Tyner // find a dbus object and path that implements the interface
224ffb4867fSBen Tyner if (0 == find(interface, path, service))
225ffb4867fSBen Tyner {
226ffb4867fSBen Tyner DBusValue value;
227ffb4867fSBen Tyner
228ffb4867fSBen Tyner // autoreboot policy is implemented as a property
229ffb4867fSBen Tyner constexpr auto property = "AutoReboot";
230ffb4867fSBen Tyner
231ffb4867fSBen Tyner if (0 == getProperty(interface, path, service, property, value))
232ffb4867fSBen Tyner {
233ffb4867fSBen Tyner // return value is a variant, autoreboot policy is boolean
234ffb4867fSBen Tyner autoReboot = std::get<bool>(value);
235ffb4867fSBen Tyner }
236ffb4867fSBen Tyner }
237ffb4867fSBen Tyner
238ffb4867fSBen Tyner return autoReboot;
239ffb4867fSBen Tyner }
240ffb4867fSBen Tyner
241fe2c50d7SBen Tyner /** @brief Get the running state of the host */
hostRunningState()242fe2c50d7SBen Tyner HostRunningState hostRunningState()
243fe2c50d7SBen Tyner {
244fe2c50d7SBen Tyner // assume not able to get host running state
245fe2c50d7SBen Tyner HostRunningState host = HostRunningState::Unknown;
246fe2c50d7SBen Tyner
247fe2c50d7SBen Tyner constexpr auto interface = "xyz.openbmc_project.State.Boot.Progress";
248fe2c50d7SBen Tyner
249fe2c50d7SBen Tyner DBusService service;
250fe2c50d7SBen Tyner DBusPath path;
251fe2c50d7SBen Tyner
252fe2c50d7SBen Tyner // find a dbus object and path that implements the interface
253fe2c50d7SBen Tyner if (0 == find(interface, path, service))
254fe2c50d7SBen Tyner {
255fe2c50d7SBen Tyner DBusValue value;
256fe2c50d7SBen Tyner
257fe2c50d7SBen Tyner // boot progress is implemented as a property
258fe2c50d7SBen Tyner constexpr auto property = "BootProgress";
259fe2c50d7SBen Tyner
260fe2c50d7SBen Tyner if (0 == getProperty(interface, path, service, property, value))
261fe2c50d7SBen Tyner {
262fe2c50d7SBen Tyner // return value is a variant, progress is in the vector of strings
263fe2c50d7SBen Tyner std::string bootProgress(std::get<std::string>(value));
264fe2c50d7SBen Tyner
265fe2c50d7SBen Tyner // convert boot progress to host state
266fe2c50d7SBen Tyner using BootProgress = sdbusplus::xyz::openbmc_project::State::Boot::
267fe2c50d7SBen Tyner server::Progress::ProgressStages;
268fe2c50d7SBen Tyner
269fe2c50d7SBen Tyner BootProgress stage = sdbusplus::xyz::openbmc_project::State::Boot::
270fe2c50d7SBen Tyner server::Progress::convertProgressStagesFromString(bootProgress);
271fe2c50d7SBen Tyner
272fe2c50d7SBen Tyner if ((stage == BootProgress::SystemInitComplete) ||
273fe2c50d7SBen Tyner (stage == BootProgress::OSRunning))
274fe2c50d7SBen Tyner {
275fe2c50d7SBen Tyner host = HostRunningState::Started;
276fe2c50d7SBen Tyner }
277fe2c50d7SBen Tyner else
278fe2c50d7SBen Tyner {
279fe2c50d7SBen Tyner host = HostRunningState::NotStarted;
280fe2c50d7SBen Tyner }
281fe2c50d7SBen Tyner }
282fe2c50d7SBen Tyner }
283fe2c50d7SBen Tyner
2841ff926e0SAndrew Geissler // See if host in process of powering off when we get NotStarted
2851ff926e0SAndrew Geissler if (host == HostRunningState::NotStarted)
2861ff926e0SAndrew Geissler {
2871ff926e0SAndrew Geissler constexpr auto hostStateInterface = "xyz.openbmc_project.State.Host";
2881ff926e0SAndrew Geissler if (0 == find(hostStateInterface, path, service))
2891ff926e0SAndrew Geissler {
2901ff926e0SAndrew Geissler DBusValue value;
2911ff926e0SAndrew Geissler
2921ff926e0SAndrew Geissler // current host state is implemented as a property
2931ff926e0SAndrew Geissler constexpr auto stateProperty = "CurrentHostState";
2941ff926e0SAndrew Geissler
2951ff926e0SAndrew Geissler if (0 == getProperty(hostStateInterface, path, service,
2961ff926e0SAndrew Geissler stateProperty, value))
2971ff926e0SAndrew Geissler {
2981ff926e0SAndrew Geissler // return value is a variant, host state is in the vector of
2991ff926e0SAndrew Geissler // strings
3001ff926e0SAndrew Geissler std::string hostState(std::get<std::string>(value));
3011ff926e0SAndrew Geissler if (hostState == "xyz.openbmc_project.State.Host.HostState."
3021ff926e0SAndrew Geissler "TransitioningToOff")
3031ff926e0SAndrew Geissler {
3041ff926e0SAndrew Geissler host = HostRunningState::Stopping;
3051ff926e0SAndrew Geissler }
3061ff926e0SAndrew Geissler }
3071ff926e0SAndrew Geissler }
3081ff926e0SAndrew Geissler }
3091ff926e0SAndrew Geissler
310fe2c50d7SBen Tyner return host;
311fe2c50d7SBen Tyner }
312fe2c50d7SBen Tyner
31339fcf65dSBen Tyner /** @brief Read state of dumpPolicyEnabled property via dbus */
dumpPolicyEnabled()31439fcf65dSBen Tyner bool dumpPolicyEnabled()
31539fcf65dSBen Tyner {
31639fcf65dSBen Tyner // Assume true In case dumpPolicyEnabled property is not available
31739fcf65dSBen Tyner bool dumpPolicyEnabled = true;
31839fcf65dSBen Tyner
31939fcf65dSBen Tyner constexpr auto interface = "xyz.openbmc_project.Object.Enable";
32039fcf65dSBen Tyner constexpr auto path = "/xyz/openbmc_project/dump/system_dump_policy";
32139fcf65dSBen Tyner
32239fcf65dSBen Tyner DBusService service; // will find this
32339fcf65dSBen Tyner
32439fcf65dSBen Tyner // find a dbus object and path that implements the interface
32539fcf65dSBen Tyner if (0 == findService(interface, path, service))
32639fcf65dSBen Tyner {
32739fcf65dSBen Tyner DBusValue value;
32839fcf65dSBen Tyner
32939fcf65dSBen Tyner // autoreboot policy is implemented as a property
33039fcf65dSBen Tyner constexpr auto property = "Enabled";
33139fcf65dSBen Tyner
33239fcf65dSBen Tyner if (0 == getProperty(interface, path, service, property, value))
33339fcf65dSBen Tyner {
33439fcf65dSBen Tyner // return value is a variant, dump policy enabled is a boolean
33539fcf65dSBen Tyner dumpPolicyEnabled = std::get<bool>(value);
33639fcf65dSBen Tyner }
33739fcf65dSBen Tyner }
33839fcf65dSBen Tyner
33939fcf65dSBen Tyner return dumpPolicyEnabled;
34039fcf65dSBen Tyner }
34139fcf65dSBen Tyner
3421315968cSBen Tyner /** @brief Create a PEL */
createPel(const std::string & i_message,const std::string & i_severity,std::map<std::string,std::string> & io_additional,const std::vector<util::FFDCTuple> & i_ffdc)3431315968cSBen Tyner uint32_t createPel(const std::string& i_message, const std::string& i_severity,
3441315968cSBen Tyner std::map<std::string, std::string>& io_additional,
3451315968cSBen Tyner const std::vector<util::FFDCTuple>& i_ffdc)
3461315968cSBen Tyner {
3471315968cSBen Tyner // CreatePELWithFFDCFiles returns plid
3481315968cSBen Tyner int plid = 0;
3491315968cSBen Tyner
3501315968cSBen Tyner // Sdbus call specifics
3511315968cSBen Tyner constexpr auto interface = "org.open_power.Logging.PEL";
3521315968cSBen Tyner constexpr auto path = "/xyz/openbmc_project/logging";
3531315968cSBen Tyner
3541315968cSBen Tyner // we need to find the service implementing the interface
3551315968cSBen Tyner util::dbus::DBusService service;
3561315968cSBen Tyner
3571315968cSBen Tyner if (0 == findService(interface, path, service))
3581315968cSBen Tyner {
3591315968cSBen Tyner try
3601315968cSBen Tyner {
3611315968cSBen Tyner constexpr auto function = "CreatePELWithFFDCFiles";
3621315968cSBen Tyner
3631315968cSBen Tyner // The "Create" method requires manually adding the process ID.
3641315968cSBen Tyner io_additional["_PID"] = std::to_string(getpid());
3651315968cSBen Tyner
3661315968cSBen Tyner // create dbus method
3671315968cSBen Tyner auto bus = sdbusplus::bus::new_system();
368e212fb06SPatrick Williams sdbusplus::message_t method =
3691315968cSBen Tyner bus.new_method_call(service.c_str(), path, interface, function);
3701315968cSBen Tyner
3711315968cSBen Tyner // append additional dbus call paramaters
3721315968cSBen Tyner method.append(i_message, i_severity, io_additional, i_ffdc);
3731315968cSBen Tyner
3741315968cSBen Tyner // using system dbus
3751315968cSBen Tyner auto response = bus.call(method);
3761315968cSBen Tyner
3771315968cSBen Tyner // reply will be tuple containing bmc log id, platform log id
3781315968cSBen Tyner std::tuple<uint32_t, uint32_t> reply = {0, 0};
3791315968cSBen Tyner
3801315968cSBen Tyner // parse dbus response into reply
3811315968cSBen Tyner response.read(reply);
3821315968cSBen Tyner plid = std::get<1>(reply); // platform log id is tuple "second"
3831315968cSBen Tyner }
3841315968cSBen Tyner catch (const sdbusplus::exception::SdBusError& e)
3851315968cSBen Tyner {
3861315968cSBen Tyner trace::err("createPel exception");
3871315968cSBen Tyner trace::err(e.what());
3881315968cSBen Tyner }
3891315968cSBen Tyner }
3901315968cSBen Tyner
3911315968cSBen Tyner return plid; // platform log id or 0
3921315968cSBen Tyner }
3931315968cSBen Tyner
getMachineType()394626270afSCaleb Palmer MachineType getMachineType()
395626270afSCaleb Palmer {
396626270afSCaleb Palmer // default to Rainier 2S4U
397626270afSCaleb Palmer MachineType machineType = MachineType::Rainier_2S4U;
398626270afSCaleb Palmer
399626270afSCaleb Palmer // The return value of the dbus operation is a vector of 4 uint8_ts
400626270afSCaleb Palmer std::vector<uint8_t> ids;
401626270afSCaleb Palmer
402626270afSCaleb Palmer constexpr auto interface = "com.ibm.ipzvpd.VSBP";
403626270afSCaleb Palmer
404626270afSCaleb Palmer DBusService service;
405626270afSCaleb Palmer DBusPath path;
406626270afSCaleb Palmer
407626270afSCaleb Palmer if (0 == find(interface, path, service))
408626270afSCaleb Palmer {
409626270afSCaleb Palmer DBusValue value;
410626270afSCaleb Palmer
411626270afSCaleb Palmer // Machine ID is given from the "IM" keyword
412626270afSCaleb Palmer constexpr auto property = "IM";
413626270afSCaleb Palmer
414626270afSCaleb Palmer if (0 == getProperty(interface, path, service, property, value))
415626270afSCaleb Palmer {
416626270afSCaleb Palmer // return value is a variant, ID value is a vector of 4 uint8_ts
417626270afSCaleb Palmer ids = std::get<std::vector<uint8_t>>(value);
418626270afSCaleb Palmer
419626270afSCaleb Palmer // Convert the returned ID value to a hex string to determine
420626270afSCaleb Palmer // machine type. The hex values corresponding to the machine type
421626270afSCaleb Palmer // are defined in /openbmc/openpower-vpd-parser/const.hpp
422626270afSCaleb Palmer // RAINIER_2S4U == 0x50001000
423626270afSCaleb Palmer // RAINIER_2S2U == 0x50001001
424626270afSCaleb Palmer // RAINIER_1S4U == 0x50001002
425626270afSCaleb Palmer // RAINIER_1S2U == 0x50001003
426626270afSCaleb Palmer // EVEREST == 0x50003000
427a7dc66baSZane Shelley // BONNELL == 0x50004000
428626270afSCaleb Palmer try
429626270afSCaleb Palmer {
430626270afSCaleb Palmer // Format the vector into a single hex string to compare to.
431a0c724d3SPatrick Williams std::string hexId =
432a0c724d3SPatrick Williams std::format("0x{:02x}{:02x}{:02x}{:02x}", ids.at(0),
433a0c724d3SPatrick Williams ids.at(1), ids.at(2), ids.at(3));
434626270afSCaleb Palmer
435626270afSCaleb Palmer std::map<std::string, MachineType> typeMap = {
436626270afSCaleb Palmer {"0x50001000", MachineType::Rainier_2S4U},
437626270afSCaleb Palmer {"0x50001001", MachineType::Rainier_2S2U},
438626270afSCaleb Palmer {"0x50001002", MachineType::Rainier_1S4U},
439626270afSCaleb Palmer {"0x50001003", MachineType::Rainier_1S2U},
440626270afSCaleb Palmer {"0x50003000", MachineType::Everest},
441a7dc66baSZane Shelley {"0x50004000", MachineType::Bonnell},
442*df9f8e40SZane Shelley {"0x60001000", MachineType::BlueRidge_2S4U},
443*df9f8e40SZane Shelley {"0x60001001", MachineType::BlueRidge_2S2U},
444*df9f8e40SZane Shelley {"0x60001002", MachineType::BlueRidge_1S4U},
445*df9f8e40SZane Shelley {"0x60002000", MachineType::Fuji},
446*df9f8e40SZane Shelley {"0x60004000", MachineType::Balcones},
447626270afSCaleb Palmer };
448626270afSCaleb Palmer
449626270afSCaleb Palmer machineType = typeMap.at(hexId);
450626270afSCaleb Palmer }
451626270afSCaleb Palmer catch (const std::out_of_range& e)
452626270afSCaleb Palmer {
453626270afSCaleb Palmer trace::err("Out of range exception caught from returned "
454626270afSCaleb Palmer "machine ID.");
455626270afSCaleb Palmer for (const auto& id : ids)
456626270afSCaleb Palmer {
457626270afSCaleb Palmer trace::err("Returned Machine ID value: 0x%x", id);
458626270afSCaleb Palmer }
459626270afSCaleb Palmer throw;
460626270afSCaleb Palmer }
461626270afSCaleb Palmer }
462626270afSCaleb Palmer }
463626270afSCaleb Palmer else
464626270afSCaleb Palmer {
465626270afSCaleb Palmer throw std::invalid_argument(
466626270afSCaleb Palmer "Unable to find dbus service to get machine type.");
467626270afSCaleb Palmer }
468626270afSCaleb Palmer
469626270afSCaleb Palmer return machineType;
470626270afSCaleb Palmer }
471626270afSCaleb Palmer
47288b10093SBen Tyner /** @brief Get list of state effecter PDRs */
getStateEffecterPdrs(std::vector<std::vector<uint8_t>> & pdrList,uint16_t stateSetId)47388b10093SBen Tyner bool getStateEffecterPdrs(std::vector<std::vector<uint8_t>>& pdrList,
47488b10093SBen Tyner uint16_t stateSetId)
47588b10093SBen Tyner {
47688b10093SBen Tyner constexpr auto service = "xyz.openbmc_project.PLDM";
47788b10093SBen Tyner constexpr auto path = "/xyz/openbmc_project/pldm";
47888b10093SBen Tyner constexpr auto interface = "xyz.openbmc_project.PLDM.PDR";
47988b10093SBen Tyner constexpr auto function = "FindStateEffecterPDR";
480324234b4SBen Tyner
48188b10093SBen Tyner constexpr uint16_t PLDM_ENTITY_PROC = 135;
48288b10093SBen Tyner
48388b10093SBen Tyner try
48488b10093SBen Tyner {
48588b10093SBen Tyner // create dbus method
48688b10093SBen Tyner auto bus = sdbusplus::bus::new_default();
487a0c724d3SPatrick Williams sdbusplus::message_t method =
488a0c724d3SPatrick Williams bus.new_method_call(service, path, interface, function);
48988b10093SBen Tyner
49088b10093SBen Tyner // append additional method data
49188b10093SBen Tyner method.append(terminusIdZero, PLDM_ENTITY_PROC, stateSetId);
49288b10093SBen Tyner
49388b10093SBen Tyner // request PDRs
49488b10093SBen Tyner auto reply = bus.call(method);
49588b10093SBen Tyner reply.read(pdrList);
49688b10093SBen Tyner }
49788b10093SBen Tyner catch (const sdbusplus::exception_t& e)
49888b10093SBen Tyner {
49988b10093SBen Tyner trace::err("failed to find state effecter PDRs");
50088b10093SBen Tyner trace::err(e.what());
50188b10093SBen Tyner return false;
50288b10093SBen Tyner }
50388b10093SBen Tyner
50488b10093SBen Tyner return true;
50588b10093SBen Tyner }
50688b10093SBen Tyner
50788b10093SBen Tyner /** @brief Get list of state sensor PDRs */
getStateSensorPdrs(std::vector<std::vector<uint8_t>> & pdrList,uint16_t stateSetId)50888b10093SBen Tyner bool getStateSensorPdrs(std::vector<std::vector<uint8_t>>& pdrList,
50988b10093SBen Tyner uint16_t stateSetId)
51088b10093SBen Tyner {
51188b10093SBen Tyner constexpr auto service = "xyz.openbmc_project.PLDM";
51288b10093SBen Tyner constexpr auto path = "/xyz/openbmc_project/pldm";
51388b10093SBen Tyner constexpr auto interface = "xyz.openbmc_project.PLDM.PDR";
51488b10093SBen Tyner constexpr auto function = "FindStateSensorPDR";
51588b10093SBen Tyner
51688b10093SBen Tyner constexpr uint16_t PLDM_ENTITY_PROC = 135;
51788b10093SBen Tyner
51888b10093SBen Tyner try
51988b10093SBen Tyner {
52088b10093SBen Tyner // create dbus method
52188b10093SBen Tyner auto bus = sdbusplus::bus::new_default();
522a0c724d3SPatrick Williams sdbusplus::message_t method =
523a0c724d3SPatrick Williams bus.new_method_call(service, path, interface, function);
52488b10093SBen Tyner
52588b10093SBen Tyner // append additional method data
52688b10093SBen Tyner method.append(terminusIdZero, PLDM_ENTITY_PROC, stateSetId);
52788b10093SBen Tyner
52888b10093SBen Tyner // request PDRs
52988b10093SBen Tyner auto reply = bus.call(method);
53088b10093SBen Tyner reply.read(pdrList);
53188b10093SBen Tyner }
53288b10093SBen Tyner catch (const sdbusplus::exception_t& e)
53388b10093SBen Tyner {
53488b10093SBen Tyner trace::err("failed to find state sensor PDRs");
53588b10093SBen Tyner trace::err(e.what());
53688b10093SBen Tyner return false;
53788b10093SBen Tyner }
53888b10093SBen Tyner
53988b10093SBen Tyner return true;
54088b10093SBen Tyner }
54188b10093SBen Tyner
5422b26b2bbSBen Tyner /** @brief Determine if power fault was detected */
powerFault()5432b26b2bbSBen Tyner bool powerFault()
5442b26b2bbSBen Tyner {
5452b26b2bbSBen Tyner // power fault based on pgood property
5462b26b2bbSBen Tyner int32_t pgood = 0; // assume fault or unknown
5472b26b2bbSBen Tyner
5482b26b2bbSBen Tyner constexpr auto interface = "org.openbmc.control.Power";
5492b26b2bbSBen Tyner
5502b26b2bbSBen Tyner DBusService service;
5512b26b2bbSBen Tyner DBusPath path;
5522b26b2bbSBen Tyner
5532b26b2bbSBen Tyner // find a dbus service and object path that implements the interface
5542b26b2bbSBen Tyner if (0 == find(interface, path, service))
5552b26b2bbSBen Tyner {
5562b26b2bbSBen Tyner DBusValue value;
5572b26b2bbSBen Tyner
5582b26b2bbSBen Tyner // chassis pgood is implemented as a property
5592b26b2bbSBen Tyner constexpr auto property = "pgood";
5602b26b2bbSBen Tyner
5612b26b2bbSBen Tyner if (0 == getProperty(interface, path, service, property, value))
5622b26b2bbSBen Tyner {
5632b26b2bbSBen Tyner // return value is a variant, int32 == 1 for pgood OK
5642b26b2bbSBen Tyner pgood = std::get<int32_t>(value);
5652b26b2bbSBen Tyner }
5662b26b2bbSBen Tyner }
5672b26b2bbSBen Tyner
5682b26b2bbSBen Tyner return pgood != 1 ? true : false; // if not pgood then power fault
5692b26b2bbSBen Tyner }
5702b26b2bbSBen Tyner
57188b10093SBen Tyner } // namespace dbus
572324234b4SBen Tyner } // namespace util
573