blob: b47c8ceefc4f4c0e2070b5ace28478754761ddda [file] [log] [blame] [edit]
#include "parser_factory.hpp"
#include "constants.hpp"
#include "ddimm_parser.hpp"
#include "exceptions.hpp"
#include "ipz_parser.hpp"
#include "isdimm_parser.hpp"
#include "keyword_vpd_parser.hpp"
namespace vpd
{
/**
* @brief Type of VPD formats.
*/
enum vpdType
{
IPZ_VPD, /**< IPZ VPD type */
KEYWORD_VPD, /**< Keyword VPD type */
DDR4_DDIMM_MEMORY_VPD, /**< DDR4 DDIMM Memory VPD type */
DDR5_DDIMM_MEMORY_VPD, /**< DDR5 DDIMM Memory VPD type */
DDR4_ISDIMM_MEMORY_VPD, /**< DDR4 ISDIMM Memory VPD type */
DDR5_ISDIMM_MEMORY_VPD, /**< DDR5 ISDIMM Memory VPD type */
INVALID_VPD_FORMAT /**< Invalid VPD type */
};
/**
* @brief API to get the type of VPD.
*
* @param[in] i_vpdVector - VPD file content
*
* @return Type of VPD data, "INVALID_VPD_FORMAT" in case of unknown type.
*/
static vpdType vpdTypeCheck(const types::BinaryVector& i_vpdVector)
{
if (i_vpdVector[constants::IPZ_DATA_START] == constants::IPZ_DATA_START_TAG)
{
return vpdType::IPZ_VPD;
}
else if (i_vpdVector[constants::KW_VPD_DATA_START] ==
constants::KW_VPD_START_TAG)
{
return vpdType::KEYWORD_VPD;
}
else if (((i_vpdVector[constants::SPD_BYTE_3] &
constants::SPD_BYTE_BIT_0_3_MASK) ==
constants::SPD_MODULE_TYPE_DDIMM))
{
std::string l_is11SFormat;
if (i_vpdVector.size() > (constants::DDIMM_11S_BARCODE_START +
constants::DDIMM_11S_BARCODE_LEN))
{
// Read first 3 Bytes to check the 11S bar code format
for (uint8_t l_index = 0; l_index < constants::DDIMM_11S_FORMAT_LEN;
l_index++)
{
l_is11SFormat +=
i_vpdVector[constants::DDIMM_11S_BARCODE_START + l_index];
}
}
if (l_is11SFormat.compare(constants::DDIMM_11S_BARCODE_START_TAG) == 0)
{
// DDIMM memory VPD format
if ((i_vpdVector[constants::SPD_BYTE_2] &
constants::SPD_BYTE_MASK) == constants::SPD_DRAM_TYPE_DDR5)
{
return vpdType::DDR5_DDIMM_MEMORY_VPD;
}
if ((i_vpdVector[constants::SPD_BYTE_2] &
constants::SPD_BYTE_MASK) == constants::SPD_DRAM_TYPE_DDR4)
{
return vpdType::DDR4_DDIMM_MEMORY_VPD;
}
}
logging::logMessage("11S format is not found in the DDIMM VPD.");
return vpdType::INVALID_VPD_FORMAT;
}
else if ((i_vpdVector[constants::SPD_BYTE_2] & constants::SPD_BYTE_MASK) ==
constants::SPD_DRAM_TYPE_DDR5)
{
// ISDIMM memory VPD format
return vpdType::DDR5_ISDIMM_MEMORY_VPD;
}
else if ((i_vpdVector[constants::SPD_BYTE_2] & constants::SPD_BYTE_MASK) ==
constants::SPD_DRAM_TYPE_DDR4)
{
// ISDIMM memory VPD format
return vpdType::DDR4_ISDIMM_MEMORY_VPD;
}
return vpdType::INVALID_VPD_FORMAT;
}
std::shared_ptr<ParserInterface> ParserFactory::getParser(
const types::BinaryVector& i_vpdVector, const std::string& i_vpdFilePath,
size_t i_vpdStartOffset)
{
if (i_vpdVector.empty())
{
throw std::runtime_error(std::string(__FUNCTION__) +
"Empty VPD vector passed to parser factory");
}
vpdType l_type = vpdTypeCheck(i_vpdVector);
switch (l_type)
{
case vpdType::IPZ_VPD:
{
return std::make_shared<IpzVpdParser>(i_vpdVector, i_vpdFilePath,
i_vpdStartOffset);
}
case vpdType::KEYWORD_VPD:
{
return std::make_shared<KeywordVpdParser>(i_vpdVector);
}
case vpdType::DDR5_DDIMM_MEMORY_VPD:
case vpdType::DDR4_DDIMM_MEMORY_VPD:
{
return std::make_shared<DdimmVpdParser>(i_vpdVector);
}
case vpdType::DDR4_ISDIMM_MEMORY_VPD:
case vpdType::DDR5_ISDIMM_MEMORY_VPD:
{
// return shared pointer to class object.
logging::logMessage(
"ISDIMM parser selected for VPD path: " + i_vpdFilePath);
return std::make_shared<JedecSpdParser>(i_vpdVector);
}
default:
throw DataException(
std::string(__FUNCTION__) + "Unable to determine VPD format");
}
}
} // namespace vpd