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