/* // Copyright (c) 2018 Intel Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. */ #pragma once #include "cpu.hpp" #include "dimm.hpp" #include "pcieslot.hpp" #include "smbios_mdrv2.hpp" #include "system.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace phosphor { namespace smbios { using RecordVariant = std::variant; static constexpr const char* defaultObjectPath = "/xyz/openbmc_project/Smbios/MDR_V2"; static constexpr const char* smbiosInterfaceName = "xyz.openbmc_project.Smbios.GetRecordType"; static constexpr const char* mapperBusName = "xyz.openbmc_project.ObjectMapper"; static constexpr const char* mapperPath = "/xyz/openbmc_project/object_mapper"; static constexpr const char* mapperInterface = "xyz.openbmc_project.ObjectMapper"; static constexpr const char* defaultInventoryPath = "/xyz/openbmc_project/inventory/system"; static constexpr const char* systemInterface = "xyz.openbmc_project.Inventory.Item.System"; static constexpr const char* boardInterface = "xyz.openbmc_project.Inventory.Item.Board"; constexpr const int limitEntryLen = 0xff; // Avoid putting multiple interfaces with same name on same object static std::string placeGetRecordType(const std::string& objectPath) { if (objectPath != defaultObjectPath) { // Place GetRecordType interface on object itself, not parent return objectPath; } std::filesystem::path path(objectPath); // As there is only one default, safe to place it on the common parent return path.parent_path().string(); } class MDRV2 : sdbusplus::server::object_t< sdbusplus::server::xyz::openbmc_project::smbios::MDRV2> { public: MDRV2() = delete; MDRV2(const MDRV2&) = delete; MDRV2& operator=(const MDRV2&) = delete; MDRV2(MDRV2&&) = delete; MDRV2& operator=(MDRV2&&) = delete; virtual ~MDRV2() { if (smbiosInterface) { if (objServer) { // Must manually undo add_interface() objServer->remove_interface(smbiosInterface); } } } MDRV2(std::shared_ptr io, std::shared_ptr conn, std::shared_ptr obj, std::string filePath, std::string objectPath, std::string inventoryPath) : sdbusplus::server::object_t< sdbusplus::server::xyz::openbmc_project::smbios::MDRV2>( *conn, objectPath.c_str()), timer(*io), bus(conn), objServer(std::move(obj)), smbiosInterface(objServer->add_interface(placeGetRecordType(objectPath), smbiosInterfaceName)), smbiosFilePath(std::move(filePath)), smbiosObjectPath(std::move(objectPath)), smbiosInventoryPath(std::move(inventoryPath)) { lg2::info("SMBIOS data file path: {F}", "F", smbiosFilePath); lg2::info("SMBIOS control object: {O}", "O", smbiosObjectPath); lg2::info("SMBIOS inventory path: {I}", "I", smbiosInventoryPath); smbiosDir.agentVersion = smbiosAgentVersion; smbiosDir.dirVersion = smbiosDirVersion; smbiosDir.dirEntries = 1; directoryEntries(smbiosDir.dirEntries); smbiosDir.status = 1; smbiosDir.remoteDirVersion = 0; std::copy(smbiosTableId.begin(), smbiosTableId.end(), smbiosDir.dir[smbiosDirIndex].common.id.dataInfo); smbiosDir.dir[smbiosDirIndex].dataStorage = smbiosTableStorage; agentSynchronizeData(); smbiosInterface->register_method("GetRecordType", [this](size_t type) { return getRecordType(type); }); smbiosInterface->initialize(); } std::vector getDirectoryInformation(uint8_t dirIndex) override; std::vector getDataInformation(uint8_t idIndex) override; bool sendDirectoryInformation(uint8_t dirVersion, uint8_t dirIndex, uint8_t returnedEntries, uint8_t remainingEntries, std::vector dirEntry) override; std::vector getDataOffer() override; bool sendDataInformation(uint8_t idIndex, uint8_t flag, uint32_t dataLen, uint32_t dataVer, uint32_t timeStamp) override; int findIdIndex(std::vector dataInfo) override; bool agentSynchronizeData() override; std::vector synchronizeDirectoryCommonData(uint8_t idIndex, uint32_t size) override; uint8_t directoryEntries(uint8_t value) override; std::vector> getRecordType(size_t type); private: boost::asio::steady_timer timer; std::shared_ptr bus; std::shared_ptr objServer; Mdr2DirStruct smbiosDir; bool readDataFromFlash(MDRSMBIOSHeader* mdrHdr, uint8_t* data); bool checkSMBIOSVersion(uint8_t* dataIn); const std::array smbiosTableId{ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 0x42}; uint8_t smbiosTableStorage[smbiosTableStorageSize] = {}; bool smbiosIsUpdating(uint8_t index); bool smbiosIsAvailForUpdate(uint8_t index); inline uint8_t smbiosValidFlag(uint8_t index); void systemInfoUpdate(void); std::optional getTotalCpuSlot(void); std::optional getTotalDimmSlot(void); std::optional getTotalPcieSlot(void); std::vector> cpus; std::vector> dimms; std::vector> pcies; std::unique_ptr system; std::shared_ptr smbiosInterface; std::string smbiosFilePath; std::string smbiosObjectPath; std::string smbiosInventoryPath; std::unique_ptr motherboardConfigMatch; }; } // namespace smbios } // namespace phosphor