| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | // Copyright (c) 2018 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 <ipmid/api.h> | 
|  | 19 | #include <sys/mman.h> | 
|  | 20 |  | 
|  | 21 | #include <oemcommands.hpp> | 
|  | 22 | #include <sdbusplus/timer.hpp> | 
| Jason M. Bills | 0748c69 | 2022-09-08 15:34:08 -0700 | [diff] [blame] | 23 | #include <types.hpp> | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 24 |  | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 25 | static constexpr const char* mdrType2File = "/var/lib/smbios/smbios2"; | 
|  | 26 | static constexpr const char* smbiosPath = "/var/lib/smbios"; | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 27 | static constexpr const size_t msgPayloadSize = | 
|  | 28 | 1024 * 60; // Total size will transfer for smbios table | 
|  | 29 | static constexpr const size_t mdriiSMSize = 0x00100000; | 
|  | 30 |  | 
|  | 31 | static constexpr const uint16_t smbiosAgentId = | 
|  | 32 | 0x0101; // Agent ID for smbios entry | 
|  | 33 | static constexpr const int firstAgentIndex = 1; | 
|  | 34 |  | 
|  | 35 | static constexpr const uint8_t maxDirEntries = 4; // Maximum directory entries | 
|  | 36 | static constexpr const uint32_t mdr2SMSize = | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 37 | 0x00100000;                                   // Size of VGA share memory | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 38 | static constexpr const uint32_t mdr2SMBaseAddress = | 
|  | 39 | 0x9FF00000; // Base address of VGA share memory | 
|  | 40 |  | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 41 | static constexpr const uint8_t mdrTypeII = 2;          // MDR V2 type | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 42 |  | 
|  | 43 | static constexpr const uint8_t mdr2Version = 2;        // MDR V2 versoin | 
|  | 44 | static constexpr const uint8_t smbiosAgentVersion = 1; // Agent version of | 
|  | 45 | // smbios | 
|  | 46 |  | 
|  | 47 | static constexpr const uint32_t pageMask = | 
|  | 48 | 0xf000; // To make data become n times of page | 
|  | 49 | static constexpr const int smbiosDirIndex = 0; // SMBIOS directory index | 
|  | 50 |  | 
|  | 51 | static constexpr const uint32_t smbiosTableVersion = | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 52 | 15;          // Version of smbios table | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 53 | static constexpr const uint32_t smbiosTableTimestamp = | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 54 | 0x45464748;  // Time stamp when smbios table created | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 55 | static constexpr const size_t smbiosSMMemoryOffset = | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 56 | 0;           // Offset of VGA share memory | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 57 | static constexpr const size_t smbiosSMMemorySize = | 
|  | 58 | 1024 * 1024; // Total size of VGA share memory | 
|  | 59 | static constexpr const size_t smbiosTableStorageSize = | 
| Patrick Williams | b37abfb | 2023-05-10 07:50:33 -0500 | [diff] [blame] | 60 | 64 * 1024;   // Total size of smbios table | 
| Jayaprakash Mutyala | fe9a700 | 2020-12-02 19:17:58 +0000 | [diff] [blame] | 61 | static constexpr const uint32_t defaultTimeout = 4000; | 
|  | 62 | static constexpr const uint16_t sysClock = 1000; | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 63 | static constexpr const int lastAgentIndex = -1; | 
|  | 64 | static constexpr const uint16_t lastAgentId = 0xFFFF; | 
|  | 65 | constexpr const uint32_t invalidChecksum = 0xffffffff; | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 66 | constexpr const char* dbusProperties = "org.freedesktop.DBus.Properties"; | 
|  | 67 | constexpr const char* mdrv2Path = "/xyz/openbmc_project/Smbios/MDR_V2"; | 
|  | 68 | constexpr const char* mdrv2Interface = "xyz.openbmc_project.Smbios.MDR_V2"; | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 69 |  | 
|  | 70 | enum class MDR2SMBIOSStatusEnum | 
|  | 71 | { | 
|  | 72 | mdr2Init = 0, | 
|  | 73 | mdr2Loaded = 1, | 
|  | 74 | mdr2Updated = 2, | 
|  | 75 | mdr2Updating = 3 | 
|  | 76 | }; | 
|  | 77 |  | 
|  | 78 | enum class DirDataRequestEnum | 
|  | 79 | { | 
|  | 80 | dirDataNotRequested = 0x00, | 
|  | 81 | dirDataRequested = 0x01 | 
|  | 82 | }; | 
|  | 83 |  | 
|  | 84 | enum MDR2DirLockEnum | 
|  | 85 | { | 
|  | 86 | mdr2DirUnlock = 0, | 
|  | 87 | mdr2DirLock = 1 | 
|  | 88 | }; | 
|  | 89 |  | 
|  | 90 | #pragma pack(push) | 
|  | 91 | #pragma pack(1) | 
|  | 92 |  | 
|  | 93 | struct MDRSMBIOSHeader | 
|  | 94 | { | 
|  | 95 | uint8_t dirVer; | 
|  | 96 | uint8_t mdrType; | 
|  | 97 | uint32_t timestamp; | 
|  | 98 | uint32_t dataSize; | 
|  | 99 | }; | 
|  | 100 |  | 
|  | 101 | struct DataIdStruct | 
|  | 102 | { | 
|  | 103 | uint8_t dataInfo[16]; | 
|  | 104 | }; | 
|  | 105 |  | 
|  | 106 | struct Mdr2DirEntry | 
|  | 107 | { | 
|  | 108 | DataIdStruct id; | 
|  | 109 | uint32_t size; | 
|  | 110 | uint32_t dataSetSize; | 
|  | 111 | uint32_t dataVersion; | 
|  | 112 | uint32_t timestamp; | 
|  | 113 | }; | 
|  | 114 |  | 
|  | 115 | struct Mdr2DirLocalStruct | 
|  | 116 | { | 
|  | 117 | Mdr2DirEntry common; | 
|  | 118 | MDR2SMBIOSStatusEnum stage; | 
|  | 119 | MDR2DirLockEnum lock; | 
|  | 120 | uint16_t lockHandle; | 
|  | 121 | uint32_t xferBuff; | 
|  | 122 | uint32_t xferSize; | 
|  | 123 | uint32_t maxDataSize; | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 124 | uint8_t* dataStorage; | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 125 | }; | 
|  | 126 |  | 
|  | 127 | struct Mdr2DirStruct | 
|  | 128 | { | 
|  | 129 | uint8_t agentVersion; | 
|  | 130 | uint8_t dirVersion; | 
|  | 131 | uint8_t dirEntries; | 
|  | 132 | uint8_t status; // valid / locked / etc | 
|  | 133 | uint8_t remoteDirVersion; | 
|  | 134 | uint16_t sessionHandle; | 
|  | 135 | Mdr2DirLocalStruct dir[maxDirEntries]; | 
|  | 136 | }; | 
|  | 137 |  | 
|  | 138 | // Three members include dataSetSize, dataVersion and timestamp | 
|  | 139 | static constexpr const size_t syncDirCommonSize = 3; | 
|  | 140 |  | 
|  | 141 | // ====================== MDR II Pull Command Structures ====================== | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 142 | struct MDRiiGetDataInfoRequest | 
|  | 143 | { | 
|  | 144 | uint16_t agentId; | 
|  | 145 | DataIdStruct dataSetInfo; | 
|  | 146 | }; | 
|  | 147 |  | 
|  | 148 | // MDR II data set information inquiry response | 
|  | 149 | struct MDRiiGetDataInfoResponse | 
|  | 150 | { | 
|  | 151 | uint8_t mdrVersion; | 
|  | 152 | DataIdStruct dataSetId; | 
|  | 153 | uint8_t validFlag; | 
|  | 154 | uint32_t dataLength; | 
| jayaprakash Mutyala | 04a38ed | 2020-05-29 01:42:26 +0000 | [diff] [blame] | 155 | uint8_t dataVersion; | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 156 | uint32_t timeStamp; | 
|  | 157 | }; | 
|  | 158 |  | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 159 | // ====================== MDR II Push Command Structures ====================== | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 160 | // MDR II Client send data set info offer response | 
|  | 161 | struct MDRiiOfferDataInfoResponse | 
|  | 162 | { | 
|  | 163 | DataIdStruct dataSetInfo; | 
|  | 164 | }; | 
|  | 165 |  | 
|  | 166 | // MDR II Push Agent send data set info command | 
|  | 167 | struct MDRiiSendDataInfoRequest | 
|  | 168 | { | 
|  | 169 | uint16_t agentId; | 
|  | 170 | DataIdStruct dataSetInfo; | 
|  | 171 | uint8_t validFlag; | 
|  | 172 | uint32_t dataLength; | 
|  | 173 | uint32_t dataVersion; // Roughly equivalent to the "file name" | 
|  | 174 | uint32_t | 
|  | 175 | timeStamp; // More info on the identity of this particular set of data | 
|  | 176 | }; | 
|  | 177 |  | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 178 | // MDR II Pull Agent lock data set command | 
|  | 179 | struct MDRiiLockDataRequest | 
|  | 180 | { | 
|  | 181 | uint16_t agentId; | 
|  | 182 | DataIdStruct dataSetInfo; | 
|  | 183 | uint16_t timeout; | 
|  | 184 | }; | 
|  | 185 |  | 
|  | 186 | // MDR II Pull Agent lock data set response | 
|  | 187 | struct MDRiiLockDataResponse | 
|  | 188 | { | 
|  | 189 | uint8_t mdrVersion; | 
|  | 190 | uint16_t lockHandle; | 
|  | 191 | uint32_t dataLength; | 
|  | 192 | uint32_t xferAddress; | 
|  | 193 | uint32_t xferLength; | 
|  | 194 | }; | 
|  | 195 |  | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 196 | // MDR II Push Agent send data start command | 
|  | 197 | struct MDRiiDataStartRequest | 
|  | 198 | { | 
|  | 199 | uint16_t agentId; | 
|  | 200 | DataIdStruct dataSetInfo; | 
|  | 201 | uint32_t dataLength; | 
|  | 202 | uint32_t xferAddress; | 
|  | 203 | uint32_t xferLength; | 
|  | 204 | uint16_t timeout; | 
|  | 205 | }; | 
|  | 206 |  | 
|  | 207 | // MDR II Client send data start response | 
|  | 208 | struct MDRiiDataStartResponse | 
|  | 209 | { | 
|  | 210 | uint8_t xferStartAck; | 
|  | 211 | uint16_t sessionHandle; | 
|  | 212 | }; | 
|  | 213 |  | 
|  | 214 | // MDR II | 
|  | 215 | struct MDRiiDataDoneRequest | 
|  | 216 | { | 
|  | 217 | uint16_t agentId; | 
|  | 218 | uint16_t lockHandle; | 
|  | 219 | }; | 
|  | 220 |  | 
|  | 221 | #pragma pack(pop) | 
|  | 222 |  | 
|  | 223 | class SharedMemoryArea | 
|  | 224 | { | 
|  | 225 | public: | 
|  | 226 | SharedMemoryArea(uint32_t addr, uint32_t areaSize) : | 
|  | 227 | vPtr(nullptr), physicalAddr(addr), size(areaSize) | 
|  | 228 | { | 
|  | 229 | Initialize(addr, areaSize); | 
|  | 230 | } | 
|  | 231 |  | 
|  | 232 | ~SharedMemoryArea() | 
|  | 233 | { | 
|  | 234 | if ((vPtr != nullptr) && (vPtr != MAP_FAILED)) | 
|  | 235 | { | 
|  | 236 | if (0 != munmap(vPtr, size)) | 
|  | 237 | { | 
|  | 238 | phosphor::logging::log<phosphor::logging::level::ERR>( | 
|  | 239 | "Ummap share memory failed"); | 
|  | 240 | } | 
|  | 241 | } | 
|  | 242 | } | 
|  | 243 |  | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 244 | void* vPtr; | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 245 |  | 
|  | 246 | private: | 
|  | 247 | uint32_t physicalAddr; | 
|  | 248 | uint32_t size; | 
|  | 249 |  | 
|  | 250 | void Initialize(uint32_t addr, uint32_t areaSize); | 
|  | 251 | }; | 
|  | 252 |  | 
|  | 253 | class MDRV2 | 
|  | 254 | { | 
|  | 255 | public: | 
|  | 256 | MDRV2() | 
|  | 257 | { | 
|  | 258 | timer = | 
| Patrick Williams | f0feb49 | 2023-12-05 12:45:02 -0600 | [diff] [blame] | 259 | std::make_unique<sdbusplus::Timer>([&](void) { timeoutHandler(); }); | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 260 | } | 
|  | 261 |  | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 262 | int agentLookup(const uint16_t& agentId); | 
|  | 263 | int findLockHandle(const uint16_t& lockHandle); | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 264 | int syncDirCommonData(uint8_t idIndex, uint32_t size, | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 265 | const std::string& service); | 
|  | 266 | int findDataId(const uint8_t* dataInfo, const size_t& len, | 
|  | 267 | const std::string& service); | 
|  | 268 | uint16_t getSessionHandle(Mdr2DirStruct* dir); | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 269 | bool smbiosIsUpdating(uint8_t index); | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 270 | uint32_t calcChecksum32(uint8_t* buf, uint32_t len); | 
|  | 271 | bool storeDatatoFlash(MDRSMBIOSHeader* mdrHdr, uint8_t* data); | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 272 | bool smbiosUnlock(uint8_t index); | 
|  | 273 | void timeoutHandler(); | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 274 | bool smbiosTryLock(uint8_t flag, uint8_t index, uint16_t* session, | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 275 | uint16_t timeout); | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 276 | int sdplusMdrv2GetProperty(const std::string& name, | 
| Jason M. Bills | 0748c69 | 2022-09-08 15:34:08 -0700 | [diff] [blame] | 277 | ipmi::DbusVariant& value, | 
| James Feist | fcd2d3a | 2020-05-28 10:38:15 -0700 | [diff] [blame] | 278 | const std::string& service); | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 279 |  | 
| Patrick Williams | 1bcced0 | 2024-08-16 15:20:24 -0400 | [diff] [blame] | 280 | Mdr2DirStruct smbiosDir{ | 
|  | 281 | smbiosAgentVersion, | 
|  | 282 | 1, | 
|  | 283 | 1, | 
|  | 284 | 1, | 
|  | 285 | 0, | 
|  | 286 | 0, | 
|  | 287 | {40, | 
|  | 288 | 41, | 
|  | 289 | 42, | 
|  | 290 | 43, | 
|  | 291 | 44, | 
|  | 292 | 45, | 
|  | 293 | 46, | 
|  | 294 | 47, | 
|  | 295 | 48, | 
|  | 296 | 49, | 
|  | 297 | 50, | 
|  | 298 | 51, | 
|  | 299 | 52, | 
|  | 300 | 53, | 
|  | 301 | 54, | 
|  | 302 | 0x42, | 
|  | 303 | 0, | 
|  | 304 | smbiosTableStorageSize, | 
|  | 305 | smbiosTableVersion, | 
|  | 306 | smbiosTableTimestamp, | 
|  | 307 | MDR2SMBIOSStatusEnum::mdr2Init, | 
|  | 308 | MDR2DirLockEnum::mdr2DirUnlock, | 
|  | 309 | 0, | 
|  | 310 | smbiosSMMemoryOffset, | 
|  | 311 | smbiosSMMemorySize, | 
|  | 312 | smbiosTableStorageSize, | 
|  | 313 | smbiosTableStorage}}; | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 314 | std::unique_ptr<SharedMemoryArea> area; | 
| Patrick Williams | f0feb49 | 2023-12-05 12:45:02 -0600 | [diff] [blame] | 315 | std::unique_ptr<sdbusplus::Timer> timer; | 
| Vernon Mauery | a3702c1 | 2019-05-22 13:20:59 -0700 | [diff] [blame] | 316 |  | 
|  | 317 | private: | 
|  | 318 | uint8_t lockIndex = 0; | 
|  | 319 | uint8_t smbiosTableStorage[smbiosTableStorageSize]; | 
|  | 320 | }; |