13e3269adSCheng C Yang /*
218a5ab91SZhikui Ren // Copyright (c) 2018 Intel Corporation
33e3269adSCheng C Yang //
43e3269adSCheng C Yang // Licensed under the Apache License, Version 2.0 (the "License");
53e3269adSCheng C Yang // you may not use this file except in compliance with the License.
63e3269adSCheng C Yang // You may obtain a copy of the License at
73e3269adSCheng C Yang //
83e3269adSCheng C Yang // http://www.apache.org/licenses/LICENSE-2.0
93e3269adSCheng C Yang //
103e3269adSCheng C Yang // Unless required by applicable law or agreed to in writing, software
113e3269adSCheng C Yang // distributed under the License is distributed on an "AS IS" BASIS,
123e3269adSCheng C Yang // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133e3269adSCheng C Yang // See the License for the specific language governing permissions and
143e3269adSCheng C Yang // limitations under the License.
153e3269adSCheng C Yang */
163e3269adSCheng C Yang
173e3269adSCheng C Yang #pragma once
1843c6a1daSCheng C Yang #include "cpu.hpp"
192ca7a0f3SCheng C Yang #include "dimm.hpp"
2008e4a6dfSJie Yang #include "pcieslot.hpp"
2118a5ab91SZhikui Ren #include "smbios_mdrv2.hpp"
222ca7a0f3SCheng C Yang #include "system.hpp"
23*5af42bbfSPrithvi Pai #include "tpm.hpp"
243e3269adSCheng C Yang
253e3269adSCheng C Yang #include <sys/stat.h>
263e3269adSCheng C Yang #include <sys/types.h>
273e3269adSCheng C Yang #include <unistd.h>
283e3269adSCheng C Yang
2918a5ab91SZhikui Ren #include <boost/asio/io_context.hpp>
3018a5ab91SZhikui Ren #include <boost/asio/steady_timer.hpp>
3118a5ab91SZhikui Ren #include <boost/container/flat_map.hpp>
323e3269adSCheng C Yang #include <phosphor-logging/elog-errors.hpp>
335f2d6275SAlex Schendel #include <phosphor-logging/lg2.hpp>
343e3269adSCheng C Yang #include <phosphor-logging/log.hpp>
3518a5ab91SZhikui Ren #include <sdbusplus/asio/object_server.hpp>
363e3269adSCheng C Yang #include <sdbusplus/server.hpp>
373e3269adSCheng C Yang #include <sdbusplus/timer.hpp>
38eecaf820SCheng C Yang #include <xyz/openbmc_project/Smbios/MDR_V2/server.hpp>
393e3269adSCheng C Yang
40027277a4SJosh Lehan #include <filesystem>
41027277a4SJosh Lehan #include <memory>
423e3269adSCheng C Yang
433e3269adSCheng C Yang namespace phosphor
443e3269adSCheng C Yang {
453e3269adSCheng C Yang namespace smbios
463e3269adSCheng C Yang {
473e3269adSCheng C Yang
48027277a4SJosh Lehan using RecordVariant =
49027277a4SJosh Lehan std::variant<std::string, uint64_t, uint32_t, uint16_t, uint8_t>;
50027277a4SJosh Lehan
51027277a4SJosh Lehan static constexpr const char* defaultObjectPath =
52027277a4SJosh Lehan "/xyz/openbmc_project/Smbios/MDR_V2";
5318a5ab91SZhikui Ren static constexpr const char* smbiosInterfaceName =
5418a5ab91SZhikui Ren "xyz.openbmc_project.Smbios.GetRecordType";
55bb9c622dSGobinath Krishnamoorthy static constexpr const char* mapperBusName = "xyz.openbmc_project.ObjectMapper";
56bb9c622dSGobinath Krishnamoorthy static constexpr const char* mapperPath = "/xyz/openbmc_project/object_mapper";
57bb9c622dSGobinath Krishnamoorthy static constexpr const char* mapperInterface =
58bb9c622dSGobinath Krishnamoorthy "xyz.openbmc_project.ObjectMapper";
59027277a4SJosh Lehan static constexpr const char* defaultInventoryPath =
60bb9c622dSGobinath Krishnamoorthy "/xyz/openbmc_project/inventory/system";
61bb9c622dSGobinath Krishnamoorthy static constexpr const char* systemInterface =
62bb9c622dSGobinath Krishnamoorthy "xyz.openbmc_project.Inventory.Item.System";
63abdccd3aSJosh Lehan static constexpr const char* boardInterface =
64abdccd3aSJosh Lehan "xyz.openbmc_project.Inventory.Item.Board";
6518a5ab91SZhikui Ren constexpr const int limitEntryLen = 0xff;
6618a5ab91SZhikui Ren
67027277a4SJosh Lehan // Avoid putting multiple interfaces with same name on same object
placeGetRecordType(const std::string & objectPath)68027277a4SJosh Lehan static std::string placeGetRecordType(const std::string& objectPath)
69027277a4SJosh Lehan {
70027277a4SJosh Lehan if (objectPath != defaultObjectPath)
71027277a4SJosh Lehan {
72027277a4SJosh Lehan // Place GetRecordType interface on object itself, not parent
73027277a4SJosh Lehan return objectPath;
74027277a4SJosh Lehan }
75027277a4SJosh Lehan
76027277a4SJosh Lehan std::filesystem::path path(objectPath);
77027277a4SJosh Lehan
78027277a4SJosh Lehan // As there is only one default, safe to place it on the common parent
79027277a4SJosh Lehan return path.parent_path().string();
80027277a4SJosh Lehan }
81027277a4SJosh Lehan
82a3f5b385SJason M. Bills class MDRV2 :
8377b9c478SPatrick Williams sdbusplus::server::object_t<
8433ae81feSJason M. Bills sdbusplus::server::xyz::openbmc_project::smbios::MDRV2>
853e3269adSCheng C Yang {
863e3269adSCheng C Yang public:
87a3f5b385SJason M. Bills MDRV2() = delete;
88a3f5b385SJason M. Bills MDRV2(const MDRV2&) = delete;
89a3f5b385SJason M. Bills MDRV2& operator=(const MDRV2&) = delete;
90a3f5b385SJason M. Bills MDRV2(MDRV2&&) = delete;
91a3f5b385SJason M. Bills MDRV2& operator=(MDRV2&&) = delete;
923e3269adSCheng C Yang
~MDRV2()93027277a4SJosh Lehan virtual ~MDRV2()
943e3269adSCheng C Yang {
95027277a4SJosh Lehan if (smbiosInterface)
96027277a4SJosh Lehan {
97027277a4SJosh Lehan if (objServer)
98027277a4SJosh Lehan {
99027277a4SJosh Lehan // Must manually undo add_interface()
100027277a4SJosh Lehan objServer->remove_interface(smbiosInterface);
101027277a4SJosh Lehan }
102027277a4SJosh Lehan }
103027277a4SJosh Lehan }
104027277a4SJosh Lehan
MDRV2(std::shared_ptr<boost::asio::io_context> io,std::shared_ptr<sdbusplus::asio::connection> conn,std::shared_ptr<sdbusplus::asio::object_server> obj,std::string filePath,std::string objectPath,std::string inventoryPath)105027277a4SJosh Lehan MDRV2(std::shared_ptr<boost::asio::io_context> io,
106027277a4SJosh Lehan std::shared_ptr<sdbusplus::asio::connection> conn,
107027277a4SJosh Lehan std::shared_ptr<sdbusplus::asio::object_server> obj,
108027277a4SJosh Lehan std::string filePath, std::string objectPath,
109027277a4SJosh Lehan std::string inventoryPath) :
110027277a4SJosh Lehan sdbusplus::server::object_t<
111027277a4SJosh Lehan sdbusplus::server::xyz::openbmc_project::smbios::MDRV2>(
112027277a4SJosh Lehan *conn, objectPath.c_str()),
113027277a4SJosh Lehan timer(*io), bus(conn), objServer(std::move(obj)),
114027277a4SJosh Lehan smbiosInterface(objServer->add_interface(placeGetRecordType(objectPath),
115027277a4SJosh Lehan smbiosInterfaceName)),
116027277a4SJosh Lehan smbiosFilePath(std::move(filePath)),
117027277a4SJosh Lehan smbiosObjectPath(std::move(objectPath)),
118027277a4SJosh Lehan smbiosInventoryPath(std::move(inventoryPath))
119027277a4SJosh Lehan {
120027277a4SJosh Lehan lg2::info("SMBIOS data file path: {F}", "F", smbiosFilePath);
121027277a4SJosh Lehan lg2::info("SMBIOS control object: {O}", "O", smbiosObjectPath);
122027277a4SJosh Lehan lg2::info("SMBIOS inventory path: {I}", "I", smbiosInventoryPath);
123027277a4SJosh Lehan
1243e3269adSCheng C Yang smbiosDir.agentVersion = smbiosAgentVersion;
125f079e836SJosh Lehan smbiosDir.dirVersion = smbiosDirVersion;
1263e3269adSCheng C Yang smbiosDir.dirEntries = 1;
1273e3269adSCheng C Yang directoryEntries(smbiosDir.dirEntries);
1283e3269adSCheng C Yang smbiosDir.status = 1;
1293e3269adSCheng C Yang smbiosDir.remoteDirVersion = 0;
1303e3269adSCheng C Yang
1313e3269adSCheng C Yang std::copy(smbiosTableId.begin(), smbiosTableId.end(),
1323e3269adSCheng C Yang smbiosDir.dir[smbiosDirIndex].common.id.dataInfo);
1333e3269adSCheng C Yang
1343e3269adSCheng C Yang smbiosDir.dir[smbiosDirIndex].dataStorage = smbiosTableStorage;
1353e3269adSCheng C Yang
1363e3269adSCheng C Yang agentSynchronizeData();
13718a5ab91SZhikui Ren
13818a5ab91SZhikui Ren smbiosInterface->register_method("GetRecordType", [this](size_t type) {
13918a5ab91SZhikui Ren return getRecordType(type);
14018a5ab91SZhikui Ren });
14118a5ab91SZhikui Ren smbiosInterface->initialize();
1423e3269adSCheng C Yang }
1433e3269adSCheng C Yang
144eecaf820SCheng C Yang std::vector<uint8_t> getDirectoryInformation(uint8_t dirIndex) override;
145eecaf820SCheng C Yang
146eecaf820SCheng C Yang std::vector<uint8_t> getDataInformation(uint8_t idIndex) override;
147eecaf820SCheng C Yang
1481d73dcccSPatrick Williams bool sendDirectoryInformation(
1491d73dcccSPatrick Williams uint8_t dirVersion, uint8_t dirIndex, uint8_t returnedEntries,
1501d73dcccSPatrick Williams uint8_t remainingEntries, std::vector<uint8_t> dirEntry) override;
151eecaf820SCheng C Yang
152eecaf820SCheng C Yang std::vector<uint8_t> getDataOffer() override;
153eecaf820SCheng C Yang
154eecaf820SCheng C Yang bool sendDataInformation(uint8_t idIndex, uint8_t flag, uint32_t dataLen,
155eecaf820SCheng C Yang uint32_t dataVer, uint32_t timeStamp) override;
156eecaf820SCheng C Yang
157eecaf820SCheng C Yang int findIdIndex(std::vector<uint8_t> dataInfo) override;
158eecaf820SCheng C Yang
159eecaf820SCheng C Yang bool agentSynchronizeData() override;
160eecaf820SCheng C Yang
16107a2c9aaSPatrick Williams std::vector<uint32_t> synchronizeDirectoryCommonData(
16207a2c9aaSPatrick Williams uint8_t idIndex, uint32_t size) override;
163eecaf820SCheng C Yang
164eecaf820SCheng C Yang uint8_t directoryEntries(uint8_t value) override;
165eecaf820SCheng C Yang
16618a5ab91SZhikui Ren std::vector<boost::container::flat_map<std::string, RecordVariant>>
16718a5ab91SZhikui Ren getRecordType(size_t type);
16818a5ab91SZhikui Ren
1693e3269adSCheng C Yang private:
17018a5ab91SZhikui Ren boost::asio::steady_timer timer;
1713e3269adSCheng C Yang
172027277a4SJosh Lehan std::shared_ptr<sdbusplus::asio::connection> bus;
173027277a4SJosh Lehan std::shared_ptr<sdbusplus::asio::object_server> objServer;
1743e3269adSCheng C Yang
1753e3269adSCheng C Yang Mdr2DirStruct smbiosDir;
1763e3269adSCheng C Yang
177ec634255SCheng C Yang bool readDataFromFlash(MDRSMBIOSHeader* mdrHdr, uint8_t* data);
1780435a483SArun P. Mohanan bool checkSMBIOSVersion(uint8_t* dataIn);
179ec634255SCheng C Yang
1803e3269adSCheng C Yang const std::array<uint8_t, 16> smbiosTableId{
1813e3269adSCheng C Yang 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 0x42};
182c6d87a5cSJosh Lehan uint8_t smbiosTableStorage[smbiosTableStorageSize] = {};
1833e3269adSCheng C Yang
1843e3269adSCheng C Yang bool smbiosIsUpdating(uint8_t index);
1853e3269adSCheng C Yang bool smbiosIsAvailForUpdate(uint8_t index);
1863e3269adSCheng C Yang inline uint8_t smbiosValidFlag(uint8_t index);
1873e3269adSCheng C Yang void systemInfoUpdate(void);
18843c6a1daSCheng C Yang
189f2d8bb48SJonathan Doman std::optional<size_t> getTotalCpuSlot(void);
190f2d8bb48SJonathan Doman std::optional<size_t> getTotalDimmSlot(void);
191f2d8bb48SJonathan Doman std::optional<size_t> getTotalPcieSlot(void);
192*5af42bbfSPrithvi Pai std::optional<size_t> getTotalTpm(void);
19343c6a1daSCheng C Yang std::vector<std::unique_ptr<Cpu>> cpus;
1948c3fab63SCheng C Yang std::vector<std::unique_ptr<Dimm>> dimms;
19508e4a6dfSJie Yang std::vector<std::unique_ptr<Pcie>> pcies;
196*5af42bbfSPrithvi Pai std::vector<std::unique_ptr<Tpm>> tpms;
197b4651b9cSCheng C Yang std::unique_ptr<System> system;
19818a5ab91SZhikui Ren std::shared_ptr<sdbusplus::asio::dbus_interface> smbiosInterface;
199027277a4SJosh Lehan
200027277a4SJosh Lehan std::string smbiosFilePath;
201027277a4SJosh Lehan std::string smbiosObjectPath;
202027277a4SJosh Lehan std::string smbiosInventoryPath;
203027277a4SJosh Lehan std::unique_ptr<sdbusplus::bus::match_t> motherboardConfigMatch;
2043e3269adSCheng C Yang };
2053e3269adSCheng C Yang
2063e3269adSCheng C Yang } // namespace smbios
2073e3269adSCheng C Yang } // namespace phosphor
208