1 /*
2 // Copyright (c) 2018 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16 
17 #pragma once
18 
19 #include <ipmid/api-types.hpp>
20 #include <ipmid/utils.hpp>
21 #include <phosphor-logging/log.hpp>
22 #include <sdbusplus/bus.hpp>
23 #include <sdbusplus/message.hpp>
24 #include <sdbusplus/timer.hpp>
25 
26 #include <vector>
27 
28 #define FAN_SENSOR_NOT_PRESENT (0 << 0)
29 #define FAN_SENSOR_PRESENT (1 << 0)
30 #define FAN_NOT_PRESENT (0 << 1)
31 #define FAN_PRESENT (1 << 1)
32 
33 namespace ipmi
34 {
35 
36 // TODO: Service names may change. Worth to consider dynamic detection.
37 static constexpr const char* fanService = "xyz.openbmc_project.FanSensor";
38 static constexpr const char* buttonService =
39     "xyz.openbmc_project.Chassis.Buttons";
40 static constexpr const char* ledService = "xyz.openbmc_project.LED.Controller";
41 
42 static constexpr const char* ledPathPrefix =
43     "/xyz/openbmc_project/led/physical/";
44 static constexpr const char* fanPwmPath =
45     "/xyz/openbmc_project/sensors/fan_pwm/";
46 static constexpr const char* fanTachBasePath =
47     "/xyz/openbmc_project/sensors/fan_tach/";
48 
49 static constexpr const char* fanIntf = "xyz.openbmc_project.Sensor.Value";
50 static constexpr const char* buttonIntf = "xyz.openbmc_project.Chassis.Buttons";
51 static constexpr const char* ledIntf = "xyz.openbmc_project.Led.Physical";
52 
53 static constexpr const char* intrusionService =
54     "xyz.openbmc_project.IntrusionSensor";
55 static constexpr const char* intrusionPath =
56     "/xyz/openbmc_project/Intrusion/Chassis_Intrusion";
57 static constexpr const char* intrusionIntf =
58     "xyz.openbmc_project.Chassis.Intrusion";
59 
60 static constexpr const char* busPropertyIntf =
61     "org.freedesktop.DBus.Properties";
62 static constexpr const char* ledStateStr =
63     "xyz.openbmc_project.Led.Physical.Action."; // Comes with postfix Off/On
64 
65 static constexpr const char* specialModeService =
66     "xyz.openbmc_project.SpecialMode";
67 static constexpr const char* specialModeObjPath =
68     "/xyz/openbmc_project/security/special_mode";
69 static constexpr const char* specialModeIntf =
70     "xyz.openbmc_project.Security.SpecialMode";
71 
72 static constexpr const char* mctpPcieSlotService =
73     "xyz.openbmc_project.MCTP_SMBus_PCIe_slot";
74 static constexpr const char* mctpHsbpService =
75     "xyz.openbmc_project.MCTP_SMBus_HSBP";
76 static constexpr const char* mctpObjPath = "/xyz/openbmc_project/mctp";
77 static constexpr const char* mctpBaseIntf = "xyz.openbmc_project.MCTP.Base";
78 
79 constexpr const uint8_t slotNumMask = 0x0F;
80 constexpr const uint8_t muxTypeMask = 0xF0;
81 constexpr const uint8_t muxTypeShift = 4;
82 
83 enum class SpecialMode : uint8_t
84 {
85     none = 0,
86     mfg = 1,
87 #ifdef BMC_VALIDATION_UNSECURE_FEATURE
88     valUnsecure = 2
89 #endif
90 };
91 
92 enum class SmActionGet : uint8_t
93 {
94     sample = 0,
95     ignore = 1,
96     revert = 2
97 };
98 
99 enum class SmActionSet : uint8_t
100 {
101     forceDeasserted = 0,
102     forceAsserted = 1,
103     revert = 2
104 };
105 
106 enum class SmSignalGet : uint8_t
107 {
108     smPowerButton = 0,
109     smResetButton = 1,
110     smSleepButton,
111     smNMIButton = 3,
112     smChassisIntrusion = 4,
113     smPowerGood,
114     smPowerRequestGet,
115     smSleepRequestGet,
116     smFrbTimerHaltGet,
117     smForceUpdate,
118     smRingIndication,
119     smCarrierDetect,
120     smIdentifyButton = 0xc,
121     smFanPwmGet = 0xd,
122     smSignalReserved,
123     smFanTachometerGet = 0xf,
124     smNcsiDiag = 0x10,
125     smGetSignalMax
126 };
127 
128 enum class SmSignalSet : uint8_t
129 {
130     smPowerLed = 0,
131     smPowerFaultLed,
132     smClusterLed,
133     smDiskFaultLed,
134     smCoolingFaultLed,
135     smFanPowerSpeed = 5,
136     smPowerRequestSet,
137     smSleepRequestSet,
138     smAcpiSci,
139     smSpeaker,
140     smFanPackFaultLed,
141     smCpuFailLed,
142     smDimmFailLed,
143     smIdentifyLed,
144     smHddLed,
145     smSystemReadyLed,
146     smLcdBacklight = 0x10,
147     smSetSignalMax
148 };
149 
150 /** @enum IntrusionStatus
151 .*
152  *  Intrusion Status
153  */
154 enum class IntrusionStatus : uint8_t
155 {
156     normal = 0,
157     hardwareIntrusion,
158     tamperingDetected
159 };
160 
161 enum SupportedFeatureControls : uint8_t
162 {
163     mctp = 0,
164     pcieScan,
165     mctpSlotSupport
166 };
167 
168 enum SupportedFeatureMuxs : uint8_t
169 {
170     pcieMuxSlot = 0,
171     pcieMcioMuxSlot,
172     pcieM2EdSffMuxSlot,
173     leftRaiserMuxSlot,
174     rightRaiserMuxSlot,
175     HsbpMuxSlot
176 };
177 
178 enum SupportedFeatureActions : uint8_t
179 {
180     stop = 0,
181     start,
182     disable,
183     enable,
184 };
185 
186 enum SupportedMCTPBindings : uint8_t
187 {
188     mctpPCIe = 0,
189     mctpSMBusHSBP,
190     mctpSMBusPCIeSlot
191 };
192 
193 struct SetSmSignalReq
194 {
195     SmSignalSet Signal;
196     uint8_t Instance;
197     SmActionSet Action;
198     uint8_t Value;
199 };
200 
201 class LedProperty
202 {
203     SmSignalSet signal;
204     std::string name;
205     std::string prevState;
206     std::string currentState;
207     bool isLocked;
208 
209   public:
LedProperty(SmSignalSet signal_,std::string name_)210     LedProperty(SmSignalSet signal_, std::string name_) :
211         signal(signal_), name(name_), prevState(""), isLocked(false)
212     {}
213 
214     LedProperty() = delete;
215 
getSignal() const216     SmSignalSet getSignal() const
217     {
218         return signal;
219     }
220 
setLock(const bool & lock)221     void setLock(const bool& lock)
222     {
223         isLocked = lock;
224     }
setPrevState(const std::string & state)225     void setPrevState(const std::string& state)
226     {
227         prevState = state;
228     }
setCurrState(const std::string & state)229     void setCurrState(const std::string& state)
230     {
231         currentState = state;
232     }
getCurrState() const233     std::string getCurrState() const
234     {
235         return currentState;
236     }
getLock() const237     bool getLock() const
238     {
239         return isLocked;
240     }
getPrevState() const241     std::string getPrevState() const
242     {
243         return prevState;
244     }
getName() const245     std::string getName() const
246     {
247         return name;
248     }
249 };
250 
251 /** @class Manufacturing
252  *
253  *  @brief Implemet commands to support Manufacturing Test Mode.
254  */
255 class Manufacturing
256 {
257     std::string path;
258     std::string gpioPaths[(uint8_t)SmSignalGet::smGetSignalMax];
259     std::vector<LedProperty> ledPropertyList;
260     void initData();
261 
262   public:
263     Manufacturing();
264 
265     ipmi_return_codes detectAccessLvl(ipmi_request_t request,
266                                       ipmi_data_len_t req_len);
267 
findLedProperty(const SmSignalSet & signal)268     LedProperty* findLedProperty(const SmSignalSet& signal)
269     {
270         auto it = std::find_if(ledPropertyList.begin(), ledPropertyList.end(),
271                                [&signal](const LedProperty& led) {
272                                    return led.getSignal() == signal;
273                                });
274         if (it != ledPropertyList.end())
275         {
276             return &(*it);
277         }
278         return nullptr;
279     }
280 
getLedPropertyName(const SmSignalSet signal)281     std::string getLedPropertyName(const SmSignalSet signal)
282     {
283         LedProperty* led = findLedProperty(signal);
284         if (led != nullptr)
285         {
286             return led->getName();
287         }
288         else
289         {
290             return "";
291         }
292     }
293 
294     int8_t getProperty(const std::string& service, const std::string& path,
295                        const std::string& interface,
296                        const std::string& propertyName, ipmi::Value* value);
297     int8_t setProperty(const std::string& service, const std::string& path,
298                        const std::string& interface,
299                        const std::string& propertyName, ipmi::Value value);
300     int8_t disablePidControlService(const bool disable);
301 
302     void revertTimerHandler();
303 
getMfgMode(void)304     SpecialMode getMfgMode(void)
305     {
306         ipmi::Value mode;
307         if (getProperty(specialModeService, specialModeObjPath, specialModeIntf,
308                         "SpecialMode", &mode) != 0)
309         {
310             return SpecialMode::none;
311         }
312         if (std::get<std::string>(mode) ==
313             "xyz.openbmc_project.Control.Security.SpecialMode.Modes."
314             "Manufacturing")
315         {
316             return SpecialMode::mfg;
317         }
318 #ifdef BMC_VALIDATION_UNSECURE_FEATURE
319         if (std::get<std::string>(mode) ==
320             "xyz.openbmc_project.Control.Security.SpecialMode.Modes."
321             "ValidationUnsecure")
322         {
323             return SpecialMode::valUnsecure;
324         }
325 #endif
326         return SpecialMode::none;
327     }
328 
329     bool revertFanPWM = false;
330     bool revertLedCallback = false;
331     sdbusplus::Timer revertTimer;
332     int mtmTestBeepFd = -1;
333 };
334 
335 } // namespace ipmi
336