blob: 75842fce4d7c5cbb66ce9d05e4c2aaa2061854ef [file] [log] [blame]
Cheng C Yangeecaf822019-12-19 00:34:23 +08001/*
Zhikui Ren18a5ab92020-09-01 21:35:20 -07002// Copyright (c) 2018 Intel Corporation
Cheng C Yangeecaf822019-12-19 00:34:23 +08003//
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#include "mdrv2.hpp"
18
Jie Yang08e4a6d2021-08-23 13:07:41 -070019#include "pcieslot.hpp"
20
Cheng C Yangeecaf822019-12-19 00:34:23 +080021#include <sys/mman.h>
22
Cheng C Yangeecaf822019-12-19 00:34:23 +080023#include <phosphor-logging/elog-errors.hpp>
24#include <sdbusplus/exception.hpp>
25#include <xyz/openbmc_project/Smbios/MDR_V2/error.hpp>
26
Zhikui Ren18a5ab92020-09-01 21:35:20 -070027#include <fstream>
28
Cheng C Yangeecaf822019-12-19 00:34:23 +080029namespace phosphor
30{
31namespace smbios
32{
33
34std::vector<uint8_t> MDR_V2::getDirectoryInformation(uint8_t dirIndex)
35{
Cheng C Yang608e52d2019-12-19 00:39:50 +080036 std::vector<uint8_t> responseDir;
37 if (dirIndex > smbiosDir.dirEntries)
38 {
39 responseDir.push_back(0);
Kuiying Wanga4c08702020-11-18 19:27:20 +080040 throw sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::
41 InvalidParameter();
Cheng C Yang608e52d2019-12-19 00:39:50 +080042 }
43 responseDir.push_back(mdr2Version);
44 responseDir.push_back(smbiosDir.dirVersion);
45 uint8_t returnedEntries = smbiosDir.dirEntries - dirIndex;
46 responseDir.push_back(returnedEntries);
47 if ((dirIndex + returnedEntries) >= smbiosDir.dirEntries)
48 {
49 responseDir.push_back(0);
50 }
51 else
52 {
53 responseDir.push_back(smbiosDir.dirEntries - dirIndex -
54 returnedEntries);
55 }
56 for (uint8_t index = dirIndex; index < smbiosDir.dirEntries; index++)
57 {
58 for (uint8_t indexId = 0; indexId < sizeof(DataIdStruct); indexId++)
59 {
60 responseDir.push_back(
61 smbiosDir.dir[index].common.id.dataInfo[indexId]);
62 }
63 }
64
65 return responseDir;
Cheng C Yangeecaf822019-12-19 00:34:23 +080066}
67
68bool MDR_V2::smbiosIsAvailForUpdate(uint8_t index)
69{
70 bool ret = false;
Chen Yugangad0e7652020-12-01 14:49:54 +080071 if (index >= maxDirEntries)
Cheng C Yangeecaf822019-12-19 00:34:23 +080072 {
73 return ret;
74 }
75
76 switch (smbiosDir.dir[index].stage)
77 {
78 case MDR2SMBIOSStatusEnum::mdr2Updating:
79 ret = false;
80 break;
81
82 case MDR2SMBIOSStatusEnum::mdr2Init:
83 // This *looks* like there should be a break statement here,
84 // as the effects of the previous statement are a noop given
85 // the following code that this falls through to.
86 // We've elected not to change it, though, since it's been
87 // this way since the old generation, and it would affect
88 // the way the code functions.
89 // If it ain't broke, don't fix it.
90
91 case MDR2SMBIOSStatusEnum::mdr2Loaded:
92 case MDR2SMBIOSStatusEnum::mdr2Updated:
93 if (smbiosDir.dir[index].lock == MDR2DirLockEnum::mdr2DirLock)
94 {
95 ret = false;
96 }
97 else
98 {
99 ret = true;
100 }
101 break;
102
103 default:
104 break;
105 }
106
107 return ret;
108}
109
110std::vector<uint8_t> MDR_V2::getDataOffer()
111{
112 std::vector<uint8_t> offer(sizeof(DataIdStruct));
113 if (smbiosIsAvailForUpdate(0))
114 {
115 std::copy(smbiosDir.dir[0].common.id.dataInfo,
116 &smbiosDir.dir[0].common.id.dataInfo[16], offer.data());
117 }
118 else
119 {
120 phosphor::logging::log<phosphor::logging::level::ERR>(
121 "smbios is not ready for update");
Kuiying Wanga4c08702020-11-18 19:27:20 +0800122 throw sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::
123 UpdateInProgress();
Cheng C Yangeecaf822019-12-19 00:34:23 +0800124 }
125 return offer;
126}
127
128inline uint8_t MDR_V2::smbiosValidFlag(uint8_t index)
129{
130 FlagStatus ret = FlagStatus::flagIsInvalid;
131 MDR2SMBIOSStatusEnum stage = smbiosDir.dir[index].stage;
132 MDR2DirLockEnum lock = smbiosDir.dir[index].lock;
133
134 switch (stage)
135 {
136 case MDR2SMBIOSStatusEnum::mdr2Loaded:
137 case MDR2SMBIOSStatusEnum::mdr2Updated:
138 if (lock == MDR2DirLockEnum::mdr2DirLock)
139 {
140 ret = FlagStatus::flagIsLocked; // locked
141 }
142 else
143 {
144 ret = FlagStatus::flagIsValid; // valid
145 }
146 break;
147
148 case MDR2SMBIOSStatusEnum::mdr2Updating:
149 case MDR2SMBIOSStatusEnum::mdr2Init:
150 ret = FlagStatus::flagIsInvalid; // invalid
151 break;
152
153 default:
154 break;
155 }
156
157 return static_cast<uint8_t>(ret);
158}
159
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700160// If source variable size is 4 bytes (uint32_t) and destination is Vector type
161// is 1 byte (uint8_t), then by using this API can copy data byte by byte. For
162// Example copying data from smbiosDir.dir[idIndex].common.size and
163// smbiosDir.dir[idIndex].common.timestamp to vector variable responseInfo
164template <typename T>
165void appendReversed(std::vector<uint8_t>& vector, const T& value)
166{
167 auto data = reinterpret_cast<const uint8_t*>(&value);
168 std::reverse_copy(data, data + sizeof(value), std::back_inserter(vector));
169}
170
Cheng C Yangeecaf822019-12-19 00:34:23 +0800171std::vector<uint8_t> MDR_V2::getDataInformation(uint8_t idIndex)
172{
173 std::vector<uint8_t> responseInfo;
174 responseInfo.push_back(mdr2Version);
175
176 if (idIndex >= maxDirEntries)
177 {
Kuiying Wanga4c08702020-11-18 19:27:20 +0800178 throw sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::
179 InvalidParameter();
Cheng C Yangeecaf822019-12-19 00:34:23 +0800180 }
181
182 for (uint8_t index = 0; index < sizeof(DataIdStruct); index++)
183 {
184 responseInfo.push_back(
185 smbiosDir.dir[idIndex].common.id.dataInfo[index]);
186 }
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700187
Cheng C Yangeecaf822019-12-19 00:34:23 +0800188 responseInfo.push_back(smbiosValidFlag(idIndex));
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700189 appendReversed(responseInfo, smbiosDir.dir[idIndex].common.size);
Cheng C Yangeecaf822019-12-19 00:34:23 +0800190 responseInfo.push_back(smbiosDir.dir[idIndex].common.dataVersion);
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700191 appendReversed(responseInfo, smbiosDir.dir[idIndex].common.timestamp);
Cheng C Yangeecaf822019-12-19 00:34:23 +0800192
193 return responseInfo;
194}
195
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700196bool MDR_V2::readDataFromFlash(MDRSMBIOSHeader* mdrHdr, uint8_t* data)
197{
198 if (mdrHdr == nullptr)
199 {
200 phosphor::logging::log<phosphor::logging::level::ERR>(
201 "Read data from flash error - Invalid mdr header");
202 return false;
203 }
204 if (data == nullptr)
205 {
206 phosphor::logging::log<phosphor::logging::level::ERR>(
207 "Read data from flash error - Invalid data point");
208 return false;
209 }
210 std::ifstream smbiosFile(mdrType2File, std::ios_base::binary);
211 if (!smbiosFile.good())
212 {
213 phosphor::logging::log<phosphor::logging::level::ERR>(
214 "Read data from flash error - Open MDRV2 table file failure");
215 return false;
216 }
217 smbiosFile.clear();
218 smbiosFile.seekg(0, std::ios_base::end);
219 int fileLength = smbiosFile.tellg();
220 smbiosFile.seekg(0, std::ios_base::beg);
221 if (fileLength < sizeof(MDRSMBIOSHeader))
222 {
223 phosphor::logging::log<phosphor::logging::level::ERR>(
224 "MDR V2 file size is smaller than mdr header");
225 return false;
226 }
227 smbiosFile.read(reinterpret_cast<char*>(mdrHdr), sizeof(MDRSMBIOSHeader));
228 if (mdrHdr->dataSize > smbiosTableStorageSize)
229 {
230 phosphor::logging::log<phosphor::logging::level::ERR>(
231 "Data size out of limitation");
232 smbiosFile.close();
233 return false;
234 }
235 fileLength -= sizeof(MDRSMBIOSHeader);
236 if (fileLength < mdrHdr->dataSize)
237 {
238 smbiosFile.read(reinterpret_cast<char*>(data), fileLength);
239 }
240 else
241 {
242 smbiosFile.read(reinterpret_cast<char*>(data), mdrHdr->dataSize);
243 }
244 smbiosFile.close();
245 return true;
246}
247
Cheng C Yangeecaf822019-12-19 00:34:23 +0800248bool MDR_V2::sendDirectoryInformation(uint8_t dirVersion, uint8_t dirIndex,
249 uint8_t returnedEntries,
250 uint8_t remainingEntries,
251 std::vector<uint8_t> dirEntry)
252{
Cheng C Yang608e52d2019-12-19 00:39:50 +0800253 bool teminate = false;
254 if ((dirIndex >= maxDirEntries) || (returnedEntries < 1))
255 {
256 phosphor::logging::log<phosphor::logging::level::ERR>(
257 "Send Dir info failed - input parameter invalid");
Kuiying Wanga4c08702020-11-18 19:27:20 +0800258 throw sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::
259 InvalidParameter();
Cheng C Yang608e52d2019-12-19 00:39:50 +0800260 }
Mansi Joshiecbd71b2021-08-10 22:14:08 +0530261 if ((static_cast<size_t>(returnedEntries) * sizeof(DataIdStruct)) !=
262 dirEntry.size())
Cheng C Yang608e52d2019-12-19 00:39:50 +0800263 {
264 phosphor::logging::log<phosphor::logging::level::ERR>(
265 "Directory size invalid");
Kuiying Wanga4c08702020-11-18 19:27:20 +0800266 throw sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::
267 InvalidParameter();
Cheng C Yang608e52d2019-12-19 00:39:50 +0800268 }
269 if (dirVersion == smbiosDir.dirVersion)
270 {
271 teminate = true;
272 }
273 else
274 {
275 if (remainingEntries > 0)
276 {
277 teminate = false;
278 }
279 else
280 {
281 teminate = true;
282 smbiosDir.dirVersion = dirVersion;
283 }
284 uint8_t idIndex = dirIndex;
Mansi Joshiecbd71b2021-08-10 22:14:08 +0530285 smbiosDir.dirEntries = returnedEntries;
Cheng C Yang608e52d2019-12-19 00:39:50 +0800286
287 uint8_t* pData = dirEntry.data();
288 if (pData == nullptr)
289 {
290 return false;
291 }
292 for (uint8_t index = 0; index < returnedEntries; index++)
293 {
Mansi Joshiecbd71b2021-08-10 22:14:08 +0530294 auto data = reinterpret_cast<const DataIdStruct*>(pData);
295 std::copy(data->dataInfo, data->dataInfo + sizeof(DataIdStruct),
Cheng C Yang608e52d2019-12-19 00:39:50 +0800296 smbiosDir.dir[idIndex + index].common.id.dataInfo);
Mansi Joshiecbd71b2021-08-10 22:14:08 +0530297 pData += sizeof(DataIdStruct);
Cheng C Yang608e52d2019-12-19 00:39:50 +0800298 }
299 }
300 return teminate;
Cheng C Yangeecaf822019-12-19 00:34:23 +0800301}
302
303bool MDR_V2::sendDataInformation(uint8_t idIndex, uint8_t flag,
304 uint32_t dataLen, uint32_t dataVer,
305 uint32_t timeStamp)
306{
307 if (idIndex >= maxDirEntries)
308 {
Kuiying Wanga4c08702020-11-18 19:27:20 +0800309 throw sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::
310 InvalidParameter();
Cheng C Yangeecaf822019-12-19 00:34:23 +0800311 }
312 int entryChanged = 0;
313 if (smbiosDir.dir[idIndex].common.dataSetSize != dataLen)
314 {
315 entryChanged++;
316 smbiosDir.dir[idIndex].common.dataSetSize = dataLen;
317 }
318
319 if (smbiosDir.dir[idIndex].common.dataVersion != dataVer)
320 {
321 entryChanged++;
322 smbiosDir.dir[idIndex].common.dataVersion = dataVer;
323 }
324
325 if (smbiosDir.dir[idIndex].common.timestamp != timeStamp)
326 {
327 entryChanged++;
328 smbiosDir.dir[idIndex].common.timestamp = timeStamp;
329 }
330 if (entryChanged == 0)
331 {
332 return false;
333 }
334 return true;
335}
336
337int MDR_V2::findIdIndex(std::vector<uint8_t> dataInfo)
338{
339 if (dataInfo.size() != sizeof(DataIdStruct))
340 {
341 phosphor::logging::log<phosphor::logging::level::ERR>(
342 "Length of dataInfo invalid");
Kuiying Wanga4c08702020-11-18 19:27:20 +0800343 throw sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::
344 InvalidId();
Cheng C Yangeecaf822019-12-19 00:34:23 +0800345 }
346 std::array<uint8_t, 16> arrayDataInfo;
347
348 std::copy(dataInfo.begin(), dataInfo.end(), arrayDataInfo.begin());
349
350 for (int index = 0; index < smbiosDir.dirEntries; index++)
351 {
352 int info = 0;
353 for (; info < arrayDataInfo.size(); info++)
354 {
355 if (arrayDataInfo[info] !=
356 smbiosDir.dir[index].common.id.dataInfo[info])
357 {
358 break;
359 }
360 }
361 if (info == arrayDataInfo.size())
362 {
363 return index;
364 }
365 }
Kuiying Wanga4c08702020-11-18 19:27:20 +0800366 throw sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::InvalidId();
Cheng C Yangeecaf822019-12-19 00:34:23 +0800367}
368
369uint8_t MDR_V2::directoryEntries(uint8_t value)
370{
371 value = smbiosDir.dirEntries;
372 return sdbusplus::xyz::openbmc_project::Smbios::server::MDR_V2::
373 directoryEntries(value);
374}
375
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800376void MDR_V2::systemInfoUpdate()
377{
Jie Yange7cf3192021-08-20 11:21:43 -0700378 std::string motherboardPath;
379 sdbusplus::message::message method =
380 bus.new_method_call("xyz.openbmc_project.EntityManager",
381 "/xyz/openbmc_project/EntityManager",
382 "xyz.openbmc_project.EntityManager", "ReScan");
383 try
384 {
385 sdbusplus::message::message reply = bus.call(method);
386 reply.read(motherboardPath);
387 }
388 catch (const sdbusplus::exception_t& e)
389 {
390 phosphor::logging::log<phosphor::logging::level::ERR>(
391 "Failed to query system motherboard",
392 phosphor::logging::entry("ERROR=%s", e.what()));
393 }
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800394
Jie Yange7cf3192021-08-20 11:21:43 -0700395 cpus.clear();
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800396 int num = getTotalCpuSlot();
397 if (num == -1)
398 {
399 phosphor::logging::log<phosphor::logging::level::ERR>(
400 "get cpu total slot failed");
401 return;
402 }
403
404 for (int index = 0; index < num; index++)
405 {
406 std::string path = cpuPath + std::to_string(index);
407 cpus.emplace_back(std::make_unique<phosphor::smbios::Cpu>(
Jie Yange7cf3192021-08-20 11:21:43 -0700408 bus, path, index, smbiosDir.dir[smbiosDirIndex].dataStorage,
409 motherboardPath));
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800410 }
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800411
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700412#ifdef DIMM_DBUS
413
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800414 dimms.clear();
415
416 num = getTotalDimmSlot();
417 if (num == -1)
418 {
419 phosphor::logging::log<phosphor::logging::level::ERR>(
420 "get dimm total slot failed");
421 return;
422 }
423
424 for (int index = 0; index < num; index++)
425 {
426 std::string path = dimmPath + std::to_string(index);
427 dimms.emplace_back(std::make_unique<phosphor::smbios::Dimm>(
Jie Yange7cf3192021-08-20 11:21:43 -0700428 bus, path, index, smbiosDir.dir[smbiosDirIndex].dataStorage,
429 motherboardPath));
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800430 }
Cheng C Yangb4651b92019-12-19 00:59:01 +0800431
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700432#endif
433
Jie Yang08e4a6d2021-08-23 13:07:41 -0700434 pcies.clear();
435 num = getTotalPcieSlot();
436 if (num == -1)
437 {
438 phosphor::logging::log<phosphor::logging::level::ERR>(
439 "get pcie total slot failed");
440 return;
441 }
442
443 for (int index = 0; index < num; index++)
444 {
445 std::string path = pciePath + std::to_string(index);
446 pcies.emplace_back(std::make_unique<phosphor::smbios::Pcie>(
Jie Yange7cf3192021-08-20 11:21:43 -0700447 bus, path, index, smbiosDir.dir[smbiosDirIndex].dataStorage,
448 motherboardPath));
Jie Yang08e4a6d2021-08-23 13:07:41 -0700449 }
450
Cheng C Yangb4651b92019-12-19 00:59:01 +0800451 system.reset();
452 system = std::make_unique<System>(
453 bus, systemPath, smbiosDir.dir[smbiosDirIndex].dataStorage);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800454}
455
456int MDR_V2::getTotalCpuSlot()
457{
458 uint8_t* dataIn = smbiosDir.dir[smbiosDirIndex].dataStorage;
459 int num = 0;
460
461 if (dataIn == nullptr)
462 {
463 phosphor::logging::log<phosphor::logging::level::ERR>(
464 "get cpu total slot failed - no storage data");
465 return -1;
466 }
467
468 while (1)
469 {
470 dataIn = getSMBIOSTypePtr(dataIn, processorsType);
471 if (dataIn == nullptr)
472 {
473 break;
474 }
475 num++;
476 dataIn = smbiosNextPtr(dataIn);
477 if (dataIn == nullptr)
478 {
479 break;
480 }
481 if (num >= limitEntryLen)
482 {
483 break;
484 }
485 }
486
487 return num;
488}
489
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800490int MDR_V2::getTotalDimmSlot()
491{
492 uint8_t* dataIn = smbiosDir.dir[smbiosDirIndex].dataStorage;
493 uint8_t num = 0;
494
495 if (dataIn == nullptr)
496 {
497 phosphor::logging::log<phosphor::logging::level::ERR>(
498 "Fail to get dimm total slot - no storage data");
499 return -1;
500 }
501
502 while (1)
503 {
504 dataIn = getSMBIOSTypePtr(dataIn, memoryDeviceType);
505 if (dataIn == nullptr)
506 {
507 break;
508 }
509 num++;
510 dataIn = smbiosNextPtr(dataIn);
511 if (dataIn == nullptr)
512 {
513 break;
514 }
515 if (num >= limitEntryLen)
516 {
517 break;
518 }
519 }
520
521 return num;
522}
523
Jie Yang08e4a6d2021-08-23 13:07:41 -0700524int MDR_V2::getTotalPcieSlot()
525{
526 uint8_t* dataIn = smbiosDir.dir[smbiosDirIndex].dataStorage;
527 int num = 0;
528
529 if (dataIn == nullptr)
530 {
531 phosphor::logging::log<phosphor::logging::level::ERR>(
532 "Fail to get total system slot - no storage data");
533 return -1;
534 }
535
536 while (1)
537 {
538 dataIn = getSMBIOSTypePtr(dataIn, systemSlots);
539 if (dataIn == nullptr)
540 {
541 break;
542 }
543
544 /* System slot type offset. Check if the slot is a PCIE slots. All
545 * PCIE slot type are hardcoded in a table.
546 */
547 if (pcieSmbiosType.find(*(dataIn + 5)) != pcieSmbiosType.end())
548 {
549 num++;
550 }
551 dataIn = smbiosNextPtr(dataIn);
552 if (dataIn == nullptr)
553 {
554 break;
555 }
556 if (num >= limitEntryLen)
557 {
558 break;
559 }
560 }
561
562 return num;
563}
564
Cheng C Yangeecaf822019-12-19 00:34:23 +0800565bool MDR_V2::agentSynchronizeData()
566{
Cheng C Yangec634252019-12-19 00:42:36 +0800567 struct MDRSMBIOSHeader mdr2SMBIOS;
568 bool status = readDataFromFlash(&mdr2SMBIOS,
569 smbiosDir.dir[smbiosDirIndex].dataStorage);
570 if (!status)
571 {
572 phosphor::logging::log<phosphor::logging::level::ERR>(
573 "agent data sync failed - read data from flash failed");
574 return false;
575 }
576 else
577 {
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800578 systemInfoUpdate();
Cheng C Yangec634252019-12-19 00:42:36 +0800579 smbiosDir.dir[smbiosDirIndex].common.dataVersion = mdr2SMBIOS.dirVer;
580 smbiosDir.dir[smbiosDirIndex].common.timestamp = mdr2SMBIOS.timestamp;
581 smbiosDir.dir[smbiosDirIndex].common.size = mdr2SMBIOS.dataSize;
582 smbiosDir.dir[smbiosDirIndex].stage = MDR2SMBIOSStatusEnum::mdr2Loaded;
583 smbiosDir.dir[smbiosDirIndex].lock = MDR2DirLockEnum::mdr2DirUnlock;
584 }
Cheng C Yangec634252019-12-19 00:42:36 +0800585 return true;
Cheng C Yangeecaf822019-12-19 00:34:23 +0800586}
587
588std::vector<uint32_t> MDR_V2::synchronizeDirectoryCommonData(uint8_t idIndex,
589 uint32_t size)
590{
Cheng C Yangec634252019-12-19 00:42:36 +0800591 std::chrono::microseconds usec(
592 defaultTimeout); // default lock time out is 2s
593 std::vector<uint32_t> result;
594 smbiosDir.dir[idIndex].common.size = size;
595 result.push_back(smbiosDir.dir[idIndex].common.dataSetSize);
596 result.push_back(smbiosDir.dir[idIndex].common.dataVersion);
597 result.push_back(smbiosDir.dir[idIndex].common.timestamp);
598
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700599 timer.expires_after(usec);
600 timer.async_wait([this](boost::system::error_code ec) {
601 if (ec || this == nullptr)
602 {
603 phosphor::logging::log<phosphor::logging::level::ERR>(
604 "Timer Error!");
605 return;
606 }
607 agentSynchronizeData();
608 });
Cheng C Yangec634252019-12-19 00:42:36 +0800609 return result;
Cheng C Yangeecaf822019-12-19 00:34:23 +0800610}
611
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700612std::vector<boost::container::flat_map<std::string, RecordVariant>>
613 MDR_V2::getRecordType(size_t type)
614{
615
616 std::vector<boost::container::flat_map<std::string, RecordVariant>> ret;
617 if (type == memoryDeviceType)
618 {
619
620 uint8_t* dataIn = smbiosDir.dir[smbiosDirIndex].dataStorage;
621
622 if (dataIn == nullptr)
623 {
Kuiying Wanga4c08702020-11-18 19:27:20 +0800624 throw std::runtime_error("Data not populated");
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700625 }
626
627 do
628 {
629 dataIn =
630 getSMBIOSTypePtr(dataIn, memoryDeviceType, sizeof(MemoryInfo));
631 if (dataIn == nullptr)
632 {
633 break;
634 }
635 boost::container::flat_map<std::string, RecordVariant>& record =
636 ret.emplace_back();
637
638 auto memoryInfo = reinterpret_cast<MemoryInfo*>(dataIn);
639
640 record["Type"] = memoryInfo->type;
641 record["Length"] = memoryInfo->length;
642 record["Handle"] = uint16_t(memoryInfo->handle);
643 record["Physical Memory Array Handle"] =
644 uint16_t(memoryInfo->phyArrayHandle);
645 record["Memory Error Information Handle"] =
646 uint16_t(memoryInfo->errInfoHandle);
647 record["Total Width"] = uint16_t(memoryInfo->totalWidth);
648 record["Data Width"] = uint16_t(memoryInfo->dataWidth);
649 record["Size"] = uint16_t(memoryInfo->size);
650 record["Form Factor"] = memoryInfo->formFactor;
651 record["Device Set"] = memoryInfo->deviceSet;
652 record["Device Locator"] = positionToString(
653 memoryInfo->deviceLocator, memoryInfo->length, dataIn);
654 record["Bank Locator"] = positionToString(
655 memoryInfo->bankLocator, memoryInfo->length, dataIn);
656 record["Memory Type"] = memoryInfo->memoryType;
657 record["Type Detail"] = uint16_t(memoryInfo->typeDetail);
658 record["Speed"] = uint16_t(memoryInfo->speed);
659 record["Manufacturer"] = positionToString(
660 memoryInfo->manufacturer, memoryInfo->length, dataIn);
661 record["Serial Number"] = positionToString(
662 memoryInfo->serialNum, memoryInfo->length, dataIn);
663 record["Asset Tag"] = positionToString(memoryInfo->assetTag,
664 memoryInfo->length, dataIn);
665 record["Part Number"] = positionToString(
666 memoryInfo->partNum, memoryInfo->length, dataIn);
667 record["Attributes"] = memoryInfo->attributes;
668 record["Extended Size"] = uint32_t(memoryInfo->extendedSize);
669 record["Configured Memory Speed"] =
670 uint32_t(memoryInfo->confClockSpeed);
671 record["Minimum voltage"] = uint16_t(memoryInfo->minimumVoltage);
672 record["Maximum voltage"] = uint16_t(memoryInfo->maximumVoltage);
673 record["Configured voltage"] =
674 uint16_t(memoryInfo->configuredVoltage);
675 record["Memory Technology"] = memoryInfo->memoryTechnology;
676 record["Memory Operating Mode Capabilty"] =
677 uint16_t(memoryInfo->memoryOperatingModeCap);
678 record["Firmare Version"] = memoryInfo->firwareVersion;
679 record["Module Manufacturer ID"] =
680 uint16_t(memoryInfo->modelManufId);
681 record["Module Product ID"] = uint16_t(memoryInfo->modelProdId);
682 record["Memory Subsystem Controller Manufacturer ID"] =
683 uint16_t(memoryInfo->memSubConManufId);
684 record["Memory Subsystem Controller Product Id"] =
685 uint16_t(memoryInfo->memSubConProdId);
686 record["Non-volatile Size"] = uint64_t(memoryInfo->nvSize);
687 record["Volatile Size"] = uint64_t(memoryInfo->volatileSize);
688 record["Cache Size"] = uint64_t(memoryInfo->cacheSize);
689 record["Logical Size"] = uint64_t(memoryInfo->logicalSize);
690 } while ((dataIn = smbiosNextPtr(dataIn)) != nullptr);
691
692 return ret;
693 }
694
Kuiying Wanga4c08702020-11-18 19:27:20 +0800695 throw std::invalid_argument("Invalid record type");
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700696 return ret;
697}
698
Cheng C Yangeecaf822019-12-19 00:34:23 +0800699} // namespace smbios
700} // namespace phosphor