| /* |
| // Copyright (c) 2018 Intel Corporation |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| */ |
| |
| #pragma once |
| #include <ipmid/api.h> |
| #include <sys/mman.h> |
| |
| #include <oemcommands.hpp> |
| #include <sdbusplus/timer.hpp> |
| |
| static constexpr const char *mdrType2File = "/var/lib/smbios/smbios2"; |
| static constexpr const char *smbiosPath = "/var/lib/smbios"; |
| static constexpr const size_t msgPayloadSize = |
| 1024 * 60; // Total size will transfer for smbios table |
| static constexpr const size_t mdriiSMSize = 0x00100000; |
| |
| static constexpr const uint16_t smbiosAgentId = |
| 0x0101; // Agent ID for smbios entry |
| static constexpr const int firstAgentIndex = 1; |
| |
| static constexpr const uint8_t maxDirEntries = 4; // Maximum directory entries |
| static constexpr const uint32_t mdr2SMSize = |
| 0x00100000; // Size of VGA share memory |
| static constexpr const uint32_t mdr2SMBaseAddress = |
| 0x9FF00000; // Base address of VGA share memory |
| |
| static constexpr const uint8_t mdrTypeII = 2; // MDR V2 type |
| |
| static constexpr const uint8_t mdr2Version = 2; // MDR V2 versoin |
| static constexpr const uint8_t smbiosAgentVersion = 1; // Agent version of |
| // smbios |
| |
| static constexpr const uint32_t pageMask = |
| 0xf000; // To make data become n times of page |
| static constexpr const int smbiosDirIndex = 0; // SMBIOS directory index |
| |
| static constexpr const uint32_t smbiosTableVersion = |
| 15; // Version of smbios table |
| static constexpr const uint32_t smbiosTableTimestamp = |
| 0x45464748; // Time stamp when smbios table created |
| static constexpr const size_t smbiosSMMemoryOffset = |
| 0; // Offset of VGA share memory |
| static constexpr const size_t smbiosSMMemorySize = |
| 1024 * 1024; // Total size of VGA share memory |
| static constexpr const size_t smbiosTableStorageSize = |
| 64 * 1024; // Total size of smbios table |
| static constexpr const uint32_t defaultTimeout = 200; |
| static constexpr const uint8_t sysClock = 100; |
| static constexpr const int lastAgentIndex = -1; |
| static constexpr const uint16_t lastAgentId = 0xFFFF; |
| constexpr const uint32_t invalidChecksum = 0xffffffff; |
| constexpr const char *dbusProperties = "org.freedesktop.DBus.Properties"; |
| constexpr const char *mdrv2Path = "/xyz/openbmc_project/Smbios/MDR_V2"; |
| constexpr const char *mdrv2Interface = "xyz.openbmc_project.Smbios.MDR_V2"; |
| |
| enum class MDR2SMBIOSStatusEnum |
| { |
| mdr2Init = 0, |
| mdr2Loaded = 1, |
| mdr2Updated = 2, |
| mdr2Updating = 3 |
| }; |
| |
| enum class DirDataRequestEnum |
| { |
| dirDataNotRequested = 0x00, |
| dirDataRequested = 0x01 |
| }; |
| |
| enum MDR2DirLockEnum |
| { |
| mdr2DirUnlock = 0, |
| mdr2DirLock = 1 |
| }; |
| |
| #pragma pack(push) |
| #pragma pack(1) |
| |
| struct MDRSMBIOSHeader |
| { |
| uint8_t dirVer; |
| uint8_t mdrType; |
| uint32_t timestamp; |
| uint32_t dataSize; |
| }; |
| |
| struct DataIdStruct |
| { |
| uint8_t dataInfo[16]; |
| }; |
| |
| struct Mdr2DirEntry |
| { |
| DataIdStruct id; |
| uint32_t size; |
| uint32_t dataSetSize; |
| uint32_t dataVersion; |
| uint32_t timestamp; |
| }; |
| |
| struct Mdr2DirLocalStruct |
| { |
| Mdr2DirEntry common; |
| MDR2SMBIOSStatusEnum stage; |
| MDR2DirLockEnum lock; |
| uint16_t lockHandle; |
| uint32_t xferBuff; |
| uint32_t xferSize; |
| uint32_t maxDataSize; |
| uint8_t *dataStorage; |
| }; |
| |
| struct Mdr2DirStruct |
| { |
| uint8_t agentVersion; |
| uint8_t dirVersion; |
| uint8_t dirEntries; |
| uint8_t status; // valid / locked / etc |
| uint8_t remoteDirVersion; |
| uint16_t sessionHandle; |
| Mdr2DirLocalStruct dir[maxDirEntries]; |
| }; |
| |
| // Three members include dataSetSize, dataVersion and timestamp |
| static constexpr const size_t syncDirCommonSize = 3; |
| |
| // ====================== MDR II Pull Command Structures ====================== |
| // MDR II Pull Agent status inquiry command |
| struct MDRiiGetAgentStatus |
| { |
| uint16_t agentId; |
| uint8_t dirVersion; |
| }; |
| |
| // MDR II status inquiry response |
| struct MDRiiAgentStatusResponse |
| { |
| uint8_t mdrVersion; |
| uint8_t agentVersion; |
| uint8_t dirVersion; |
| uint8_t dirEntries; |
| uint8_t dataRequest; |
| }; |
| |
| struct MDRiiGetDirRequest |
| { |
| uint16_t agentId; |
| uint8_t dirIndex; |
| }; |
| |
| // MDR II directory information inquiry response |
| struct MDRiiGetDirResponse |
| { |
| uint8_t mdrVersion; |
| uint8_t dirVersion; |
| uint8_t returnedEntries; |
| uint8_t remainingEntries; |
| uint8_t data[1]; |
| }; |
| |
| struct MDRiiGetDataInfoRequest |
| { |
| uint16_t agentId; |
| DataIdStruct dataSetInfo; |
| }; |
| |
| // MDR II data set information inquiry response |
| struct MDRiiGetDataInfoResponse |
| { |
| uint8_t mdrVersion; |
| DataIdStruct dataSetId; |
| uint8_t validFlag; |
| uint32_t dataLength; |
| uint32_t dataVersion; |
| uint32_t timeStamp; |
| }; |
| |
| // MDR II Pull Agent get data block command |
| struct MDRiiGetDataBlockRequest |
| { |
| uint16_t agentId; |
| uint16_t lockHandle; |
| uint32_t xferOffset; |
| uint32_t xferLength; |
| }; |
| |
| // MDR II Pull Agent get data block response |
| struct MDRiiGetDataBlockResponse |
| { |
| uint32_t xferLength; |
| uint32_t checksum; |
| uint8_t data[msgPayloadSize]; |
| }; |
| |
| // ====================== MDR II Push Command Structures ====================== |
| // MDR II Push Agent send dir info command |
| struct MDRiiSendDirRequest |
| { |
| uint16_t agentId; |
| uint8_t dirVersion; |
| uint8_t dirIndex; |
| uint8_t returnedEntries; |
| uint8_t remainingEntries; |
| Mdr2DirEntry data[1]; // place holder for N directory entries |
| }; |
| |
| struct MDRiiOfferDataInfo |
| { |
| uint16_t agentId; |
| }; |
| |
| // MDR II Client send data set info offer response |
| struct MDRiiOfferDataInfoResponse |
| { |
| DataIdStruct dataSetInfo; |
| }; |
| |
| // MDR II Push Agent send data set info command |
| struct MDRiiSendDataInfoRequest |
| { |
| uint16_t agentId; |
| DataIdStruct dataSetInfo; |
| uint8_t validFlag; |
| uint32_t dataLength; |
| uint32_t dataVersion; // Roughly equivalent to the "file name" |
| uint32_t |
| timeStamp; // More info on the identity of this particular set of data |
| }; |
| |
| // MDR II Push Agent send data block command |
| struct MDRiiSendDataBlockRequest |
| { |
| uint16_t agentId; |
| uint16_t lockHandle; |
| uint32_t xferOffset; |
| uint32_t xferLength; |
| uint32_t checksum; |
| }; |
| |
| // MDR II Pull Agent lock data set command |
| struct MDRiiLockDataRequest |
| { |
| uint16_t agentId; |
| DataIdStruct dataSetInfo; |
| uint16_t timeout; |
| }; |
| |
| // MDR II Pull Agent lock data set response |
| struct MDRiiLockDataResponse |
| { |
| uint8_t mdrVersion; |
| uint16_t lockHandle; |
| uint32_t dataLength; |
| uint32_t xferAddress; |
| uint32_t xferLength; |
| }; |
| |
| // MDR II Pull Agent unlock data set command |
| struct MDRiiUnlockDataRequest |
| { |
| uint16_t agentId; |
| uint16_t lockHandle; |
| }; |
| |
| // MDR II Push Agent send data start command |
| struct MDRiiDataStartRequest |
| { |
| uint16_t agentId; |
| DataIdStruct dataSetInfo; |
| uint32_t dataLength; |
| uint32_t xferAddress; |
| uint32_t xferLength; |
| uint16_t timeout; |
| }; |
| |
| // MDR II Client send data start response |
| struct MDRiiDataStartResponse |
| { |
| uint8_t xferStartAck; |
| uint16_t sessionHandle; |
| }; |
| |
| // MDR II |
| struct MDRiiDataDoneRequest |
| { |
| uint16_t agentId; |
| uint16_t lockHandle; |
| }; |
| |
| #pragma pack(pop) |
| |
| class SharedMemoryArea |
| { |
| public: |
| SharedMemoryArea(uint32_t addr, uint32_t areaSize) : |
| vPtr(nullptr), physicalAddr(addr), size(areaSize) |
| { |
| Initialize(addr, areaSize); |
| } |
| |
| ~SharedMemoryArea() |
| { |
| if ((vPtr != nullptr) && (vPtr != MAP_FAILED)) |
| { |
| if (0 != munmap(vPtr, size)) |
| { |
| phosphor::logging::log<phosphor::logging::level::ERR>( |
| "Ummap share memory failed"); |
| } |
| } |
| } |
| |
| void *vPtr; |
| |
| private: |
| uint32_t physicalAddr; |
| uint32_t size; |
| |
| void Initialize(uint32_t addr, uint32_t areaSize); |
| }; |
| |
| class MDRV2 |
| { |
| public: |
| MDRV2() |
| { |
| timer = |
| std::make_unique<phosphor::Timer>([&](void) { timeoutHandler(); }); |
| } |
| |
| int agentLookup(const uint16_t &agentId); |
| int findLockHandle(const uint16_t &lockHandle); |
| int syncDirCommonData(uint8_t idIndex, uint32_t size, |
| const std::string &service); |
| int findDataId(const uint8_t *dataInfo, const size_t &len, |
| const std::string &service); |
| uint16_t getSessionHandle(Mdr2DirStruct *dir); |
| bool smbiosIsUpdating(uint8_t index); |
| uint32_t calcChecksum32(uint8_t *buf, uint32_t len); |
| bool storeDatatoFlash(MDRSMBIOSHeader *mdrHdr, uint8_t *data); |
| bool smbiosUnlock(uint8_t index); |
| void timeoutHandler(); |
| bool smbiosTryLock(uint8_t flag, uint8_t index, uint16_t *session, |
| uint16_t timeout); |
| int sdplusMdrv2GetProperty(const std::string &name, |
| sdbusplus::message::variant<uint8_t> &value, |
| const std::string &service); |
| |
| Mdr2DirStruct smbiosDir{smbiosAgentVersion, |
| 1, |
| 1, |
| 1, |
| 0, |
| 0, |
| {40, |
| 41, |
| 42, |
| 43, |
| 44, |
| 45, |
| 46, |
| 47, |
| 48, |
| 49, |
| 50, |
| 51, |
| 52, |
| 53, |
| 54, |
| 0x42, |
| 0, |
| smbiosTableStorageSize, |
| smbiosTableVersion, |
| smbiosTableTimestamp, |
| MDR2SMBIOSStatusEnum::mdr2Init, |
| MDR2DirLockEnum::mdr2DirUnlock, |
| 0, |
| smbiosSMMemoryOffset, |
| smbiosSMMemorySize, |
| smbiosTableStorageSize, |
| smbiosTableStorage}}; |
| std::unique_ptr<SharedMemoryArea> area; |
| std::unique_ptr<phosphor::Timer> timer; |
| |
| private: |
| uint8_t lockIndex = 0; |
| uint8_t smbiosTableStorage[smbiosTableStorageSize]; |
| }; |