/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* $Source: src/usr/vpd/ipvpd.H $ */ /* */ /* OpenPOWER HostBoot Project */ /* */ /* Contributors Listed Below - COPYRIGHT 2013,2015 */ /* [+] Google Inc. */ /* [+] International Business Machines Corp. */ /* */ /* */ /* 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. */ /* */ /* IBM_PROLOG_END_TAG */ #ifndef _VPD_IPVPD_H #define _VPD_IPVPD_H #include #include #include #include "vpd.H" /** @file ipvpd.H * @brief Provides base support for i/p-Series style IBM VPD */ /** * @brief Base class for i/p-Series VPD * */ class IpVpdFacade { public: /** * @brief Miscellaneous IPVPD definitions */ enum { RECORD_BYTE_SIZE = 4, RECORD_ADDR_BYTE_SIZE = 2, KEYWORD_BYTE_SIZE = 2, KEYWORD_SIZE_BYTE_SIZE = 1, RECORD_TOC_UNUSED = 2, RT_SKIP_BYTES = 3, VHDR_ECC_DATA_SIZE = 11, VHDR_RESOURCE_ID_SIZE = 1, }; /** * @brief Structure representing the format of each record * in the PT keyword of the VTOC or VHDR. */ struct TocPtRecord { char record_name[4]; // All uint16 fields are stored in little endian. uint16_t record_type; uint16_t record_offset; uint16_t record_length; uint16_t ecc_offset; uint16_t ecc_length; } PACKED; /** * @brief Structure for all VPD dd input parameter arguments */ typedef struct { VPD::vpdRecord record; VPD::vpdKeyword keyword; VPD::vpdCmdTarget location; } input_args_t; /** * @brief Structure of information needed to access requested * record/keyword combinations. */ typedef struct { VPD::vpdRecord record; char recordName[RECORD_BYTE_SIZE+1]; } recordInfo; /** */ typedef struct { VPD::vpdKeyword keyword; char keywordName[KEYWORD_BYTE_SIZE+1]; } keywordInfo; /** * @brief Structure defining where to read/write VPD data */ typedef struct { bool vpdReadPNOR; bool vpdReadHW; bool vpdWritePNOR; bool vpdWriteHW; } configInfo; /** * @brief - Data Struct for TOC Entry */ struct tocData { tocData() { bzero(asciiRec, sizeof(asciiRec)); bzero(offset, sizeof(offset)); bzero(unusedByte, sizeof(unusedByte)); } uint8_t asciiRec[RECORD_BYTE_SIZE]; uint8_t offset[RECORD_ADDR_BYTE_SIZE]; uint8_t unusedByte[RECORD_ADDR_BYTE_SIZE]; }; /** * @brief Constructor * * @param[in] i_vpdSectionSize - Space allocated in PNOR for each * instance of the current chip. * * @param[in] i_vpdMaxSections - Number of sections allocated in PNOR * for the current chip. * * @param[in] i_vpdRecords - Pointer to array of VPD Records to use * * @param[in] i_recSize - size of i_vpdRecords array * * @param[in] i_vpdKeywords - Pointer to array of VPD Keywords to use * * @param[in] i_keyCount - size of i_vpdKeywords array * * @param[in] i_pnorSection - PNOR Section containing VPD for current * chip * * @param[in] i_mutex - Mutex to ensure instance variable updates * are thread safe * * @param[in] i_vpdMsgType - Message type to use when sending write * data to FSP * */ IpVpdFacade(uint64_t i_vpdSectionSize, uint64_t i_vpdMaxSections, const recordInfo* i_vpdRecords, uint64_t i_recSize, const keywordInfo* i_vpdKeywords, uint64_t i_keySize, PNOR::SectionId i_pnorSection, mutex_t i_mutex, VPD::VPD_MSG_TYPE i_vpdMsgType ); /** * @brief This function will perform the steps required to do a read from * the Hostboot I/P Series VPD data. * * @param[in] i_target -Target device * * @param [in/out] io_buffer - Pointer to the data that was read from * the target device. This parameter, when set to NULL, will return * the keyword size value in io_buflen. * * @param [in/out] io_buflen - Length of the buffer to be read or written * to/from the target. This value should indicate the size of the * io_buffer parameter that has been allocated. Being returned it * will indicate the number of valid bytes in the buffer being * returned. This parameter will contain the size of a keyword when * the io_buffer parameter is passed in NULL. * * @param [in] i_args - Records/Keyword struct * * @return errlHndl_t - NULL if successful, otherwise a pointer to the * error log. */ errlHndl_t read ( TARGETING::Target * i_target, void* io_buffer, size_t & io_buflen, input_args_t i_args ); /** * @brief This function will perform the steps required to do a write to * the Hostboot I/P Series VPD data. * * @param[in] i_target -Target device * * @param [in/out] io_buffer - Pointer to the data that was read from * the target device. It will also be used to contain data to * be written to the device. * * @param [in/out] io_buflen - Length of the buffer to be read or written * to/from the target. This value should indicate the size of the * io_buffer parameter that has been allocated. Being returned it * willindicate the number of valid bytes in the buffer being * returned. * * @param [in] i_args - Records/Keyword struct * * @return errlHndl_t - NULL if successful, otherwise a pointer to the * error log. */ errlHndl_t write ( TARGETING::Target * i_target, void* io_buffer, size_t & io_buflen, input_args_t i_args ); /** * @brief this function checks to see if the given target * is present. * * @param[in] i_target - target VPD to search for. * * @return - bool - true if vpd is present, false if it is not. */ bool hasVpdPresent ( TARGETING::Target * i_target, VPD::vpdRecord record, VPD::vpdKeyword keyword ); /** * @brief This function compares the specified record/keyword * in PNOR/SEEPROM and returns the result. A mismatch * will not return an error. * * @param[in] i_target - Target device * * @param[in] i_record - Record to compare * * @param[in] i_keyword - Keyword to compare * * @param[out] o_match - Result of compare * * @return errlHndl_t - NULL if successful, otherwise a pointer to the * error log. */ errlHndl_t cmpPnorToSeeprom ( TARGETING::Target * i_target, VPD::vpdRecord i_record, VPD::vpdKeyword i_keyword, bool &o_match ); /** * @brief This function compares the specified record/keyword * in SEEPROM to zero and returns the result. A mismatch * will not return an error. * * @param[in] i_target - Target device * * @param[in] i_record - Record to compare * * @param[in] i_keyword - Keyword to compare * * @param[out] o_match - Result of compare * * @return errlHndl_t - NULL if successful, otherwise a pointer to the * error log. */ errlHndl_t cmpSeepromToZero ( TARGETING::Target * i_target, VPD::vpdRecord i_record, VPD::vpdKeyword i_keyword, bool &o_match ); /** * @brief This function will perform the steps required to load the * MVPD data from SEEPROM into the PNOR cache. * * @param[in] i_target - Target device * * @return errlHndl_t - NULL if successful, otherwise a pointer to the * error log. */ errlHndl_t loadPnor ( TARGETING::Target * i_target ); /** * @brief This function will perform the steps required to invalidate * the MVPD in the PNOR cache. * * @param[in] i_target - Target device * * @return errlHndl_t - NULL if successful, otherwise a pointer to the * error log. */ errlHndl_t invalidatePnor ( TARGETING::Target * i_target ); /** * @brief This function sets the config flags to use HW and not PNOR */ void setConfigFlagsHW ( ); protected: /** * @brief This function will translate the enumeration for the VPD record * into a char * variable to be used for comparing what was read from * the VPD data. * * @param[in] i_record - The record enumeration. * * @param[out] o_record - The char representation of the record. * * @return errHndl_t - NULL if successful, otherwise a pointer to the * error log. */ errlHndl_t translateRecord ( VPD::vpdRecord i_record, const char *& o_record ); /** * @brief This function will translate the enumeration for the VPD keyword * into a char * variable to be used for comparing what was read from * the VPD data. * * @param[in] i_keyword - The keyword enumeration. * * @param[out] o_keyword - The char representation of the record. * * @return errHndl_t - NULL if successful, otherwise a pointer to the * error log. */ errlHndl_t translateKeyword ( VPD::vpdKeyword i_keyword, const char *& o_keyword ); /** * @brief This function calls the PNOR or EEPROM version of * the findRecordOffset fuction based on the configInfo. * * @param[in] i_record - String value for the record to look for. * * @param[out] o_offset - The offset where the record is located. * * @param[in] i_rwPnorEnabled - Config value specifying * whether PNOR reads/writes are enabled for this VPD type * * @param[in] i_rwHwEnabled - Config value specifying * whether SEEPROM reads/writes are enabled for this VPD type * * @param[in] i_target - The target to retrieve the data for. * * @param[in] i_args - The input arguments. * * @return errHndl_t - NULL if successful, otherwise a pointer to the * error log. */ errlHndl_t findRecordOffset ( const char * i_record, uint16_t & o_offset, bool i_rwPnorEnabled, bool i_rwHwEnabled, TARGETING::Target * i_target, input_args_t i_args ); /** * @brief This function searches for the VPD record and returns * True if it is there, False otherwise. This function works similarly * to findRecordOffsetPnor except it does not create error logs if * the record was not found. This will replace some of the code in * findRecordOffsetPnor * * @param[in] i_record - String value for the record to look for. * * @param[out] offset - The offset where the record is located. * * @param[in] i_target - The target to retrieve the data for. * * @param[in] i_location - VPD location to fetch data from (PNOR/SEEPROM) * * @return bool - True if the record is found, False otherwise. */ bool recordPresent( const char * i_record, uint16_t & offset, TARGETING::Target * i_target, VPD::vpdCmdTarget i_location ); /** * @brief This function will read the VPD TOC to find the offset where the * given record is located within the chunk of data. * * @param[in] i_record - String value for the record to look for. * * @param[out] o_offset - The offset where the record is located. * * @param[in] i_target - The target to retrieve the data for. * * @param[in] i_args - The input arguments. * * @return errHndl_t - NULL if successful, otherwise a pointer to the * error log. */ errlHndl_t findRecordOffsetPnor ( const char * i_record, uint16_t & o_offset, TARGETING::Target * i_target, input_args_t i_args ); /** * @brief This function will read the VPD VTOC to find the offset where the * given record is located within the chunk of data. * * @param[in] i_record - String value for the record to look for. * * @param[out] o_offset - The offset where the record is located. * * @param[out] o_length - The length of the record. * * @param[in] i_target - The target to retrieve the data for. * * @param[in] i_args - The input arguments. * * @return errHndl_t - NULL if successful, otherwise a pointer to the * error log. */ errlHndl_t findRecordOffsetSeeprom ( const char * i_record, uint16_t & o_offset, uint16_t & o_length, TARGETING::Target * i_target, input_args_t i_args ); /** * @brief This function will scan the SEEPROM and return a list of VPD * records for this target. * * @param[out] o_recList - The list of VPD records. * * @param[in] i_target - The target to retrieve the data for. * * @param[in] i_args - The input arguments. * * @return errHndl_t - NULL if successful, otherwise a pointer to the * error log. */ errlHndl_t getRecordListSeeprom ( std::list & o_recList, TARGETING::Target * i_target, input_args_t i_args ); /** * @brief This function will read the required keyword from the VPD data. * * @param[in] i_keywordName - String representation of the keyword. * * @param[in] i_recordName - String representation of the record. * * @param[in] i_offset - The offset to start reading. * * @param[in] i_index - The index of the keyword to return if there are * multiple instances of the same keyword. * * @param[in] i_target - The target to retrieve data for. * * @param[out] io_buffer - The buffer to place the data in. * * @param[in/out] io_buflen - Length of the buffer to be read or written * to/from the target. This value should indicate the size of the * io_buffer parameter that has been allocated. Being returned it * will indicate the number of valid bytes in the buffer being * returned. * * @param[in] i_args - The input arguments. * * @return errHndl_t - NULL if successful, otherwise a pointer to the * error log. */ errlHndl_t retrieveKeyword ( const char * i_keywordName, const char * i_recordName, uint16_t i_offset, uint16_t i_index, TARGETING::Target * i_target, void * io_buffer, size_t & io_buflen, input_args_t i_args ); /** * @brief This function will read the required record from the VPD data. * * @param[in] i_recordName - String representation of the record. * * @param[in] i_offset - The offset to start reading. * * @param[in] i_target - The target to retrieve data for. * * @param[out] io_buffer - The buffer to place the data in. * * @param[in/out] io_buflen - Length of the buffer to be read or written * to/from the target. This value should indicate the size of the * io_buffer parameter that has been allocated. Being returned it * will indicate the number of valid bytes in the buffer being * returned. * * @param[in] i_args - The input arguments. * * @return errHndl_t - NULL if successful, otherwise a pointer to the * error log. */ errlHndl_t retrieveRecord ( const char * i_recordName, uint16_t i_offset, TARGETING::Target * i_target, void * io_buffer, size_t & io_buflen, input_args_t i_args ); /** * @brief This function will write the required keyword into the VPD data. * * @param[in] i_keywordName - String representation of the keyword. * * @param[in] i_recordName - String representation of the record. * * @param[in] i_offset - The offset to start writing. * * @param[in] i_target - The target to write data for. * * @param[in] i_buffer - The buffer to pull the data from. * * @param[in] i_buflen - Length of the buffer to be written * to the target's VPD area. This value should indicate the * size of the io_buffer parameter that has been allocated. * * @param[in] i_args - The input arguments. * * @return errHndl_t - NULL if successful, otherwise a pointer to the * error log. */ errlHndl_t writeKeyword ( const char * i_keywordName, const char * i_recordName, uint16_t i_offset, TARGETING::Target * i_target, void * i_buffer, size_t & i_buflen, input_args_t i_args ); /** * @brief This function will locate the byte address of a keyword * within its VPD section. * * @param[in] i_keywordName - String representation of the keyword. * * @param[in] i_recordName - String representation of the record. * * @param[in] i_offset - The offset to start searching. * * @param[in] i_index - The index of the keyword to return if there are * multiple instances of the same keyword. * * @param[in] i_target - The target to write data for. * * @param[out] o_keywordSize - Size of keyword in bytes. * * @param[out] o_byteAddr - Address of keyword, relative to this target's * section. * * @param[in] i_args - The original input arguments. * * @return errHndl_t - NULL if successful, otherwise a pointer to the * error log. */ errlHndl_t findKeywordAddr ( const char * i_keywordName, const char * i_recordName, uint16_t i_offset, uint16_t i_index, TARGETING::Target * i_target, size_t& o_keywordSize, uint64_t& o_byteAddr, input_args_t i_args ); /** * @brief This function calls the PNOR or EEPROM version of * the fetchData function based on the configInfo * * @param[in] i_byteAddr - The offset to be read. * * @param[in] i_numBytes - The number of bytes to read. * * @param[out] o_data - The data buffer where the data will be placed. * * @param[in] i_target - Target device. * * @param[in] i_location - VPD location to fetch data from (PNOR/SEEPROM) * * @return errHndl_t - NULL if successful, otherwise a pointer to the * error log. */ errlHndl_t fetchData ( uint64_t i_byteAddr, size_t i_numBytes, void * o_data, TARGETING::Target * i_target, VPD::vpdCmdTarget i_location ); /** * @brief This function actually reads the data from PNOR * * @param[in] i_byteAddr - The offset to be read. * * @param[in] i_numBytes - The number of bytes to read. * * @param[out] o_data - The data buffer where the data will be placed. * * @param[in] i_target - Target device. * * @return errHndl_t - NULL if successful, otherwise a pointer to the * error log. */ errlHndl_t fetchDataFromPnor ( uint64_t i_byteAddr, size_t i_numBytes, void * o_data, TARGETING::Target * i_target ); /** * @brief This function actually reads the data from EEPROM * * @param[in] i_byteAddr - The offset to be read. * * @param[in] i_numBytes - The number of bytes to read. * * @param[out] o_data - The data buffer where the data will be placed. * * @param[in] i_target - Target device. * * @return errHndl_t - NULL if successful, otherwise a pointer to the * error log. */ errlHndl_t fetchDataFromEeprom ( uint64_t i_byteAddr, size_t i_numBytes, void * o_data, TARGETING::Target * i_target ); /** * @brief This function compares 2 ipvpd record values. Used for binary * search to find a match. * * @param[in] e1 - Entry 1 to be compared. * * @param[in] e2 - Entry 2 to be compared. * * @return bool - Whether or not the e2 value is larger than the e1 value. */ static bool compareKeywords ( const keywordInfo e1, const keywordInfo e2 ); /** * @brief This function compares 2 vpd keyword values. Used for binary * search to find a match. * * @param[in] e1 - Entry 1 to be compared. * * @param[in] e2 - Entry 2 to be compared. * * @return bool - Whether or not the e2 value is larger than the e1 value. */ static bool compareRecords ( const recordInfo e1, const recordInfo e2 ); /** * @brief This function compares sizes to be sure buffers are large enough * to handle the data to be put in them. If it is not, it will return * an error. * * @param[in] i_bufferSize - The size of the buffer to check. * * @param[in] i_expectedSize - The minimum size the buffer should be. * * @param[in] i_target - Target device. (Only used for error callout) * * @return errlHndl_t - An error log will be returned if the buffer is not * large enough. */ errlHndl_t checkBufferSize( size_t i_bufferSize, size_t i_expectedSize, TARGETING::Target * i_target ); /** * @brief This function returns a primary and an alternate list of records * that should be copied to pnor. The Alternate list is optional. * * @param[out] o_primaryVpdRecords - Pointer to array of VPD Records to use * * @param[out] o_primaryRecSize - Size of o_primaryVpdRecords array * * @param[out] o_altVpdRecords - Pointer to array of VPD Records to use * * @param[out] o_altRecSize - Size of o_altVpdRecords array * */ virtual void getRecordLists( const recordInfo* & o_primaryVpdRecords, uint64_t & o_primaryRecSize, const recordInfo* & o_altVpdRecords, uint64_t & o_altRecSize); protected: // Variables /** * @brief Indicates allocated space for each chip's VPD * data in PNOR. */ uint64_t iv_vpdSectionSize; /** * @brief Indicates number of VPD sections in PNOR for * current type of chip */ uint64_t iv_vpdMaxSections; public: // Variables /** * @brief Pointer to array of VPD Record information * */ const recordInfo* iv_vpdRecords; /** * @brief Number of VPD Records for current chip * */ uint64_t iv_recSize; protected: // Variables /** * @brief Pointer to array of VPD Keyword information * */ const keywordInfo* iv_vpdKeywords; /** * @brief Number of VPD Keywords for current chip * */ uint64_t iv_keySize; /** * @brief PNOR section enum for vpd type * */ PNOR::SectionId iv_pnorSection; /** * @brief VPD Operation Mutex * */ mutex_t iv_mutex; /** * @brief cached PNOR offset for VPD * */ uint64_t iv_cachePnorAddr; /** * @brief cached PNOR offset for VPD * */ VPD::VPD_MSG_TYPE iv_vpdMsgType; /** * @brief Config defining where to read/write * VPD data */ configInfo iv_configInfo; }; #endif /* _VPD_IPVPD_H */