xref: /openbmc/pldm/oem/meta/event/oem_event_manager.hpp (revision c86cd0427d889484440912722a7e5ec861673378)
1 #pragma once
2 
3 #define PLDM_OEM_EVENT_CLASS_0xFB 0xFB
4 
5 #include "oem/meta/event/types.hpp"
6 #include "platform-mc/manager.hpp"
7 
8 #include <libpldm/base.h>
9 
10 namespace pldm::oem_meta
11 {
12 
13 class OemEventManager
14 {
15   public:
16     OemEventManager() = default;
17     OemEventManager(const OemEventManager&) = delete;
18     OemEventManager(OemEventManager&&) = delete;
19     OemEventManager& operator=(const OemEventManager&) = delete;
20     OemEventManager& operator=(OemEventManager&&) = delete;
21     virtual ~OemEventManager() = default;
22 
23     /** @brief Handle a PLDM OEM event.
24      *
25      *  @param[in] request - The PLDM request message.
26      *  @param[in] payloadLength - The length of the PLDM request payload.
27      *  @param[in] formatVersion - The format version of the event message.
28      *  @param[in] tid - The PLDM terminal ID.
29      *  @param[in] eventDataOffset - The offset of the event data in the
30      * request.
31      *
32      *  @return 0 on success, error code on failure.
33      */
34     int handleOemEvent(const pldm_msg* request, size_t payloadLength,
35                        uint8_t /* formatVersion */, pldm_tid_t tid,
36                        size_t eventDataOffset) const;
37 
38   private:
39     /** @brief Process an OEM Meta event.
40      *
41      *  @param[in] tid - The PLDM terminal ID.
42      *  @param[in] eventData - A pointer to the event data.
43      *  @param[in] eventDataSize - The size of the event data.
44      *
45      *  @return 0 on success, error code on failure.
46      */
47     int processOemMetaEvent(pldm_tid_t tid, const uint8_t* eventData,
48                             size_t eventDataSize) const;
49 
50     /** @brief Handle a system event.
51      *
52      *  @param[in] eventData - A pointer to the event data.
53      *  @param[out] message - The resulting event message.
54      */
55     void handleSystemEvent(const uint8_t* eventData,
56                            std::string& message) const;
57 
58     /** @brief Handle a unified BIOS event.
59      *
60      *  @param[in] eventData - A pointer to the event data.
61      *  @param[out] message - The resulting event message.
62      */
63     void handleUnifiedBIOSEvent(const uint8_t* eventData,
64                                 std::string& message) const;
65 
66     /** @brief Handle a memory error event.
67      *
68      *  @param[in] eventData - A pointer to the event data.
69      *  @param[out] message - The resulting event message.
70      *  @param[in] dimmInfo - Information about the DIMM.
71      *  @param[in] generalInfo - General information about the event.
72      */
73     void handleMemoryError(const uint8_t* eventData, std::string& message,
74                            const DimmInfo& dimmInfo, uint8_t generalInfo) const;
75 
76     /** @brief Handle a system POST event.
77      *
78      *  @param[in] eventData - A pointer to the event data.
79      *  @param[out] message - The resulting event message.
80      *  @param[in] generalInfo - General information about the event.
81      */
82     void handleSystemPostEvent(const uint8_t* eventData, std::string& message,
83                                uint8_t generalInfo) const;
84 
85     /** @brief Get the DIMM device name.
86      *
87      *  @param[in] eventData - A pointer to the event data.
88      *  @param[in] bdfIdx - The index of the BDF (Bus/Device/Function).
89      *
90      *  @return The DIMM device name.
91      */
getDimmDeviceName(const uint8_t * eventData,int bdfIdx) const92     std::string getDimmDeviceName(const uint8_t* eventData, int bdfIdx) const
93     {
94         std::string dimmDevName = "";
95         for (size_t i = 0; i < cxlBdfMap.size(); i++)
96         {
97             if ((eventData[bdfIdx] == cxlBdfMap[i].Bus) &&
98                 ((eventData[bdfIdx + 1] >> 3) == cxlBdfMap[i].Dev) &&
99                 ((eventData[bdfIdx + 1] & 0x7) == cxlBdfMap[i].Fun))
100             {
101                 dimmDevName = std::string(cxlBdfMap[i].Name) + "_";
102                 break;
103             }
104         }
105         return dimmDevName;
106     };
107 
108     /** @brief Convert a byte to a hex string.
109      *
110      *  @param[in] value - The byte value to convert.
111      *  @param[in] len - The length of the resulting string.
112      *
113      *  @return The hex string representation of the byte.
114      */
to_hex_string(uint8_t value,size_t len=2) const115     inline auto to_hex_string(uint8_t value, size_t len = 2) const
116     {
117         return std::format("{:02x}", value, len);
118     }
119 
120     /** @brief Convert CPU, channel, and slot to a DIMM string.
121      *
122      *  @param[in] cpu - The CPU number.
123      *  @param[in] channel - The channel number.
124      *  @param[in] slot - The slot number.
125      *  @param[out] str - The resulting DIMM string.
126      */
convertToDimmString(uint8_t cpu,uint8_t channel,uint8_t slot,std::string & str) const127     void convertToDimmString(uint8_t cpu, uint8_t channel, uint8_t slot,
128                              std::string& str) const
129     {
130         constexpr char label[] = {'A', 'C', 'B', 'D'};
131         constexpr size_t labelSize = sizeof(label);
132 
133         size_t idx = cpu * 2 + slot;
134         if (idx < labelSize)
135         {
136             str = label[idx] + std::to_string(channel);
137         }
138         else
139         {
140             str = "NA";
141         }
142     }
143 
144     /** @brief Get the common DIMM location string.
145      *
146      *  @param[in] dimmInfo - Information about the DIMM.
147      *  @param[out] dimmLocation - The resulting DIMM location string.
148      *  @param[out] dimm - The resulting DIMM string.
149      */
getCommonDimmLocation(const DimmInfo & dimmInfo,std::string & dimmLocation,std::string & dimm) const150     void getCommonDimmLocation(const DimmInfo& dimmInfo,
151                                std::string& dimmLocation,
152                                std::string& dimm) const
153     {
154         std::string sled_str = std::to_string(dimmInfo.sled);
155         std::string socket_str = std::to_string(dimmInfo.socket);
156 
157         // Check Channel and Slot
158         if (dimmInfo.channel == 0xFF && dimmInfo.slot == 0xFF)
159         {
160             dimm = "unknown";
161             dimmLocation = "DIMM Slot Location: Sled " + sled_str + "/Socket " +
162                            socket_str +
163                            ", Channel unknown, Slot unknown, DIMM unknown";
164         }
165         else
166         {
167             uint8_t channel = dimmInfo.channel & 0x0F;
168             uint8_t slot = dimmInfo.slot & 0x07;
169             convertToDimmString(dimmInfo.socket, channel, slot, dimm);
170 
171             std::string channel_str = std::to_string(channel);
172             std::string slot_str = std::to_string(slot);
173 
174             dimmLocation = "DIMM Slot Location: Sled " + sled_str + "/Socket " +
175                            socket_str + ", Channel " + channel_str + ", Slot " +
176                            slot_str + ", DIMM " + dimm;
177         }
178     }
179 };
180 
181 } // namespace pldm::oem_meta
182