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