1 /* 2 // Copyright (c) 2019 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 "cpu.hpp" 19 #include "dimm.hpp" 20 #include "smbios.hpp" 21 #include "system.hpp" 22 23 #include <sys/stat.h> 24 #include <sys/types.h> 25 #include <unistd.h> 26 27 #include <phosphor-logging/elog-errors.hpp> 28 #include <phosphor-logging/log.hpp> 29 #include <sdbusplus/server.hpp> 30 #include <sdbusplus/timer.hpp> 31 #include <smbios.hpp> 32 #include <xyz/openbmc_project/Smbios/MDR_V2/server.hpp> 33 34 static constexpr int limitEntryLen = 0xff; 35 static constexpr uint8_t mdr2Version = 2; 36 static constexpr uint32_t mdr2SMSize = 0x00100000; 37 static constexpr uint32_t mdr2SMBaseAddress = 0x9FF00000; 38 static constexpr const char* mdrType2File = "/var/lib/smbios/smbios2"; 39 static constexpr const char* mdrV2Path = "/xyz/openbmc_project/Smbios/MDR_V2"; 40 41 enum class MDR2SMBIOSStatusEnum 42 { 43 mdr2Init = 0, 44 mdr2Loaded = 1, 45 mdr2Updated = 2, 46 mdr2Updating = 3 47 }; 48 49 enum class MDR2DirLockEnum 50 { 51 mdr2DirUnlock = 0, 52 mdr2DirLock = 1 53 }; 54 55 typedef struct 56 { 57 uint8_t dataInfo[16]; 58 } DataIdStruct; 59 60 typedef struct 61 { 62 DataIdStruct id; 63 uint32_t size; 64 uint32_t dataSetSize; 65 uint32_t dataVersion; 66 uint32_t timestamp; 67 } Mdr2DirEntry; 68 69 typedef struct 70 { 71 Mdr2DirEntry common; 72 MDR2SMBIOSStatusEnum stage; 73 MDR2DirLockEnum lock; 74 uint16_t lockHandle; 75 uint32_t xferBuff; 76 uint32_t xferSize; 77 uint32_t maxDataSize; 78 uint8_t* dataStorage; 79 } Mdr2DirLocalStruct; 80 81 typedef struct 82 { 83 uint8_t agentVersion; 84 uint8_t dirVersion; 85 uint8_t dirEntries; 86 uint8_t status; // valid / locked / etc 87 uint8_t remoteDirVersion; 88 uint16_t sessionHandle; 89 Mdr2DirLocalStruct dir[maxDirEntries]; 90 } Mdr2DirStruct; 91 92 struct MDRSMBIOSHeader 93 { 94 uint8_t dirVer; 95 uint8_t mdrType; 96 uint32_t timestamp; 97 uint32_t dataSize; 98 } __attribute__((packed)); 99 100 namespace phosphor 101 { 102 namespace smbios 103 { 104 105 class MDR_V2 : sdbusplus::server::object::object< 106 sdbusplus::xyz::openbmc_project::Smbios::server::MDR_V2> 107 { 108 public: 109 MDR_V2() = delete; 110 MDR_V2(const MDR_V2&) = delete; 111 MDR_V2& operator=(const MDR_V2&) = delete; 112 MDR_V2(MDR_V2&&) = delete; 113 MDR_V2& operator=(MDR_V2&&) = delete; 114 ~MDR_V2() = default; 115 116 MDR_V2(sdbusplus::bus::bus& bus, const char* path, sd_event* event) : 117 sdbusplus::server::object::object< 118 sdbusplus::xyz::openbmc_project::Smbios::server::MDR_V2>(bus, path), 119 bus(bus), timer(event, [&](void) { agentSynchronizeData(); }) 120 { 121 122 smbiosDir.agentVersion = smbiosAgentVersion; 123 smbiosDir.dirVersion = 1; 124 smbiosDir.dirEntries = 1; 125 directoryEntries(smbiosDir.dirEntries); 126 smbiosDir.status = 1; 127 smbiosDir.remoteDirVersion = 0; 128 129 std::copy(smbiosTableId.begin(), smbiosTableId.end(), 130 smbiosDir.dir[smbiosDirIndex].common.id.dataInfo); 131 132 smbiosDir.dir[smbiosDirIndex].dataStorage = smbiosTableStorage; 133 134 agentSynchronizeData(); 135 } 136 137 std::vector<uint8_t> getDirectoryInformation(uint8_t dirIndex) override; 138 139 std::vector<uint8_t> getDataInformation(uint8_t idIndex) override; 140 141 bool sendDirectoryInformation(uint8_t dirVersion, uint8_t dirIndex, 142 uint8_t returnedEntries, 143 uint8_t remainingEntries, 144 std::vector<uint8_t> dirEntry) override; 145 146 std::vector<uint8_t> getDataOffer() override; 147 148 bool sendDataInformation(uint8_t idIndex, uint8_t flag, uint32_t dataLen, 149 uint32_t dataVer, uint32_t timeStamp) override; 150 151 int findIdIndex(std::vector<uint8_t> dataInfo) override; 152 153 bool agentSynchronizeData() override; 154 155 std::vector<uint32_t> 156 synchronizeDirectoryCommonData(uint8_t idIndex, uint32_t size) override; 157 158 uint8_t directoryEntries(uint8_t value) override; 159 160 private: 161 Timer timer; 162 163 sdbusplus::bus::bus& bus; 164 165 Mdr2DirStruct smbiosDir; 166 167 bool readDataFromFlash(MDRSMBIOSHeader* mdrHdr, uint8_t* data); 168 169 const std::array<uint8_t, 16> smbiosTableId{ 170 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 0x42}; 171 uint8_t smbiosTableStorage[smbiosTableStorageSize]; 172 173 bool smbiosIsUpdating(uint8_t index); 174 bool smbiosIsAvailForUpdate(uint8_t index); 175 inline uint8_t smbiosValidFlag(uint8_t index); 176 void systemInfoUpdate(void); 177 178 int getTotalCpuSlot(void); 179 int getTotalDimmSlot(void); 180 std::vector<std::unique_ptr<Cpu>> cpus; 181 std::vector<std::unique_ptr<Dimm>> dimms; 182 std::unique_ptr<System> system; 183 }; 184 185 } // namespace smbios 186 } // namespace phosphor 187