blob: 3ebe8ab9e19071e0b03a4e7310cde226db776e83 [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
Brandon Kime4ea3772022-02-23 20:21:10 -0800128struct EntryPointStructure21
Arun P. Mohanan0435a482022-02-01 21:45:55 +0530129{
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
Brandon Kime4ea3772022-02-23 20:21:10 -0800145struct EntryPointStructure30
146{
147 uint8_t anchorString[5];
148 uint8_t epChecksum;
149 uint8_t epLength;
150 SMBIOSVersion smbiosVersion;
151 uint8_t smbiosDocRev;
152 uint8_t epRevision;
153 uint8_t reserved;
154 uint32_t structTableMaxSize;
155 uint64_t structTableAddr;
156} __attribute__((packed));
157
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700158static constexpr const char* cpuPath =
159 "/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu";
160
161static constexpr const char* dimmPath =
162 "/xyz/openbmc_project/inventory/system/chassis/motherboard/dimm";
163
Jie Yang08e4a6d2021-08-23 13:07:41 -0700164static constexpr const char* pciePath =
165 "/xyz/openbmc_project/inventory/system/chassis/motherboard/pcieslot";
166
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700167static constexpr const char* systemPath =
168 "/xyz/openbmc_project/inventory/system/chassis/motherboard/bios";
169
Arun P. Mohanan0435a482022-02-01 21:45:55 +0530170constexpr std::array<SMBIOSVersion, 2> supportedSMBIOSVersions{
171 SMBIOSVersion{3, 2}, SMBIOSVersion{3, 3}};
172
Cheng C Yang3e3269a2019-12-02 15:11:30 +0800173typedef enum
174{
175 biosType = 0,
176 systemType = 1,
177 baseboardType = 2,
178 chassisType = 3,
179 processorsType = 4,
180 memoryControllerType = 5,
181 memoryModuleInformationType = 6,
182 cacheType = 7,
183 portConnectorType = 8,
184 systemSlots = 9,
185 onBoardDevicesType = 10,
186 oemStringsType = 11,
187 systemCconfigurationOptionsType = 12,
188 biosLanguageType = 13,
189 groupAssociatonsType = 14,
190 systemEventLogType = 15,
191 physicalMemoryArrayType = 16,
192 memoryDeviceType = 17,
193} SmbiosType;
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800194
195static constexpr uint8_t separateLen = 2;
196
197static inline uint8_t* smbiosNextPtr(uint8_t* smbiosDataIn)
198{
199 if (smbiosDataIn == nullptr)
200 {
201 return nullptr;
202 }
203 uint8_t* smbiosData = smbiosDataIn + *(smbiosDataIn + 1);
204 int len = 0;
205 while ((*smbiosData | *(smbiosData + 1)) != 0)
206 {
207 smbiosData++;
208 len++;
209 if (len >= mdrSMBIOSSize) // To avoid endless loop
210 {
211 return nullptr;
212 }
213 }
214 return smbiosData + separateLen;
215}
216
217// When first time run getSMBIOSTypePtr, need to send the RegionS[].regionData
218// to smbiosDataIn
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700219static inline uint8_t* getSMBIOSTypePtr(uint8_t* smbiosDataIn, uint8_t typeId,
220 size_t size = 0)
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800221{
222 if (smbiosDataIn == nullptr)
223 {
224 return nullptr;
225 }
226 char* smbiosData = reinterpret_cast<char*>(smbiosDataIn);
227 while ((*smbiosData != '\0') || (*(smbiosData + 1) != '\0'))
228 {
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700229 uint32_t len = *(smbiosData + 1);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800230 if (*smbiosData != typeId)
231 {
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700232
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800233 smbiosData += len;
234 while ((*smbiosData != '\0') || (*(smbiosData + 1) != '\0'))
235 {
236 smbiosData++;
237 len++;
238 if (len >= mdrSMBIOSSize) // To avoid endless loop
239 {
240 return nullptr;
241 }
242 }
243 smbiosData += separateLen;
244 continue;
245 }
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700246 if (len < size)
247 {
248 phosphor::logging::log<phosphor::logging::level::ERR>(
249 "Record size mismatch!");
250 return nullptr;
251 }
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800252 return reinterpret_cast<uint8_t*>(smbiosData);
253 }
254 return nullptr;
255}
256
257static inline std::string positionToString(uint8_t positionNum,
258 uint8_t structLen, uint8_t* dataIn)
259{
Gokul Sanker V G473d8902022-02-18 01:13:53 +0530260 if (dataIn == nullptr || positionNum == 0)
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800261 {
262 return "";
263 }
264 uint16_t limit = mdrSMBIOSSize; // set a limit to avoid endless loop
265
266 char* target = reinterpret_cast<char*>(dataIn + structLen);
Kuiying Wang59bb9d92020-10-27 15:30:46 +0800267 if (target == nullptr)
268 {
269 return "";
270 }
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800271 for (uint8_t index = 1; index < positionNum; index++)
272 {
273 for (; *target != '\0'; target++)
274 {
275 limit--;
Kuiying Wang59bb9d92020-10-27 15:30:46 +0800276 // When target = dataIn + structLen + limit,
277 // following target++ will be nullptr
278 if (limit < 1 || target == nullptr)
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800279 {
280 return "";
281 }
282 }
283 target++;
Kuiying Wang59bb9d92020-10-27 15:30:46 +0800284 if (target == nullptr || *target == '\0')
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800285 {
286 return ""; // 0x00 0x00 means end of the entry.
287 }
288 }
289
290 std::string result = target;
291 return result;
292}