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 Push Command Structures ====================== 159 // MDR II Client send data set info offer response 160 struct MDRiiOfferDataInfoResponse 161 { 162 DataIdStruct dataSetInfo; 163 }; 164 165 // MDR II Push Agent send data set info command 166 struct MDRiiSendDataInfoRequest 167 { 168 uint16_t agentId; 169 DataIdStruct dataSetInfo; 170 uint8_t validFlag; 171 uint32_t dataLength; 172 uint32_t dataVersion; // Roughly equivalent to the "file name" 173 uint32_t 174 timeStamp; // More info on the identity of this particular set of data 175 }; 176 177 // MDR II Pull Agent lock data set command 178 struct MDRiiLockDataRequest 179 { 180 uint16_t agentId; 181 DataIdStruct dataSetInfo; 182 uint16_t timeout; 183 }; 184 185 // MDR II Pull Agent lock data set response 186 struct MDRiiLockDataResponse 187 { 188 uint8_t mdrVersion; 189 uint16_t lockHandle; 190 uint32_t dataLength; 191 uint32_t xferAddress; 192 uint32_t xferLength; 193 }; 194 195 // MDR II Push Agent send data start command 196 struct MDRiiDataStartRequest 197 { 198 uint16_t agentId; 199 DataIdStruct dataSetInfo; 200 uint32_t dataLength; 201 uint32_t xferAddress; 202 uint32_t xferLength; 203 uint16_t timeout; 204 }; 205 206 // MDR II Client send data start response 207 struct MDRiiDataStartResponse 208 { 209 uint8_t xferStartAck; 210 uint16_t sessionHandle; 211 }; 212 213 // MDR II 214 struct MDRiiDataDoneRequest 215 { 216 uint16_t agentId; 217 uint16_t lockHandle; 218 }; 219 220 #pragma pack(pop) 221 222 class SharedMemoryArea 223 { 224 public: 225 SharedMemoryArea(uint32_t addr, uint32_t areaSize) : 226 vPtr(nullptr), physicalAddr(addr), size(areaSize) 227 { 228 Initialize(addr, areaSize); 229 } 230 231 ~SharedMemoryArea() 232 { 233 if ((vPtr != nullptr) && (vPtr != MAP_FAILED)) 234 { 235 if (0 != munmap(vPtr, size)) 236 { 237 phosphor::logging::log<phosphor::logging::level::ERR>( 238 "Ummap share memory failed"); 239 } 240 } 241 } 242 243 void* vPtr; 244 245 private: 246 uint32_t physicalAddr; 247 uint32_t size; 248 249 void Initialize(uint32_t addr, uint32_t areaSize); 250 }; 251 252 class MDRV2 253 { 254 public: 255 MDRV2() 256 { 257 timer = 258 std::make_unique<phosphor::Timer>([&](void) { timeoutHandler(); }); 259 } 260 261 int agentLookup(const uint16_t& agentId); 262 int findLockHandle(const uint16_t& lockHandle); 263 int syncDirCommonData(uint8_t idIndex, uint32_t size, 264 const std::string& service); 265 int findDataId(const uint8_t* dataInfo, const size_t& len, 266 const std::string& service); 267 uint16_t getSessionHandle(Mdr2DirStruct* dir); 268 bool smbiosIsUpdating(uint8_t index); 269 uint32_t calcChecksum32(uint8_t* buf, uint32_t len); 270 bool storeDatatoFlash(MDRSMBIOSHeader* mdrHdr, uint8_t* data); 271 bool smbiosUnlock(uint8_t index); 272 void timeoutHandler(); 273 bool smbiosTryLock(uint8_t flag, uint8_t index, uint16_t* session, 274 uint16_t timeout); 275 int sdplusMdrv2GetProperty(const std::string& name, 276 std::variant<uint8_t>& value, 277 const std::string& service); 278 279 Mdr2DirStruct smbiosDir{smbiosAgentVersion, 280 1, 281 1, 282 1, 283 0, 284 0, 285 {40, 286 41, 287 42, 288 43, 289 44, 290 45, 291 46, 292 47, 293 48, 294 49, 295 50, 296 51, 297 52, 298 53, 299 54, 300 0x42, 301 0, 302 smbiosTableStorageSize, 303 smbiosTableVersion, 304 smbiosTableTimestamp, 305 MDR2SMBIOSStatusEnum::mdr2Init, 306 MDR2DirLockEnum::mdr2DirUnlock, 307 0, 308 smbiosSMMemoryOffset, 309 smbiosSMMemorySize, 310 smbiosTableStorageSize, 311 smbiosTableStorage}}; 312 std::unique_ptr<SharedMemoryArea> area; 313 std::unique_ptr<phosphor::Timer> timer; 314 315 private: 316 uint8_t lockIndex = 0; 317 uint8_t smbiosTableStorage[smbiosTableStorageSize]; 318 }; 319