xref: /openbmc/smbios-mdr/include/mdrv2.hpp (revision 2ca7a0f3ac092e3b6c6ccacdc1504310853ea720)
1 /*
2 // Copyright (c) 2019 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 "cpu.hpp"
19 #include "dimm.hpp"
20 #include "smbios.hpp"
21 #include "system.hpp"
22 
23 #include <sys/stat.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26 
27 #include <phosphor-logging/elog-errors.hpp>
28 #include <phosphor-logging/log.hpp>
29 #include <sdbusplus/server.hpp>
30 #include <sdbusplus/timer.hpp>
31 #include <smbios.hpp>
32 #include <xyz/openbmc_project/Smbios/MDR_V2/server.hpp>
33 
34 static constexpr int limitEntryLen = 0xff;
35 static constexpr uint8_t mdr2Version = 2;
36 static constexpr uint32_t mdr2SMSize = 0x00100000;
37 static constexpr uint32_t mdr2SMBaseAddress = 0x9FF00000;
38 static constexpr const char* mdrType2File = "/var/lib/smbios/smbios2";
39 static constexpr const char* mdrV2Path = "/xyz/openbmc_project/Smbios/MDR_V2";
40 
41 enum class MDR2SMBIOSStatusEnum
42 {
43     mdr2Init = 0,
44     mdr2Loaded = 1,
45     mdr2Updated = 2,
46     mdr2Updating = 3
47 };
48 
49 enum class MDR2DirLockEnum
50 {
51     mdr2DirUnlock = 0,
52     mdr2DirLock = 1
53 };
54 
55 typedef struct
56 {
57     uint8_t dataInfo[16];
58 } DataIdStruct;
59 
60 typedef struct
61 {
62     DataIdStruct id;
63     uint32_t size;
64     uint32_t dataSetSize;
65     uint32_t dataVersion;
66     uint32_t timestamp;
67 } Mdr2DirEntry;
68 
69 typedef struct
70 {
71     Mdr2DirEntry common;
72     MDR2SMBIOSStatusEnum stage;
73     MDR2DirLockEnum lock;
74     uint16_t lockHandle;
75     uint32_t xferBuff;
76     uint32_t xferSize;
77     uint32_t maxDataSize;
78     uint8_t* dataStorage;
79 } Mdr2DirLocalStruct;
80 
81 typedef struct
82 {
83     uint8_t agentVersion;
84     uint8_t dirVersion;
85     uint8_t dirEntries;
86     uint8_t status; // valid / locked / etc
87     uint8_t remoteDirVersion;
88     uint16_t sessionHandle;
89     Mdr2DirLocalStruct dir[maxDirEntries];
90 } Mdr2DirStruct;
91 
92 struct MDRSMBIOSHeader
93 {
94     uint8_t dirVer;
95     uint8_t mdrType;
96     uint32_t timestamp;
97     uint32_t dataSize;
98 } __attribute__((packed));
99 
100 namespace phosphor
101 {
102 namespace smbios
103 {
104 
105 class MDR_V2 : sdbusplus::server::object::object<
106                    sdbusplus::xyz::openbmc_project::Smbios::server::MDR_V2>
107 {
108   public:
109     MDR_V2() = delete;
110     MDR_V2(const MDR_V2&) = delete;
111     MDR_V2& operator=(const MDR_V2&) = delete;
112     MDR_V2(MDR_V2&&) = delete;
113     MDR_V2& operator=(MDR_V2&&) = delete;
114     ~MDR_V2() = default;
115 
116     MDR_V2(sdbusplus::bus::bus& bus, const char* path, sd_event* event) :
117         sdbusplus::server::object::object<
118             sdbusplus::xyz::openbmc_project::Smbios::server::MDR_V2>(bus, path),
119         bus(bus), timer(event, [&](void) { agentSynchronizeData(); })
120     {
121 
122         smbiosDir.agentVersion = smbiosAgentVersion;
123         smbiosDir.dirVersion = 1;
124         smbiosDir.dirEntries = 1;
125         directoryEntries(smbiosDir.dirEntries);
126         smbiosDir.status = 1;
127         smbiosDir.remoteDirVersion = 0;
128 
129         std::copy(smbiosTableId.begin(), smbiosTableId.end(),
130                   smbiosDir.dir[smbiosDirIndex].common.id.dataInfo);
131 
132         smbiosDir.dir[smbiosDirIndex].dataStorage = smbiosTableStorage;
133 
134         agentSynchronizeData();
135     }
136 
137     std::vector<uint8_t> getDirectoryInformation(uint8_t dirIndex) override;
138 
139     std::vector<uint8_t> getDataInformation(uint8_t idIndex) override;
140 
141     bool sendDirectoryInformation(uint8_t dirVersion, uint8_t dirIndex,
142                                   uint8_t returnedEntries,
143                                   uint8_t remainingEntries,
144                                   std::vector<uint8_t> dirEntry) override;
145 
146     std::vector<uint8_t> getDataOffer() override;
147 
148     bool sendDataInformation(uint8_t idIndex, uint8_t flag, uint32_t dataLen,
149                              uint32_t dataVer, uint32_t timeStamp) override;
150 
151     int findIdIndex(std::vector<uint8_t> dataInfo) override;
152 
153     bool agentSynchronizeData() override;
154 
155     std::vector<uint32_t>
156         synchronizeDirectoryCommonData(uint8_t idIndex, uint32_t size) override;
157 
158     uint8_t directoryEntries(uint8_t value) override;
159 
160   private:
161     Timer timer;
162 
163     sdbusplus::bus::bus& bus;
164 
165     Mdr2DirStruct smbiosDir;
166 
167     bool readDataFromFlash(MDRSMBIOSHeader* mdrHdr, uint8_t* data);
168 
169     const std::array<uint8_t, 16> smbiosTableId{
170         40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 0x42};
171     uint8_t smbiosTableStorage[smbiosTableStorageSize];
172 
173     bool smbiosIsUpdating(uint8_t index);
174     bool smbiosIsAvailForUpdate(uint8_t index);
175     inline uint8_t smbiosValidFlag(uint8_t index);
176     void systemInfoUpdate(void);
177 
178     int getTotalCpuSlot(void);
179     int getTotalDimmSlot(void);
180     std::vector<std::unique_ptr<Cpu>> cpus;
181     std::vector<std::unique_ptr<Dimm>> dimms;
182     std::unique_ptr<System> system;
183 };
184 
185 } // namespace smbios
186 } // namespace phosphor
187