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 #include <types.hpp> 24 25 static constexpr const char* mdrType2File = "/var/lib/smbios/smbios2"; 26 static constexpr const char* smbiosPath = "/var/lib/smbios"; 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 = 37 0x00100000; // Size of VGA share memory 38 static constexpr const uint32_t mdr2SMBaseAddress = 39 0x9FF00000; // Base address of VGA share memory 40 41 static constexpr const uint8_t mdrTypeII = 2; // MDR V2 type 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 = 52 15; // Version of smbios table 53 static constexpr const uint32_t smbiosTableTimestamp = 54 0x45464748; // Time stamp when smbios table created 55 static constexpr const size_t smbiosSMMemoryOffset = 56 0; // Offset of VGA share memory 57 static constexpr const size_t smbiosSMMemorySize = 58 1024 * 1024; // Total size of VGA share memory 59 static constexpr const size_t smbiosTableStorageSize = 60 64 * 1024; // Total size of smbios table 61 static constexpr const uint32_t defaultTimeout = 4000; 62 static constexpr const uint16_t sysClock = 1000; 63 static constexpr const int lastAgentIndex = -1; 64 static constexpr const uint16_t lastAgentId = 0xFFFF; 65 constexpr const uint32_t invalidChecksum = 0xffffffff; 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"; 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; 124 uint8_t* dataStorage; 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 ====================== 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; 155 uint8_t dataVersion; 156 uint32_t timeStamp; 157 }; 158 159 // ====================== MDR II Push Command Structures ====================== 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 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 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: SharedMemoryArea(uint32_t addr,uint32_t areaSize)226 SharedMemoryArea(uint32_t addr, uint32_t areaSize) : 227 vPtr(nullptr), physicalAddr(addr), size(areaSize) 228 { 229 Initialize(addr, areaSize); 230 } 231 ~SharedMemoryArea()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 244 void* vPtr; 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: MDRV2()256 MDRV2() 257 { 258 timer = 259 std::make_unique<sdbusplus::Timer>([&](void) { timeoutHandler(); }); 260 } 261 262 int agentLookup(const uint16_t& agentId); 263 int findLockHandle(const uint16_t& lockHandle); 264 int syncDirCommonData(uint8_t idIndex, uint32_t size, 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); 269 bool smbiosIsUpdating(uint8_t index); 270 uint32_t calcChecksum32(uint8_t* buf, uint32_t len); 271 bool storeDatatoFlash(MDRSMBIOSHeader* mdrHdr, uint8_t* data); 272 bool smbiosUnlock(uint8_t index); 273 void timeoutHandler(); 274 bool smbiosTryLock(uint8_t flag, uint8_t index, uint16_t* session, 275 uint16_t timeout); 276 int sdplusMdrv2GetProperty(const std::string& name, 277 ipmi::DbusVariant& value, 278 const std::string& service); 279 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}}; 314 std::unique_ptr<SharedMemoryArea> area; 315 std::unique_ptr<sdbusplus::Timer> timer; 316 317 private: 318 uint8_t lockIndex = 0; 319 uint8_t smbiosTableStorage[smbiosTableStorageSize]; 320 }; 321