blob: 0d8ec303be90d97a7997b64f687b0223372fcff3 [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
122static constexpr const char* cpuPath =
123 "/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu";
124
125static constexpr const char* dimmPath =
126 "/xyz/openbmc_project/inventory/system/chassis/motherboard/dimm";
127
Jie Yang08e4a6d2021-08-23 13:07:41 -0700128static constexpr const char* pciePath =
129 "/xyz/openbmc_project/inventory/system/chassis/motherboard/pcieslot";
130
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700131static constexpr const char* systemPath =
132 "/xyz/openbmc_project/inventory/system/chassis/motherboard/bios";
133
Cheng C Yang3e3269a2019-12-02 15:11:30 +0800134typedef enum
135{
136 biosType = 0,
137 systemType = 1,
138 baseboardType = 2,
139 chassisType = 3,
140 processorsType = 4,
141 memoryControllerType = 5,
142 memoryModuleInformationType = 6,
143 cacheType = 7,
144 portConnectorType = 8,
145 systemSlots = 9,
146 onBoardDevicesType = 10,
147 oemStringsType = 11,
148 systemCconfigurationOptionsType = 12,
149 biosLanguageType = 13,
150 groupAssociatonsType = 14,
151 systemEventLogType = 15,
152 physicalMemoryArrayType = 16,
153 memoryDeviceType = 17,
154} SmbiosType;
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800155
156static constexpr uint8_t separateLen = 2;
157
158static inline uint8_t* smbiosNextPtr(uint8_t* smbiosDataIn)
159{
160 if (smbiosDataIn == nullptr)
161 {
162 return nullptr;
163 }
164 uint8_t* smbiosData = smbiosDataIn + *(smbiosDataIn + 1);
165 int len = 0;
166 while ((*smbiosData | *(smbiosData + 1)) != 0)
167 {
168 smbiosData++;
169 len++;
170 if (len >= mdrSMBIOSSize) // To avoid endless loop
171 {
172 return nullptr;
173 }
174 }
175 return smbiosData + separateLen;
176}
177
178// When first time run getSMBIOSTypePtr, need to send the RegionS[].regionData
179// to smbiosDataIn
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700180static inline uint8_t* getSMBIOSTypePtr(uint8_t* smbiosDataIn, uint8_t typeId,
181 size_t size = 0)
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800182{
183 if (smbiosDataIn == nullptr)
184 {
185 return nullptr;
186 }
187 char* smbiosData = reinterpret_cast<char*>(smbiosDataIn);
188 while ((*smbiosData != '\0') || (*(smbiosData + 1) != '\0'))
189 {
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700190 uint32_t len = *(smbiosData + 1);
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800191 if (*smbiosData != typeId)
192 {
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700193
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800194 smbiosData += len;
195 while ((*smbiosData != '\0') || (*(smbiosData + 1) != '\0'))
196 {
197 smbiosData++;
198 len++;
199 if (len >= mdrSMBIOSSize) // To avoid endless loop
200 {
201 return nullptr;
202 }
203 }
204 smbiosData += separateLen;
205 continue;
206 }
Zhikui Ren18a5ab92020-09-01 21:35:20 -0700207 if (len < size)
208 {
209 phosphor::logging::log<phosphor::logging::level::ERR>(
210 "Record size mismatch!");
211 return nullptr;
212 }
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800213 return reinterpret_cast<uint8_t*>(smbiosData);
214 }
215 return nullptr;
216}
217
218static inline std::string positionToString(uint8_t positionNum,
219 uint8_t structLen, uint8_t* dataIn)
220{
221 if (dataIn == nullptr)
222 {
223 return "";
224 }
225 uint16_t limit = mdrSMBIOSSize; // set a limit to avoid endless loop
226
227 char* target = reinterpret_cast<char*>(dataIn + structLen);
Kuiying Wang59bb9d92020-10-27 15:30:46 +0800228 if (target == nullptr)
229 {
230 return "";
231 }
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800232 for (uint8_t index = 1; index < positionNum; index++)
233 {
234 for (; *target != '\0'; target++)
235 {
236 limit--;
Kuiying Wang59bb9d92020-10-27 15:30:46 +0800237 // When target = dataIn + structLen + limit,
238 // following target++ will be nullptr
239 if (limit < 1 || target == nullptr)
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800240 {
241 return "";
242 }
243 }
244 target++;
Kuiying Wang59bb9d92020-10-27 15:30:46 +0800245 if (target == nullptr || *target == '\0')
Cheng C Yang43c6a1d2019-12-19 00:48:34 +0800246 {
247 return ""; // 0x00 0x00 means end of the entry.
248 }
249 }
250
251 std::string result = target;
252 return result;
253}