blob: 00fbdcce39ea940f53a541e5d6a6ec10ea76c107 [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
19#include <sys/mman.h>
20
Cheng C Yangeecaf822019-12-19 00:34:23 +080021#include <phosphor-logging/elog-errors.hpp>
22#include <sdbusplus/exception.hpp>
23#include <xyz/openbmc_project/Smbios/MDR_V2/error.hpp>
24
Zhikui Ren18a5ab92020-09-01 21:35:20 -070025#include <fstream>
26
Cheng C Yangeecaf822019-12-19 00:34:23 +080027namespace phosphor
28{
29namespace smbios
30{
31
32std::vector<uint8_t> MDR_V2::getDirectoryInformation(uint8_t dirIndex)
33{
Cheng C Yang608e52d2019-12-19 00:39:50 +080034 std::vector<uint8_t> responseDir;
35 if (dirIndex > smbiosDir.dirEntries)
36 {
37 responseDir.push_back(0);
Kuiying Wanga4c08702020-11-18 19:27:20 +080038 throw sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::
39 InvalidParameter();
Cheng C Yang608e52d2019-12-19 00:39:50 +080040 }
41 responseDir.push_back(mdr2Version);
42 responseDir.push_back(smbiosDir.dirVersion);
43 uint8_t returnedEntries = smbiosDir.dirEntries - dirIndex;
44 responseDir.push_back(returnedEntries);
45 if ((dirIndex + returnedEntries) >= smbiosDir.dirEntries)
46 {
47 responseDir.push_back(0);
48 }
49 else
50 {
51 responseDir.push_back(smbiosDir.dirEntries - dirIndex -
52 returnedEntries);
53 }
54 for (uint8_t index = dirIndex; index < smbiosDir.dirEntries; index++)
55 {
56 for (uint8_t indexId = 0; indexId < sizeof(DataIdStruct); indexId++)
57 {
58 responseDir.push_back(
59 smbiosDir.dir[index].common.id.dataInfo[indexId]);
60 }
61 }
62
63 return responseDir;
Cheng C Yangeecaf822019-12-19 00:34:23 +080064}
65
66bool MDR_V2::smbiosIsAvailForUpdate(uint8_t index)
67{
68 bool ret = false;
Chen Yugangad0e7652020-12-01 14:49:54 +080069 if (index >= maxDirEntries)
Cheng C Yangeecaf822019-12-19 00:34:23 +080070 {
71 return ret;
72 }
73
74 switch (smbiosDir.dir[index].stage)
75 {
76 case MDR2SMBIOSStatusEnum::mdr2Updating:
77 ret = false;
78 break;
79
80 case MDR2SMBIOSStatusEnum::mdr2Init:
81 // This *looks* like there should be a break statement here,
82 // as the effects of the previous statement are a noop given
83 // the following code that this falls through to.
84 // We've elected not to change it, though, since it's been
85 // this way since the old generation, and it would affect
86 // the way the code functions.
87 // If it ain't broke, don't fix it.
88
89 case MDR2SMBIOSStatusEnum::mdr2Loaded:
90 case MDR2SMBIOSStatusEnum::mdr2Updated:
91 if (smbiosDir.dir[index].lock == MDR2DirLockEnum::mdr2DirLock)
92 {
93 ret = false;
94 }
95 else
96 {
97 ret = true;
98 }
99 break;
100
101 default:
102 break;
103 }
104
105 return ret;
106}
107
108std::vector<uint8_t> MDR_V2::getDataOffer()
109{
110 std::vector<uint8_t> offer(sizeof(DataIdStruct));
111 if (smbiosIsAvailForUpdate(0))
112 {
113 std::copy(smbiosDir.dir[0].common.id.dataInfo,
114 &smbiosDir.dir[0].common.id.dataInfo[16], offer.data());
115 }
116 else
117 {
118 phosphor::logging::log<phosphor::logging::level::ERR>(
119 "smbios is not ready for update");
Kuiying Wanga4c08702020-11-18 19:27:20 +0800120 throw sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::
121 UpdateInProgress();
Cheng C Yangeecaf822019-12-19 00:34:23 +0800122 }
123 return offer;
124}
125
126inline uint8_t MDR_V2::smbiosValidFlag(uint8_t index)
127{
128 FlagStatus ret = FlagStatus::flagIsInvalid;
129 MDR2SMBIOSStatusEnum stage = smbiosDir.dir[index].stage;
130 MDR2DirLockEnum lock = smbiosDir.dir[index].lock;
131
132 switch (stage)
133 {
134 case MDR2SMBIOSStatusEnum::mdr2Loaded:
135 case MDR2SMBIOSStatusEnum::mdr2Updated:
136 if (lock == MDR2DirLockEnum::mdr2DirLock)
137 {
138 ret = FlagStatus::flagIsLocked; // locked
139 }
140 else
141 {
142 ret = FlagStatus::flagIsValid; // valid
143 }
144 break;
145
146 case MDR2SMBIOSStatusEnum::mdr2Updating:
147 case MDR2SMBIOSStatusEnum::mdr2Init:
148 ret = FlagStatus::flagIsInvalid; // invalid
149 break;
150
151 default:
152 break;
153 }
154
155 return static_cast<uint8_t>(ret);
156}
157
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700158// If source variable size is 4 bytes (uint32_t) and destination is Vector type
159// is 1 byte (uint8_t), then by using this API can copy data byte by byte. For
160// Example copying data from smbiosDir.dir[idIndex].common.size and
161// smbiosDir.dir[idIndex].common.timestamp to vector variable responseInfo
162template <typename T>
163void appendReversed(std::vector<uint8_t>& vector, const T& value)
164{
165 auto data = reinterpret_cast<const uint8_t*>(&value);
166 std::reverse_copy(data, data + sizeof(value), std::back_inserter(vector));
167}
168
Cheng C Yangeecaf822019-12-19 00:34:23 +0800169std::vector<uint8_t> MDR_V2::getDataInformation(uint8_t idIndex)
170{
171 std::vector<uint8_t> responseInfo;
172 responseInfo.push_back(mdr2Version);
173
174 if (idIndex >= maxDirEntries)
175 {
Kuiying Wanga4c08702020-11-18 19:27:20 +0800176 throw sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::
177 InvalidParameter();
Cheng C Yangeecaf822019-12-19 00:34:23 +0800178 }
179
180 for (uint8_t index = 0; index < sizeof(DataIdStruct); index++)
181 {
182 responseInfo.push_back(
183 smbiosDir.dir[idIndex].common.id.dataInfo[index]);
184 }
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700185
Cheng C Yangeecaf822019-12-19 00:34:23 +0800186 responseInfo.push_back(smbiosValidFlag(idIndex));
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700187 appendReversed(responseInfo, smbiosDir.dir[idIndex].common.size);
Cheng C Yangeecaf822019-12-19 00:34:23 +0800188 responseInfo.push_back(smbiosDir.dir[idIndex].common.dataVersion);
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700189 appendReversed(responseInfo, smbiosDir.dir[idIndex].common.timestamp);
Cheng C Yangeecaf822019-12-19 00:34:23 +0800190
191 return responseInfo;
192}
193
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700194bool MDR_V2::readDataFromFlash(MDRSMBIOSHeader* mdrHdr, uint8_t* data)
195{
196 if (mdrHdr == nullptr)
197 {
198 phosphor::logging::log<phosphor::logging::level::ERR>(
199 "Read data from flash error - Invalid mdr header");
200 return false;
201 }
202 if (data == nullptr)
203 {
204 phosphor::logging::log<phosphor::logging::level::ERR>(
205 "Read data from flash error - Invalid data point");
206 return false;
207 }
208 std::ifstream smbiosFile(mdrType2File, std::ios_base::binary);
209 if (!smbiosFile.good())
210 {
211 phosphor::logging::log<phosphor::logging::level::ERR>(
212 "Read data from flash error - Open MDRV2 table file failure");
213 return false;
214 }
215 smbiosFile.clear();
216 smbiosFile.seekg(0, std::ios_base::end);
217 int fileLength = smbiosFile.tellg();
218 smbiosFile.seekg(0, std::ios_base::beg);
219 if (fileLength < sizeof(MDRSMBIOSHeader))
220 {
221 phosphor::logging::log<phosphor::logging::level::ERR>(
222 "MDR V2 file size is smaller than mdr header");
223 return false;
224 }
225 smbiosFile.read(reinterpret_cast<char*>(mdrHdr), sizeof(MDRSMBIOSHeader));
226 if (mdrHdr->dataSize > smbiosTableStorageSize)
227 {
228 phosphor::logging::log<phosphor::logging::level::ERR>(
229 "Data size out of limitation");
230 smbiosFile.close();
231 return false;
232 }
233 fileLength -= sizeof(MDRSMBIOSHeader);
234 if (fileLength < mdrHdr->dataSize)
235 {
236 smbiosFile.read(reinterpret_cast<char*>(data), fileLength);
237 }
238 else
239 {
240 smbiosFile.read(reinterpret_cast<char*>(data), mdrHdr->dataSize);
241 }
242 smbiosFile.close();
243 return true;
244}
245
Cheng C Yangeecaf822019-12-19 00:34:23 +0800246bool MDR_V2::sendDirectoryInformation(uint8_t dirVersion, uint8_t dirIndex,
247 uint8_t returnedEntries,
248 uint8_t remainingEntries,
249 std::vector<uint8_t> dirEntry)
250{
Cheng C Yang608e52d2019-12-19 00:39:50 +0800251 bool teminate = false;
252 if ((dirIndex >= maxDirEntries) || (returnedEntries < 1))
253 {
254 phosphor::logging::log<phosphor::logging::level::ERR>(
255 "Send Dir info failed - input parameter invalid");
Kuiying Wanga4c08702020-11-18 19:27:20 +0800256 throw sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::
257 InvalidParameter();
Cheng C Yang608e52d2019-12-19 00:39:50 +0800258 }
259 if (dirEntry.size() < sizeof(Mdr2DirEntry))
260 {
261 phosphor::logging::log<phosphor::logging::level::ERR>(
262 "Directory size invalid");
Kuiying Wanga4c08702020-11-18 19:27:20 +0800263 throw sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::
264 InvalidParameter();
Cheng C Yang608e52d2019-12-19 00:39:50 +0800265 }
266 if (dirVersion == smbiosDir.dirVersion)
267 {
268 teminate = true;
269 }
270 else
271 {
272 if (remainingEntries > 0)
273 {
274 teminate = false;
275 }
276 else
277 {
278 teminate = true;
279 smbiosDir.dirVersion = dirVersion;
280 }
281 uint8_t idIndex = dirIndex;
282
283 uint8_t* pData = dirEntry.data();
284 if (pData == nullptr)
285 {
286 return false;
287 }
288 for (uint8_t index = 0; index < returnedEntries; index++)
289 {
290 auto data = reinterpret_cast<const Mdr2DirEntry*>(pData);
291 smbiosDir.dir[idIndex + index].common.dataVersion =
292 data->dataVersion;
293 std::copy(data->id.dataInfo,
294 data->id.dataInfo + sizeof(DataIdStruct),
295 smbiosDir.dir[idIndex + index].common.id.dataInfo);
296 smbiosDir.dir[idIndex + index].common.dataSetSize = data->size;
297 smbiosDir.dir[idIndex + index].common.timestamp = data->timestamp;
298 pData += sizeof(returnedEntries);
299 }
300 }
301 return teminate;
Cheng C Yangeecaf822019-12-19 00:34:23 +0800302}
303
304bool MDR_V2::sendDataInformation(uint8_t idIndex, uint8_t flag,
305 uint32_t dataLen, uint32_t dataVer,
306 uint32_t timeStamp)
307{
308 if (idIndex >= maxDirEntries)
309 {
Kuiying Wanga4c08702020-11-18 19:27:20 +0800310 throw sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::
311 InvalidParameter();
Cheng C Yangeecaf822019-12-19 00:34:23 +0800312 }
313 int entryChanged = 0;
314 if (smbiosDir.dir[idIndex].common.dataSetSize != dataLen)
315 {
316 entryChanged++;
317 smbiosDir.dir[idIndex].common.dataSetSize = dataLen;
318 }
319
320 if (smbiosDir.dir[idIndex].common.dataVersion != dataVer)
321 {
322 entryChanged++;
323 smbiosDir.dir[idIndex].common.dataVersion = dataVer;
324 }
325
326 if (smbiosDir.dir[idIndex].common.timestamp != timeStamp)
327 {
328 entryChanged++;
329 smbiosDir.dir[idIndex].common.timestamp = timeStamp;
330 }
331 if (entryChanged == 0)
332 {
333 return false;
334 }
335 return true;
336}
337
338int MDR_V2::findIdIndex(std::vector<uint8_t> dataInfo)
339{
340 if (dataInfo.size() != sizeof(DataIdStruct))
341 {
342 phosphor::logging::log<phosphor::logging::level::ERR>(
343 "Length of dataInfo invalid");
Kuiying Wanga4c08702020-11-18 19:27:20 +0800344 throw sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::
345 InvalidId();
Cheng C Yangeecaf822019-12-19 00:34:23 +0800346 }
347 std::array<uint8_t, 16> arrayDataInfo;
348
349 std::copy(dataInfo.begin(), dataInfo.end(), arrayDataInfo.begin());
350
351 for (int index = 0; index < smbiosDir.dirEntries; index++)
352 {
353 int info = 0;
354 for (; info < arrayDataInfo.size(); info++)
355 {
356 if (arrayDataInfo[info] !=
357 smbiosDir.dir[index].common.id.dataInfo[info])
358 {
359 break;
360 }
361 }
362 if (info == arrayDataInfo.size())
363 {
364 return index;
365 }
366 }
Kuiying Wanga4c08702020-11-18 19:27:20 +0800367 throw sdbusplus::xyz::openbmc_project::Smbios::MDR_V2::Error::InvalidId();
Cheng C Yangeecaf822019-12-19 00:34:23 +0800368}
369
370uint8_t MDR_V2::directoryEntries(uint8_t value)
371{
372 value = smbiosDir.dirEntries;
373 return sdbusplus::xyz::openbmc_project::Smbios::server::MDR_V2::
374 directoryEntries(value);
375}
376
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800377void MDR_V2::systemInfoUpdate()
378{
379 cpus.clear();
380
381 int num = getTotalCpuSlot();
382 if (num == -1)
383 {
384 phosphor::logging::log<phosphor::logging::level::ERR>(
385 "get cpu total slot failed");
386 return;
387 }
388
389 for (int index = 0; index < num; index++)
390 {
391 std::string path = cpuPath + std::to_string(index);
392 cpus.emplace_back(std::make_unique<phosphor::smbios::Cpu>(
393 bus, path, index, smbiosDir.dir[smbiosDirIndex].dataStorage));
394 }
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800395
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700396#ifdef DIMM_DBUS
397
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800398 dimms.clear();
399
400 num = getTotalDimmSlot();
401 if (num == -1)
402 {
403 phosphor::logging::log<phosphor::logging::level::ERR>(
404 "get dimm total slot failed");
405 return;
406 }
407
408 for (int index = 0; index < num; index++)
409 {
410 std::string path = dimmPath + std::to_string(index);
411 dimms.emplace_back(std::make_unique<phosphor::smbios::Dimm>(
412 bus, path, index, smbiosDir.dir[smbiosDirIndex].dataStorage));
413 }
Cheng C Yangb4651b92019-12-19 00:59:01 +0800414
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700415#endif
416
Cheng C Yangb4651b92019-12-19 00:59:01 +0800417 system.reset();
418 system = std::make_unique<System>(
419 bus, systemPath, smbiosDir.dir[smbiosDirIndex].dataStorage);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800420}
421
422int MDR_V2::getTotalCpuSlot()
423{
424 uint8_t* dataIn = smbiosDir.dir[smbiosDirIndex].dataStorage;
425 int num = 0;
426
427 if (dataIn == nullptr)
428 {
429 phosphor::logging::log<phosphor::logging::level::ERR>(
430 "get cpu total slot failed - no storage data");
431 return -1;
432 }
433
434 while (1)
435 {
436 dataIn = getSMBIOSTypePtr(dataIn, processorsType);
437 if (dataIn == nullptr)
438 {
439 break;
440 }
441 num++;
442 dataIn = smbiosNextPtr(dataIn);
443 if (dataIn == nullptr)
444 {
445 break;
446 }
447 if (num >= limitEntryLen)
448 {
449 break;
450 }
451 }
452
453 return num;
454}
455
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800456int MDR_V2::getTotalDimmSlot()
457{
458 uint8_t* dataIn = smbiosDir.dir[smbiosDirIndex].dataStorage;
459 uint8_t num = 0;
460
461 if (dataIn == nullptr)
462 {
463 phosphor::logging::log<phosphor::logging::level::ERR>(
464 "Fail to get dimm total slot - no storage data");
465 return -1;
466 }
467
468 while (1)
469 {
470 dataIn = getSMBIOSTypePtr(dataIn, memoryDeviceType);
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 Yangeecaf822019-12-19 00:34:23 +0800490bool MDR_V2::agentSynchronizeData()
491{
Cheng C Yangec634252019-12-19 00:42:36 +0800492 struct MDRSMBIOSHeader mdr2SMBIOS;
493 bool status = readDataFromFlash(&mdr2SMBIOS,
494 smbiosDir.dir[smbiosDirIndex].dataStorage);
495 if (!status)
496 {
497 phosphor::logging::log<phosphor::logging::level::ERR>(
498 "agent data sync failed - read data from flash failed");
499 return false;
500 }
501 else
502 {
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800503 systemInfoUpdate();
Cheng C Yangec634252019-12-19 00:42:36 +0800504 smbiosDir.dir[smbiosDirIndex].common.dataVersion = mdr2SMBIOS.dirVer;
505 smbiosDir.dir[smbiosDirIndex].common.timestamp = mdr2SMBIOS.timestamp;
506 smbiosDir.dir[smbiosDirIndex].common.size = mdr2SMBIOS.dataSize;
507 smbiosDir.dir[smbiosDirIndex].stage = MDR2SMBIOSStatusEnum::mdr2Loaded;
508 smbiosDir.dir[smbiosDirIndex].lock = MDR2DirLockEnum::mdr2DirUnlock;
509 }
Cheng C Yangec634252019-12-19 00:42:36 +0800510 return true;
Cheng C Yangeecaf822019-12-19 00:34:23 +0800511}
512
513std::vector<uint32_t> MDR_V2::synchronizeDirectoryCommonData(uint8_t idIndex,
514 uint32_t size)
515{
Cheng C Yangec634252019-12-19 00:42:36 +0800516 std::chrono::microseconds usec(
517 defaultTimeout); // default lock time out is 2s
518 std::vector<uint32_t> result;
519 smbiosDir.dir[idIndex].common.size = size;
520 result.push_back(smbiosDir.dir[idIndex].common.dataSetSize);
521 result.push_back(smbiosDir.dir[idIndex].common.dataVersion);
522 result.push_back(smbiosDir.dir[idIndex].common.timestamp);
523
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700524 timer.expires_after(usec);
525 timer.async_wait([this](boost::system::error_code ec) {
526 if (ec || this == nullptr)
527 {
528 phosphor::logging::log<phosphor::logging::level::ERR>(
529 "Timer Error!");
530 return;
531 }
532 agentSynchronizeData();
533 });
Cheng C Yangec634252019-12-19 00:42:36 +0800534 return result;
Cheng C Yangeecaf822019-12-19 00:34:23 +0800535}
536
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700537std::vector<boost::container::flat_map<std::string, RecordVariant>>
538 MDR_V2::getRecordType(size_t type)
539{
540
541 std::vector<boost::container::flat_map<std::string, RecordVariant>> ret;
542 if (type == memoryDeviceType)
543 {
544
545 uint8_t* dataIn = smbiosDir.dir[smbiosDirIndex].dataStorage;
546
547 if (dataIn == nullptr)
548 {
Kuiying Wanga4c08702020-11-18 19:27:20 +0800549 throw std::runtime_error("Data not populated");
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700550 }
551
552 do
553 {
554 dataIn =
555 getSMBIOSTypePtr(dataIn, memoryDeviceType, sizeof(MemoryInfo));
556 if (dataIn == nullptr)
557 {
558 break;
559 }
560 boost::container::flat_map<std::string, RecordVariant>& record =
561 ret.emplace_back();
562
563 auto memoryInfo = reinterpret_cast<MemoryInfo*>(dataIn);
564
565 record["Type"] = memoryInfo->type;
566 record["Length"] = memoryInfo->length;
567 record["Handle"] = uint16_t(memoryInfo->handle);
568 record["Physical Memory Array Handle"] =
569 uint16_t(memoryInfo->phyArrayHandle);
570 record["Memory Error Information Handle"] =
571 uint16_t(memoryInfo->errInfoHandle);
572 record["Total Width"] = uint16_t(memoryInfo->totalWidth);
573 record["Data Width"] = uint16_t(memoryInfo->dataWidth);
574 record["Size"] = uint16_t(memoryInfo->size);
575 record["Form Factor"] = memoryInfo->formFactor;
576 record["Device Set"] = memoryInfo->deviceSet;
577 record["Device Locator"] = positionToString(
578 memoryInfo->deviceLocator, memoryInfo->length, dataIn);
579 record["Bank Locator"] = positionToString(
580 memoryInfo->bankLocator, memoryInfo->length, dataIn);
581 record["Memory Type"] = memoryInfo->memoryType;
582 record["Type Detail"] = uint16_t(memoryInfo->typeDetail);
583 record["Speed"] = uint16_t(memoryInfo->speed);
584 record["Manufacturer"] = positionToString(
585 memoryInfo->manufacturer, memoryInfo->length, dataIn);
586 record["Serial Number"] = positionToString(
587 memoryInfo->serialNum, memoryInfo->length, dataIn);
588 record["Asset Tag"] = positionToString(memoryInfo->assetTag,
589 memoryInfo->length, dataIn);
590 record["Part Number"] = positionToString(
591 memoryInfo->partNum, memoryInfo->length, dataIn);
592 record["Attributes"] = memoryInfo->attributes;
593 record["Extended Size"] = uint32_t(memoryInfo->extendedSize);
594 record["Configured Memory Speed"] =
595 uint32_t(memoryInfo->confClockSpeed);
596 record["Minimum voltage"] = uint16_t(memoryInfo->minimumVoltage);
597 record["Maximum voltage"] = uint16_t(memoryInfo->maximumVoltage);
598 record["Configured voltage"] =
599 uint16_t(memoryInfo->configuredVoltage);
600 record["Memory Technology"] = memoryInfo->memoryTechnology;
601 record["Memory Operating Mode Capabilty"] =
602 uint16_t(memoryInfo->memoryOperatingModeCap);
603 record["Firmare Version"] = memoryInfo->firwareVersion;
604 record["Module Manufacturer ID"] =
605 uint16_t(memoryInfo->modelManufId);
606 record["Module Product ID"] = uint16_t(memoryInfo->modelProdId);
607 record["Memory Subsystem Controller Manufacturer ID"] =
608 uint16_t(memoryInfo->memSubConManufId);
609 record["Memory Subsystem Controller Product Id"] =
610 uint16_t(memoryInfo->memSubConProdId);
611 record["Non-volatile Size"] = uint64_t(memoryInfo->nvSize);
612 record["Volatile Size"] = uint64_t(memoryInfo->volatileSize);
613 record["Cache Size"] = uint64_t(memoryInfo->cacheSize);
614 record["Logical Size"] = uint64_t(memoryInfo->logicalSize);
615 } while ((dataIn = smbiosNextPtr(dataIn)) != nullptr);
616
617 return ret;
618 }
619
Kuiying Wanga4c08702020-11-18 19:27:20 +0800620 throw std::invalid_argument("Invalid record type");
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700621 return ret;
622}
623
Cheng C Yangeecaf822019-12-19 00:34:23 +0800624} // namespace smbios
625} // namespace phosphor