blob: bc70d845254ab6cc665b583d955e9481174888a3 [file] [log] [blame]
Vernon Mauerya3702c12019-05-22 13:20:59 -07001/*
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#include <variantvisitors.hpp>
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
33namespace ipmi
34{
35
36// TODO: Service names may change. Worth to consider dynamic detection.
37static constexpr const char* fanService = "xyz.openbmc_project.FanSensor";
38static constexpr const char* gpioService = "xyz.openbmc_project.Gpio";
39static constexpr const char* ledServicePrefix =
40 "xyz.openbmc_project.LED.Controller.";
41
42static constexpr const char* ledPathPrefix =
43 "/xyz/openbmc_project/led/physical/";
44static constexpr const char* fanPwmPath =
45 "/xyz/openbmc_project/sensors/fan_pwm/Pwm_";
46static constexpr const char* fanTachPathPrefix =
47 "/xyz/openbmc_project/sensors/fan_tach/Fan_";
48
49static constexpr const char* fanIntf = "xyz.openbmc_project.Sensor.Value";
50static constexpr const char* gpioIntf = "xyz.openbmc_project.Control.Gpio";
51static constexpr const char* ledIntf = "xyz.openbmc_project.Led.Physical";
52
53static constexpr const char* busPropertyIntf =
54 "org.freedesktop.DBus.Properties";
55static constexpr const char* ledStateStr =
56 "xyz.openbmc_project.Led.Physical.Action."; // Comes with postfix Off/On
57static constexpr const char* smGetSignalPathPrefix =
58 "/xyz/openbmc_project/control/gpio/";
59
60/** @enum MtmLvl
61.*
62 * Manufacturing command access levels
63 */
64enum class MtmLvl
65{
66 mtmNotRunning = 0x00,
67 mtmExpired = 0x01,
68 mtmAvailable = 0x02,
69};
70
71enum class SmActionGet : uint8_t
72{
73 sample = 0,
74 ignore = 1,
75 revert = 2
76};
77
78enum class SmActionSet : uint8_t
79{
80 forceDeasserted = 0,
81 forceAsserted = 1,
82 revert = 2
83};
84
85enum class SmSignalGet : uint8_t
86{
87 smPowerButton = 0,
88 smResetButton = 1,
89 smSleepButton,
90 smNmiButton = 3,
91 smChassisIntrusion = 4,
92 smPowerGood,
93 smPowerRequestGet,
94 smSleepRequestGet,
95 smFrbTimerHaltGet,
96 smForceUpdate,
97 smRingIndication,
98 smCarrierDetect,
99 smIdentifyButton = 0xc,
100 smFanPwmGet = 0xd,
101 smSignalReserved,
102 smFanTachometerGet = 0xf,
103 smNcsiDiag = 0x10,
104 smFpLcpLeftButton = 0x11,
105 smFpLcpRightButton,
106 smFpLcpEnterButton,
107 smGetSignalMax
108};
109
110enum class SmSignalSet : uint8_t
111{
112 smPowerLed = 0,
113 smPowerFaultLed,
114 smClusterLed,
115 smDiskFaultLed,
116 smCoolingFaultLed,
117 smFanPowerSpeed = 5,
118 smPowerRequestSet,
119 smSleepRequestSet,
120 smAcpiSci,
121 smSpeaker,
122 smFanPackFaultLed,
123 smCpuFailLed,
124 smDimmFailLed,
125 smIdentifyLed,
126 smHddLed,
127 smSystemReadyLed,
128 smLcdBacklight = 0x10,
129 smSetSignalMax
130};
131
132struct SetSmSignalReq
133{
134 SmSignalSet Signal;
135 uint8_t Instance;
136 SmActionSet Action;
137 uint8_t Value;
138};
139
140struct GetSmSignalReq
141{
142 SmSignalGet Signal;
143 uint8_t Instance;
144 SmActionGet Action;
145};
146
147struct GetSmSignalRsp
148{
149 uint8_t SigVal;
150 uint8_t SigVal1;
151 uint8_t SigVal2;
152};
153
154class LedProperty
155{
156 SmSignalSet signal;
157 std::string name;
158 std::string prevState;
159 std::string currentState;
160 bool isLocked;
161
162 public:
163 LedProperty(SmSignalSet signal_, std::string name_) :
164 signal(signal_), name(name_), prevState(""), isLocked(false)
165 {
166 }
167
168 LedProperty() = delete;
169
170 SmSignalSet getSignal() const
171 {
172 return signal;
173 }
174
175 void setLock(const bool& lock)
176 {
177 isLocked = lock;
178 }
179 void setPrevState(const std::string& state)
180 {
181 prevState = state;
182 }
183 void setCurrState(const std::string& state)
184 {
185 currentState = state;
186 }
187 std::string getCurrState() const
188 {
189 return currentState;
190 }
191 bool getLock() const
192 {
193 return isLocked;
194 }
195 std::string getPrevState() const
196 {
197 return prevState;
198 }
199 std::string getName() const
200 {
201 return name;
202 }
203};
204
205/** @class Manufacturing
206 *
207 * @brief Implemet commands to support Manufacturing Test Mode.
208 */
209class Manufacturing
210{
211 std::string path;
212 std::string gpioPaths[(uint8_t)SmSignalGet::smGetSignalMax];
213 std::vector<LedProperty> ledPropertyList;
214 void initData();
215
216 public:
217 Manufacturing();
218
219 ipmi_return_codes detectAccessLvl(ipmi_request_t request,
220 ipmi_data_len_t req_len);
221
222 LedProperty* findLedProperty(const SmSignalSet& signal)
223 {
224 auto it = std::find_if(ledPropertyList.begin(), ledPropertyList.end(),
225 [&signal](const LedProperty& led) {
226 return led.getSignal() == signal;
227 });
228 if (it != ledPropertyList.end())
229 {
230 return &(*it);
231 }
232 return nullptr;
233 }
234
235 std::string getLedPropertyName(const SmSignalSet signal)
236 {
237 LedProperty* led = findLedProperty(signal);
238 if (led != nullptr)
239 {
240 return led->getName();
241 }
242 else
243 {
244 return "";
245 }
246 }
247
248 int8_t getProperty(const char* service, std::string path,
249 const char* interface, std::string propertyName,
250 ipmi::Value* value);
251 int8_t setProperty(const char* service, std::string path,
252 const char* interface, std::string propertyName,
253 ipmi::Value value);
254 int8_t disablePidControlService(const bool disable);
255
256 void revertTimerHandler();
257
258 std::tuple<uint8_t, ipmi_ret_t, uint8_t> proccessSignal(SmSignalGet signal,
259 SmActionGet action);
260
261 std::string getGpioPathForSmSignal(uint8_t gpioInstane)
262 {
263 return smGetSignalPathPrefix + gpioPaths[gpioInstane];
264 }
265
266 MtmLvl getAccessLvl(void)
267 {
268 static MtmLvl mtmMode = MtmLvl::mtmNotRunning;
269 if (mtmMode != MtmLvl::mtmExpired)
270 {
271 ipmi::Value mode;
272 if (getProperty("xyz.openbmc_project.SpeciaMode",
273 "/xyz/openbmc_project/security/specialMode",
274 "xyz.openbmc_project.Security.SpecialMode",
275 "SpecialMode", &mode) != 0)
276 {
277 mtmMode = MtmLvl::mtmExpired;
278 return mtmMode;
279 }
280 mtmMode = static_cast<MtmLvl>(std::get<std::uint8_t>(mode));
281 }
282 return mtmMode;
283 }
284
285 std::vector<SmSignalGet> revertSmSignalGetVector;
286 bool revertFanPWM = false;
287 bool revertLedCallback = false;
288 phosphor::Timer revertTimer;
289};
290
291} // namespace ipmi