blob: 9bfb54fd482b3a15cb6e504b81bc75297be0824e [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>
Jason M. Bills0748c692022-09-08 15:34:08 -070023#include <types.hpp>
Vernon Mauerya3702c12019-05-22 13:20:59 -070024
James Feistfcd2d3a2020-05-28 10:38:15 -070025static constexpr const char* mdrType2File = "/var/lib/smbios/smbios2";
26static constexpr const char* smbiosPath = "/var/lib/smbios";
Vernon Mauerya3702c12019-05-22 13:20:59 -070027static constexpr const size_t msgPayloadSize =
28 1024 * 60; // Total size will transfer for smbios table
29static constexpr const size_t mdriiSMSize = 0x00100000;
30
31static constexpr const uint16_t smbiosAgentId =
32 0x0101; // Agent ID for smbios entry
33static constexpr const int firstAgentIndex = 1;
34
35static constexpr const uint8_t maxDirEntries = 4; // Maximum directory entries
36static constexpr const uint32_t mdr2SMSize =
37 0x00100000; // Size of VGA share memory
38static constexpr const uint32_t mdr2SMBaseAddress =
39 0x9FF00000; // Base address of VGA share memory
40
41static constexpr const uint8_t mdrTypeII = 2; // MDR V2 type
42
43static constexpr const uint8_t mdr2Version = 2; // MDR V2 versoin
44static constexpr const uint8_t smbiosAgentVersion = 1; // Agent version of
45 // smbios
46
47static constexpr const uint32_t pageMask =
48 0xf000; // To make data become n times of page
49static constexpr const int smbiosDirIndex = 0; // SMBIOS directory index
50
51static constexpr const uint32_t smbiosTableVersion =
52 15; // Version of smbios table
53static constexpr const uint32_t smbiosTableTimestamp =
54 0x45464748; // Time stamp when smbios table created
55static constexpr const size_t smbiosSMMemoryOffset =
56 0; // Offset of VGA share memory
57static constexpr const size_t smbiosSMMemorySize =
58 1024 * 1024; // Total size of VGA share memory
59static constexpr const size_t smbiosTableStorageSize =
60 64 * 1024; // Total size of smbios table
Jayaprakash Mutyalafe9a7002020-12-02 19:17:58 +000061static constexpr const uint32_t defaultTimeout = 4000;
62static constexpr const uint16_t sysClock = 1000;
Vernon Mauerya3702c12019-05-22 13:20:59 -070063static constexpr const int lastAgentIndex = -1;
64static constexpr const uint16_t lastAgentId = 0xFFFF;
65constexpr const uint32_t invalidChecksum = 0xffffffff;
James Feistfcd2d3a2020-05-28 10:38:15 -070066constexpr const char* dbusProperties = "org.freedesktop.DBus.Properties";
67constexpr const char* mdrv2Path = "/xyz/openbmc_project/Smbios/MDR_V2";
68constexpr const char* mdrv2Interface = "xyz.openbmc_project.Smbios.MDR_V2";
Vernon Mauerya3702c12019-05-22 13:20:59 -070069
70enum class MDR2SMBIOSStatusEnum
71{
72 mdr2Init = 0,
73 mdr2Loaded = 1,
74 mdr2Updated = 2,
75 mdr2Updating = 3
76};
77
78enum class DirDataRequestEnum
79{
80 dirDataNotRequested = 0x00,
81 dirDataRequested = 0x01
82};
83
84enum MDR2DirLockEnum
85{
86 mdr2DirUnlock = 0,
87 mdr2DirLock = 1
88};
89
90#pragma pack(push)
91#pragma pack(1)
92
93struct MDRSMBIOSHeader
94{
95 uint8_t dirVer;
96 uint8_t mdrType;
97 uint32_t timestamp;
98 uint32_t dataSize;
99};
100
101struct DataIdStruct
102{
103 uint8_t dataInfo[16];
104};
105
106struct Mdr2DirEntry
107{
108 DataIdStruct id;
109 uint32_t size;
110 uint32_t dataSetSize;
111 uint32_t dataVersion;
112 uint32_t timestamp;
113};
114
115struct Mdr2DirLocalStruct
116{
117 Mdr2DirEntry common;
118 MDR2SMBIOSStatusEnum stage;
119 MDR2DirLockEnum lock;
120 uint16_t lockHandle;
121 uint32_t xferBuff;
122 uint32_t xferSize;
123 uint32_t maxDataSize;
James Feistfcd2d3a2020-05-28 10:38:15 -0700124 uint8_t* dataStorage;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700125};
126
127struct Mdr2DirStruct
128{
129 uint8_t agentVersion;
130 uint8_t dirVersion;
131 uint8_t dirEntries;
132 uint8_t status; // valid / locked / etc
133 uint8_t remoteDirVersion;
134 uint16_t sessionHandle;
135 Mdr2DirLocalStruct dir[maxDirEntries];
136};
137
138// Three members include dataSetSize, dataVersion and timestamp
139static constexpr const size_t syncDirCommonSize = 3;
140
141// ====================== MDR II Pull Command Structures ======================
Vernon Mauerya3702c12019-05-22 13:20:59 -0700142struct MDRiiGetDataInfoRequest
143{
144 uint16_t agentId;
145 DataIdStruct dataSetInfo;
146};
147
148// MDR II data set information inquiry response
149struct MDRiiGetDataInfoResponse
150{
151 uint8_t mdrVersion;
152 DataIdStruct dataSetId;
153 uint8_t validFlag;
154 uint32_t dataLength;
jayaprakash Mutyala04a38ed2020-05-29 01:42:26 +0000155 uint8_t dataVersion;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700156 uint32_t timeStamp;
157};
158
Vernon Mauerya3702c12019-05-22 13:20:59 -0700159// ====================== MDR II Push Command Structures ======================
Vernon Mauerya3702c12019-05-22 13:20:59 -0700160// MDR II Client send data set info offer response
161struct MDRiiOfferDataInfoResponse
162{
163 DataIdStruct dataSetInfo;
164};
165
166// MDR II Push Agent send data set info command
167struct MDRiiSendDataInfoRequest
168{
169 uint16_t agentId;
170 DataIdStruct dataSetInfo;
171 uint8_t validFlag;
172 uint32_t dataLength;
173 uint32_t dataVersion; // Roughly equivalent to the "file name"
174 uint32_t
175 timeStamp; // More info on the identity of this particular set of data
176};
177
Vernon Mauerya3702c12019-05-22 13:20:59 -0700178// MDR II Pull Agent lock data set command
179struct MDRiiLockDataRequest
180{
181 uint16_t agentId;
182 DataIdStruct dataSetInfo;
183 uint16_t timeout;
184};
185
186// MDR II Pull Agent lock data set response
187struct MDRiiLockDataResponse
188{
189 uint8_t mdrVersion;
190 uint16_t lockHandle;
191 uint32_t dataLength;
192 uint32_t xferAddress;
193 uint32_t xferLength;
194};
195
Vernon Mauerya3702c12019-05-22 13:20:59 -0700196// MDR II Push Agent send data start command
197struct MDRiiDataStartRequest
198{
199 uint16_t agentId;
200 DataIdStruct dataSetInfo;
201 uint32_t dataLength;
202 uint32_t xferAddress;
203 uint32_t xferLength;
204 uint16_t timeout;
205};
206
207// MDR II Client send data start response
208struct MDRiiDataStartResponse
209{
210 uint8_t xferStartAck;
211 uint16_t sessionHandle;
212};
213
214// MDR II
215struct MDRiiDataDoneRequest
216{
217 uint16_t agentId;
218 uint16_t lockHandle;
219};
220
221#pragma pack(pop)
222
223class SharedMemoryArea
224{
225 public:
226 SharedMemoryArea(uint32_t addr, uint32_t areaSize) :
227 vPtr(nullptr), physicalAddr(addr), size(areaSize)
228 {
229 Initialize(addr, areaSize);
230 }
231
232 ~SharedMemoryArea()
233 {
234 if ((vPtr != nullptr) && (vPtr != MAP_FAILED))
235 {
236 if (0 != munmap(vPtr, size))
237 {
238 phosphor::logging::log<phosphor::logging::level::ERR>(
239 "Ummap share memory failed");
240 }
241 }
242 }
243
James Feistfcd2d3a2020-05-28 10:38:15 -0700244 void* vPtr;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700245
246 private:
247 uint32_t physicalAddr;
248 uint32_t size;
249
250 void Initialize(uint32_t addr, uint32_t areaSize);
251};
252
253class MDRV2
254{
255 public:
256 MDRV2()
257 {
258 timer =
259 std::make_unique<phosphor::Timer>([&](void) { timeoutHandler(); });
260 }
261
James Feistfcd2d3a2020-05-28 10:38:15 -0700262 int agentLookup(const uint16_t& agentId);
263 int findLockHandle(const uint16_t& lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700264 int syncDirCommonData(uint8_t idIndex, uint32_t size,
James Feistfcd2d3a2020-05-28 10:38:15 -0700265 const std::string& service);
266 int findDataId(const uint8_t* dataInfo, const size_t& len,
267 const std::string& service);
268 uint16_t getSessionHandle(Mdr2DirStruct* dir);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700269 bool smbiosIsUpdating(uint8_t index);
James Feistfcd2d3a2020-05-28 10:38:15 -0700270 uint32_t calcChecksum32(uint8_t* buf, uint32_t len);
271 bool storeDatatoFlash(MDRSMBIOSHeader* mdrHdr, uint8_t* data);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700272 bool smbiosUnlock(uint8_t index);
273 void timeoutHandler();
James Feistfcd2d3a2020-05-28 10:38:15 -0700274 bool smbiosTryLock(uint8_t flag, uint8_t index, uint16_t* session,
Vernon Mauerya3702c12019-05-22 13:20:59 -0700275 uint16_t timeout);
James Feistfcd2d3a2020-05-28 10:38:15 -0700276 int sdplusMdrv2GetProperty(const std::string& name,
Jason M. Bills0748c692022-09-08 15:34:08 -0700277 ipmi::DbusVariant& value,
James Feistfcd2d3a2020-05-28 10:38:15 -0700278 const std::string& service);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700279
280 Mdr2DirStruct smbiosDir{smbiosAgentVersion,
281 1,
282 1,
283 1,
284 0,
285 0,
286 {40,
287 41,
288 42,
289 43,
290 44,
291 45,
292 46,
293 47,
294 48,
295 49,
296 50,
297 51,
298 52,
299 53,
300 54,
301 0x42,
302 0,
303 smbiosTableStorageSize,
304 smbiosTableVersion,
305 smbiosTableTimestamp,
306 MDR2SMBIOSStatusEnum::mdr2Init,
307 MDR2DirLockEnum::mdr2DirUnlock,
308 0,
309 smbiosSMMemoryOffset,
310 smbiosSMMemorySize,
311 smbiosTableStorageSize,
312 smbiosTableStorage}};
313 std::unique_ptr<SharedMemoryArea> area;
314 std::unique_ptr<phosphor::Timer> timer;
315
316 private:
317 uint8_t lockIndex = 0;
318 uint8_t smbiosTableStorage[smbiosTableStorageSize];
319};