1a9b44344SZane Shelley #include <analyzer/ras-data/ras-data-parser.hpp>
2a9b44344SZane Shelley #include <util/data_file.hpp>
3a9b44344SZane Shelley #include <util/trace.hpp>
4a9b44344SZane Shelley 
5a9b44344SZane Shelley #include <filesystem>
6a9b44344SZane Shelley #include <fstream>
702d59af5SZane Shelley #include <stdexcept>
8a9b44344SZane Shelley #include <string>
9a9b44344SZane Shelley 
10a9b44344SZane Shelley namespace fs = std::filesystem;
11a9b44344SZane Shelley 
12a9b44344SZane Shelley namespace analyzer
13a9b44344SZane Shelley {
14a9b44344SZane Shelley //------------------------------------------------------------------------------
15a9b44344SZane Shelley 
16a9b44344SZane Shelley std::shared_ptr<Resolution>
getResolution(const libhei::Signature & i_signature)177698b304SZane Shelley     RasDataParser::getResolution(const libhei::Signature& i_signature)
18a9b44344SZane Shelley {
192fbd267eSZane Shelley     nlohmann::json data;
202fbd267eSZane Shelley 
212fbd267eSZane Shelley     try
222fbd267eSZane Shelley     {
232fbd267eSZane Shelley         data = iv_dataFiles.at(i_signature.getChip().getType());
242fbd267eSZane Shelley     }
252fbd267eSZane Shelley     catch (const std::out_of_range& e)
262fbd267eSZane Shelley     {
272fbd267eSZane Shelley         trace::err("No RAS data defined for chip type: 0x%08x",
282fbd267eSZane Shelley                    i_signature.getChip().getType());
292fbd267eSZane Shelley         throw; // caught later downstream
302fbd267eSZane Shelley     }
317698b304SZane Shelley 
327698b304SZane Shelley     const auto action = parseSignature(data, i_signature);
337698b304SZane Shelley 
342fbd267eSZane Shelley     std::shared_ptr<Resolution> resolution;
352fbd267eSZane Shelley 
362fbd267eSZane Shelley     try
372fbd267eSZane Shelley     {
382fbd267eSZane Shelley         resolution = parseAction(data, action);
392fbd267eSZane Shelley     }
402fbd267eSZane Shelley     catch (...)
412fbd267eSZane Shelley     {
422fbd267eSZane Shelley         trace::err("Unable to get resolution for action: %s", action.c_str());
432fbd267eSZane Shelley         throw; // caught later downstream
442fbd267eSZane Shelley     }
452fbd267eSZane Shelley 
462fbd267eSZane Shelley     return resolution;
47a9b44344SZane Shelley }
48a9b44344SZane Shelley 
49a9b44344SZane Shelley //------------------------------------------------------------------------------
50a9b44344SZane Shelley 
__checkActionForFlag(const std::string & i_action,const std::string & i_flag,const nlohmann::json & i_data)511a4f0e70SCaleb Palmer bool __checkActionForFlag(const std::string& i_action,
521a4f0e70SCaleb Palmer                           const std::string& i_flag,
531a4f0e70SCaleb Palmer                           const nlohmann::json& i_data)
541a4f0e70SCaleb Palmer {
551a4f0e70SCaleb Palmer     bool o_isFlagSet = false;
561a4f0e70SCaleb Palmer 
571a4f0e70SCaleb Palmer     // Loop through the array of actions.
581a4f0e70SCaleb Palmer     for (const auto& a : i_data.at("actions").at(i_action))
591a4f0e70SCaleb Palmer     {
601a4f0e70SCaleb Palmer         // Get the action type
611a4f0e70SCaleb Palmer         auto type = a.at("type").get<std::string>();
621a4f0e70SCaleb Palmer 
631a4f0e70SCaleb Palmer         // If the action is another action, recursively call this function
641a4f0e70SCaleb Palmer         if ("action" == type)
651a4f0e70SCaleb Palmer         {
661a4f0e70SCaleb Palmer             auto name = a.at("name").get<std::string>();
671a4f0e70SCaleb Palmer             o_isFlagSet = __checkActionForFlag(name, i_flag, i_data);
681a4f0e70SCaleb Palmer             if (o_isFlagSet)
691a4f0e70SCaleb Palmer             {
701a4f0e70SCaleb Palmer                 break;
711a4f0e70SCaleb Palmer             }
721a4f0e70SCaleb Palmer         }
731a4f0e70SCaleb Palmer         // If the action is a flag, check if it's the one
741a4f0e70SCaleb Palmer         else if ("flag" == type)
751a4f0e70SCaleb Palmer         {
761a4f0e70SCaleb Palmer             auto name = a.at("name").get<std::string>();
771a4f0e70SCaleb Palmer             if (name == i_flag)
781a4f0e70SCaleb Palmer             {
791a4f0e70SCaleb Palmer                 o_isFlagSet = true;
801a4f0e70SCaleb Palmer                 break;
811a4f0e70SCaleb Palmer             }
821a4f0e70SCaleb Palmer         }
831a4f0e70SCaleb Palmer     }
841a4f0e70SCaleb Palmer 
851a4f0e70SCaleb Palmer     return o_isFlagSet;
861a4f0e70SCaleb Palmer }
871a4f0e70SCaleb Palmer 
881a4f0e70SCaleb Palmer //------------------------------------------------------------------------------
891a4f0e70SCaleb Palmer 
isFlagSet(const libhei::Signature & i_signature,const RasDataFlags i_flag) const90f1184392SCaleb Palmer bool RasDataParser::isFlagSet(const libhei::Signature& i_signature,
911a4f0e70SCaleb Palmer                               const RasDataFlags i_flag) const
92f1184392SCaleb Palmer {
93f1184392SCaleb Palmer     bool o_isFlagSet = false;
94f1184392SCaleb Palmer 
95f1184392SCaleb Palmer     // List of all flag enums mapping to their corresponding string
96f1184392SCaleb Palmer     std::map<RasDataFlags, std::string> flagMap = {
97f1184392SCaleb Palmer         {SUE_SOURCE, "sue_source"},
98f1184392SCaleb Palmer         {SUE_SEEN, "sue_seen"},
99f1184392SCaleb Palmer         {CS_POSSIBLE, "cs_possible"},
100f1184392SCaleb Palmer         {RECOVERED_ERROR, "recovered_error"},
101f1184392SCaleb Palmer         {INFORMATIONAL_ONLY, "informational_only"},
102f1184392SCaleb Palmer         {MNFG_INFORMATIONAL_ONLY, "mnfg_informational_only"},
103f1184392SCaleb Palmer         {MASK_BUT_DONT_CLEAR, "mask_but_dont_clear"},
104f1184392SCaleb Palmer         {CRC_RELATED_ERR, "crc_related_err"},
105f1184392SCaleb Palmer         {CRC_ROOT_CAUSE, "crc_root_cause"},
106f1184392SCaleb Palmer         {ODP_DATA_CORRUPT_SIDE_EFFECT, "odp_data_corrupt_side_effect"},
107f1184392SCaleb Palmer         {ODP_DATA_CORRUPT_ROOT_CAUSE, "odp_data_corrupt_root_cause"},
10851f8202cSCaleb Palmer         {ATTN_FROM_OCMB, "attn_from_ocmb"},
109f1184392SCaleb Palmer     };
1101a4f0e70SCaleb Palmer     std::string strFlag = flagMap[i_flag];
111f1184392SCaleb Palmer 
112f1184392SCaleb Palmer     // If the input flag does not exist in the map, that's a code bug.
113f1184392SCaleb Palmer     assert(0 != flagMap.count(i_flag));
114f1184392SCaleb Palmer 
115f1184392SCaleb Palmer     nlohmann::json data;
116f1184392SCaleb Palmer     try
117f1184392SCaleb Palmer     {
118f1184392SCaleb Palmer         data = iv_dataFiles.at(i_signature.getChip().getType());
119f1184392SCaleb Palmer     }
120f1184392SCaleb Palmer     catch (const std::out_of_range& e)
121f1184392SCaleb Palmer     {
122f1184392SCaleb Palmer         trace::err("No RAS data defined for chip type: 0x%08x",
123f1184392SCaleb Palmer                    i_signature.getChip().getType());
124f1184392SCaleb Palmer         throw; // caught later downstream
125f1184392SCaleb Palmer     }
126f1184392SCaleb Palmer 
127f1184392SCaleb Palmer     // Get the signature keys. All are hex (lower case) with no prefix.
128f1184392SCaleb Palmer     char buf[5];
129f1184392SCaleb Palmer     sprintf(buf, "%04x", i_signature.getId());
130f1184392SCaleb Palmer     std::string id{buf};
131f1184392SCaleb Palmer 
132f1184392SCaleb Palmer     sprintf(buf, "%02x", i_signature.getBit());
133f1184392SCaleb Palmer     std::string bit{buf};
134f1184392SCaleb Palmer 
135f1184392SCaleb Palmer     // Get the list of flags in string format from the data.
13602d59af5SZane Shelley     try
137f1184392SCaleb Palmer     {
138f1184392SCaleb Palmer         auto flags = data.at("signatures")
139f1184392SCaleb Palmer                          .at(id)
140f1184392SCaleb Palmer                          .at(bit)
141f1184392SCaleb Palmer                          .at("flags")
142f1184392SCaleb Palmer                          .get<std::vector<std::string>>();
143f1184392SCaleb Palmer 
144f1184392SCaleb Palmer         // Check if the input flag exists
1451a4f0e70SCaleb Palmer         if (flags.end() != std::find(flags.begin(), flags.end(), strFlag))
146f1184392SCaleb Palmer         {
147f1184392SCaleb Palmer             o_isFlagSet = true;
148f1184392SCaleb Palmer         }
149f1184392SCaleb Palmer     }
1505836f4a6SZane Shelley     catch (const nlohmann::json::out_of_range& e)
15102d59af5SZane Shelley     {
15202d59af5SZane Shelley         // Do nothing. Assume there is no flag defined. If for some reason
15302d59af5SZane Shelley         // the `id` or `bit` were not defined, that will be cause below when the
15402d59af5SZane Shelley         // signture is parsed.
15502d59af5SZane Shelley     }
156f1184392SCaleb Palmer 
157f1184392SCaleb Palmer     // If the flag hasn't been found, check if it was defined as part of the
158f1184392SCaleb Palmer     // action for this input signature.
159f1184392SCaleb Palmer     if (!o_isFlagSet)
160f1184392SCaleb Palmer     {
161f1184392SCaleb Palmer         const auto action = parseSignature(data, i_signature);
16202d59af5SZane Shelley         try
16302d59af5SZane Shelley         {
1641a4f0e70SCaleb Palmer             __checkActionForFlag(action, strFlag, data);
165f1184392SCaleb Palmer         }
1665836f4a6SZane Shelley         catch (const nlohmann::json::out_of_range& e)
16702d59af5SZane Shelley         {
16802d59af5SZane Shelley             // Again, do nothing. Assume there is no flag defined. If for some
16902d59af5SZane Shelley             // reason the action is not defined, that will be handled later when
17002d59af5SZane Shelley             // attempting to get the resolution.
17102d59af5SZane Shelley         }
17202d59af5SZane Shelley     }
173f1184392SCaleb Palmer 
174f1184392SCaleb Palmer     return o_isFlagSet;
175f1184392SCaleb Palmer }
176f1184392SCaleb Palmer 
177f1184392SCaleb Palmer //------------------------------------------------------------------------------
178f1184392SCaleb Palmer 
1791a4f0e70SCaleb Palmer unsigned int
getVersion(const libhei::Signature & i_signature) const1801a4f0e70SCaleb Palmer     RasDataParser::getVersion(const libhei::Signature& i_signature) const
1811a4f0e70SCaleb Palmer {
1821a4f0e70SCaleb Palmer     unsigned int o_version = 0;
1831a4f0e70SCaleb Palmer 
1841a4f0e70SCaleb Palmer     nlohmann::json data;
1851a4f0e70SCaleb Palmer     try
1861a4f0e70SCaleb Palmer     {
1871a4f0e70SCaleb Palmer         data = iv_dataFiles.at(i_signature.getChip().getType());
1881a4f0e70SCaleb Palmer     }
1891a4f0e70SCaleb Palmer     catch (const std::out_of_range& e)
1901a4f0e70SCaleb Palmer     {
1911a4f0e70SCaleb Palmer         trace::err("No RAS data defined for chip type: 0x%08x",
1921a4f0e70SCaleb Palmer                    i_signature.getChip().getType());
1931a4f0e70SCaleb Palmer         throw; // caught later downstream
1941a4f0e70SCaleb Palmer     }
1951a4f0e70SCaleb Palmer 
1961a4f0e70SCaleb Palmer     o_version = data.at("version").get<unsigned int>();
1971a4f0e70SCaleb Palmer 
1981a4f0e70SCaleb Palmer     return o_version;
1991a4f0e70SCaleb Palmer }
2001a4f0e70SCaleb Palmer 
2011a4f0e70SCaleb Palmer //------------------------------------------------------------------------------
2021a4f0e70SCaleb Palmer 
initDataFiles()203a9b44344SZane Shelley void RasDataParser::initDataFiles()
204a9b44344SZane Shelley {
205a9b44344SZane Shelley     iv_dataFiles.clear(); // initially empty
206a9b44344SZane Shelley 
207a9b44344SZane Shelley     // Get the RAS data schema files from the package `schema` subdirectory.
208a9b44344SZane Shelley     fs::path schemaDir{PACKAGE_DIR "schema"};
209ee54c99fSZane Shelley     auto schemaRegex = R"(ras-data-schema-v[0-9]{2}\.json)";
210ee54c99fSZane Shelley     std::vector<fs::path> schemaPaths;
211ee54c99fSZane Shelley     util::findFiles(schemaDir, schemaRegex, schemaPaths);
212a9b44344SZane Shelley 
213ee54c99fSZane Shelley     // Parse each of the schema files.
214ee54c99fSZane Shelley     std::map<unsigned int, nlohmann::json> schemaFiles;
215ee54c99fSZane Shelley     for (const auto& path : schemaPaths)
216ee54c99fSZane Shelley     {
217ee54c99fSZane Shelley         // Trace each data file for debug.
218ee54c99fSZane Shelley         trace::inf("File found: path=%s", path.string().c_str());
219a9b44344SZane Shelley 
220a9b44344SZane Shelley         // Open the file.
221ee54c99fSZane Shelley         std::ifstream file{path};
222ee54c99fSZane Shelley         assert(file.good()); // The file must be readable.
223a9b44344SZane Shelley 
2242fbd267eSZane Shelley         try
2252fbd267eSZane Shelley         {
226a9b44344SZane Shelley             // Parse the JSON.
227ee54c99fSZane Shelley             auto schema = nlohmann::json::parse(file);
228a9b44344SZane Shelley 
229ee54c99fSZane Shelley             // Get the schema version.
230ee54c99fSZane Shelley             auto version = schema.at("version").get<unsigned int>();
23193b001c5SZane Shelley             assert(2 <= version); // check support version
232ee54c99fSZane Shelley 
233ee54c99fSZane Shelley             // Keep track of the schemas.
234ee54c99fSZane Shelley             auto ret = schemaFiles.emplace(version, schema);
235ee54c99fSZane Shelley             assert(ret.second); // Should not have duplicate entries
236ee54c99fSZane Shelley         }
2372fbd267eSZane Shelley         catch (...)
2382fbd267eSZane Shelley         {
2392fbd267eSZane Shelley             trace::err("Failed to parse file: %s", path.string().c_str());
2402fbd267eSZane Shelley             throw; // caught later downstream
2412fbd267eSZane Shelley         }
2422fbd267eSZane Shelley     }
243ee54c99fSZane Shelley 
244ee54c99fSZane Shelley     // Get the RAS data files from the package `data` subdirectory.
245a9b44344SZane Shelley     fs::path dataDir{PACKAGE_DIR "ras-data"};
246a9b44344SZane Shelley     std::vector<fs::path> dataPaths;
247a9b44344SZane Shelley     util::findFiles(dataDir, R"(.*\.json)", dataPaths);
248a9b44344SZane Shelley 
249a9b44344SZane Shelley     // Parse each of the data files.
250a9b44344SZane Shelley     for (const auto& path : dataPaths)
251a9b44344SZane Shelley     {
252a9b44344SZane Shelley         // Trace each data file for debug.
253a9b44344SZane Shelley         trace::inf("File found: path=%s", path.string().c_str());
254a9b44344SZane Shelley 
255a9b44344SZane Shelley         // Open the file.
256a9b44344SZane Shelley         std::ifstream file{path};
257a9b44344SZane Shelley         assert(file.good()); // The file must be readable.
258a9b44344SZane Shelley 
2592fbd267eSZane Shelley         try
2602fbd267eSZane Shelley         {
261a9b44344SZane Shelley             // Parse the JSON.
262a9b44344SZane Shelley             const auto data = nlohmann::json::parse(file);
263a9b44344SZane Shelley 
264ee54c99fSZane Shelley             // Get the data version.
265ee54c99fSZane Shelley             auto version = data.at("version").get<unsigned int>();
26693b001c5SZane Shelley             assert(2 <= version); // check support version
267ee54c99fSZane Shelley 
268ee54c99fSZane Shelley             // Get the schema for this file.
269ee54c99fSZane Shelley             auto schema = schemaFiles.at(version);
270ee54c99fSZane Shelley 
271a9b44344SZane Shelley             // Validate the data against the schema.
272a9b44344SZane Shelley             assert(util::validateJson(schema, data));
273a9b44344SZane Shelley 
274a9b44344SZane Shelley             // Get the chip model/EC level from the data. The value is currently
2752fbd267eSZane Shelley             // stored as a string representation of the hex value. So it will
2762fbd267eSZane Shelley             // have to be converted to an integer.
277a9b44344SZane Shelley             libhei::ChipType_t chipType =
278a9b44344SZane Shelley                 std::stoul(data.at("model_ec").get<std::string>(), 0, 16);
279a9b44344SZane Shelley 
280a9b44344SZane Shelley             // So far, so good. Add the entry.
281a9b44344SZane Shelley             auto ret = iv_dataFiles.emplace(chipType, data);
282a9b44344SZane Shelley             assert(ret.second); // Should not have duplicate entries
283a9b44344SZane Shelley         }
2842fbd267eSZane Shelley         catch (...)
2852fbd267eSZane Shelley         {
2862fbd267eSZane Shelley             trace::err("Failed to parse file: %s", path.string().c_str());
2872fbd267eSZane Shelley             throw; // caught later downstream
2882fbd267eSZane Shelley         }
2892fbd267eSZane Shelley     }
290a9b44344SZane Shelley }
291a9b44344SZane Shelley 
292a9b44344SZane Shelley //------------------------------------------------------------------------------
293a9b44344SZane Shelley 
parseSignature(const nlohmann::json & i_data,const libhei::Signature & i_signature) const294*a0c724d3SPatrick Williams std::string RasDataParser::parseSignature(
295*a0c724d3SPatrick Williams     const nlohmann::json& i_data, const libhei::Signature& i_signature) const
2967698b304SZane Shelley {
2977698b304SZane Shelley     // Get the signature keys. All are hex (lower case) with no prefix.
2987698b304SZane Shelley     char buf[5];
2997698b304SZane Shelley     sprintf(buf, "%04x", i_signature.getId());
3007698b304SZane Shelley     std::string id{buf};
3017698b304SZane Shelley 
3027698b304SZane Shelley     sprintf(buf, "%02x", i_signature.getBit());
3037698b304SZane Shelley     std::string bit{buf};
3047698b304SZane Shelley 
3057698b304SZane Shelley     sprintf(buf, "%02x", i_signature.getInstance());
3067698b304SZane Shelley     std::string inst{buf};
3077698b304SZane Shelley 
3082fbd267eSZane Shelley     std::string action;
3092fbd267eSZane Shelley 
3102fbd267eSZane Shelley     try
3112fbd267eSZane Shelley     {
3122fbd267eSZane Shelley         action =
3132fbd267eSZane Shelley             i_data.at("signatures").at(id).at(bit).at(inst).get<std::string>();
3142fbd267eSZane Shelley     }
3155836f4a6SZane Shelley     catch (const nlohmann::json::out_of_range& e)
3162fbd267eSZane Shelley     {
3172fbd267eSZane Shelley         trace::err("No action defined for signature: %s %s %s", id.c_str(),
3182fbd267eSZane Shelley                    bit.c_str(), inst.c_str());
319e36866c3SCaleb Palmer 
320e36866c3SCaleb Palmer         // Default to 'level2_M_th1' if no signature is found.
321e36866c3SCaleb Palmer         action = "level2_M_th1";
322e36866c3SCaleb Palmer     }
3232fbd267eSZane Shelley 
3247698b304SZane Shelley     // Return the action.
3252fbd267eSZane Shelley     return action;
3267698b304SZane Shelley }
3277698b304SZane Shelley 
3287698b304SZane Shelley //------------------------------------------------------------------------------
3297698b304SZane Shelley 
parseBus(const nlohmann::json & i_data,const std::string & i_name)330*a0c724d3SPatrick Williams std::tuple<callout::BusType, std::string> RasDataParser::parseBus(
331*a0c724d3SPatrick Williams     const nlohmann::json& i_data, const std::string& i_name)
3325d63cefcSZane Shelley {
3335d63cefcSZane Shelley     auto bus = i_data.at("buses").at(i_name);
3345d63cefcSZane Shelley 
3355d63cefcSZane Shelley     // clang-format off
3365d63cefcSZane Shelley     static const std::map<std::string, callout::BusType> m =
3375d63cefcSZane Shelley     {
3385d63cefcSZane Shelley         {"SMP_BUS", callout::BusType::SMP_BUS},
3395d63cefcSZane Shelley         {"OMI_BUS", callout::BusType::OMI_BUS},
3405d63cefcSZane Shelley     };
3415d63cefcSZane Shelley     // clang-format on
3425d63cefcSZane Shelley 
3435d63cefcSZane Shelley     auto busType = m.at(bus.at("type").get<std::string>());
3445d63cefcSZane Shelley 
3455d63cefcSZane Shelley     std::string unitPath{}; // default empty if unit does not exist
3465d63cefcSZane Shelley     if (bus.contains("unit"))
3475d63cefcSZane Shelley     {
3483e8f2958SZane Shelley         auto unit = bus.at("unit").get<std::string>();
3493e8f2958SZane Shelley         unitPath = i_data.at("units").at(unit).get<std::string>();
3505d63cefcSZane Shelley     }
3515d63cefcSZane Shelley 
3525d63cefcSZane Shelley     return std::make_tuple(busType, unitPath);
3535d63cefcSZane Shelley }
3545d63cefcSZane Shelley 
3555d63cefcSZane Shelley //------------------------------------------------------------------------------
3565d63cefcSZane Shelley 
parseAction(const nlohmann::json & i_data,const std::string & i_action)357*a0c724d3SPatrick Williams std::shared_ptr<Resolution> RasDataParser::parseAction(
358*a0c724d3SPatrick Williams     const nlohmann::json& i_data, const std::string& i_action)
3597698b304SZane Shelley {
3607698b304SZane Shelley     auto o_list = std::make_shared<ResolutionList>();
3617698b304SZane Shelley 
3627698b304SZane Shelley     // This function will be called recursively and we want to prevent cyclic
3637698b304SZane Shelley     // recursion.
3647698b304SZane Shelley     static std::vector<std::string> stack;
3657698b304SZane Shelley     assert(stack.end() == std::find(stack.begin(), stack.end(), i_action));
3667698b304SZane Shelley     stack.push_back(i_action);
3677698b304SZane Shelley 
3687698b304SZane Shelley     // Iterate the action list and apply the changes.
3697698b304SZane Shelley     for (const auto& a : i_data.at("actions").at(i_action))
3707698b304SZane Shelley     {
3717698b304SZane Shelley         auto type = a.at("type").get<std::string>();
3727698b304SZane Shelley 
3737698b304SZane Shelley         if ("action" == type)
3747698b304SZane Shelley         {
3757698b304SZane Shelley             auto name = a.at("name").get<std::string>();
3767698b304SZane Shelley 
3777698b304SZane Shelley             o_list->push(parseAction(i_data, name));
3787698b304SZane Shelley         }
3797698b304SZane Shelley         else if ("callout_self" == type)
3807698b304SZane Shelley         {
3817698b304SZane Shelley             auto priority = a.at("priority").get<std::string>();
3827698b304SZane Shelley             auto guard = a.at("guard").get<bool>();
3837698b304SZane Shelley 
384e4bfb47cSZane Shelley             std::string path{}; // Must be empty to callout the chip.
385e4bfb47cSZane Shelley 
386e4bfb47cSZane Shelley             o_list->push(std::make_shared<HardwareCalloutResolution>(
387e4bfb47cSZane Shelley                 path, getPriority(priority), guard));
3887698b304SZane Shelley         }
3897698b304SZane Shelley         else if ("callout_unit" == type)
3907698b304SZane Shelley         {
3917698b304SZane Shelley             auto name = a.at("name").get<std::string>();
3927698b304SZane Shelley             auto priority = a.at("priority").get<std::string>();
3937698b304SZane Shelley             auto guard = a.at("guard").get<bool>();
3947698b304SZane Shelley 
395e4bfb47cSZane Shelley             auto path = i_data.at("units").at(name).get<std::string>();
396e4bfb47cSZane Shelley 
397e4bfb47cSZane Shelley             o_list->push(std::make_shared<HardwareCalloutResolution>(
398e4bfb47cSZane Shelley                 path, getPriority(priority), guard));
3997698b304SZane Shelley         }
4007698b304SZane Shelley         else if ("callout_connected" == type)
4017698b304SZane Shelley         {
4027698b304SZane Shelley             auto name = a.at("name").get<std::string>();
4037698b304SZane Shelley             auto priority = a.at("priority").get<std::string>();
4047698b304SZane Shelley             auto guard = a.at("guard").get<bool>();
4057698b304SZane Shelley 
4065d63cefcSZane Shelley             auto busData = parseBus(i_data, name);
4075d63cefcSZane Shelley 
4085d63cefcSZane Shelley             o_list->push(std::make_shared<ConnectedCalloutResolution>(
4095d63cefcSZane Shelley                 std::get<0>(busData), std::get<1>(busData),
4105d63cefcSZane Shelley                 getPriority(priority), guard));
4117698b304SZane Shelley         }
4127698b304SZane Shelley         else if ("callout_bus" == type)
4137698b304SZane Shelley         {
4147698b304SZane Shelley             auto name = a.at("name").get<std::string>();
4154757a7bcSZane Shelley             auto priority = a.at("priority").get<std::string>();
4167698b304SZane Shelley             auto guard = a.at("guard").get<bool>();
4177698b304SZane Shelley 
4184757a7bcSZane Shelley             auto busData = parseBus(i_data, name);
4194757a7bcSZane Shelley 
4204757a7bcSZane Shelley             o_list->push(std::make_shared<BusCalloutResolution>(
4214757a7bcSZane Shelley                 std::get<0>(busData), std::get<1>(busData),
4224757a7bcSZane Shelley                 getPriority(priority), guard));
4237698b304SZane Shelley         }
4247698b304SZane Shelley         else if ("callout_clock" == type)
4257698b304SZane Shelley         {
42684721d90SZane Shelley             auto name = a.at("name").get<std::string>();
4277698b304SZane Shelley             auto priority = a.at("priority").get<std::string>();
4287698b304SZane Shelley             auto guard = a.at("guard").get<bool>();
4297698b304SZane Shelley 
43084721d90SZane Shelley             // clang-format off
43184721d90SZane Shelley             static const std::map<std::string, callout::ClockType> m =
43284721d90SZane Shelley             {
43384721d90SZane Shelley                 {"OSC_REF_CLOCK_0", callout::ClockType::OSC_REF_CLOCK_0},
43484721d90SZane Shelley                 {"OSC_REF_CLOCK_1", callout::ClockType::OSC_REF_CLOCK_1},
435d195b716SZane Shelley                 {"TOD_CLOCK",       callout::ClockType::TOD_CLOCK},
43684721d90SZane Shelley             };
43784721d90SZane Shelley             // clang-format on
43884721d90SZane Shelley 
43984721d90SZane Shelley             o_list->push(std::make_shared<ClockCalloutResolution>(
44084721d90SZane Shelley                 m.at(name), getPriority(priority), guard));
4417698b304SZane Shelley         }
4427698b304SZane Shelley         else if ("callout_procedure" == type)
4437698b304SZane Shelley         {
4447698b304SZane Shelley             auto name = a.at("name").get<std::string>();
4457698b304SZane Shelley             auto priority = a.at("priority").get<std::string>();
4467698b304SZane Shelley 
4477698b304SZane Shelley             // clang-format off
448c85716caSZane Shelley             static const std::map<std::string, callout::Procedure> m =
4497698b304SZane Shelley             {
450c85716caSZane Shelley                 {"LEVEL2",   callout::Procedure::NEXTLVL},
451d8b70184SZane Shelley                 {"SUE_SEEN", callout::Procedure::SUE_SEEN},
4527698b304SZane Shelley             };
4537698b304SZane Shelley             // clang-format on
4547698b304SZane Shelley 
4557698b304SZane Shelley             o_list->push(std::make_shared<ProcedureCalloutResolution>(
4567698b304SZane Shelley                 m.at(name), getPriority(priority)));
4577698b304SZane Shelley         }
4587698b304SZane Shelley         else if ("callout_part" == type)
4597698b304SZane Shelley         {
4607698b304SZane Shelley             auto name = a.at("name").get<std::string>();
4617698b304SZane Shelley             auto priority = a.at("priority").get<std::string>();
4627698b304SZane Shelley 
463a4134770SZane Shelley             // clang-format off
464a4134770SZane Shelley             static const std::map<std::string, callout::PartType> m =
465a4134770SZane Shelley             {
466a4134770SZane Shelley                 {"PNOR", callout::PartType::PNOR},
467a4134770SZane Shelley             };
468a4134770SZane Shelley             // clang-format on
469a4134770SZane Shelley 
470a4134770SZane Shelley             o_list->push(std::make_shared<PartCalloutResolution>(
471a4134770SZane Shelley                 m.at(name), getPriority(priority)));
4727698b304SZane Shelley         }
4737698b304SZane Shelley         else if ("plugin" == type)
4747698b304SZane Shelley         {
4757698b304SZane Shelley             auto name = a.at("name").get<std::string>();
476e13a9f95SZane Shelley             auto inst = a.at("instance").get<unsigned int>();
4777698b304SZane Shelley 
478e13a9f95SZane Shelley             o_list->push(std::make_shared<PluginResolution>(name, inst));
4797698b304SZane Shelley         }
480f1184392SCaleb Palmer         else if ("flag" == type)
481f1184392SCaleb Palmer         {
482f1184392SCaleb Palmer             // No action, flags will be handled with the isFlagSet function
483f1184392SCaleb Palmer         }
4847698b304SZane Shelley         else
4857698b304SZane Shelley         {
4867698b304SZane Shelley             throw std::logic_error("Unsupported action type: " + type);
4877698b304SZane Shelley         }
4887698b304SZane Shelley     }
4897698b304SZane Shelley 
4907698b304SZane Shelley     // Done with this action pop it off the stack.
4917698b304SZane Shelley     stack.pop_back();
4927698b304SZane Shelley 
4937698b304SZane Shelley     return o_list;
4947698b304SZane Shelley }
4957698b304SZane Shelley 
4967698b304SZane Shelley //------------------------------------------------------------------------------
4977698b304SZane Shelley 
getPriority(const std::string & i_priority)498c85716caSZane Shelley callout::Priority RasDataParser::getPriority(const std::string& i_priority)
4997698b304SZane Shelley {
5007698b304SZane Shelley     // clang-format off
501c85716caSZane Shelley     static const std::map<std::string, callout::Priority> m =
5027698b304SZane Shelley     {
503c85716caSZane Shelley         {"HIGH",  callout::Priority::HIGH},
504c85716caSZane Shelley         {"MED",   callout::Priority::MED},
505c85716caSZane Shelley         {"MED_A", callout::Priority::MED_A},
506c85716caSZane Shelley         {"MED_B", callout::Priority::MED_B},
507c85716caSZane Shelley         {"MED_C", callout::Priority::MED_C},
508c85716caSZane Shelley         {"LOW",   callout::Priority::LOW},
5097698b304SZane Shelley     };
5107698b304SZane Shelley     // clang-format on
5117698b304SZane Shelley 
5127698b304SZane Shelley     return m.at(i_priority);
5137698b304SZane Shelley }
5147698b304SZane Shelley 
5157698b304SZane Shelley //------------------------------------------------------------------------------
5167698b304SZane Shelley 
517a9b44344SZane Shelley } // namespace analyzer
518