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 Pull Agent get data block command
159 struct MDRiiGetDataBlockRequest
160 {
161     uint16_t agentId;
162     uint16_t lockHandle;
163     uint32_t xferOffset;
164     uint32_t xferLength;
165 };
166 
167 // MDR II Pull Agent get data block response
168 struct MDRiiGetDataBlockResponse
169 {
170     uint32_t xferLength;
171     uint32_t checksum;
172     uint8_t data[msgPayloadSize];
173 };
174 
175 // ====================== MDR II Push Command Structures ======================
176 // MDR II Client send data set info offer response
177 struct MDRiiOfferDataInfoResponse
178 {
179     DataIdStruct dataSetInfo;
180 };
181 
182 // MDR II Push Agent send data set info command
183 struct MDRiiSendDataInfoRequest
184 {
185     uint16_t agentId;
186     DataIdStruct dataSetInfo;
187     uint8_t validFlag;
188     uint32_t dataLength;
189     uint32_t dataVersion; // Roughly equivalent to the "file name"
190     uint32_t
191         timeStamp; // More info on the identity of this particular set of data
192 };
193 
194 // MDR II Pull Agent lock data set command
195 struct MDRiiLockDataRequest
196 {
197     uint16_t agentId;
198     DataIdStruct dataSetInfo;
199     uint16_t timeout;
200 };
201 
202 // MDR II Pull Agent lock data set response
203 struct MDRiiLockDataResponse
204 {
205     uint8_t mdrVersion;
206     uint16_t lockHandle;
207     uint32_t dataLength;
208     uint32_t xferAddress;
209     uint32_t xferLength;
210 };
211 
212 // MDR II Push Agent send data start command
213 struct MDRiiDataStartRequest
214 {
215     uint16_t agentId;
216     DataIdStruct dataSetInfo;
217     uint32_t dataLength;
218     uint32_t xferAddress;
219     uint32_t xferLength;
220     uint16_t timeout;
221 };
222 
223 // MDR II Client send data start response
224 struct MDRiiDataStartResponse
225 {
226     uint8_t xferStartAck;
227     uint16_t sessionHandle;
228 };
229 
230 // MDR II
231 struct MDRiiDataDoneRequest
232 {
233     uint16_t agentId;
234     uint16_t lockHandle;
235 };
236 
237 #pragma pack(pop)
238 
239 class SharedMemoryArea
240 {
241   public:
242     SharedMemoryArea(uint32_t addr, uint32_t areaSize) :
243         vPtr(nullptr), physicalAddr(addr), size(areaSize)
244     {
245         Initialize(addr, areaSize);
246     }
247 
248     ~SharedMemoryArea()
249     {
250         if ((vPtr != nullptr) && (vPtr != MAP_FAILED))
251         {
252             if (0 != munmap(vPtr, size))
253             {
254                 phosphor::logging::log<phosphor::logging::level::ERR>(
255                     "Ummap share memory failed");
256             }
257         }
258     }
259 
260     void *vPtr;
261 
262   private:
263     uint32_t physicalAddr;
264     uint32_t size;
265 
266     void Initialize(uint32_t addr, uint32_t areaSize);
267 };
268 
269 class MDRV2
270 {
271   public:
272     MDRV2()
273     {
274         timer =
275             std::make_unique<phosphor::Timer>([&](void) { timeoutHandler(); });
276     }
277 
278     int agentLookup(const uint16_t &agentId);
279     int findLockHandle(const uint16_t &lockHandle);
280     int syncDirCommonData(uint8_t idIndex, uint32_t size,
281                           const std::string &service);
282     int findDataId(const uint8_t *dataInfo, const size_t &len,
283                    const std::string &service);
284     uint16_t getSessionHandle(Mdr2DirStruct *dir);
285     bool smbiosIsUpdating(uint8_t index);
286     uint32_t calcChecksum32(uint8_t *buf, uint32_t len);
287     bool storeDatatoFlash(MDRSMBIOSHeader *mdrHdr, uint8_t *data);
288     bool smbiosUnlock(uint8_t index);
289     void timeoutHandler();
290     bool smbiosTryLock(uint8_t flag, uint8_t index, uint16_t *session,
291                        uint16_t timeout);
292     int sdplusMdrv2GetProperty(const std::string &name,
293                                sdbusplus::message::variant<uint8_t> &value,
294                                const std::string &service);
295 
296     Mdr2DirStruct smbiosDir{smbiosAgentVersion,
297                             1,
298                             1,
299                             1,
300                             0,
301                             0,
302                             {40,
303                              41,
304                              42,
305                              43,
306                              44,
307                              45,
308                              46,
309                              47,
310                              48,
311                              49,
312                              50,
313                              51,
314                              52,
315                              53,
316                              54,
317                              0x42,
318                              0,
319                              smbiosTableStorageSize,
320                              smbiosTableVersion,
321                              smbiosTableTimestamp,
322                              MDR2SMBIOSStatusEnum::mdr2Init,
323                              MDR2DirLockEnum::mdr2DirUnlock,
324                              0,
325                              smbiosSMMemoryOffset,
326                              smbiosSMMemorySize,
327                              smbiosTableStorageSize,
328                              smbiosTableStorage}};
329     std::unique_ptr<SharedMemoryArea> area;
330     std::unique_ptr<phosphor::Timer> timer;
331 
332   private:
333     uint8_t lockIndex = 0;
334     uint8_t smbiosTableStorage[smbiosTableStorageSize];
335 };
336