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