1fa5e4d32SSunny Srivastava #pragma once 2fa5e4d32SSunny Srivastava 3fa5e4d32SSunny Srivastava #include "logger.hpp" 4fa5e4d32SSunny Srivastava #include "parser_interface.hpp" 5fa5e4d32SSunny Srivastava #include "types.hpp" 6fa5e4d32SSunny Srivastava 7fa5e4d32SSunny Srivastava #include <fstream> 8fa5e4d32SSunny Srivastava #include <string_view> 9fa5e4d32SSunny Srivastava 10fa5e4d32SSunny Srivastava namespace vpd 11fa5e4d32SSunny Srivastava { 12fa5e4d32SSunny Srivastava /** 13fa5e4d32SSunny Srivastava * @brief Concrete class to implement IPZ VPD parsing. 14fa5e4d32SSunny Srivastava * 15fa5e4d32SSunny Srivastava * The class inherits ParserInterface interface class and overrides the parser 16fa5e4d32SSunny Srivastava * functionality to implement parsing logic for IPZ VPD format. 17fa5e4d32SSunny Srivastava */ 18fa5e4d32SSunny Srivastava class IpzVpdParser : public ParserInterface 19fa5e4d32SSunny Srivastava { 20fa5e4d32SSunny Srivastava public: 21fa5e4d32SSunny Srivastava // Deleted APIs 22fa5e4d32SSunny Srivastava IpzVpdParser() = delete; 23fa5e4d32SSunny Srivastava IpzVpdParser(const IpzVpdParser&) = delete; 24fa5e4d32SSunny Srivastava IpzVpdParser& operator=(const IpzVpdParser&) = delete; 25fa5e4d32SSunny Srivastava IpzVpdParser(IpzVpdParser&&) = delete; 26fa5e4d32SSunny Srivastava IpzVpdParser& operator=(IpzVpdParser&&) = delete; 27fa5e4d32SSunny Srivastava 28fa5e4d32SSunny Srivastava /** 29fa5e4d32SSunny Srivastava * @brief Constructor. 30fa5e4d32SSunny Srivastava * 31fa5e4d32SSunny Srivastava * @param[in] vpdVector - VPD data. 32fa5e4d32SSunny Srivastava * @param[in] vpdFilePath - Path to VPD EEPROM. 33fa5e4d32SSunny Srivastava * @param[in] vpdStartOffset - Offset from where VPD starts in the file. 34fa5e4d32SSunny Srivastava * Defaulted to 0. 35fa5e4d32SSunny Srivastava */ IpzVpdParser(const types::BinaryVector & vpdVector,const std::string & vpdFilePath,size_t vpdStartOffset=0)36fa5e4d32SSunny Srivastava IpzVpdParser(const types::BinaryVector& vpdVector, 37fa5e4d32SSunny Srivastava const std::string& vpdFilePath, size_t vpdStartOffset = 0) : 38fa5e4d32SSunny Srivastava m_vpdVector(vpdVector), m_vpdFilePath(vpdFilePath), 39fa5e4d32SSunny Srivastava m_vpdStartOffset(vpdStartOffset) 40fa5e4d32SSunny Srivastava { 41fa5e4d32SSunny Srivastava try 42fa5e4d32SSunny Srivastava { 43fa5e4d32SSunny Srivastava m_vpdFileStream.exceptions( 44fa5e4d32SSunny Srivastava std::ifstream::badbit | std::ifstream::failbit); 45fa5e4d32SSunny Srivastava m_vpdFileStream.open(vpdFilePath, std::ios::in | std::ios::out | 46fa5e4d32SSunny Srivastava std::ios::binary); 47fa5e4d32SSunny Srivastava } 48fa5e4d32SSunny Srivastava catch (const std::fstream::failure& e) 49fa5e4d32SSunny Srivastava { 50fa5e4d32SSunny Srivastava logging::logMessage(e.what()); 51fa5e4d32SSunny Srivastava } 52fa5e4d32SSunny Srivastava } 53fa5e4d32SSunny Srivastava 54fa5e4d32SSunny Srivastava /** 55fa5e4d32SSunny Srivastava * @brief Defaul destructor. 56fa5e4d32SSunny Srivastava */ 57fa5e4d32SSunny Srivastava ~IpzVpdParser() = default; 58fa5e4d32SSunny Srivastava 59fa5e4d32SSunny Srivastava /** 60fa5e4d32SSunny Srivastava * @brief API to parse IPZ VPD file. 61fa5e4d32SSunny Srivastava * 62fa5e4d32SSunny Srivastava * Note: Caller needs to check validity of the map returned. Throws 63fa5e4d32SSunny Srivastava * exception in certain situation, needs to be handled accordingly. 64fa5e4d32SSunny Srivastava * 65fa5e4d32SSunny Srivastava * @return parsed VPD data. 66fa5e4d32SSunny Srivastava */ 67fa5e4d32SSunny Srivastava virtual types::VPDMapVariant parse() override; 68fa5e4d32SSunny Srivastava 69fa5e4d32SSunny Srivastava /** 70fa5e4d32SSunny Srivastava * @brief API to check validity of VPD header. 71fa5e4d32SSunny Srivastava * 72fa5e4d32SSunny Srivastava * Note: The API throws exception in case of any failure or malformed VDP. 73fa5e4d32SSunny Srivastava * 74fa5e4d32SSunny Srivastava * @param[in] itrToVPD - Iterator to the beginning of VPD file. 75fa5e4d32SSunny Srivastava * Don't change the parameter to reference as movement of passsed iterator 76fa5e4d32SSunny Srivastava * to an offset is not required after header check. 77fa5e4d32SSunny Srivastava */ 78fa5e4d32SSunny Srivastava void checkHeader(types::BinaryVector::const_iterator itrToVPD); 79fa5e4d32SSunny Srivastava 80fa5e4d32SSunny Srivastava /** 81fa5e4d32SSunny Srivastava * @brief API to read keyword's value from hardware 82fa5e4d32SSunny Srivastava * 83fa5e4d32SSunny Srivastava * @param[in] i_paramsToReadData - Data required to perform read 84fa5e4d32SSunny Srivastava * 85fa5e4d32SSunny Srivastava * @throw 86fa5e4d32SSunny Srivastava * sdbusplus::xyz::openbmc_project::Common::Device::Error::ReadFailure. 87fa5e4d32SSunny Srivastava * 88fa5e4d32SSunny Srivastava * @return On success return the value read. On failure throw exception. 89fa5e4d32SSunny Srivastava */ 90*43fedabcSPatrick Williams types::DbusVariantType readKeywordFromHardware( 91*43fedabcSPatrick Williams const types::ReadVpdParams i_paramsToReadData); 92fa5e4d32SSunny Srivastava 93fa5e4d32SSunny Srivastava /** 94fa5e4d32SSunny Srivastava * @brief API to write keyword's value on hardware. 95fa5e4d32SSunny Srivastava * 96fa5e4d32SSunny Srivastava * @param[in] i_paramsToWriteData - Data required to perform write. 97fa5e4d32SSunny Srivastava * 98fa5e4d32SSunny Srivastava * @throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument. 99fa5e4d32SSunny Srivastava * @throw sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed. 100fa5e4d32SSunny Srivastava * @throw DataException 101fa5e4d32SSunny Srivastava * @throw EccException 102fa5e4d32SSunny Srivastava * 103fa5e4d32SSunny Srivastava * 104fa5e4d32SSunny Srivastava * @return On success returns number of bytes written on hardware, On 105fa5e4d32SSunny Srivastava * failure throws exception. 106fa5e4d32SSunny Srivastava */ 107fa5e4d32SSunny Srivastava int writeKeywordOnHardware(const types::WriteVpdParams i_paramsToWriteData); 108fa5e4d32SSunny Srivastava 109fa5e4d32SSunny Srivastava private: 110fa5e4d32SSunny Srivastava /** 111fa5e4d32SSunny Srivastava * @brief Check ECC of VPD header. 112fa5e4d32SSunny Srivastava * 113fa5e4d32SSunny Srivastava * @return true/false based on check result. 114fa5e4d32SSunny Srivastava */ 115fa5e4d32SSunny Srivastava bool vhdrEccCheck(); 116fa5e4d32SSunny Srivastava 117fa5e4d32SSunny Srivastava /** 118fa5e4d32SSunny Srivastava * @brief Check ECC of VTOC. 119fa5e4d32SSunny Srivastava * 120fa5e4d32SSunny Srivastava * @return true/false based on check result. 121fa5e4d32SSunny Srivastava */ 122fa5e4d32SSunny Srivastava bool vtocEccCheck(); 123fa5e4d32SSunny Srivastava 124fa5e4d32SSunny Srivastava /** 125fa5e4d32SSunny Srivastava * @brief Check ECC of a record. 126fa5e4d32SSunny Srivastava * 127fa5e4d32SSunny Srivastava * Note: Throws exception in case of failure. Caller need to handle as 128fa5e4d32SSunny Srivastava * required. 129fa5e4d32SSunny Srivastava * 130fa5e4d32SSunny Srivastava * @param[in] iterator - Iterator to the record. 131fa5e4d32SSunny Srivastava * @return success/failre 132fa5e4d32SSunny Srivastava */ 133fa5e4d32SSunny Srivastava bool recordEccCheck(types::BinaryVector::const_iterator iterator); 134fa5e4d32SSunny Srivastava 135fa5e4d32SSunny Srivastava /** 136fa5e4d32SSunny Srivastava * @brief API to read VTOC record. 137fa5e4d32SSunny Srivastava * 138fa5e4d32SSunny Srivastava * The API reads VTOC record and returns the length of PT keyword. 139fa5e4d32SSunny Srivastava * 140fa5e4d32SSunny Srivastava * Note: Throws exception in case of any error. Caller need to handle as 141fa5e4d32SSunny Srivastava * required. 142fa5e4d32SSunny Srivastava * 143fa5e4d32SSunny Srivastava * @param[in] itrToVPD - Iterator to begining of VPD data. 144fa5e4d32SSunny Srivastava * @return Length of PT keyword. 145fa5e4d32SSunny Srivastava */ 146fa5e4d32SSunny Srivastava auto readTOC(types::BinaryVector::const_iterator& itrToVPD); 147fa5e4d32SSunny Srivastava 148fa5e4d32SSunny Srivastava /** 149fa5e4d32SSunny Srivastava * @brief API to read PT record. 150fa5e4d32SSunny Srivastava * 151fa5e4d32SSunny Srivastava * Note: Throws exception in case ECC check fails. 152fa5e4d32SSunny Srivastava * 153fa5e4d32SSunny Srivastava * @param[in] itrToPT - Iterator to PT record in VPD vector. 154fa5e4d32SSunny Srivastava * @param[in] ptLength - length of the PT record. 155fa5e4d32SSunny Srivastava * @return List of record's offset. 156fa5e4d32SSunny Srivastava */ 157fa5e4d32SSunny Srivastava types::RecordOffsetList readPT(types::BinaryVector::const_iterator& itrToPT, 158fa5e4d32SSunny Srivastava auto ptLength); 159fa5e4d32SSunny Srivastava 160fa5e4d32SSunny Srivastava /** 161fa5e4d32SSunny Srivastava * @brief API to read keyword data based on its encoding type. 162fa5e4d32SSunny Srivastava * 163fa5e4d32SSunny Srivastava * @param[in] kwdName - Name of the keyword. 164fa5e4d32SSunny Srivastava * @param[in] kwdDataLength - Length of keyword data. 165fa5e4d32SSunny Srivastava * @param[in] itrToKwdData - Iterator to start of keyword data. 166fa5e4d32SSunny Srivastava * @return keyword data, empty otherwise. 167fa5e4d32SSunny Srivastava */ 168fa5e4d32SSunny Srivastava std::string readKwData(std::string_view kwdName, std::size_t kwdDataLength, 169fa5e4d32SSunny Srivastava types::BinaryVector::const_iterator itrToKwdData); 170fa5e4d32SSunny Srivastava 171fa5e4d32SSunny Srivastava /** 172fa5e4d32SSunny Srivastava * @brief API to read keyword and its value under a record. 173fa5e4d32SSunny Srivastava * 174fa5e4d32SSunny Srivastava * @param[in] iterator - pointer to the start of keywords under the record. 175fa5e4d32SSunny Srivastava * @return keyword-value map of keywords under that record. 176fa5e4d32SSunny Srivastava */ 177*43fedabcSPatrick Williams types::IPZVpdMap::mapped_type readKeywords( 178*43fedabcSPatrick Williams types::BinaryVector::const_iterator& itrToKwds); 179fa5e4d32SSunny Srivastava 180fa5e4d32SSunny Srivastava /** 181fa5e4d32SSunny Srivastava * @brief API to process a record. 182fa5e4d32SSunny Srivastava * 183fa5e4d32SSunny Srivastava * @param[in] recordOffset - Offset of the record in VPD. 184fa5e4d32SSunny Srivastava */ 185fa5e4d32SSunny Srivastava void processRecord(auto recordOffset); 186fa5e4d32SSunny Srivastava 187fa5e4d32SSunny Srivastava /** 188fa5e4d32SSunny Srivastava * @brief Get keyword's value from record 189fa5e4d32SSunny Srivastava * 190fa5e4d32SSunny Srivastava * @param[in] i_record - Record's name 191fa5e4d32SSunny Srivastava * @param[in] i_keyword - Keyword's name 192fa5e4d32SSunny Srivastava * @param[in] i_recordDataOffset - Record's offset value 193fa5e4d32SSunny Srivastava * 194fa5e4d32SSunny Srivastava * @throw std::runtime_error 195fa5e4d32SSunny Srivastava * 196fa5e4d32SSunny Srivastava * @return On success return bytes read, on failure throws error. 197fa5e4d32SSunny Srivastava */ 198fa5e4d32SSunny Srivastava types::BinaryVector getKeywordValueFromRecord( 199fa5e4d32SSunny Srivastava const types::Record& i_recordName, const types::Keyword& i_keywordName, 200fa5e4d32SSunny Srivastava const types::RecordOffset& i_recordDataOffset); 201fa5e4d32SSunny Srivastava 202fa5e4d32SSunny Srivastava /** 203fa5e4d32SSunny Srivastava * @brief Get record's details from VTOC's PT keyword value 204fa5e4d32SSunny Srivastava * 205fa5e4d32SSunny Srivastava * This API parses through VTOC's PT keyword value and returns the given 206fa5e4d32SSunny Srivastava * record's offset, record's length, ECC offset and ECC length. 207fa5e4d32SSunny Srivastava * 208fa5e4d32SSunny Srivastava * @param[in] i_record - Record's name. 209fa5e4d32SSunny Srivastava * @param[in] i_vtocOffset - Offset to VTOC record 210fa5e4d32SSunny Srivastava * 211fa5e4d32SSunny Srivastava * @return On success return record's details, on failure return empty 212fa5e4d32SSunny Srivastava * buffer. 213fa5e4d32SSunny Srivastava */ 214*43fedabcSPatrick Williams types::RecordData getRecordDetailsFromVTOC( 215*43fedabcSPatrick Williams const types::Record& l_recordName, 216fa5e4d32SSunny Srivastava const types::RecordOffset& i_vtocOffset); 217fa5e4d32SSunny Srivastava 218fa5e4d32SSunny Srivastava /** 219fa5e4d32SSunny Srivastava * @brief API to update record's ECC 220fa5e4d32SSunny Srivastava * 221fa5e4d32SSunny Srivastava * This API is required to update the record's ECC based on the record's 222fa5e4d32SSunny Srivastava * current data. 223fa5e4d32SSunny Srivastava * 224fa5e4d32SSunny Srivastava * @param[in] i_recordDataOffset - Record's data offset 225fa5e4d32SSunny Srivastava * @param[in] i_recordDataLength - Record's data length 226fa5e4d32SSunny Srivastava * @param[in] i_recordECCOffset - Record's ECC offset 227fa5e4d32SSunny Srivastava * @param[in] i_recordECCLength - Record's ECC length 228fa5e4d32SSunny Srivastava * @param[in,out] io_vpdVector - FRU VPD in vector to update record's ECC. 229fa5e4d32SSunny Srivastava * 230fa5e4d32SSunny Srivastava * @throw EccException 231fa5e4d32SSunny Srivastava */ 232fa5e4d32SSunny Srivastava void updateRecordECC(const auto& i_recordDataOffset, 233fa5e4d32SSunny Srivastava const auto& i_recordDataLength, 234fa5e4d32SSunny Srivastava const auto& i_recordECCOffset, 235fa5e4d32SSunny Srivastava size_t i_recordECCLength, 236fa5e4d32SSunny Srivastava types::BinaryVector& io_vpdVector); 237fa5e4d32SSunny Srivastava 238fa5e4d32SSunny Srivastava /** 239fa5e4d32SSunny Srivastava * @brief API to set record's keyword's value on hardware. 240fa5e4d32SSunny Srivastava * 241fa5e4d32SSunny Srivastava * @param[in] i_recordName - Record name. 242fa5e4d32SSunny Srivastava * @param[in] i_keywordName - Keyword name. 243fa5e4d32SSunny Srivastava * @param[in] i_keywordData - Keyword data. 244fa5e4d32SSunny Srivastava * @param[in] i_recordDataOffset - Offset to record's data. 245fa5e4d32SSunny Srivastava * @param[in,out] io_vpdVector - FRU VPD in vector to read and write 246fa5e4d32SSunny Srivastava * keyword's value. 247fa5e4d32SSunny Srivastava * 248fa5e4d32SSunny Srivastava * @throw DataException 249fa5e4d32SSunny Srivastava * 250fa5e4d32SSunny Srivastava * @return On success returns number of bytes set. On failure returns -1. 251fa5e4d32SSunny Srivastava */ 252fa5e4d32SSunny Srivastava int setKeywordValueInRecord(const types::Record& i_recordName, 253fa5e4d32SSunny Srivastava const types::Keyword& i_keywordName, 254fa5e4d32SSunny Srivastava const types::BinaryVector& i_keywordData, 255fa5e4d32SSunny Srivastava const types::RecordOffset& i_recordDataOffset, 256fa5e4d32SSunny Srivastava types::BinaryVector& io_vpdVector); 257fa5e4d32SSunny Srivastava 258fa5e4d32SSunny Srivastava // Holds VPD data. 259fa5e4d32SSunny Srivastava const types::BinaryVector& m_vpdVector; 260fa5e4d32SSunny Srivastava 261fa5e4d32SSunny Srivastava // stores parsed VPD data. 262fa5e4d32SSunny Srivastava types::IPZVpdMap m_parsedVPDMap{}; 263fa5e4d32SSunny Srivastava 264fa5e4d32SSunny Srivastava // Holds the VPD file path 265fa5e4d32SSunny Srivastava const std::string& m_vpdFilePath; 266fa5e4d32SSunny Srivastava 267fa5e4d32SSunny Srivastava // Stream to the VPD file. Required to correct ECC 268fa5e4d32SSunny Srivastava std::fstream m_vpdFileStream; 269fa5e4d32SSunny Srivastava 270fa5e4d32SSunny Srivastava // VPD start offset. Required for ECC correction. 271fa5e4d32SSunny Srivastava size_t m_vpdStartOffset = 0; 272fa5e4d32SSunny Srivastava }; 273fa5e4d32SSunny Srivastava } // namespace vpd 274