blob: 59926757fea940f7f8d92ffad206c5460b6c916b [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 ======================
Vernon Mauerya3702c12019-05-22 13:20:59 -0700141struct MDRiiGetDirRequest
142{
143 uint16_t agentId;
144 uint8_t dirIndex;
145};
146
147// MDR II directory information inquiry response
148struct MDRiiGetDirResponse
149{
150 uint8_t mdrVersion;
151 uint8_t dirVersion;
152 uint8_t returnedEntries;
153 uint8_t remainingEntries;
154 uint8_t data[1];
155};
156
157struct MDRiiGetDataInfoRequest
158{
159 uint16_t agentId;
160 DataIdStruct dataSetInfo;
161};
162
163// MDR II data set information inquiry response
164struct MDRiiGetDataInfoResponse
165{
166 uint8_t mdrVersion;
167 DataIdStruct dataSetId;
168 uint8_t validFlag;
169 uint32_t dataLength;
170 uint32_t dataVersion;
171 uint32_t timeStamp;
172};
173
174// MDR II Pull Agent get data block command
175struct MDRiiGetDataBlockRequest
176{
177 uint16_t agentId;
178 uint16_t lockHandle;
179 uint32_t xferOffset;
180 uint32_t xferLength;
181};
182
183// MDR II Pull Agent get data block response
184struct MDRiiGetDataBlockResponse
185{
186 uint32_t xferLength;
187 uint32_t checksum;
188 uint8_t data[msgPayloadSize];
189};
190
191// ====================== MDR II Push Command Structures ======================
192// MDR II Push Agent send dir info command
193struct MDRiiSendDirRequest
194{
195 uint16_t agentId;
196 uint8_t dirVersion;
197 uint8_t dirIndex;
198 uint8_t returnedEntries;
199 uint8_t remainingEntries;
200 Mdr2DirEntry data[1]; // place holder for N directory entries
201};
202
Vernon Mauerya3702c12019-05-22 13:20:59 -0700203// MDR II Client send data set info offer response
204struct MDRiiOfferDataInfoResponse
205{
206 DataIdStruct dataSetInfo;
207};
208
209// MDR II Push Agent send data set info command
210struct MDRiiSendDataInfoRequest
211{
212 uint16_t agentId;
213 DataIdStruct dataSetInfo;
214 uint8_t validFlag;
215 uint32_t dataLength;
216 uint32_t dataVersion; // Roughly equivalent to the "file name"
217 uint32_t
218 timeStamp; // More info on the identity of this particular set of data
219};
220
221// MDR II Push Agent send data block command
222struct MDRiiSendDataBlockRequest
223{
224 uint16_t agentId;
225 uint16_t lockHandle;
226 uint32_t xferOffset;
227 uint32_t xferLength;
228 uint32_t checksum;
229};
230
231// MDR II Pull Agent lock data set command
232struct MDRiiLockDataRequest
233{
234 uint16_t agentId;
235 DataIdStruct dataSetInfo;
236 uint16_t timeout;
237};
238
239// MDR II Pull Agent lock data set response
240struct MDRiiLockDataResponse
241{
242 uint8_t mdrVersion;
243 uint16_t lockHandle;
244 uint32_t dataLength;
245 uint32_t xferAddress;
246 uint32_t xferLength;
247};
248
249// MDR II Pull Agent unlock data set command
250struct MDRiiUnlockDataRequest
251{
252 uint16_t agentId;
253 uint16_t lockHandle;
254};
255
256// MDR II Push Agent send data start command
257struct MDRiiDataStartRequest
258{
259 uint16_t agentId;
260 DataIdStruct dataSetInfo;
261 uint32_t dataLength;
262 uint32_t xferAddress;
263 uint32_t xferLength;
264 uint16_t timeout;
265};
266
267// MDR II Client send data start response
268struct MDRiiDataStartResponse
269{
270 uint8_t xferStartAck;
271 uint16_t sessionHandle;
272};
273
274// MDR II
275struct MDRiiDataDoneRequest
276{
277 uint16_t agentId;
278 uint16_t lockHandle;
279};
280
281#pragma pack(pop)
282
283class SharedMemoryArea
284{
285 public:
286 SharedMemoryArea(uint32_t addr, uint32_t areaSize) :
287 vPtr(nullptr), physicalAddr(addr), size(areaSize)
288 {
289 Initialize(addr, areaSize);
290 }
291
292 ~SharedMemoryArea()
293 {
294 if ((vPtr != nullptr) && (vPtr != MAP_FAILED))
295 {
296 if (0 != munmap(vPtr, size))
297 {
298 phosphor::logging::log<phosphor::logging::level::ERR>(
299 "Ummap share memory failed");
300 }
301 }
302 }
303
304 void *vPtr;
305
306 private:
307 uint32_t physicalAddr;
308 uint32_t size;
309
310 void Initialize(uint32_t addr, uint32_t areaSize);
311};
312
313class MDRV2
314{
315 public:
316 MDRV2()
317 {
318 timer =
319 std::make_unique<phosphor::Timer>([&](void) { timeoutHandler(); });
320 }
321
322 int agentLookup(const uint16_t &agentId);
323 int findLockHandle(const uint16_t &lockHandle);
324 int syncDirCommonData(uint8_t idIndex, uint32_t size,
325 const std::string &service);
326 int findDataId(const uint8_t *dataInfo, const size_t &len,
327 const std::string &service);
328 uint16_t getSessionHandle(Mdr2DirStruct *dir);
329 bool smbiosIsUpdating(uint8_t index);
330 uint32_t calcChecksum32(uint8_t *buf, uint32_t len);
331 bool storeDatatoFlash(MDRSMBIOSHeader *mdrHdr, uint8_t *data);
332 bool smbiosUnlock(uint8_t index);
333 void timeoutHandler();
334 bool smbiosTryLock(uint8_t flag, uint8_t index, uint16_t *session,
335 uint16_t timeout);
336 int sdplusMdrv2GetProperty(const std::string &name,
337 sdbusplus::message::variant<uint8_t> &value,
338 const std::string &service);
339
340 Mdr2DirStruct smbiosDir{smbiosAgentVersion,
341 1,
342 1,
343 1,
344 0,
345 0,
346 {40,
347 41,
348 42,
349 43,
350 44,
351 45,
352 46,
353 47,
354 48,
355 49,
356 50,
357 51,
358 52,
359 53,
360 54,
361 0x42,
362 0,
363 smbiosTableStorageSize,
364 smbiosTableVersion,
365 smbiosTableTimestamp,
366 MDR2SMBIOSStatusEnum::mdr2Init,
367 MDR2DirLockEnum::mdr2DirUnlock,
368 0,
369 smbiosSMMemoryOffset,
370 smbiosSMMemorySize,
371 smbiosTableStorageSize,
372 smbiosTableStorage}};
373 std::unique_ptr<SharedMemoryArea> area;
374 std::unique_ptr<phosphor::Timer> timer;
375
376 private:
377 uint8_t lockIndex = 0;
378 uint8_t smbiosTableStorage[smbiosTableStorageSize];
379};