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 
readIntoMemory(uint32_t,uint32_t,uint64_t,oem_platform::Handler *)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 
read(uint32_t,uint32_t &,Response &,oem_platform::Handler *)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 
newFileAvailable(uint64_t)167     virtual int newFileAvailable(uint64_t /*length*/)
168     {
169         return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
170     }
171 
fileAckWithMetaData(uint8_t,uint32_t,uint32_t,uint32_t,uint32_t)172     virtual int fileAckWithMetaData(
173         uint8_t /*fileStatus*/, uint32_t /*metaDataValue1*/,
174         uint32_t /*metaDataValue2*/, uint32_t /*metaDataValue3*/,
175         uint32_t /*metaDataValue4*/)
176     {
177         return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
178     }
179 
newFileAvailableWithMetaData(uint64_t,uint32_t,uint32_t,uint32_t,uint32_t)180     virtual int newFileAvailableWithMetaData(
181         uint64_t /*length*/, uint32_t /*metaDataValue1*/,
182         uint32_t /*metaDataValue2*/, uint32_t /*metaDataValue3*/,
183         uint32_t /*metaDataValue4*/)
184     {
185         return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
186     }
187 
188     /** @brief method to parse the pcie topology information */
189     virtual void parseTopologyData();
190 
191     /** @brief method to parse the cable information */
192     virtual void parseCableInfo();
193 
194     /** @brief PCIeInfoHandler destructor
195      */
~PCIeInfoHandler()196     ~PCIeInfoHandler() {}
197 
198   private:
199     uint16_t infoType; //!< type of the information
200 
201     /**
202      * @brief Map contains Topology data
203      *
204      * This static unordered map associates link IDs with link attributes.
205      * Key - LinkID (LinkId)
206      * Value - Tuple
207      *         link status (LinkStatus)
208      *         link type (LinkType)
209      *         link speed (LinkSpeed)
210      *         link width (LinkWidth)
211      *         PCIe host bridge location (PcieHostBridgeLoc)
212      *         Local port (LocalPort - Pair of local port top and bottom)
213      *         Remote port (RemotePort - Pair of remote port top and bottom)
214      *         I/O slot location (IoSlotLocation - Vector of strings)
215      */
216     static std::unordered_map<
217         LinkId, std::tuple<LinkStatus, linkTypeData, LinkSpeed, LinkWidth,
218                            PcieHostBridgeLoc, LocalPort, RemotePort,
219                            IoSlotLocation, LinkId>>
220         topologyInformation;
221     /**
222      * @brief Static unordered map containing cable information.
223      *
224      * This map associates cable link numbers with a tuple containing various
225      * cable attributes.
226      *
227      * Key - CableLinkID (CableLinkNum)
228      * Value - Tuple
229      *         Link ID (LinkId)
230      *         Local port location code (LocalPortLocCode)
231      *         I/O slot location code (IoSlotLocationCode)
232      *         Cable part number (CablePartNum)
233      *         Cable length (CableLength)
234      *         Cable type (CableType)
235      *         Cable status (CableStatus)
236      */
237 
238     static std::unordered_map<
239         CableLinkNum,
240         std::tuple<LinkId, LocalPortLocCode, IoSlotLocationCode, CablePartNum,
241                    CableLength, CableType, CableStatus>>
242         cableInformation;
243     /**
244      * @brief Static unordered map containing linkId to link type information.
245      *
246      * This map associates link numbers to the link type
247      *
248      * Key - LinkID (LinkId)
249      * Value - linkTypeData (linkTypeData)
250      */
251     static std::unordered_map<LinkId, linkTypeData> linkTypeInfo;
252 
253     /** @brief A static unordered map storing information about received files.
254      *
255      *  This unordered map associates file type with a boolean value indicating
256      *  whether the file of that type has been received or not.
257      */
258     static std::unordered_map<uint16_t, bool> receivedFiles;
259 };
260 
261 } // namespace responder
262 } // namespace pldm
263