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 #pragma once 18 #include "smbios_mdrv2.hpp" 19 20 #include <nlohmann/json.hpp> 21 #include <xyz/openbmc_project/Association/Definitions/server.hpp> 22 #include <xyz/openbmc_project/Inventory/Connector/Slot/server.hpp> 23 #include <xyz/openbmc_project/Inventory/Decorator/Asset/server.hpp> 24 #include <xyz/openbmc_project/Inventory/Decorator/LocationCode/server.hpp> 25 #include <xyz/openbmc_project/Inventory/Item/Dimm/MemoryLocation/server.hpp> 26 #include <xyz/openbmc_project/Inventory/Item/Dimm/server.hpp> 27 #include <xyz/openbmc_project/Inventory/Item/server.hpp> 28 #include <xyz/openbmc_project/State/Decorator/OperationalStatus/server.hpp> 29 30 namespace phosphor 31 { 32 33 namespace smbios 34 { 35 36 using DeviceType = 37 sdbusplus::server::xyz::openbmc_project::inventory::item::Dimm::DeviceType; 38 39 using EccType = 40 sdbusplus::server::xyz::openbmc_project::inventory::item::Dimm::Ecc; 41 42 using MemoryTechType = 43 sdbusplus::server::xyz::openbmc_project::inventory::item::Dimm::MemoryTech; 44 45 using Json = nlohmann::json; 46 47 class Dimm : 48 sdbusplus::server::object_t< 49 sdbusplus::server::xyz::openbmc_project::inventory::item::Dimm>, 50 sdbusplus::server::object_t<sdbusplus::server::xyz::openbmc_project:: 51 inventory::item::dimm::MemoryLocation>, 52 sdbusplus::server::object_t< 53 sdbusplus::server::xyz::openbmc_project::inventory::decorator::Asset>, 54 sdbusplus::server::object_t<sdbusplus::server::xyz::openbmc_project:: 55 inventory::decorator::LocationCode>, 56 sdbusplus::server::object_t< 57 sdbusplus::server::xyz::openbmc_project::inventory::connector::Slot>, 58 sdbusplus::server::object_t< 59 sdbusplus::server::xyz::openbmc_project::inventory::Item>, 60 sdbusplus::server::object_t< 61 sdbusplus::server::xyz::openbmc_project::association::Definitions>, 62 sdbusplus::server::object_t<sdbusplus::server::xyz::openbmc_project::state:: 63 decorator::OperationalStatus> 64 { 65 public: 66 Dimm() = delete; 67 ~Dimm() = default; 68 Dimm(const Dimm&) = delete; 69 Dimm& operator=(const Dimm&) = delete; 70 Dimm(Dimm&&) = default; 71 Dimm& operator=(Dimm&&) = default; 72 Dimm(sdbusplus::bus_t & bus,const std::string & objPath,const uint8_t & dimmId,uint8_t * smbiosTableStorage,const std::string & motherboard)73 Dimm(sdbusplus::bus_t& bus, const std::string& objPath, 74 const uint8_t& dimmId, uint8_t* smbiosTableStorage, 75 const std::string& motherboard) : 76 77 sdbusplus::server::object_t< 78 sdbusplus::server::xyz::openbmc_project::inventory::item::Dimm>( 79 bus, objPath.c_str()), 80 sdbusplus::server::object_t<sdbusplus::server::xyz::openbmc_project:: 81 inventory::item::dimm::MemoryLocation>( 82 bus, objPath.c_str()), 83 sdbusplus::server::object_t<sdbusplus::server::xyz::openbmc_project:: 84 inventory::decorator::Asset>( 85 bus, objPath.c_str()), 86 sdbusplus::server::object_t<sdbusplus::server::xyz::openbmc_project:: 87 inventory::decorator::LocationCode>( 88 bus, objPath.c_str()), 89 sdbusplus::server::object_t<sdbusplus::server::xyz::openbmc_project:: 90 inventory::connector::Slot>( 91 bus, objPath.c_str()), 92 sdbusplus::server::object_t< 93 sdbusplus::server::xyz::openbmc_project::inventory::Item>( 94 bus, objPath.c_str()), 95 sdbusplus::server::object_t< 96 sdbusplus::server::xyz::openbmc_project::association::Definitions>( 97 bus, objPath.c_str()), 98 sdbusplus::server::object_t<sdbusplus::server::xyz::openbmc_project:: 99 state::decorator::OperationalStatus>( 100 bus, objPath.c_str()), 101 dimmNum(dimmId) 102 { 103 memoryInfoUpdate(smbiosTableStorage, motherboard); 104 } 105 106 void memoryInfoUpdate(uint8_t* smbiosTableStorage, 107 const std::string& motherboard); 108 109 uint16_t memoryDataWidth(uint16_t value) override; 110 uint16_t memoryTotalWidth(uint16_t value) override; 111 size_t memorySizeInKB(size_t value) override; 112 std::string memoryDeviceLocator(std::string value) override; 113 DeviceType memoryType(DeviceType value) override; 114 std::string memoryTypeDetail(std::string value) override; 115 uint16_t maxMemorySpeedInMhz(uint16_t value) override; 116 std::string manufacturer(std::string value) override; 117 bool present(bool value) override; 118 std::string serialNumber(std::string value) override; 119 std::string partNumber(std::string value) override; 120 std::string locationCode(std::string value) override; 121 size_t memoryAttributes(size_t value) override; 122 MemoryTechType memoryMedia(MemoryTechType value) override; 123 uint8_t slot(uint8_t value) override; 124 uint8_t socket(uint8_t value) override; 125 uint8_t memoryController(uint8_t value) override; 126 uint8_t channel(uint8_t value) override; 127 uint16_t memoryConfiguredSpeedInMhz(uint16_t value) override; 128 bool functional(bool value) override; 129 EccType ecc(EccType value) override; 130 Json parseConfigFile(); 131 132 private: 133 uint8_t dimmNum; 134 135 uint8_t* storage; 136 137 std::string motherboardPath; 138 139 void dimmSize(const uint16_t size); 140 void dimmSizeExt(const uint32_t size); 141 void dimmDeviceLocator(const uint8_t bankLocatorPositionNum, 142 const uint8_t deviceLocatorPositionNum, 143 const uint8_t structLen, uint8_t* dataIn); 144 void dimmType(const uint8_t type); 145 void dimmTypeDetail(const uint16_t detail); 146 void dimmManufacturer(const uint8_t positionNum, const uint8_t structLen, 147 uint8_t* dataIn); 148 void dimmMedia(const uint8_t type); 149 void dimmSerialNum(const uint8_t positionNum, const uint8_t structLen, 150 uint8_t* dataIn); 151 void dimmPartNum(const uint8_t positionNum, const uint8_t structLen, 152 uint8_t* dataIn); 153 void updateEccType(uint16_t exPhyArrayHandle); 154 }; 155 156 struct MemoryInfo 157 { 158 uint8_t type; 159 uint8_t length; 160 uint16_t handle; 161 uint16_t phyArrayHandle; 162 uint16_t errInfoHandle; 163 uint16_t totalWidth; 164 uint16_t dataWidth; 165 uint16_t size; 166 uint8_t formFactor; 167 uint8_t deviceSet; 168 uint8_t deviceLocator; 169 uint8_t bankLocator; 170 uint8_t memoryType; 171 uint16_t typeDetail; 172 uint16_t speed; 173 uint8_t manufacturer; 174 uint8_t serialNum; 175 uint8_t assetTag; 176 uint8_t partNum; 177 uint8_t attributes; 178 uint32_t extendedSize; 179 uint16_t confClockSpeed; 180 uint16_t minimumVoltage; 181 uint16_t maximumVoltage; 182 uint16_t configuredVoltage; 183 uint8_t memoryTechnology; 184 uint16_t memoryOperatingModeCap; 185 uint8_t firwareVersion; 186 uint16_t modelManufId; 187 uint16_t modelProdId; 188 uint16_t memSubConManufId; 189 uint16_t memSubConProdId; 190 uint64_t nvSize; 191 uint64_t volatileSize; 192 uint64_t cacheSize; 193 uint64_t logicalSize; 194 } __attribute__((packed)); 195 196 /** 197 * @brief Struct to represent SMBIOS 3.2 type-16 (Physical Memory Array) data. 198 */ 199 struct PhysicalMemoryArrayInfo 200 { 201 uint8_t type; 202 uint8_t length; 203 uint16_t handle; 204 uint8_t location; 205 uint8_t use; 206 uint8_t memoryErrorCorrection; 207 uint32_t maximumCapacity; 208 uint16_t memoryErrorInformationHandle; 209 uint16_t numberOfMemoryDevices; 210 uint64_t extendedMaximumCapacity; 211 } __attribute__((packed)); 212 static_assert(sizeof(PhysicalMemoryArrayInfo) == 23, 213 "Size of PhysicalMemoryArrayInfo struct is incorrect."); 214 215 const std::map<uint8_t, DeviceType> dimmTypeTable = { 216 {0x1, DeviceType::Other}, {0x2, DeviceType::Unknown}, 217 {0x3, DeviceType::DRAM}, {0x4, DeviceType::EDRAM}, 218 {0x5, DeviceType::VRAM}, {0x6, DeviceType::SRAM}, 219 {0x7, DeviceType::RAM}, {0x8, DeviceType::ROM}, 220 {0x9, DeviceType::FLASH}, {0xa, DeviceType::EEPROM}, 221 {0xb, DeviceType::FEPROM}, {0xc, DeviceType::EPROM}, 222 {0xd, DeviceType::CDRAM}, {0xe, DeviceType::ThreeDRAM}, 223 {0xf, DeviceType::SDRAM}, {0x10, DeviceType::DDR_SGRAM}, 224 {0x11, DeviceType::RDRAM}, {0x12, DeviceType::DDR}, 225 {0x13, DeviceType::DDR2}, {0x14, DeviceType::DDR2_SDRAM_FB_DIMM}, 226 {0x18, DeviceType::DDR3}, {0x19, DeviceType::FBD2}, 227 {0x1a, DeviceType::DDR4}, {0x1b, DeviceType::LPDDR_SDRAM}, 228 {0x1c, DeviceType::LPDDR2_SDRAM}, {0x1d, DeviceType::LPDDR3_SDRAM}, 229 {0x1e, DeviceType::LPDDR4_SDRAM}, {0x1f, DeviceType::Logical}, 230 {0x20, DeviceType::HBM}, {0x21, DeviceType::HBM2}, 231 {0x22, DeviceType::DDR5}, {0x23, DeviceType::LPDDR5_SDRAM}}; 232 233 const std::array<std::string, 16> detailTable{ 234 "Reserved", "Other", "Unknown", "Fast-paged", 235 "Static column", "Pseudo-static", "RAMBUS", "Synchronous", 236 "CMOS", "EDO", "Window DRAM", "Cache DRAM", 237 "Non-volatile", "Registered", "Unbuffered", "LRDIMM"}; 238 239 /** 240 * @brief Map SMBIOS 3.2 Memory Array Error Correction Types to 241 * xyz.openbmc_project.Inventory.Item.Dimm.Ecc types. 242 * 243 * SMBIOS 3.2 Memory Array Error Correction Types 'Unknown', 'None', 'CRC' are 244 * mapped to EccType::NoECC since the DBUs interface does not support those 245 * representations. 246 */ 247 const std::map<uint8_t, EccType> dimmEccTypeMap = { 248 {0x1, EccType::NoECC}, {0x2, EccType::NoECC}, 249 {0x3, EccType::NoECC}, {0x4, EccType::AddressParity}, 250 {0x5, EccType::SingleBitECC}, {0x6, EccType::MultiBitECC}, 251 {0x7, EccType::NoECC}}; 252 253 const std::map<uint8_t, MemoryTechType> dimmMemoryTechTypeMap = { 254 {0x1, MemoryTechType::Other}, {0x2, MemoryTechType::Unknown}, 255 {0x3, MemoryTechType::DRAM}, {0x4, MemoryTechType::NVDIMM_N}, 256 {0x5, MemoryTechType::NVDIMM_F}, {0x6, MemoryTechType::NVDIMM_P}, 257 {0x7, MemoryTechType::IntelOptane}}; 258 259 struct memoryLocation 260 { 261 uint8_t memoryController; 262 uint8_t socket; 263 uint8_t slot; 264 uint8_t channel; 265 }; 266 267 } // namespace smbios 268 269 } // namespace phosphor 270