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 if (!motherboardPath.empty()) 78 { 79 std::vector<std::tuple<std::string, std::string, std::string>> assocs; 80 assocs.emplace_back("chassis", "memories", motherboardPath); 81 association::associations(assocs); 82 } 83 84 return; 85 } 86 87 uint16_t Dimm::memoryDataWidth(uint16_t value) 88 { 89 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm:: 90 memoryDataWidth(value); 91 } 92 93 static constexpr uint16_t baseNewVersionDimmSize = 0x8000; 94 static constexpr uint16_t dimmSizeUnit = 1024; 95 void Dimm::dimmSize(const uint16_t size) 96 { 97 size_t result = size & maxOldDimmSize; 98 if (0 == (size & baseNewVersionDimmSize)) 99 { 100 result = result * dimmSizeUnit; 101 } 102 memorySizeInKB(result); 103 } 104 105 void Dimm::dimmSizeExt(size_t size) 106 { 107 size = size * dimmSizeUnit; 108 memorySizeInKB(size); 109 } 110 111 size_t Dimm::memorySizeInKB(size_t value) 112 { 113 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm:: 114 memorySizeInKB(value); 115 } 116 117 void Dimm::dimmDeviceLocator(const uint8_t positionNum, const uint8_t structLen, 118 uint8_t* dataIn) 119 { 120 std::string result = positionToString(positionNum, structLen, dataIn); 121 122 memoryDeviceLocator(result); 123 124 locationCode(result); 125 } 126 127 std::string Dimm::memoryDeviceLocator(std::string value) 128 { 129 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm:: 130 memoryDeviceLocator(value); 131 } 132 133 void Dimm::dimmType(const uint8_t type) 134 { 135 std::map<uint8_t, DeviceType>::const_iterator it = dimmTypeTable.find(type); 136 if (it == dimmTypeTable.end()) 137 { 138 memoryType(DeviceType::Unknown); 139 } 140 else 141 { 142 memoryType(it->second); 143 } 144 } 145 146 DeviceType Dimm::memoryType(DeviceType value) 147 { 148 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm:: 149 memoryType(value); 150 } 151 152 void Dimm::dimmTypeDetail(uint16_t detail) 153 { 154 std::string result; 155 for (uint8_t index = 0; index < (8 * sizeof(detail)); index++) 156 { 157 if (detail & 0x01) 158 { 159 result += detailTable[index]; 160 } 161 detail >>= 1; 162 } 163 memoryTypeDetail(result); 164 } 165 166 std::string Dimm::memoryTypeDetail(std::string value) 167 { 168 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm:: 169 memoryTypeDetail(value); 170 } 171 172 uint16_t Dimm::maxMemorySpeedInMhz(uint16_t value) 173 { 174 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm:: 175 maxMemorySpeedInMhz(value); 176 } 177 178 void Dimm::dimmManufacturer(const uint8_t positionNum, const uint8_t structLen, 179 uint8_t* dataIn) 180 { 181 std::string result = positionToString(positionNum, structLen, dataIn); 182 183 bool val = true; 184 if (result == "NO DIMM") 185 { 186 val = false; 187 188 // No dimm presence so making manufacturer value as "" (instead of 189 // NO DIMM - as there won't be any manufacturer for DIMM which is not 190 // present). 191 result = ""; 192 } 193 manufacturer(result); 194 present(val); 195 } 196 197 std::string Dimm::manufacturer(std::string value) 198 { 199 return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server:: 200 Asset::manufacturer(value); 201 } 202 203 bool Dimm::present(bool value) 204 { 205 return sdbusplus::xyz::openbmc_project::Inventory::server::Item::present( 206 value); 207 } 208 209 void Dimm::dimmSerialNum(const uint8_t positionNum, const uint8_t structLen, 210 uint8_t* dataIn) 211 { 212 std::string result = positionToString(positionNum, structLen, dataIn); 213 214 serialNumber(result); 215 } 216 217 std::string Dimm::serialNumber(std::string value) 218 { 219 return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server:: 220 Asset::serialNumber(value); 221 } 222 223 void Dimm::dimmPartNum(const uint8_t positionNum, const uint8_t structLen, 224 uint8_t* dataIn) 225 { 226 std::string result = positionToString(positionNum, structLen, dataIn); 227 228 partNumber(result); 229 } 230 231 std::string Dimm::partNumber(std::string value) 232 { 233 return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server:: 234 Asset::partNumber(value); 235 } 236 237 std::string Dimm::locationCode(std::string value) 238 { 239 return sdbusplus::xyz::openbmc_project::Inventory::Decorator::server:: 240 LocationCode::locationCode(value); 241 } 242 243 uint8_t Dimm::memoryAttributes(uint8_t value) 244 { 245 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm:: 246 memoryAttributes(value); 247 } 248 249 uint16_t Dimm::memoryConfiguredSpeedInMhz(uint16_t value) 250 { 251 return sdbusplus::xyz::openbmc_project::Inventory::Item::server::Dimm:: 252 memoryConfiguredSpeedInMhz(value); 253 } 254 255 } // namespace smbios 256 } // namespace phosphor 257