blob: 4f3b6546897e628302b0630d3cab3c22e270e676 [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
18
Zhikui Ren18a5ab92020-09-01 21:35:20 -070019#include <phosphor-logging/elog-errors.hpp>
20
Cheng C Yang3e3269a2019-12-02 15:11:30 +080021#include <array>
22
Zhikui Ren18a5ab92020-09-01 21:35:20 -070023static constexpr const char* mdrType2File = "/var/lib/smbios/smbios2";
Cheng C Yang3e3269a2019-12-02 15:11:30 +080024static constexpr const char* smbiosPath = "/var/lib/smbios";
Zhikui Ren18a5ab92020-09-01 21:35:20 -070025
Cheng C Yangeecaf822019-12-19 00:34:23 +080026static constexpr uint16_t mdrSMBIOSSize = 32 * 1024;
Cheng C Yang3e3269a2019-12-02 15:11:30 +080027
Zhikui Ren18a5ab92020-09-01 21:35:20 -070028constexpr uint16_t smbiosAgentId = 0x0101;
29constexpr int firstAgentIndex = 1;
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +080030
Zhikui Ren18a5ab92020-09-01 21:35:20 -070031constexpr uint8_t maxDirEntries = 4;
32constexpr uint32_t mdr2SMSize = 0x00100000;
33constexpr uint32_t mdr2SMBaseAddress = 0x9FF00000;
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +080034
Zhikui Ren18a5ab92020-09-01 21:35:20 -070035constexpr uint8_t mdrTypeII = 2;
36
37constexpr uint8_t mdr2Version = 2;
38constexpr uint8_t smbiosAgentVersion = 1;
39
40constexpr uint32_t pageMask = 0xf000;
41constexpr int smbiosDirIndex = 0;
42
43constexpr uint32_t smbiosTableVersion = 15;
44constexpr uint32_t smbiosTableTimestamp = 0x45464748;
45constexpr uint32_t smbiosSMMemoryOffset = 0;
46constexpr uint32_t smbiosSMMemorySize = 1024 * 1024;
47constexpr uint32_t smbiosTableStorageSize = 64 * 1024;
48constexpr uint32_t defaultTimeout = 20000;
49
50enum class MDR2SMBIOSStatusEnum
51{
52 mdr2Init = 0,
53 mdr2Loaded = 1,
54 mdr2Updated = 2,
55 mdr2Updating = 3
56};
57
58enum class MDR2DirLockEnum
59{
60 mdr2DirUnlock = 0,
61 mdr2DirLock = 1
62};
Cheng C Yang2ca7a0f2019-12-19 10:46:42 +080063
Cheng C Yang3e3269a2019-12-02 15:11:30 +080064enum class DirDataRequestEnum
65{
66 dirDataNotRequested = 0x00,
67 dirDataRequested = 0x01
68};
69
70enum class FlagStatus
71{
72 flagIsInvalid = 0,
73 flagIsValid = 1,
74 flagIsLocked = 2
75};
76
Zhikui Ren18a5ab92020-09-01 21:35:20 -070077typedef struct
78{
79 uint8_t dataInfo[16];
80} DataIdStruct;
81
82typedef struct
83{
84 DataIdStruct id;
85 uint32_t size;
86 uint32_t dataSetSize;
87 uint8_t dataVersion;
88 uint32_t timestamp;
89} Mdr2DirEntry;
90
91typedef struct
92{
93 Mdr2DirEntry common;
94 MDR2SMBIOSStatusEnum stage;
95 MDR2DirLockEnum lock;
96 uint16_t lockHandle;
97 uint32_t xferBuff;
98 uint32_t xferSize;
99 uint32_t maxDataSize;
100 uint8_t* dataStorage;
101} Mdr2DirLocalStruct;
102
103typedef struct
104{
105 uint8_t agentVersion;
106 uint8_t dirVersion;
107 uint8_t dirEntries;
108 uint8_t status; // valid / locked / etc
109 uint8_t remoteDirVersion;
110 uint16_t sessionHandle;
111 Mdr2DirLocalStruct dir[maxDirEntries];
112} Mdr2DirStruct;
113
114struct MDRSMBIOSHeader
115{
116 uint8_t dirVer;
117 uint8_t mdrType;
118 uint32_t timestamp;
119 uint32_t dataSize;
120} __attribute__((packed));
121
Arun P. Mohanan0435a482022-02-01 21:45:55 +0530122typedef struct
123{
124 uint8_t majorVersion;
125 uint8_t minorVersion;
126} SMBIOSVersion;
127
128struct EntryPointStructure
129{
130 uint32_t anchorString;
131 uint8_t epChecksum;
132 uint8_t epLength;
133 SMBIOSVersion smbiosVersion;
134 uint16_t maxStructSize;
135 uint8_t epRevision;
136 uint8_t formattedArea[5];
137 uint8_t intermediateAnchorString[5];
138 uint8_t intermediateChecksum;
139 uint16_t structTableLength;
140 uint32_t structTableAddress;
141 uint16_t noOfSmbiosStruct;
142 uint8_t smbiosBDCRevision;
143} __attribute__((packed));
144
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700145static constexpr const char* cpuPath =
146 "/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu";
147
148static constexpr const char* dimmPath =
149 "/xyz/openbmc_project/inventory/system/chassis/motherboard/dimm";
150
Jie Yang08e4a6d2021-08-23 13:07:41 -0700151static constexpr const char* pciePath =
152 "/xyz/openbmc_project/inventory/system/chassis/motherboard/pcieslot";
153
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700154static constexpr const char* systemPath =
155 "/xyz/openbmc_project/inventory/system/chassis/motherboard/bios";
156
Arun P. Mohanan0435a482022-02-01 21:45:55 +0530157constexpr std::array<SMBIOSVersion, 2> supportedSMBIOSVersions{
158 SMBIOSVersion{3, 2}, SMBIOSVersion{3, 3}};
159
Cheng C Yang3e3269a2019-12-02 15:11:30 +0800160typedef enum
161{
162 biosType = 0,
163 systemType = 1,
164 baseboardType = 2,
165 chassisType = 3,
166 processorsType = 4,
167 memoryControllerType = 5,
168 memoryModuleInformationType = 6,
169 cacheType = 7,
170 portConnectorType = 8,
171 systemSlots = 9,
172 onBoardDevicesType = 10,
173 oemStringsType = 11,
174 systemCconfigurationOptionsType = 12,
175 biosLanguageType = 13,
176 groupAssociatonsType = 14,
177 systemEventLogType = 15,
178 physicalMemoryArrayType = 16,
179 memoryDeviceType = 17,
180} SmbiosType;
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800181
182static constexpr uint8_t separateLen = 2;
183
184static inline uint8_t* smbiosNextPtr(uint8_t* smbiosDataIn)
185{
186 if (smbiosDataIn == nullptr)
187 {
188 return nullptr;
189 }
190 uint8_t* smbiosData = smbiosDataIn + *(smbiosDataIn + 1);
191 int len = 0;
192 while ((*smbiosData | *(smbiosData + 1)) != 0)
193 {
194 smbiosData++;
195 len++;
196 if (len >= mdrSMBIOSSize) // To avoid endless loop
197 {
198 return nullptr;
199 }
200 }
201 return smbiosData + separateLen;
202}
203
204// When first time run getSMBIOSTypePtr, need to send the RegionS[].regionData
205// to smbiosDataIn
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700206static inline uint8_t* getSMBIOSTypePtr(uint8_t* smbiosDataIn, uint8_t typeId,
207 size_t size = 0)
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800208{
209 if (smbiosDataIn == nullptr)
210 {
211 return nullptr;
212 }
213 char* smbiosData = reinterpret_cast<char*>(smbiosDataIn);
214 while ((*smbiosData != '\0') || (*(smbiosData + 1) != '\0'))
215 {
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700216 uint32_t len = *(smbiosData + 1);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800217 if (*smbiosData != typeId)
218 {
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700219
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800220 smbiosData += len;
221 while ((*smbiosData != '\0') || (*(smbiosData + 1) != '\0'))
222 {
223 smbiosData++;
224 len++;
225 if (len >= mdrSMBIOSSize) // To avoid endless loop
226 {
227 return nullptr;
228 }
229 }
230 smbiosData += separateLen;
231 continue;
232 }
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700233 if (len < size)
234 {
235 phosphor::logging::log<phosphor::logging::level::ERR>(
236 "Record size mismatch!");
237 return nullptr;
238 }
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800239 return reinterpret_cast<uint8_t*>(smbiosData);
240 }
241 return nullptr;
242}
243
244static inline std::string positionToString(uint8_t positionNum,
245 uint8_t structLen, uint8_t* dataIn)
246{
247 if (dataIn == nullptr)
248 {
249 return "";
250 }
251 uint16_t limit = mdrSMBIOSSize; // set a limit to avoid endless loop
252
253 char* target = reinterpret_cast<char*>(dataIn + structLen);
Kuiying Wang59bb9d92020-10-27 15:30:46 +0800254 if (target == nullptr)
255 {
256 return "";
257 }
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800258 for (uint8_t index = 1; index < positionNum; index++)
259 {
260 for (; *target != '\0'; target++)
261 {
262 limit--;
Kuiying Wang59bb9d92020-10-27 15:30:46 +0800263 // When target = dataIn + structLen + limit,
264 // following target++ will be nullptr
265 if (limit < 1 || target == nullptr)
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800266 {
267 return "";
268 }
269 }
270 target++;
Kuiying Wang59bb9d92020-10-27 15:30:46 +0800271 if (target == nullptr || *target == '\0')
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800272 {
273 return ""; // 0x00 0x00 means end of the entry.
274 }
275 }
276
277 std::string result = target;
278 return result;
279}