blob: b83e2d4bd1d1918c221dee6c33e8e91765c21099 [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
James Feistfcd2d3a2020-05-28 10:38:15 -070024static constexpr const char* mdrType2File = "/var/lib/smbios/smbios2";
25static constexpr const char* smbiosPath = "/var/lib/smbios";
Vernon Mauerya3702c12019-05-22 13:20:59 -070026static 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
Jayaprakash Mutyalafe9a7002020-12-02 19:17:58 +000060static constexpr const uint32_t defaultTimeout = 4000;
61static constexpr const uint16_t sysClock = 1000;
Vernon Mauerya3702c12019-05-22 13:20:59 -070062static constexpr const int lastAgentIndex = -1;
63static constexpr const uint16_t lastAgentId = 0xFFFF;
64constexpr const uint32_t invalidChecksum = 0xffffffff;
James Feistfcd2d3a2020-05-28 10:38:15 -070065constexpr 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";
Vernon Mauerya3702c12019-05-22 13:20:59 -070068
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;
James Feistfcd2d3a2020-05-28 10:38:15 -0700123 uint8_t* dataStorage;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700124};
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;
jayaprakash Mutyala04a38ed2020-05-29 01:42:26 +0000154 uint8_t dataVersion;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700155 uint32_t timeStamp;
156};
157
Vernon Mauerya3702c12019-05-22 13:20:59 -0700158// ====================== MDR II Push Command Structures ======================
Vernon Mauerya3702c12019-05-22 13:20:59 -0700159// MDR II Client send data set info offer response
160struct MDRiiOfferDataInfoResponse
161{
162 DataIdStruct dataSetInfo;
163};
164
165// MDR II Push Agent send data set info command
166struct 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
Vernon Mauerya3702c12019-05-22 13:20:59 -0700177// MDR II Pull Agent lock data set command
178struct MDRiiLockDataRequest
179{
180 uint16_t agentId;
181 DataIdStruct dataSetInfo;
182 uint16_t timeout;
183};
184
185// MDR II Pull Agent lock data set response
186struct MDRiiLockDataResponse
187{
188 uint8_t mdrVersion;
189 uint16_t lockHandle;
190 uint32_t dataLength;
191 uint32_t xferAddress;
192 uint32_t xferLength;
193};
194
Vernon Mauerya3702c12019-05-22 13:20:59 -0700195// MDR II Push Agent send data start command
196struct 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
207struct MDRiiDataStartResponse
208{
209 uint8_t xferStartAck;
210 uint16_t sessionHandle;
211};
212
213// MDR II
214struct MDRiiDataDoneRequest
215{
216 uint16_t agentId;
217 uint16_t lockHandle;
218};
219
220#pragma pack(pop)
221
222class 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
James Feistfcd2d3a2020-05-28 10:38:15 -0700243 void* vPtr;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700244
245 private:
246 uint32_t physicalAddr;
247 uint32_t size;
248
249 void Initialize(uint32_t addr, uint32_t areaSize);
250};
251
252class MDRV2
253{
254 public:
255 MDRV2()
256 {
257 timer =
258 std::make_unique<phosphor::Timer>([&](void) { timeoutHandler(); });
259 }
260
James Feistfcd2d3a2020-05-28 10:38:15 -0700261 int agentLookup(const uint16_t& agentId);
262 int findLockHandle(const uint16_t& lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700263 int syncDirCommonData(uint8_t idIndex, uint32_t size,
James Feistfcd2d3a2020-05-28 10:38:15 -0700264 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);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700268 bool smbiosIsUpdating(uint8_t index);
James Feistfcd2d3a2020-05-28 10:38:15 -0700269 uint32_t calcChecksum32(uint8_t* buf, uint32_t len);
270 bool storeDatatoFlash(MDRSMBIOSHeader* mdrHdr, uint8_t* data);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700271 bool smbiosUnlock(uint8_t index);
272 void timeoutHandler();
James Feistfcd2d3a2020-05-28 10:38:15 -0700273 bool smbiosTryLock(uint8_t flag, uint8_t index, uint16_t* session,
Vernon Mauerya3702c12019-05-22 13:20:59 -0700274 uint16_t timeout);
James Feistfcd2d3a2020-05-28 10:38:15 -0700275 int sdplusMdrv2GetProperty(const std::string& name,
276 std::variant<uint8_t>& value,
277 const std::string& service);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700278
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};