1 #include <analyzer/resolution.hpp>
2 #include <util/pdbg.hpp>
3 #include <util/trace.hpp>
4 
5 namespace analyzer
6 {
7 
8 //------------------------------------------------------------------------------
9 
10 // Helper function to get the root cause chip target from the service data.
11 pdbg_target* __getRootCauseChipTarget(const ServiceData& i_sd)
12 {
13     auto target = util::pdbg::getTrgt(i_sd.getRootCause().getChip());
14     assert(nullptr != target); // This would be a really bad bug.
15     return target;
16 }
17 
18 //------------------------------------------------------------------------------
19 
20 // Helper function to get a unit target from the given unit path, which is a
21 // devtree path relative the the containing chip. An empty string indicates the
22 // chip target should be returned.
23 pdbg_target* __getUnitTarget(pdbg_target* i_chipTarget,
24                              const std::string& i_unitPath)
25 {
26     assert(nullptr != i_chipTarget);
27 
28     auto target = i_chipTarget; // default, if i_unitPath is empty
29 
30     if (!i_unitPath.empty())
31     {
32         auto path = std::string{util::pdbg::getPath(target)} + "/" + i_unitPath;
33 
34         target = util::pdbg::getTrgt(path);
35         if (nullptr == target)
36         {
37             // Likely a bug the RAS data files.
38             throw std::logic_error("Unable to find target for " + path);
39         }
40     }
41 
42     return target;
43 }
44 
45 //------------------------------------------------------------------------------
46 
47 void HardwareCalloutResolution::resolve(ServiceData& io_sd) const
48 {
49     // Get the target for the hardware callout.
50     auto target = __getUnitTarget(__getRootCauseChipTarget(io_sd), iv_unitPath);
51 
52     // Get the location code and entity path for this target.
53     auto locCode    = util::pdbg::getLocationCode(target);
54     auto entityPath = util::pdbg::getPhysDevPath(target);
55 
56     // Add the actual callout to the service data.
57     nlohmann::json callout;
58     callout["LocationCode"] = locCode;
59     callout["Priority"]     = iv_priority.getUserDataString();
60     io_sd.addCallout(callout);
61 
62     // Add the guard info to the service data.
63     Guard guard = io_sd.addGuard(entityPath, iv_guard);
64 
65     // Add the callout FFDC to the service data.
66     nlohmann::json ffdc;
67     ffdc["Callout Type"] = "Hardware Callout";
68     ffdc["Target"]       = entityPath;
69     ffdc["Priority"]     = iv_priority.getRegistryString();
70     ffdc["Guard Type"]   = guard.getString();
71     io_sd.addCalloutFFDC(ffdc);
72 }
73 
74 //------------------------------------------------------------------------------
75 
76 void ClockCalloutResolution::resolve(ServiceData& io_sd) const
77 {
78     // Add the callout to the service data.
79     // TODO: For P10, the callout is simply the backplane. There isn't a devtree
80     //       object for this, yet. So will need to hardcode the location code
81     //       for now. In the future, we will need a mechanism to make this data
82     //       driven.
83     nlohmann::json callout;
84     callout["LocationCode"] = "P0";
85     callout["Priority"]     = iv_priority.getUserDataString();
86     io_sd.addCallout(callout);
87 
88     // Add the guard info to the service data.
89     // TODO: Still waiting for clock targets to be defined in the device tree.
90     //       For get the processor path for the FFDC.
91     // static const std::map<callout::ClockType, std::string> m = {
92     //     {callout::ClockType::OSC_REF_CLOCK_0, ""},
93     //     {callout::ClockType::OSC_REF_CLOCK_1, ""},
94     // };
95     // auto target = std::string{util::pdbg::getPath(m.at(iv_clockType))};
96     // auto guardPath = util::pdbg::getPhysDevPath(target);
97     // Guard guard = io_sd.addGuard(guardPath, iv_guard);
98     auto target    = __getRootCauseChipTarget(io_sd);
99     auto guardPath = util::pdbg::getPhysDevPath(target);
100 
101     // Add the callout FFDC to the service data.
102     nlohmann::json ffdc;
103     ffdc["Callout Type"] = "Clock Callout";
104     ffdc["Clock Type"]   = iv_clockType.getString();
105     ffdc["Target"]       = guardPath;
106     ffdc["Priority"]     = iv_priority.getRegistryString();
107     ffdc["Guard Type"]   = ""; // TODO: guard.getString();
108     io_sd.addCalloutFFDC(ffdc);
109 }
110 
111 //------------------------------------------------------------------------------
112 
113 void ProcedureCalloutResolution::resolve(ServiceData& io_sd) const
114 {
115     // Add the actual callout to the service data.
116     nlohmann::json callout;
117     callout["Procedure"] = iv_procedure.getString();
118     callout["Priority"]  = iv_priority.getUserDataString();
119     io_sd.addCallout(callout);
120 
121     // Add the callout FFDC to the service data.
122     nlohmann::json ffdc;
123     ffdc["Callout Type"] = "Procedure Callout";
124     ffdc["Procedure"]    = iv_procedure.getString();
125     ffdc["Priority"]     = iv_priority.getRegistryString();
126     io_sd.addCalloutFFDC(ffdc);
127 }
128 
129 //------------------------------------------------------------------------------
130 
131 } // namespace analyzer
132