blob: 636cbdb52518002819f2bed2f708abc614018843 [file] [log] [blame]
Vernon Mauerya3702c12019-05-22 13:20:59 -07001/*
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
24static constexpr const char *mdrType2File = "/var/lib/smbios/smbios2";
25static constexpr const char *smbiosPath = "/var/lib/smbios";
26static constexpr const size_t msgPayloadSize =
27 1024 * 60; // Total size will transfer for smbios table
28static constexpr const size_t mdriiSMSize = 0x00100000;
29
30static constexpr const uint16_t smbiosAgentId =
31 0x0101; // Agent ID for smbios entry
32static constexpr const int firstAgentIndex = 1;
33
34static constexpr const uint8_t maxDirEntries = 4; // Maximum directory entries
35static constexpr const uint32_t mdr2SMSize =
36 0x00100000; // Size of VGA share memory
37static constexpr const uint32_t mdr2SMBaseAddress =
38 0x9FF00000; // Base address of VGA share memory
39
40static constexpr const uint8_t mdrTypeII = 2; // MDR V2 type
41
42static constexpr const uint8_t mdr2Version = 2; // MDR V2 versoin
43static constexpr const uint8_t smbiosAgentVersion = 1; // Agent version of
44 // smbios
45
46static constexpr const uint32_t pageMask =
47 0xf000; // To make data become n times of page
48static constexpr const int smbiosDirIndex = 0; // SMBIOS directory index
49
50static constexpr const uint32_t smbiosTableVersion =
51 15; // Version of smbios table
52static constexpr const uint32_t smbiosTableTimestamp =
53 0x45464748; // Time stamp when smbios table created
54static constexpr const size_t smbiosSMMemoryOffset =
55 0; // Offset of VGA share memory
56static constexpr const size_t smbiosSMMemorySize =
57 1024 * 1024; // Total size of VGA share memory
58static constexpr const size_t smbiosTableStorageSize =
59 64 * 1024; // Total size of smbios table
60static constexpr const uint32_t defaultTimeout = 200;
61static constexpr const uint8_t sysClock = 100;
62static constexpr const int lastAgentIndex = -1;
63static constexpr const uint16_t lastAgentId = 0xFFFF;
64constexpr const uint32_t invalidChecksum = 0xffffffff;
65constexpr const char *dbusProperties = "org.freedesktop.DBus.Properties";
66constexpr const char *mdrv2Path = "/xyz/openbmc_project/Smbios/MDR_V2";
67constexpr const char *mdrv2Interface = "xyz.openbmc_project.Smbios.MDR_V2";
68
69enum class MDR2SMBIOSStatusEnum
70{
71 mdr2Init = 0,
72 mdr2Loaded = 1,
73 mdr2Updated = 2,
74 mdr2Updating = 3
75};
76
77enum class DirDataRequestEnum
78{
79 dirDataNotRequested = 0x00,
80 dirDataRequested = 0x01
81};
82
83enum MDR2DirLockEnum
84{
85 mdr2DirUnlock = 0,
86 mdr2DirLock = 1
87};
88
89#pragma pack(push)
90#pragma pack(1)
91
92struct MDRSMBIOSHeader
93{
94 uint8_t dirVer;
95 uint8_t mdrType;
96 uint32_t timestamp;
97 uint32_t dataSize;
98};
99
100struct DataIdStruct
101{
102 uint8_t dataInfo[16];
103};
104
105struct Mdr2DirEntry
106{
107 DataIdStruct id;
108 uint32_t size;
109 uint32_t dataSetSize;
110 uint32_t dataVersion;
111 uint32_t timestamp;
112};
113
114struct 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
126struct 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
138static constexpr const size_t syncDirCommonSize = 3;
139
140// ====================== MDR II Pull Command Structures ======================
141// MDR II Pull Agent status inquiry command
142struct MDRiiGetAgentStatus
143{
144 uint16_t agentId;
145 uint8_t dirVersion;
146};
147
148// MDR II status inquiry response
149struct MDRiiAgentStatusResponse
150{
151 uint8_t mdrVersion;
152 uint8_t agentVersion;
153 uint8_t dirVersion;
154 uint8_t dirEntries;
155 uint8_t dataRequest;
156};
157
158struct MDRiiGetDirRequest
159{
160 uint16_t agentId;
161 uint8_t dirIndex;
162};
163
164// MDR II directory information inquiry response
165struct MDRiiGetDirResponse
166{
167 uint8_t mdrVersion;
168 uint8_t dirVersion;
169 uint8_t returnedEntries;
170 uint8_t remainingEntries;
171 uint8_t data[1];
172};
173
174struct MDRiiGetDataInfoRequest
175{
176 uint16_t agentId;
177 DataIdStruct dataSetInfo;
178};
179
180// MDR II data set information inquiry response
181struct MDRiiGetDataInfoResponse
182{
183 uint8_t mdrVersion;
184 DataIdStruct dataSetId;
185 uint8_t validFlag;
186 uint32_t dataLength;
187 uint32_t dataVersion;
188 uint32_t timeStamp;
189};
190
191// MDR II Pull Agent get data block command
192struct MDRiiGetDataBlockRequest
193{
194 uint16_t agentId;
195 uint16_t lockHandle;
196 uint32_t xferOffset;
197 uint32_t xferLength;
198};
199
200// MDR II Pull Agent get data block response
201struct MDRiiGetDataBlockResponse
202{
203 uint32_t xferLength;
204 uint32_t checksum;
205 uint8_t data[msgPayloadSize];
206};
207
208// ====================== MDR II Push Command Structures ======================
209// MDR II Push Agent send dir info command
210struct MDRiiSendDirRequest
211{
212 uint16_t agentId;
213 uint8_t dirVersion;
214 uint8_t dirIndex;
215 uint8_t returnedEntries;
216 uint8_t remainingEntries;
217 Mdr2DirEntry data[1]; // place holder for N directory entries
218};
219
220struct MDRiiOfferDataInfo
221{
222 uint16_t agentId;
223};
224
225// MDR II Client send data set info offer response
226struct MDRiiOfferDataInfoResponse
227{
228 DataIdStruct dataSetInfo;
229};
230
231// MDR II Push Agent send data set info command
232struct MDRiiSendDataInfoRequest
233{
234 uint16_t agentId;
235 DataIdStruct dataSetInfo;
236 uint8_t validFlag;
237 uint32_t dataLength;
238 uint32_t dataVersion; // Roughly equivalent to the "file name"
239 uint32_t
240 timeStamp; // More info on the identity of this particular set of data
241};
242
243// MDR II Push Agent send data block command
244struct MDRiiSendDataBlockRequest
245{
246 uint16_t agentId;
247 uint16_t lockHandle;
248 uint32_t xferOffset;
249 uint32_t xferLength;
250 uint32_t checksum;
251};
252
253// MDR II Pull Agent lock data set command
254struct MDRiiLockDataRequest
255{
256 uint16_t agentId;
257 DataIdStruct dataSetInfo;
258 uint16_t timeout;
259};
260
261// MDR II Pull Agent lock data set response
262struct MDRiiLockDataResponse
263{
264 uint8_t mdrVersion;
265 uint16_t lockHandle;
266 uint32_t dataLength;
267 uint32_t xferAddress;
268 uint32_t xferLength;
269};
270
271// MDR II Pull Agent unlock data set command
272struct MDRiiUnlockDataRequest
273{
274 uint16_t agentId;
275 uint16_t lockHandle;
276};
277
278// MDR II Push Agent send data start command
279struct MDRiiDataStartRequest
280{
281 uint16_t agentId;
282 DataIdStruct dataSetInfo;
283 uint32_t dataLength;
284 uint32_t xferAddress;
285 uint32_t xferLength;
286 uint16_t timeout;
287};
288
289// MDR II Client send data start response
290struct MDRiiDataStartResponse
291{
292 uint8_t xferStartAck;
293 uint16_t sessionHandle;
294};
295
296// MDR II
297struct MDRiiDataDoneRequest
298{
299 uint16_t agentId;
300 uint16_t lockHandle;
301};
302
303#pragma pack(pop)
304
305class SharedMemoryArea
306{
307 public:
308 SharedMemoryArea(uint32_t addr, uint32_t areaSize) :
309 vPtr(nullptr), physicalAddr(addr), size(areaSize)
310 {
311 Initialize(addr, areaSize);
312 }
313
314 ~SharedMemoryArea()
315 {
316 if ((vPtr != nullptr) && (vPtr != MAP_FAILED))
317 {
318 if (0 != munmap(vPtr, size))
319 {
320 phosphor::logging::log<phosphor::logging::level::ERR>(
321 "Ummap share memory failed");
322 }
323 }
324 }
325
326 void *vPtr;
327
328 private:
329 uint32_t physicalAddr;
330 uint32_t size;
331
332 void Initialize(uint32_t addr, uint32_t areaSize);
333};
334
335class MDRV2
336{
337 public:
338 MDRV2()
339 {
340 timer =
341 std::make_unique<phosphor::Timer>([&](void) { timeoutHandler(); });
342 }
343
344 int agentLookup(const uint16_t &agentId);
345 int findLockHandle(const uint16_t &lockHandle);
346 int syncDirCommonData(uint8_t idIndex, uint32_t size,
347 const std::string &service);
348 int findDataId(const uint8_t *dataInfo, const size_t &len,
349 const std::string &service);
350 uint16_t getSessionHandle(Mdr2DirStruct *dir);
351 bool smbiosIsUpdating(uint8_t index);
352 uint32_t calcChecksum32(uint8_t *buf, uint32_t len);
353 bool storeDatatoFlash(MDRSMBIOSHeader *mdrHdr, uint8_t *data);
354 bool smbiosUnlock(uint8_t index);
355 void timeoutHandler();
356 bool smbiosTryLock(uint8_t flag, uint8_t index, uint16_t *session,
357 uint16_t timeout);
358 int sdplusMdrv2GetProperty(const std::string &name,
359 sdbusplus::message::variant<uint8_t> &value,
360 const std::string &service);
361
362 Mdr2DirStruct smbiosDir{smbiosAgentVersion,
363 1,
364 1,
365 1,
366 0,
367 0,
368 {40,
369 41,
370 42,
371 43,
372 44,
373 45,
374 46,
375 47,
376 48,
377 49,
378 50,
379 51,
380 52,
381 53,
382 54,
383 0x42,
384 0,
385 smbiosTableStorageSize,
386 smbiosTableVersion,
387 smbiosTableTimestamp,
388 MDR2SMBIOSStatusEnum::mdr2Init,
389 MDR2DirLockEnum::mdr2DirUnlock,
390 0,
391 smbiosSMMemoryOffset,
392 smbiosSMMemorySize,
393 smbiosTableStorageSize,
394 smbiosTableStorage}};
395 std::unique_ptr<SharedMemoryArea> area;
396 std::unique_ptr<phosphor::Timer> timer;
397
398 private:
399 uint8_t lockIndex = 0;
400 uint8_t smbiosTableStorage[smbiosTableStorageSize];
401};