1 /* 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 #include "dimm.hpp" 18 19 #include "mdrv2.hpp" 20 21 namespace phosphor 22 { 23 namespace smbios 24 { 25 26 using DeviceType = 27 sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm::DeviceType; 28 29 static constexpr uint16_t maxOldDimmSize = 0x7fff; 30 void Dimm::memoryInfoUpdate(void) 31 { 32 uint8_t* dataIn = storage; 33 34 dataIn = getSMBIOSTypePtr(dataIn, memoryDeviceType); 35 36 if (dataIn == nullptr) 37 { 38 return; 39 } 40 for (uint8_t index = 0; index < dimmNum; index++) 41 { 42 dataIn = smbiosNextPtr(dataIn); 43 if (dataIn == nullptr) 44 { 45 return; 46 } 47 dataIn = getSMBIOSTypePtr(dataIn, memoryDeviceType); 48 if (dataIn == nullptr) 49 { 50 return; 51 } 52 } 53 54 auto memoryInfo = reinterpret_cast<struct MemoryInfo*>(dataIn); 55 56 memoryDataWidth(memoryInfo->dataWidth); 57 58 if (memoryInfo->size == maxOldDimmSize) 59 { 60 dimmSizeExt(memoryInfo->extendedSize); 61 } 62 else 63 { 64 dimmSize(memoryInfo->size); 65 } 66 67 dimmDeviceLocator(memoryInfo->deviceLocator, memoryInfo->length, dataIn); 68 dimmType(memoryInfo->memoryType); 69 dimmTypeDetail(memoryInfo->typeDetail); 70 maxMemorySpeedInMhz(memoryInfo->speed); 71 dimmManufacturer(memoryInfo->manufacturer, memoryInfo->length, dataIn); 72 dimmSerialNum(memoryInfo->serialNum, memoryInfo->length, dataIn); 73 dimmPartNum(memoryInfo->partNum, memoryInfo->length, dataIn); 74 memoryAttributes(memoryInfo->attributes); 75 memoryConfiguredSpeedInMhz(memoryInfo->confClockSpeed); 76 77 return; 78 } 79 80 uint16_t Dimm::memoryDataWidth(uint16_t value) 81 { 82 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm:: 83 memoryDataWidth(value); 84 } 85 86 static constexpr uint16_t baseNewVersionDimmSize = 0x8000; 87 static constexpr uint16_t dimmSizeUnit = 1024; 88 void Dimm::dimmSize(const uint16_t size) 89 { 90 uint32_t result = size & maxOldDimmSize; 91 if (0 == (size & baseNewVersionDimmSize)) 92 { 93 result = result * dimmSizeUnit; 94 } 95 memorySizeInKB(result); 96 } 97 98 void Dimm::dimmSizeExt(uint32_t size) 99 { 100 size = size * dimmSizeUnit; 101 memorySizeInKB(size); 102 } 103 104 uint32_t Dimm::memorySizeInKB(uint32_t value) 105 { 106 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm:: 107 memorySizeInKB(value); 108 } 109 110 void Dimm::dimmDeviceLocator(const uint8_t positionNum, const uint8_t structLen, 111 uint8_t* dataIn) 112 { 113 std::string result = positionToString(positionNum, structLen, dataIn); 114 115 memoryDeviceLocator(result); 116 } 117 118 std::string Dimm::memoryDeviceLocator(std::string value) 119 { 120 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm:: 121 memoryDeviceLocator(value); 122 } 123 124 void Dimm::dimmType(const uint8_t type) 125 { 126 std::map<uint8_t, DeviceType>::const_iterator it = dimmTypeTable.find(type); 127 if (it == dimmTypeTable.end()) 128 { 129 memoryType(DeviceType::Unknown); 130 } 131 else 132 { 133 memoryType(it->second); 134 } 135 } 136 137 DeviceType Dimm::memoryType(DeviceType value) 138 { 139 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm:: 140 memoryType(value); 141 } 142 143 void Dimm::dimmTypeDetail(uint16_t detail) 144 { 145 std::string result; 146 for (uint8_t index = 0; index < (8 * sizeof(detail)); index++) 147 { 148 if (detail & 0x01) 149 { 150 result += detailTable[index]; 151 } 152 detail >>= 1; 153 } 154 memoryTypeDetail(result); 155 } 156 157 std::string Dimm::memoryTypeDetail(std::string value) 158 { 159 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm:: 160 memoryTypeDetail(value); 161 } 162 163 uint16_t Dimm::maxMemorySpeedInMhz(uint16_t value) 164 { 165 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm:: 166 maxMemorySpeedInMhz(value); 167 } 168 169 void Dimm::dimmManufacturer(const uint8_t positionNum, const uint8_t structLen, 170 uint8_t* dataIn) 171 { 172 std::string result = positionToString(positionNum, structLen, dataIn); 173 174 manufacturer(result); 175 } 176 177 std::string Dimm::manufacturer(std::string value) 178 { 179 return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server:: 180 Asset::manufacturer(value); 181 } 182 183 void Dimm::dimmSerialNum(const uint8_t positionNum, const uint8_t structLen, 184 uint8_t* dataIn) 185 { 186 std::string result = positionToString(positionNum, structLen, dataIn); 187 188 serialNumber(result); 189 } 190 191 std::string Dimm::serialNumber(std::string value) 192 { 193 return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server:: 194 Asset::serialNumber(value); 195 } 196 197 void Dimm::dimmPartNum(const uint8_t positionNum, const uint8_t structLen, 198 uint8_t* dataIn) 199 { 200 std::string result = positionToString(positionNum, structLen, dataIn); 201 202 partNumber(result); 203 } 204 205 std::string Dimm::partNumber(std::string value) 206 { 207 return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server:: 208 Asset::partNumber(value); 209 } 210 211 uint8_t Dimm::memoryAttributes(uint8_t value) 212 { 213 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm:: 214 memoryAttributes(value); 215 } 216 217 uint16_t Dimm::memoryConfiguredSpeedInMhz(uint16_t value) 218 { 219 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm:: 220 memoryConfiguredSpeedInMhz(value); 221 } 222 223 } // namespace smbios 224 } // namespace phosphor 225