1 #pragma once
2 
3 #include "file_io_by_type.hpp"
4 
5 #include <sys/mman.h>
6 
7 #include <unordered_map>
8 
9 namespace pldm
10 {
11 namespace responder
12 {
13 /* Topology enum definitions*/
14 
15 extern std::unordered_map<uint8_t, std::string> linkStateMap;
16 extern std::unordered_map<uint8_t, std::string> linkSpeed;
17 extern std::unordered_map<uint8_t, size_t> linkWidth;
18 
19 enum class linkTypeData : uint8_t
20 {
21     Primary = 0x0,
22     Secondary = 0x1,
23     OpenCAPI = 0x2,
24     Unknown = 0xFF
25 };
26 
27 struct slotLocCode
28 {
29     uint8_t numSlotLocCodes;
30     uint8_t slotLocCodesCmnPrtSize;
31     uint8_t slotLocCodesCmnPrt[1];
32 } __attribute__((packed));
33 
34 struct slotLocCodeSuf
35 {
36     uint8_t slotLocCodeSz;
37     uint8_t slotLocCodeSuf[1];
38 } __attribute__((packed));
39 
40 struct pcieLinkEntry
41 {
42     uint16_t entryLength;
43     uint8_t version;
44     uint8_t reserved1;
45     uint16_t linkId;
46     uint16_t parentLinkId;
47     uint32_t linkDrcIndex;
48     uint32_t hubDrcIndex;
49     uint8_t linkStatus;
50     pldm::responder::linkTypeData linkType;
51     uint16_t reserved2;
52     uint8_t linkSpeed;
53     uint8_t linkWidth;
54     uint8_t pcieHostBridgeLocCodeSize;
55     uint16_t pcieHostBridgeLocCodeOff;
56     uint8_t topLocalPortLocCodeSize;
57     uint16_t topLocalPortLocCodeOff;
58     uint8_t bottomLocalPortLocCodeSize;
59     uint16_t bottomLocalPortLocCodeOff;
60     uint8_t topRemotePortLocCodeSize;
61     uint16_t topRemotePortLocCodeOff;
62     uint8_t bottomRemotePortLocCodeSize;
63     uint16_t bottomRemotePortLocCodeOff;
64     uint16_t slotLocCodesOffset;
65     uint8_t pciLinkEntryLocCode[1];
66 } __attribute__((packed));
67 
68 struct topologyBlob
69 {
70     uint32_t totalDataSize;
71     int16_t numPcieLinkEntries;
72     uint16_t reserved;
73     pcieLinkEntry pciLinkEntry[1];
74 } __attribute__((packed));
75 
76 using LinkId = uint16_t;
77 using LinkStatus = std::string;
78 using LinkType = uint8_t;
79 using LinkSpeed = uint8_t;
80 using LinkWidth = int64_t;
81 using PcieHostBridgeLoc = std::string;
82 using LocalPortTop = std::string;
83 using LocalPortBot = std::string;
84 using LocalPort = std::pair<LocalPortTop, LocalPortBot>;
85 using RemotePortTop = std::string;
86 using RemotePortBot = std::string;
87 using RemotePort = std::pair<RemotePortTop, RemotePortBot>;
88 using IoSlotLocation = std::vector<std::string>;
89 using CableLinkNum = unsigned short int;
90 using LocalPortLocCode = std::string;
91 using IoSlotLocationCode = std::string;
92 using CablePartNum = std::string;
93 using CableLength = double;
94 using CableType = std::string;
95 using CableStatus = std::string;
96 
97 /* Cable Attributes Info */
98 
99 extern std::unordered_map<uint8_t, double> cableLengthMap;
100 extern std::unordered_map<uint8_t, std::string> cableTypeMap;
101 extern std::unordered_map<uint8_t, std::string> cableStatusMap;
102 
103 struct pcieLinkCableAttr
104 {
105     uint16_t entryLength;
106     uint8_t version;
107     uint8_t reserved1;
108     uint16_t linkId;
109     uint16_t reserved2;
110     uint32_t linkDrcIndex;
111     uint8_t cableLength;
112     uint8_t cableType;
113     uint8_t cableStatus;
114     uint8_t hostPortLocationCodeSize;
115     uint8_t ioEnclosurePortLocationCodeSize;
116     uint8_t cablePartNumberSize;
117     uint16_t hostPortLocationCodeOffset;
118     uint16_t ioEnclosurePortLocationCodeOffset;
119     uint16_t cablePartNumberOffset;
120     uint8_t cableAttrLocCode[1];
121 };
122 
123 struct cableAttributesList
124 {
125     uint32_t lengthOfResponse;
126     uint16_t numOfCables;
127     uint16_t reserved;
128     pcieLinkCableAttr pciLinkCableAttr[1];
129 };
130 
131 /** @class PCIeInfoHandler
132  *
133  *  @brief Inherits and implements FileHandler. This class is used to handle the
134  *  pcie topology file and cable information from remote PLDM terminus to the
135  *  bmc
136  */
137 class PCIeInfoHandler : public FileHandler
138 {
139   public:
140     /** @brief PCIeInfoHandler constructor
141      */
142     PCIeInfoHandler(uint32_t fileHandle, uint16_t fileType);
143 
144     virtual int writeFromMemory(uint32_t offset, uint32_t length,
145                                 uint64_t address,
146                                 oem_platform::Handler* /*oemPlatformHandler*/);
147 
148     virtual int write(const char* buffer, uint32_t offset, uint32_t& length,
149                       oem_platform::Handler* /*oemPlatformHandler*/);
150 
151     virtual int fileAck(uint8_t fileStatus);
152 
153     virtual int readIntoMemory(uint32_t /*offset*/, uint32_t /*length*/,
154                                uint64_t /*address*/,
155                                oem_platform::Handler* /*oemPlatformHandler*/)
156     {
157         return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
158     }
159 
160     virtual int read(uint32_t /*offset*/, uint32_t& /*length*/,
161                      Response& /*response*/,
162                      oem_platform::Handler* /*oemPlatformHandler*/)
163     {
164         return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
165     }
166 
167     virtual int newFileAvailable(uint64_t /*length*/)
168     {
169         return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
170     }
171 
172     virtual int fileAckWithMetaData(uint8_t /*fileStatus*/,
173                                     uint32_t /*metaDataValue1*/,
174                                     uint32_t /*metaDataValue2*/,
175                                     uint32_t /*metaDataValue3*/,
176                                     uint32_t /*metaDataValue4*/)
177     {
178         return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
179     }
180 
181     virtual int newFileAvailableWithMetaData(uint64_t /*length*/,
182                                              uint32_t /*metaDataValue1*/,
183                                              uint32_t /*metaDataValue2*/,
184                                              uint32_t /*metaDataValue3*/,
185                                              uint32_t /*metaDataValue4*/)
186     {
187         return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
188     }
189 
190     /** @brief method to parse the pcie topology information */
191     virtual void parseTopologyData();
192 
193     /** @brief method to parse the cable information */
194     virtual void parseCableInfo();
195 
196     /** @brief PCIeInfoHandler destructor
197      */
198     ~PCIeInfoHandler() {}
199 
200   private:
201     uint16_t infoType; //!< type of the information
202 
203     /**
204      * @brief Map contains Topology data
205      *
206      * This static unordered map associates link IDs with link attributes.
207      * Key - LinkID (LinkId)
208      * Value - Tuple
209      *         link status (LinkStatus)
210      *         link type (LinkType)
211      *         link speed (LinkSpeed)
212      *         link width (LinkWidth)
213      *         PCIe host bridge location (PcieHostBridgeLoc)
214      *         Local port (LocalPort - Pair of local port top and bottom)
215      *         Remote port (RemotePort - Pair of remote port top and bottom)
216      *         I/O slot location (IoSlotLocation - Vector of strings)
217      */
218     static std::unordered_map<
219         LinkId, std::tuple<LinkStatus, linkTypeData, LinkSpeed, LinkWidth,
220                            PcieHostBridgeLoc, LocalPort, RemotePort,
221                            IoSlotLocation, LinkId>>
222         topologyInformation;
223     /**
224      * @brief Static unordered map containing cable information.
225      *
226      * This map associates cable link numbers with a tuple containing various
227      * cable attributes.
228      *
229      * Key - CableLinkID (CableLinkNum)
230      * Value - Tuple
231      *         Link ID (LinkId)
232      *         Local port location code (LocalPortLocCode)
233      *         I/O slot location code (IoSlotLocationCode)
234      *         Cable part number (CablePartNum)
235      *         Cable length (CableLength)
236      *         Cable type (CableType)
237      *         Cable status (CableStatus)
238      */
239 
240     static std::unordered_map<
241         CableLinkNum,
242         std::tuple<LinkId, LocalPortLocCode, IoSlotLocationCode, CablePartNum,
243                    CableLength, CableType, CableStatus>>
244         cableInformation;
245     /**
246      * @brief Static unordered map containing linkId to link type information.
247      *
248      * This map associates link numbers to the link type
249      *
250      * Key - LinkID (LinkId)
251      * Value - linkTypeData (linkTypeData)
252      */
253     static std::unordered_map<LinkId, linkTypeData> linkTypeInfo;
254 
255     /** @brief A static unordered map storing information about received files.
256      *
257      *  This unordered map associates file type with a boolean value indicating
258      *  whether the file of that type has been received or not.
259      */
260     static std::unordered_map<uint16_t, bool> receivedFiles;
261 };
262 
263 } // namespace responder
264 } // namespace pldm
265