blob: c60633c222fab9517824096c873f1439a7bd05eb [file] [log] [blame]
Cheng C Yang3e3269a2019-12-02 15:11:30 +08001/*
Zhikui Ren18a5ab92020-09-01 21:35:20 -07002// Copyright (c) 2018 Intel Corporation
Cheng C Yang3e3269a2019-12-02 15:11:30 +08003//
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
Cheng C Yang43c6a1d2019-12-19 00:48:34 +080018#include "cpu.hpp"
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +080019#include "dimm.hpp"
Prithvi Pai6f9e7a72025-03-14 13:05:02 +053020#include "firmware_inventory.hpp"
Jie Yang08e4a6d2021-08-23 13:07:41 -070021#include "pcieslot.hpp"
Zhikui Ren18a5ab92020-09-01 21:35:20 -070022#include "smbios_mdrv2.hpp"
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +080023#include "system.hpp"
Prithvi Pai5af42bb2025-02-11 17:59:07 +053024#include "tpm.hpp"
Cheng C Yang3e3269a2019-12-02 15:11:30 +080025
26#include <sys/stat.h>
27#include <sys/types.h>
28#include <unistd.h>
29
Zhikui Ren18a5ab92020-09-01 21:35:20 -070030#include <boost/asio/io_context.hpp>
31#include <boost/asio/steady_timer.hpp>
32#include <boost/container/flat_map.hpp>
Cheng C Yang3e3269a2019-12-02 15:11:30 +080033#include <phosphor-logging/elog-errors.hpp>
Alex Schendel5f2d6272021-09-22 10:35:40 -070034#include <phosphor-logging/lg2.hpp>
Cheng C Yang3e3269a2019-12-02 15:11:30 +080035#include <phosphor-logging/log.hpp>
Zhikui Ren18a5ab92020-09-01 21:35:20 -070036#include <sdbusplus/asio/object_server.hpp>
Cheng C Yang3e3269a2019-12-02 15:11:30 +080037#include <sdbusplus/server.hpp>
38#include <sdbusplus/timer.hpp>
Cheng C Yangeecaf822019-12-19 00:34:23 +080039#include <xyz/openbmc_project/Smbios/MDR_V2/server.hpp>
Cheng C Yang3e3269a2019-12-02 15:11:30 +080040
Josh Lehan027277a2023-09-11 05:28:19 -070041#include <filesystem>
42#include <memory>
Cheng C Yang3e3269a2019-12-02 15:11:30 +080043
Cheng C Yang3e3269a2019-12-02 15:11:30 +080044namespace phosphor
45{
46namespace smbios
47{
48
Josh Lehan027277a2023-09-11 05:28:19 -070049using RecordVariant =
50 std::variant<std::string, uint64_t, uint32_t, uint16_t, uint8_t>;
51
52static constexpr const char* defaultObjectPath =
53 "/xyz/openbmc_project/Smbios/MDR_V2";
Zhikui Ren18a5ab92020-09-01 21:35:20 -070054static constexpr const char* smbiosInterfaceName =
55 "xyz.openbmc_project.Smbios.GetRecordType";
Gobinath Krishnamoorthybb9c6222022-11-03 20:08:01 +000056static constexpr const char* mapperBusName = "xyz.openbmc_project.ObjectMapper";
57static constexpr const char* mapperPath = "/xyz/openbmc_project/object_mapper";
58static constexpr const char* mapperInterface =
59 "xyz.openbmc_project.ObjectMapper";
Josh Lehan027277a2023-09-11 05:28:19 -070060static constexpr const char* defaultInventoryPath =
Gobinath Krishnamoorthybb9c6222022-11-03 20:08:01 +000061 "/xyz/openbmc_project/inventory/system";
62static constexpr const char* systemInterface =
63 "xyz.openbmc_project.Inventory.Item.System";
Josh Lehanabdccd32024-01-26 15:49:50 -080064static constexpr const char* boardInterface =
65 "xyz.openbmc_project.Inventory.Item.Board";
Prithvi Pai6f9e7a72025-03-14 13:05:02 +053066static constexpr const char* versionInterface =
67 "xyz.openbmc_project.Software.Version";
Zhikui Ren18a5ab92020-09-01 21:35:20 -070068constexpr const int limitEntryLen = 0xff;
69
Josh Lehan027277a2023-09-11 05:28:19 -070070// Avoid putting multiple interfaces with same name on same object
71static std::string placeGetRecordType(const std::string& objectPath)
72{
73 if (objectPath != defaultObjectPath)
74 {
75 // Place GetRecordType interface on object itself, not parent
76 return objectPath;
77 }
78
79 std::filesystem::path path(objectPath);
80
81 // As there is only one default, safe to place it on the common parent
82 return path.parent_path().string();
83}
84
Jason M. Billsa3f5b382023-04-26 08:17:28 -070085class MDRV2 :
Patrick Williams77b9c472022-07-22 19:26:57 -050086 sdbusplus::server::object_t<
Jason M. Bills33ae81f2023-04-26 09:06:08 -070087 sdbusplus::server::xyz::openbmc_project::smbios::MDRV2>
Cheng C Yang3e3269a2019-12-02 15:11:30 +080088{
89 public:
Jason M. Billsa3f5b382023-04-26 08:17:28 -070090 MDRV2() = delete;
91 MDRV2(const MDRV2&) = delete;
92 MDRV2& operator=(const MDRV2&) = delete;
93 MDRV2(MDRV2&&) = delete;
94 MDRV2& operator=(MDRV2&&) = delete;
Cheng C Yang3e3269a2019-12-02 15:11:30 +080095
Josh Lehan027277a2023-09-11 05:28:19 -070096 virtual ~MDRV2()
Cheng C Yang3e3269a2019-12-02 15:11:30 +080097 {
Josh Lehan027277a2023-09-11 05:28:19 -070098 if (smbiosInterface)
99 {
100 if (objServer)
101 {
102 // Must manually undo add_interface()
103 objServer->remove_interface(smbiosInterface);
104 }
105 }
106 }
107
108 MDRV2(std::shared_ptr<boost::asio::io_context> io,
109 std::shared_ptr<sdbusplus::asio::connection> conn,
110 std::shared_ptr<sdbusplus::asio::object_server> obj,
111 std::string filePath, std::string objectPath,
112 std::string inventoryPath) :
113 sdbusplus::server::object_t<
114 sdbusplus::server::xyz::openbmc_project::smbios::MDRV2>(
115 *conn, objectPath.c_str()),
116 timer(*io), bus(conn), objServer(std::move(obj)),
117 smbiosInterface(objServer->add_interface(placeGetRecordType(objectPath),
118 smbiosInterfaceName)),
119 smbiosFilePath(std::move(filePath)),
120 smbiosObjectPath(std::move(objectPath)),
121 smbiosInventoryPath(std::move(inventoryPath))
122 {
123 lg2::info("SMBIOS data file path: {F}", "F", smbiosFilePath);
124 lg2::info("SMBIOS control object: {O}", "O", smbiosObjectPath);
125 lg2::info("SMBIOS inventory path: {I}", "I", smbiosInventoryPath);
126
Cheng C Yang3e3269a2019-12-02 15:11:30 +0800127 smbiosDir.agentVersion = smbiosAgentVersion;
Josh Lehanf079e832023-09-19 15:52:52 -0700128 smbiosDir.dirVersion = smbiosDirVersion;
Cheng C Yang3e3269a2019-12-02 15:11:30 +0800129 smbiosDir.dirEntries = 1;
130 directoryEntries(smbiosDir.dirEntries);
131 smbiosDir.status = 1;
132 smbiosDir.remoteDirVersion = 0;
133
134 std::copy(smbiosTableId.begin(), smbiosTableId.end(),
135 smbiosDir.dir[smbiosDirIndex].common.id.dataInfo);
136
137 smbiosDir.dir[smbiosDirIndex].dataStorage = smbiosTableStorage;
138
139 agentSynchronizeData();
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700140
141 smbiosInterface->register_method("GetRecordType", [this](size_t type) {
142 return getRecordType(type);
143 });
144 smbiosInterface->initialize();
Cheng C Yang3e3269a2019-12-02 15:11:30 +0800145 }
146
Cheng C Yangeecaf822019-12-19 00:34:23 +0800147 std::vector<uint8_t> getDirectoryInformation(uint8_t dirIndex) override;
148
149 std::vector<uint8_t> getDataInformation(uint8_t idIndex) override;
150
Patrick Williams1d73dcc2024-08-16 15:21:42 -0400151 bool sendDirectoryInformation(
152 uint8_t dirVersion, uint8_t dirIndex, uint8_t returnedEntries,
153 uint8_t remainingEntries, std::vector<uint8_t> dirEntry) override;
Cheng C Yangeecaf822019-12-19 00:34:23 +0800154
155 std::vector<uint8_t> getDataOffer() override;
156
157 bool sendDataInformation(uint8_t idIndex, uint8_t flag, uint32_t dataLen,
158 uint32_t dataVer, uint32_t timeStamp) override;
159
160 int findIdIndex(std::vector<uint8_t> dataInfo) override;
161
162 bool agentSynchronizeData() override;
163
Patrick Williams07a2c9a2025-02-01 08:23:10 -0500164 std::vector<uint32_t> synchronizeDirectoryCommonData(
165 uint8_t idIndex, uint32_t size) override;
Cheng C Yangeecaf822019-12-19 00:34:23 +0800166
167 uint8_t directoryEntries(uint8_t value) override;
168
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700169 std::vector<boost::container::flat_map<std::string, RecordVariant>>
170 getRecordType(size_t type);
171
Cheng C Yang3e3269a2019-12-02 15:11:30 +0800172 private:
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700173 boost::asio::steady_timer timer;
Cheng C Yang3e3269a2019-12-02 15:11:30 +0800174
Josh Lehan027277a2023-09-11 05:28:19 -0700175 std::shared_ptr<sdbusplus::asio::connection> bus;
176 std::shared_ptr<sdbusplus::asio::object_server> objServer;
Cheng C Yang3e3269a2019-12-02 15:11:30 +0800177
178 Mdr2DirStruct smbiosDir;
179
Cheng C Yangec634252019-12-19 00:42:36 +0800180 bool readDataFromFlash(MDRSMBIOSHeader* mdrHdr, uint8_t* data);
Arun P. Mohanan0435a482022-02-01 21:45:55 +0530181 bool checkSMBIOSVersion(uint8_t* dataIn);
Cheng C Yangec634252019-12-19 00:42:36 +0800182
Cheng C Yang3e3269a2019-12-02 15:11:30 +0800183 const std::array<uint8_t, 16> smbiosTableId{
184 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 0x42};
Josh Lehanc6d87a52024-02-08 19:01:29 -0800185 uint8_t smbiosTableStorage[smbiosTableStorageSize] = {};
Cheng C Yang3e3269a2019-12-02 15:11:30 +0800186
187 bool smbiosIsUpdating(uint8_t index);
188 bool smbiosIsAvailForUpdate(uint8_t index);
189 inline uint8_t smbiosValidFlag(uint8_t index);
190 void systemInfoUpdate(void);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800191
Jonathan Domanf2d8bb42023-07-26 10:13:34 -0700192 std::optional<size_t> getTotalCpuSlot(void);
193 std::optional<size_t> getTotalDimmSlot(void);
194 std::optional<size_t> getTotalPcieSlot(void);
Prithvi Pai5af42bb2025-02-11 17:59:07 +0530195 std::optional<size_t> getTotalTpm(void);
Prithvi Pai6f9e7a72025-03-14 13:05:02 +0530196 std::optional<size_t> getTotalFirmwareInventory(void);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800197 std::vector<std::unique_ptr<Cpu>> cpus;
Cheng C Yang8c3fab62019-12-19 00:51:06 +0800198 std::vector<std::unique_ptr<Dimm>> dimms;
Jie Yang08e4a6d2021-08-23 13:07:41 -0700199 std::vector<std::unique_ptr<Pcie>> pcies;
Prithvi Pai5af42bb2025-02-11 17:59:07 +0530200 std::vector<std::unique_ptr<Tpm>> tpms;
Prithvi Pai6f9e7a72025-03-14 13:05:02 +0530201 std::vector<std::unique_ptr<FirmwareInventory>> firmwareCollection;
Cheng C Yangb4651b92019-12-19 00:59:01 +0800202 std::unique_ptr<System> system;
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700203 std::shared_ptr<sdbusplus::asio::dbus_interface> smbiosInterface;
Josh Lehan027277a2023-09-11 05:28:19 -0700204
205 std::string smbiosFilePath;
206 std::string smbiosObjectPath;
207 std::string smbiosInventoryPath;
208 std::unique_ptr<sdbusplus::bus::match_t> motherboardConfigMatch;
Cheng C Yang3e3269a2019-12-02 15:11:30 +0800209};
210
211} // namespace smbios
212} // namespace phosphor