blob: c1bc09d3b55e1eb697ba88edd45f9c8c8cbcc90c [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 Wang9c362662020-10-20 15:44:41 +080038 phosphor::logging::log<phosphor::logging::level::ERR>(
39 "getDirectoryInformation: Invalid Parameter");
40 return responseDir;
Cheng C Yang608e52d2019-12-19 00:39:50 +080041 }
42 responseDir.push_back(mdr2Version);
43 responseDir.push_back(smbiosDir.dirVersion);
44 uint8_t returnedEntries = smbiosDir.dirEntries - dirIndex;
45 responseDir.push_back(returnedEntries);
46 if ((dirIndex + returnedEntries) >= smbiosDir.dirEntries)
47 {
48 responseDir.push_back(0);
49 }
50 else
51 {
52 responseDir.push_back(smbiosDir.dirEntries - dirIndex -
53 returnedEntries);
54 }
55 for (uint8_t index = dirIndex; index < smbiosDir.dirEntries; index++)
56 {
57 for (uint8_t indexId = 0; indexId < sizeof(DataIdStruct); indexId++)
58 {
59 responseDir.push_back(
60 smbiosDir.dir[index].common.id.dataInfo[indexId]);
61 }
62 }
63
64 return responseDir;
Cheng C Yangeecaf822019-12-19 00:34:23 +080065}
66
67bool MDR_V2::smbiosIsAvailForUpdate(uint8_t index)
68{
69 bool ret = false;
70 if (index > maxDirEntries)
71 {
72 return ret;
73 }
74
75 switch (smbiosDir.dir[index].stage)
76 {
77 case MDR2SMBIOSStatusEnum::mdr2Updating:
78 ret = false;
79 break;
80
81 case MDR2SMBIOSStatusEnum::mdr2Init:
82 // This *looks* like there should be a break statement here,
83 // as the effects of the previous statement are a noop given
84 // the following code that this falls through to.
85 // We've elected not to change it, though, since it's been
86 // this way since the old generation, and it would affect
87 // the way the code functions.
88 // If it ain't broke, don't fix it.
89
90 case MDR2SMBIOSStatusEnum::mdr2Loaded:
91 case MDR2SMBIOSStatusEnum::mdr2Updated:
92 if (smbiosDir.dir[index].lock == MDR2DirLockEnum::mdr2DirLock)
93 {
94 ret = false;
95 }
96 else
97 {
98 ret = true;
99 }
100 break;
101
102 default:
103 break;
104 }
105
106 return ret;
107}
108
109std::vector<uint8_t> MDR_V2::getDataOffer()
110{
111 std::vector<uint8_t> offer(sizeof(DataIdStruct));
112 if (smbiosIsAvailForUpdate(0))
113 {
114 std::copy(smbiosDir.dir[0].common.id.dataInfo,
115 &smbiosDir.dir[0].common.id.dataInfo[16], offer.data());
116 }
117 else
118 {
119 phosphor::logging::log<phosphor::logging::level::ERR>(
120 "smbios is not ready for update");
Cheng C Yangeecaf822019-12-19 00:34:23 +0800121 }
122 return offer;
123}
124
125inline uint8_t MDR_V2::smbiosValidFlag(uint8_t index)
126{
127 FlagStatus ret = FlagStatus::flagIsInvalid;
128 MDR2SMBIOSStatusEnum stage = smbiosDir.dir[index].stage;
129 MDR2DirLockEnum lock = smbiosDir.dir[index].lock;
130
131 switch (stage)
132 {
133 case MDR2SMBIOSStatusEnum::mdr2Loaded:
134 case MDR2SMBIOSStatusEnum::mdr2Updated:
135 if (lock == MDR2DirLockEnum::mdr2DirLock)
136 {
137 ret = FlagStatus::flagIsLocked; // locked
138 }
139 else
140 {
141 ret = FlagStatus::flagIsValid; // valid
142 }
143 break;
144
145 case MDR2SMBIOSStatusEnum::mdr2Updating:
146 case MDR2SMBIOSStatusEnum::mdr2Init:
147 ret = FlagStatus::flagIsInvalid; // invalid
148 break;
149
150 default:
151 break;
152 }
153
154 return static_cast<uint8_t>(ret);
155}
156
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700157// If source variable size is 4 bytes (uint32_t) and destination is Vector type
158// is 1 byte (uint8_t), then by using this API can copy data byte by byte. For
159// Example copying data from smbiosDir.dir[idIndex].common.size and
160// smbiosDir.dir[idIndex].common.timestamp to vector variable responseInfo
161template <typename T>
162void appendReversed(std::vector<uint8_t>& vector, const T& value)
163{
164 auto data = reinterpret_cast<const uint8_t*>(&value);
165 std::reverse_copy(data, data + sizeof(value), std::back_inserter(vector));
166}
167
Cheng C Yangeecaf822019-12-19 00:34:23 +0800168std::vector<uint8_t> MDR_V2::getDataInformation(uint8_t idIndex)
169{
170 std::vector<uint8_t> responseInfo;
171 responseInfo.push_back(mdr2Version);
172
173 if (idIndex >= maxDirEntries)
174 {
Kuiying Wang9c362662020-10-20 15:44:41 +0800175 phosphor::logging::log<phosphor::logging::level::ERR>(
176 "getDataInformation: Invalid Parameter");
177 return responseInfo;
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 Wang9c362662020-10-20 15:44:41 +0800256 return teminate;
Cheng C Yang608e52d2019-12-19 00:39:50 +0800257 }
258 if (dirEntry.size() < sizeof(Mdr2DirEntry))
259 {
260 phosphor::logging::log<phosphor::logging::level::ERR>(
261 "Directory size invalid");
Kuiying Wang9c362662020-10-20 15:44:41 +0800262 return teminate;
Cheng C Yang608e52d2019-12-19 00:39:50 +0800263 }
264 if (dirVersion == smbiosDir.dirVersion)
265 {
266 teminate = true;
267 }
268 else
269 {
270 if (remainingEntries > 0)
271 {
272 teminate = false;
273 }
274 else
275 {
276 teminate = true;
277 smbiosDir.dirVersion = dirVersion;
278 }
279 uint8_t idIndex = dirIndex;
280
281 uint8_t* pData = dirEntry.data();
282 if (pData == nullptr)
283 {
284 return false;
285 }
286 for (uint8_t index = 0; index < returnedEntries; index++)
287 {
288 auto data = reinterpret_cast<const Mdr2DirEntry*>(pData);
289 smbiosDir.dir[idIndex + index].common.dataVersion =
290 data->dataVersion;
291 std::copy(data->id.dataInfo,
292 data->id.dataInfo + sizeof(DataIdStruct),
293 smbiosDir.dir[idIndex + index].common.id.dataInfo);
294 smbiosDir.dir[idIndex + index].common.dataSetSize = data->size;
295 smbiosDir.dir[idIndex + index].common.timestamp = data->timestamp;
296 pData += sizeof(returnedEntries);
297 }
298 }
299 return teminate;
Cheng C Yangeecaf822019-12-19 00:34:23 +0800300}
301
302bool MDR_V2::sendDataInformation(uint8_t idIndex, uint8_t flag,
303 uint32_t dataLen, uint32_t dataVer,
304 uint32_t timeStamp)
305{
306 if (idIndex >= maxDirEntries)
307 {
Kuiying Wang9c362662020-10-20 15:44:41 +0800308 phosphor::logging::log<phosphor::logging::level::ERR>(
309 "sendDataInformation: Invalid Parameter");
310 return false;
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 Wang9c362662020-10-20 15:44:41 +0800343 return -1;
Cheng C Yangeecaf822019-12-19 00:34:23 +0800344 }
345 std::array<uint8_t, 16> arrayDataInfo;
346
347 std::copy(dataInfo.begin(), dataInfo.end(), arrayDataInfo.begin());
348
349 for (int index = 0; index < smbiosDir.dirEntries; index++)
350 {
351 int info = 0;
352 for (; info < arrayDataInfo.size(); info++)
353 {
354 if (arrayDataInfo[info] !=
355 smbiosDir.dir[index].common.id.dataInfo[info])
356 {
357 break;
358 }
359 }
360 if (info == arrayDataInfo.size())
361 {
362 return index;
363 }
364 }
Kuiying Wang9c362662020-10-20 15:44:41 +0800365 phosphor::logging::log<phosphor::logging::level::ERR>(
366 "findIdIndex: Invalid ID");
367 return -1;
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 Wang9c362662020-10-20 15:44:41 +0800549 phosphor::logging::log<phosphor::logging::level::ERR>(
550 "Data not populated");
551 return ret;
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700552 }
553
554 do
555 {
556 dataIn =
557 getSMBIOSTypePtr(dataIn, memoryDeviceType, sizeof(MemoryInfo));
558 if (dataIn == nullptr)
559 {
560 break;
561 }
562 boost::container::flat_map<std::string, RecordVariant>& record =
563 ret.emplace_back();
564
565 auto memoryInfo = reinterpret_cast<MemoryInfo*>(dataIn);
566
567 record["Type"] = memoryInfo->type;
568 record["Length"] = memoryInfo->length;
569 record["Handle"] = uint16_t(memoryInfo->handle);
570 record["Physical Memory Array Handle"] =
571 uint16_t(memoryInfo->phyArrayHandle);
572 record["Memory Error Information Handle"] =
573 uint16_t(memoryInfo->errInfoHandle);
574 record["Total Width"] = uint16_t(memoryInfo->totalWidth);
575 record["Data Width"] = uint16_t(memoryInfo->dataWidth);
576 record["Size"] = uint16_t(memoryInfo->size);
577 record["Form Factor"] = memoryInfo->formFactor;
578 record["Device Set"] = memoryInfo->deviceSet;
579 record["Device Locator"] = positionToString(
580 memoryInfo->deviceLocator, memoryInfo->length, dataIn);
581 record["Bank Locator"] = positionToString(
582 memoryInfo->bankLocator, memoryInfo->length, dataIn);
583 record["Memory Type"] = memoryInfo->memoryType;
584 record["Type Detail"] = uint16_t(memoryInfo->typeDetail);
585 record["Speed"] = uint16_t(memoryInfo->speed);
586 record["Manufacturer"] = positionToString(
587 memoryInfo->manufacturer, memoryInfo->length, dataIn);
588 record["Serial Number"] = positionToString(
589 memoryInfo->serialNum, memoryInfo->length, dataIn);
590 record["Asset Tag"] = positionToString(memoryInfo->assetTag,
591 memoryInfo->length, dataIn);
592 record["Part Number"] = positionToString(
593 memoryInfo->partNum, memoryInfo->length, dataIn);
594 record["Attributes"] = memoryInfo->attributes;
595 record["Extended Size"] = uint32_t(memoryInfo->extendedSize);
596 record["Configured Memory Speed"] =
597 uint32_t(memoryInfo->confClockSpeed);
598 record["Minimum voltage"] = uint16_t(memoryInfo->minimumVoltage);
599 record["Maximum voltage"] = uint16_t(memoryInfo->maximumVoltage);
600 record["Configured voltage"] =
601 uint16_t(memoryInfo->configuredVoltage);
602 record["Memory Technology"] = memoryInfo->memoryTechnology;
603 record["Memory Operating Mode Capabilty"] =
604 uint16_t(memoryInfo->memoryOperatingModeCap);
605 record["Firmare Version"] = memoryInfo->firwareVersion;
606 record["Module Manufacturer ID"] =
607 uint16_t(memoryInfo->modelManufId);
608 record["Module Product ID"] = uint16_t(memoryInfo->modelProdId);
609 record["Memory Subsystem Controller Manufacturer ID"] =
610 uint16_t(memoryInfo->memSubConManufId);
611 record["Memory Subsystem Controller Product Id"] =
612 uint16_t(memoryInfo->memSubConProdId);
613 record["Non-volatile Size"] = uint64_t(memoryInfo->nvSize);
614 record["Volatile Size"] = uint64_t(memoryInfo->volatileSize);
615 record["Cache Size"] = uint64_t(memoryInfo->cacheSize);
616 record["Logical Size"] = uint64_t(memoryInfo->logicalSize);
617 } while ((dataIn = smbiosNextPtr(dataIn)) != nullptr);
618
619 return ret;
620 }
621
Kuiying Wang9c362662020-10-20 15:44:41 +0800622 phosphor::logging::log<phosphor::logging::level::ERR>(
623 "Invalid record type");
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700624 return ret;
625}
626
Cheng C Yangeecaf822019-12-19 00:34:23 +0800627} // namespace smbios
628} // namespace phosphor