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