xref: /openbmc/phosphor-bmc-code-mgmt/i2c-vr/mps/mps.cpp (revision dcf4b607bd2937a8964d68fe9dcc59daaf20c720)
1*dcf4b607SKevin Tung #include "mps.hpp"
2*dcf4b607SKevin Tung 
3*dcf4b607SKevin Tung namespace phosphor::software::VR
4*dcf4b607SKevin Tung {
5*dcf4b607SKevin Tung 
isValidDataTokens(const std::vector<std::string_view> & tokens)6*dcf4b607SKevin Tung bool MPSImageParser::isValidDataTokens(
7*dcf4b607SKevin Tung     const std::vector<std::string_view>& tokens)
8*dcf4b607SKevin Tung {
9*dcf4b607SKevin Tung     return tokens.size() > static_cast<size_t>(ATE::regName) &&
10*dcf4b607SKevin Tung            !tokens[0].starts_with('*');
11*dcf4b607SKevin Tung }
12*dcf4b607SKevin Tung 
extractData(const std::vector<std::string_view> & tokens)13*dcf4b607SKevin Tung MPSData MPSImageParser::extractData(const std::vector<std::string_view>& tokens)
14*dcf4b607SKevin Tung {
15*dcf4b607SKevin Tung     MPSData data;
16*dcf4b607SKevin Tung     data.page = getVal<uint8_t>(tokens, ATE::pageNum);
17*dcf4b607SKevin Tung     data.addr = getVal<uint8_t>(tokens, ATE::regAddrHex);
18*dcf4b607SKevin Tung 
19*dcf4b607SKevin Tung     std::string regData = getVal<std::string>(tokens, ATE::regDataHex);
20*dcf4b607SKevin Tung     size_t byteCount = std::min(regData.length() / 2, size_t(4));
21*dcf4b607SKevin Tung     for (size_t i = 0; i < byteCount; ++i)
22*dcf4b607SKevin Tung     {
23*dcf4b607SKevin Tung         data.data[byteCount - 1 - i] = static_cast<uint8_t>(
24*dcf4b607SKevin Tung             std::stoul(regData.substr(i * 2, 2), nullptr, 16));
25*dcf4b607SKevin Tung     }
26*dcf4b607SKevin Tung 
27*dcf4b607SKevin Tung     data.length = static_cast<uint8_t>(byteCount);
28*dcf4b607SKevin Tung     return data;
29*dcf4b607SKevin Tung }
30*dcf4b607SKevin Tung 
getRegistersData()31*dcf4b607SKevin Tung std::vector<MPSData> MPSImageParser::getRegistersData()
32*dcf4b607SKevin Tung {
33*dcf4b607SKevin Tung     std::vector<MPSData> registersData;
34*dcf4b607SKevin Tung     for (const auto& tokens : lineTokens)
35*dcf4b607SKevin Tung     {
36*dcf4b607SKevin Tung         if (tokens[0].starts_with("END"))
37*dcf4b607SKevin Tung         {
38*dcf4b607SKevin Tung             break;
39*dcf4b607SKevin Tung         }
40*dcf4b607SKevin Tung 
41*dcf4b607SKevin Tung         if (isValidDataTokens(tokens))
42*dcf4b607SKevin Tung         {
43*dcf4b607SKevin Tung             registersData.push_back(extractData(tokens));
44*dcf4b607SKevin Tung         }
45*dcf4b607SKevin Tung     }
46*dcf4b607SKevin Tung     return registersData;
47*dcf4b607SKevin Tung }
48*dcf4b607SKevin Tung 
parseImage(const uint8_t * image,size_t imageSize)49*dcf4b607SKevin Tung sdbusplus::async::task<bool> MPSVoltageRegulator::parseImage(
50*dcf4b607SKevin Tung     const uint8_t* image, size_t imageSize)
51*dcf4b607SKevin Tung {
52*dcf4b607SKevin Tung     parser = std::make_unique<MPSImageParser>(image, imageSize);
53*dcf4b607SKevin Tung 
54*dcf4b607SKevin Tung     configuration = std::make_unique<MPSConfig>();
55*dcf4b607SKevin Tung     configuration->registersData = parser->getRegistersData();
56*dcf4b607SKevin Tung 
57*dcf4b607SKevin Tung     if (!co_await parseDeviceConfiguration())
58*dcf4b607SKevin Tung     {
59*dcf4b607SKevin Tung         co_return false;
60*dcf4b607SKevin Tung     }
61*dcf4b607SKevin Tung 
62*dcf4b607SKevin Tung     lg2::debug(
63*dcf4b607SKevin Tung         "Parsed configuration: Data Size={SIZE}, Vendor ID={VID}, "
64*dcf4b607SKevin Tung         "Product ID={PID}, Config ID={CID}, CRC User={CRCUSR}, "
65*dcf4b607SKevin Tung         "CRC Multi={CRCMULTI}",
66*dcf4b607SKevin Tung         "SIZE", configuration->registersData.size(), "VID", lg2::hex,
67*dcf4b607SKevin Tung         configuration->vendorId, "PID", lg2::hex, configuration->productId,
68*dcf4b607SKevin Tung         "CID", lg2::hex, configuration->configId, "CRCUSR", lg2::hex,
69*dcf4b607SKevin Tung         configuration->crcUser, "CRCMULTI", lg2::hex, configuration->crcMulti);
70*dcf4b607SKevin Tung 
71*dcf4b607SKevin Tung     co_return true;
72*dcf4b607SKevin Tung }
73*dcf4b607SKevin Tung 
74*dcf4b607SKevin Tung std::map<uint8_t, std::vector<MPSData>>
getGroupedConfigData(uint8_t configMask,uint8_t shift)75*dcf4b607SKevin Tung     MPSVoltageRegulator::getGroupedConfigData(uint8_t configMask, uint8_t shift)
76*dcf4b607SKevin Tung {
77*dcf4b607SKevin Tung     std::map<uint8_t, std::vector<MPSData>> groupedData;
78*dcf4b607SKevin Tung 
79*dcf4b607SKevin Tung     if (!configuration)
80*dcf4b607SKevin Tung     {
81*dcf4b607SKevin Tung         return groupedData;
82*dcf4b607SKevin Tung     }
83*dcf4b607SKevin Tung 
84*dcf4b607SKevin Tung     for (const auto& data : configuration->registersData)
85*dcf4b607SKevin Tung     {
86*dcf4b607SKevin Tung         uint8_t config = (data.page & configMask) >> shift;
87*dcf4b607SKevin Tung         groupedData[config].push_back(data);
88*dcf4b607SKevin Tung     }
89*dcf4b607SKevin Tung 
90*dcf4b607SKevin Tung     return groupedData;
91*dcf4b607SKevin Tung }
92*dcf4b607SKevin Tung 
93*dcf4b607SKevin Tung } // namespace phosphor::software::VR
94