1 /*
2 // Copyright (c) 2018 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16 
17 #pragma once
18 #include <ipmid/api.h>
19 #include <sys/mman.h>
20 
21 #include <oemcommands.hpp>
22 #include <sdbusplus/timer.hpp>
23 
24 static constexpr const char* mdrType2File = "/var/lib/smbios/smbios2";
25 static constexpr const char* smbiosPath = "/var/lib/smbios";
26 static constexpr const size_t msgPayloadSize =
27     1024 * 60; // Total size will transfer for smbios table
28 static constexpr const size_t mdriiSMSize = 0x00100000;
29 
30 static constexpr const uint16_t smbiosAgentId =
31     0x0101; // Agent ID for smbios entry
32 static constexpr const int firstAgentIndex = 1;
33 
34 static constexpr const uint8_t maxDirEntries = 4; // Maximum directory entries
35 static constexpr const uint32_t mdr2SMSize =
36     0x00100000; // Size of VGA share memory
37 static constexpr const uint32_t mdr2SMBaseAddress =
38     0x9FF00000; // Base address of VGA share memory
39 
40 static constexpr const uint8_t mdrTypeII = 2; // MDR V2 type
41 
42 static constexpr const uint8_t mdr2Version = 2;        // MDR V2 versoin
43 static constexpr const uint8_t smbiosAgentVersion = 1; // Agent version of
44                                                        // smbios
45 
46 static constexpr const uint32_t pageMask =
47     0xf000; // To make data become n times of page
48 static constexpr const int smbiosDirIndex = 0; // SMBIOS directory index
49 
50 static constexpr const uint32_t smbiosTableVersion =
51     15; // Version of smbios table
52 static constexpr const uint32_t smbiosTableTimestamp =
53     0x45464748; // Time stamp when smbios table created
54 static constexpr const size_t smbiosSMMemoryOffset =
55     0; // Offset of VGA share memory
56 static constexpr const size_t smbiosSMMemorySize =
57     1024 * 1024; // Total size of VGA share memory
58 static constexpr const size_t smbiosTableStorageSize =
59     64 * 1024; // Total size of smbios table
60 static constexpr const uint32_t defaultTimeout = 200;
61 static constexpr const uint8_t sysClock = 100;
62 static constexpr const int lastAgentIndex = -1;
63 static constexpr const uint16_t lastAgentId = 0xFFFF;
64 constexpr const uint32_t invalidChecksum = 0xffffffff;
65 constexpr const char* dbusProperties = "org.freedesktop.DBus.Properties";
66 constexpr const char* mdrv2Path = "/xyz/openbmc_project/Smbios/MDR_V2";
67 constexpr const char* mdrv2Interface = "xyz.openbmc_project.Smbios.MDR_V2";
68 
69 enum class MDR2SMBIOSStatusEnum
70 {
71     mdr2Init = 0,
72     mdr2Loaded = 1,
73     mdr2Updated = 2,
74     mdr2Updating = 3
75 };
76 
77 enum class DirDataRequestEnum
78 {
79     dirDataNotRequested = 0x00,
80     dirDataRequested = 0x01
81 };
82 
83 enum MDR2DirLockEnum
84 {
85     mdr2DirUnlock = 0,
86     mdr2DirLock = 1
87 };
88 
89 #pragma pack(push)
90 #pragma pack(1)
91 
92 struct MDRSMBIOSHeader
93 {
94     uint8_t dirVer;
95     uint8_t mdrType;
96     uint32_t timestamp;
97     uint32_t dataSize;
98 };
99 
100 struct DataIdStruct
101 {
102     uint8_t dataInfo[16];
103 };
104 
105 struct Mdr2DirEntry
106 {
107     DataIdStruct id;
108     uint32_t size;
109     uint32_t dataSetSize;
110     uint32_t dataVersion;
111     uint32_t timestamp;
112 };
113 
114 struct Mdr2DirLocalStruct
115 {
116     Mdr2DirEntry common;
117     MDR2SMBIOSStatusEnum stage;
118     MDR2DirLockEnum lock;
119     uint16_t lockHandle;
120     uint32_t xferBuff;
121     uint32_t xferSize;
122     uint32_t maxDataSize;
123     uint8_t* dataStorage;
124 };
125 
126 struct Mdr2DirStruct
127 {
128     uint8_t agentVersion;
129     uint8_t dirVersion;
130     uint8_t dirEntries;
131     uint8_t status; // valid / locked / etc
132     uint8_t remoteDirVersion;
133     uint16_t sessionHandle;
134     Mdr2DirLocalStruct dir[maxDirEntries];
135 };
136 
137 // Three members include dataSetSize, dataVersion and timestamp
138 static constexpr const size_t syncDirCommonSize = 3;
139 
140 // ====================== MDR II Pull Command Structures ======================
141 struct MDRiiGetDataInfoRequest
142 {
143     uint16_t agentId;
144     DataIdStruct dataSetInfo;
145 };
146 
147 // MDR II data set information inquiry response
148 struct MDRiiGetDataInfoResponse
149 {
150     uint8_t mdrVersion;
151     DataIdStruct dataSetId;
152     uint8_t validFlag;
153     uint32_t dataLength;
154     uint32_t dataVersion;
155     uint32_t timeStamp;
156 };
157 
158 // ====================== MDR II Push Command Structures ======================
159 // MDR II Client send data set info offer response
160 struct MDRiiOfferDataInfoResponse
161 {
162     DataIdStruct dataSetInfo;
163 };
164 
165 // MDR II Push Agent send data set info command
166 struct MDRiiSendDataInfoRequest
167 {
168     uint16_t agentId;
169     DataIdStruct dataSetInfo;
170     uint8_t validFlag;
171     uint32_t dataLength;
172     uint32_t dataVersion; // Roughly equivalent to the "file name"
173     uint32_t
174         timeStamp; // More info on the identity of this particular set of data
175 };
176 
177 // MDR II Pull Agent lock data set command
178 struct MDRiiLockDataRequest
179 {
180     uint16_t agentId;
181     DataIdStruct dataSetInfo;
182     uint16_t timeout;
183 };
184 
185 // MDR II Pull Agent lock data set response
186 struct MDRiiLockDataResponse
187 {
188     uint8_t mdrVersion;
189     uint16_t lockHandle;
190     uint32_t dataLength;
191     uint32_t xferAddress;
192     uint32_t xferLength;
193 };
194 
195 // MDR II Push Agent send data start command
196 struct MDRiiDataStartRequest
197 {
198     uint16_t agentId;
199     DataIdStruct dataSetInfo;
200     uint32_t dataLength;
201     uint32_t xferAddress;
202     uint32_t xferLength;
203     uint16_t timeout;
204 };
205 
206 // MDR II Client send data start response
207 struct MDRiiDataStartResponse
208 {
209     uint8_t xferStartAck;
210     uint16_t sessionHandle;
211 };
212 
213 // MDR II
214 struct MDRiiDataDoneRequest
215 {
216     uint16_t agentId;
217     uint16_t lockHandle;
218 };
219 
220 #pragma pack(pop)
221 
222 class SharedMemoryArea
223 {
224   public:
225     SharedMemoryArea(uint32_t addr, uint32_t areaSize) :
226         vPtr(nullptr), physicalAddr(addr), size(areaSize)
227     {
228         Initialize(addr, areaSize);
229     }
230 
231     ~SharedMemoryArea()
232     {
233         if ((vPtr != nullptr) && (vPtr != MAP_FAILED))
234         {
235             if (0 != munmap(vPtr, size))
236             {
237                 phosphor::logging::log<phosphor::logging::level::ERR>(
238                     "Ummap share memory failed");
239             }
240         }
241     }
242 
243     void* vPtr;
244 
245   private:
246     uint32_t physicalAddr;
247     uint32_t size;
248 
249     void Initialize(uint32_t addr, uint32_t areaSize);
250 };
251 
252 class MDRV2
253 {
254   public:
255     MDRV2()
256     {
257         timer =
258             std::make_unique<phosphor::Timer>([&](void) { timeoutHandler(); });
259     }
260 
261     int agentLookup(const uint16_t& agentId);
262     int findLockHandle(const uint16_t& lockHandle);
263     int syncDirCommonData(uint8_t idIndex, uint32_t size,
264                           const std::string& service);
265     int findDataId(const uint8_t* dataInfo, const size_t& len,
266                    const std::string& service);
267     uint16_t getSessionHandle(Mdr2DirStruct* dir);
268     bool smbiosIsUpdating(uint8_t index);
269     uint32_t calcChecksum32(uint8_t* buf, uint32_t len);
270     bool storeDatatoFlash(MDRSMBIOSHeader* mdrHdr, uint8_t* data);
271     bool smbiosUnlock(uint8_t index);
272     void timeoutHandler();
273     bool smbiosTryLock(uint8_t flag, uint8_t index, uint16_t* session,
274                        uint16_t timeout);
275     int sdplusMdrv2GetProperty(const std::string& name,
276                                std::variant<uint8_t>& value,
277                                const std::string& service);
278 
279     Mdr2DirStruct smbiosDir{smbiosAgentVersion,
280                             1,
281                             1,
282                             1,
283                             0,
284                             0,
285                             {40,
286                              41,
287                              42,
288                              43,
289                              44,
290                              45,
291                              46,
292                              47,
293                              48,
294                              49,
295                              50,
296                              51,
297                              52,
298                              53,
299                              54,
300                              0x42,
301                              0,
302                              smbiosTableStorageSize,
303                              smbiosTableVersion,
304                              smbiosTableTimestamp,
305                              MDR2SMBIOSStatusEnum::mdr2Init,
306                              MDR2DirLockEnum::mdr2DirUnlock,
307                              0,
308                              smbiosSMMemoryOffset,
309                              smbiosSMMemorySize,
310                              smbiosTableStorageSize,
311                              smbiosTableStorage}};
312     std::unique_ptr<SharedMemoryArea> area;
313     std::unique_ptr<phosphor::Timer> timer;
314 
315   private:
316     uint8_t lockIndex = 0;
317     uint8_t smbiosTableStorage[smbiosTableStorageSize];
318 };
319