1 #pragma once
2 
3 #include "libpldm/pldm.h"
4 
5 #include "common/instance_id.hpp"
6 #include "common/types.hpp"
7 #include "oem_event_manager.hpp"
8 #include "platform-mc/manager.hpp"
9 #include "requester/handler.hpp"
10 #include "requester/request.hpp"
11 
12 namespace pldm
13 {
14 namespace oem_ampere
15 {
16 using namespace pldm::pdr;
17 
18 using EventToMsgMap_t = std::unordered_map<uint8_t, std::string>;
19 
20 enum sensor_ids
21 {
22     DDR_STATUS = 51,
23     PCP_VR_STATE = 75,
24     SOC_VR_STATE = 80,
25     DPHY_VR1_STATE = 85,
26     DPHY_VR2_STATE = 90,
27     D2D_VR_STATE = 95,
28     IOC_VR1_STATE = 100,
29     IOC_VR2_STATE = 105,
30     PCI_D_VR_STATE = 110,
31     PCI_A_VR_STATE = 115,
32     PCIE_HOT_PLUG = 169,
33     SOC_HEALTH_AVAILABILITY = 170,
34     BOOT_OVERALL = 175,
35     WATCH_DOG = 179,
36 };
37 
38 namespace boot
39 {
40 namespace status
41 {
42 enum boot_status
43 {
44     BOOT_STATUS_SUCCESS = 0x80,
45     BOOT_STATUS_FAILURE = 0x81,
46 };
47 } // namespace status
48 namespace stage
49 {
50 enum boot_stage
51 {
52     UEFI_STATUS_CLASS_CODE_MIN = 0x00,
53     UEFI_STATUS_CLASS_CODE_MAX = 0x7f,
54     SECPRO = 0x90,
55     MPRO = 0x91,
56     ATF_BL1 = 0x92,
57     ATF_BL2 = 0x93,
58     DDR_INITIALIZATION = 0x94,
59     DDR_TRAINING = 0x95,
60     S0_DDR_TRAINING_FAILURE = 0x96,
61     ATF_BL31 = 0x97,
62     ATF_BL32 = 0x98,
63     S1_DDR_TRAINING_FAILURE = 0x99,
64 };
65 } // namespace stage
66 } // namespace boot
67 
68 enum class log_level : int
69 {
70     OK,
71     WARNING,
72     CRITICAL,
73     BIOSFWPANIC,
74 };
75 
76 /*
77  * PresentReading value format
78  * FIELD       |                   COMMENT
79  * Bit 31      |   Reserved
80  * Bit 30:24   |   Media slot number (0 - 63) This field can be used by UEFI
81  *             |   to indicate the media slot number (such as NVMe/SSD slot)
82  *             |   (7 bits)
83  * Bit 23      |   Operation status: 1 = operation failed
84  *             |   0 = operation successful
85  * Bit 22      |   Action: 0 - Insertion 1 - Removal
86  * Bit 21:18   |   Function (4 bits)
87  * Bit 17:13   |   Device (5 bits)
88  * Bit 12:5    |   Bus (8 bits)
89  * Bit 4:0     |   Segment (5 bits)
90  */
91 typedef union
92 {
93     uint32_t value;
94     struct
95     {
96         uint32_t segment:5;
97         uint32_t bus:8;
98         uint32_t device:5;
99         uint32_t function:4;
100         uint32_t action:1;
101         uint32_t opStatus:1;
102         uint32_t mediaSlot:7;
103         uint32_t reserved:1;
104     } __attribute__((packed)) bits;
105 } PCIeHotPlugEventRecord_t;
106 
107 typedef union
108 {
109     uint32_t value;
110     struct
111     {
112         uint32_t type:2;
113         uint32_t mcuRankIdx:3;
114         uint32_t reserved_1:3; // byte0
115         uint32_t sliceNum:4;
116         uint32_t upperNibbStatErr:1;
117         uint32_t lowerNibbStatErr:1;
118         uint32_t reserved_2:2; // byte1
119         uint32_t syndrome:4;
120         uint32_t reserved_3:4; // byte2
121         uint32_t reserved_byte:8;
122     } __attribute__((packed)) bits;
123 } DIMMTrainingFailure_t;
124 
125 namespace ddr
126 {
127 namespace status
128 {
129 enum ddr_status
130 {
131     NO_SYSTEM_LEVEL_ERROR = 0x01,
132     ECC_INITIALIZATION_FAILURE = 0x04,
133     CONFIGURATION_FAILURE = 0x05,
134     TRAINING_FAILURE = 0x06,
135     OTHER_FAILURE = 0x07,
136     BOOT_FAILURE_NO_VALID_CONFIG = 0x08,
137     FAILSAFE_ACTIVATED_NEXT_BOOT_SUCCESS = 0x09,
138 };
139 }
140 } // namespace ddr
141 
142 namespace dimm
143 {
144 namespace status
145 {
146 enum dimm_status
147 {
148     INSTALLED_NO_ERROR = 0x01,
149     NOT_INSTALLED = 0x02,
150     OTHER_FAILURE = 0x07,
151     INSTALLED_BUT_DISABLED = 0x10,
152     TRAINING_FAILURE = 0x12,
153     PMIC_HIGH_TEMP = 0x13,
154     TSx_HIGH_TEMP = 0x14,
155     SPD_HUB_HIGH_TEMP = 0x15,
156     PMIC_TEMP_ALERT = 0x16,
157 };
158 } // namespace status
159 
160 namespace training_failure
161 {
162 enum dimm_training_failure_type
163 {
164     PHY_TRAINING_FAILURE_TYPE = 0x01,
165     DIMM_TRAINING_FAILURE_TYPE = 0x02,
166 };
167 
168 namespace phy_syndrome
169 {
170 enum phy_training_failure_syndrome
171 {
172     NA = 0x00,
173     PHY_TRAINING_SETUP_FAILURE = 0x01,
174     CA_LEVELING = 0x02,
175     PHY_WRITE_LEVEL_FAILURE = 0x03,
176     PHY_READ_GATE_LEVELING_FAILURE = 0x04,
177     PHY_READ_LEVEL_FAILURE = 0x05,
178     WRITE_DQ_LEVELING = 0x06,
179     PHY_SW_TRAINING_FAILURE = 0x07,
180 };
181 } // namespace phy_syndrome
182 
183 namespace dimm_syndrome
184 {
185 enum dimm_training_failure_syndrome
186 {
187     NA = 0x00,
188     DRAM_VREFDQ_TRAINING_FAILURE = 0x01,
189     LRDIMM_DB_TRAINING_FAILURE = 0x02,
190     LRDRIMM_DB_SW_TRAINING_FAILURE = 0x03,
191 };
192 } // namespace dimm_syndrome
193 } // namespace training_failure
194 } // namespace dimm
195 
196 /*
197  * PresentReading value format
198  * FIELD       |                   COMMENT
199  * Bit 31:30   |   Reserved (2 bits)
200  * Bit 29      |   A VR Critical condition observed (1 bit)
201  * Bit 28      |   A VR Warning condition observed (1 bit)
202  * Bit 27:16   |   Reserved (12 bits)
203  * Bit 15:8    |   VR status byte high - The bit definition is the same as the
204  *             |   corresponding VR PMBUS STATUS_WORD (upper byte) (8 bits)
205  * Bit 7:0     |   VR status byte low - The bit definition is the same as the
206  *             |   corresponding VR PMBUS STATUS_WORD (lower byte) (8 bits)
207  */
208 typedef union
209 {
210     uint32_t value;
211     struct
212     {
213         uint32_t vr_status_byte_low:8;
214         uint32_t vr_status_byte_high:8;
215         uint32_t reserved_1:12;
216         uint32_t warning:1;
217         uint32_t critical:1;
218         uint32_t reserved_2:2;
219     } __attribute__((packed)) bits;
220 } VRDStatus_t;
221 
222 /**
223  * @brief OemEventManager
224  *
225  *
226  */
227 class OemEventManager
228 {
229   public:
230     OemEventManager() = delete;
231     OemEventManager(const OemEventManager&) = delete;
232     OemEventManager(OemEventManager&&) = delete;
233     OemEventManager& operator=(const OemEventManager&) = delete;
234     OemEventManager& operator=(OemEventManager&&) = delete;
235     virtual ~OemEventManager() = default;
236 
237     explicit OemEventManager(
238         sdeventplus::Event& event,
239         requester::Handler<requester::Request>* /* handler */,
240         pldm::InstanceIdDb& /* instanceIdDb */) : event(event) {};
241 
242     /** @brief Decode sensor event messages and handle correspondingly.
243      *
244      *  @param[in] request - the request message of sensor event
245      *  @param[in] payloadLength - the payload length of sensor event
246      *  @param[in] formatVersion - the format version of sensor event
247      *  @param[in] tid - TID
248      *  @param[in] eventDataOffset - the event data offset of sensor event
249      *
250      *  @return int - returned error code
251      */
252     int handleSensorEvent(const pldm_msg* request, size_t payloadLength,
253                           uint8_t /* formatVersion */, pldm_tid_t tid,
254                           size_t eventDataOffset);
255 
256   protected:
257     /** @brief Create prefix string for logging message.
258      *
259      *  @param[in] tid - TID
260      *  @param[in] sensorId - Sensor ID
261      *
262      *  @return std::string - the prefeix string
263      */
264     std::string prefixMsgStrCreation(pldm_tid_t tid, uint16_t sensorId);
265 
266     /** @brief Log the message into Redfish SEL.
267      *
268      *  @param[in] description - the logging message
269      *  @param[in] logLevel - the logging level
270      */
271     void sendJournalRedfish(const std::string& description,
272                             log_level& logLevel);
273 
274     /** @brief Convert the one-hot DIMM index byte into a string of DIMM
275      * indexes.
276      *
277      *  @param[in] dimmIdxs - the one-hot DIMM index byte
278      *
279      *  @return std::string - the string of DIMM indexes
280      */
281     std::string dimmIdxsToString(uint32_t dimmIdxs);
282 
283     /** @brief Convert sensor ID to DIMM index. Return maxDIMMInstantNum
284      * in failure.
285      *
286      *  @param[in] sensorId - sensorID
287      *
288      *  @return uint8_t - DIMM index
289      */
290     uint8_t sensorIdToDIMMIdx(const uint16_t& sensorId);
291 
292     /** @brief Convert the DIMM training failure into logging string.
293      *
294      *  @param[in] failureInfo - the one-hot DIMM index byte
295      *
296      *  @return std::string - the returned logging string
297      */
298     std::string dimmTrainingFailureToMsg(uint32_t failureInfo);
299 
300     /** @brief Handle numeric sensor event message from PCIe hot-plug sensor.
301      *
302      *  @param[in] tid - TID
303      *  @param[in] sensorId - Sensor ID
304      *  @param[in] presentReading - the present reading of the sensor
305      */
306     void handlePCIeHotPlugEvent(pldm_tid_t tid, uint16_t sensorId,
307                                 uint32_t presentReading);
308 
309     /** @brief Handle numeric sensor event message from boot overall sensor.
310      *
311      *  @param[in] tid - TID
312      *  @param[in] sensorId - Sensor ID
313      *  @param[in] presentReading - the present reading of the sensor
314      */
315     void handleBootOverallEvent(pldm_tid_t /*tid*/, uint16_t /*sensorId*/,
316                                 uint32_t presentReading);
317 
318     /** @brief Handle numeric sensor event message from DIMM status sensor.
319      *
320      *  @param[in] tid - TID
321      *  @param[in] sensorId - Sensor ID
322      *  @param[in] presentReading - the present reading of the sensor
323      */
324     void handleDIMMStatusEvent(pldm_tid_t tid, uint16_t sensorId,
325                                uint32_t presentReading);
326 
327     /** @brief Handle numeric sensor event message from DDR status sensor.
328      *
329      *  @param[in] tid - TID
330      *  @param[in] sensorId - Sensor ID
331      *  @param[in] presentReading - the present reading of the sensor
332      */
333     void handleDDRStatusEvent(pldm_tid_t tid, uint16_t sensorId,
334                               uint32_t presentReading);
335 
336     /** @brief Handle numeric sensor event message from VRD status sensor.
337      *
338      *  @param[in] tid - TID
339      *  @param[in] sensorId - Sensor ID
340      *  @param[in] presentReading - the present reading of the sensor
341      */
342     void handleVRDStatusEvent(pldm_tid_t tid, uint16_t sensorId,
343                               uint32_t presentReading);
344 
345     /** @brief Handle numeric sensor event message from Watchdog status sensor.
346      *
347      *  @param[in] tid - TID
348      *  @param[in] sensorId - Sensor ID
349      *  @param[in] presentReading - the present reading of the sensor
350      */
351     void handleNumericWatchdogEvent(pldm_tid_t tid, uint16_t sensorId,
352                                     uint32_t presentReading);
353 
354     /** @brief Handle numeric sensor event messages.
355      *
356      *  @param[in] tid - TID
357      *  @param[in] sensorId - Sensor ID
358      *  @param[in] sensorData - the sensor data
359      *  @param[in] sensorDataLength - the length of sensor data
360      *
361      *  @return int - returned error code
362      */
363     int processNumericSensorEvent(pldm_tid_t tid, uint16_t sensorId,
364                                   const uint8_t* sensorData,
365                                   size_t sensorDataLength);
366 
367     /** @brief Handle state sensor event messages.
368      *
369      *  @param[in] tid - TID
370      *  @param[in] sensorId - Sensor ID
371      *  @param[in] sensorData - the sensor data
372      *  @param[in] sensorDataLength - the length of sensor data
373      *
374      *  @return int - returned error code
375      */
376     int processStateSensorEvent(pldm_tid_t tid, uint16_t sensorId,
377                                 const uint8_t* sensorData,
378                                 size_t sensorDataLength);
379 
380     /** @brief Handle op state sensor event messages.
381      *
382      *  @param[in] tid - TID
383      *  @param[in] sensorId - Sensor ID
384      *  @param[in] sensorData - the sensor data
385      *  @param[in] sensorDataLength - the length of sensor data
386      *
387      *  @return int - returned error code
388      */
389     int processSensorOpStateEvent(pldm_tid_t tid, uint16_t sensorId,
390                                   const uint8_t* sensorData,
391                                   size_t sensorDataLength);
392 
393     /** @brief reference of main event loop of pldmd, primarily used to schedule
394      *  work
395      */
396     sdeventplus::Event& event;
397 };
398 } // namespace oem_ampere
399 } // namespace pldm
400