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