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