Add support for clock callout resolutions
Signed-off-by: Zane Shelley <zshelle@us.ibm.com>
Change-Id: I67f02a2fafaa63a0bafaa1116150da35ef4dece1
diff --git a/analyzer/callout.hpp b/analyzer/callout.hpp
index cee3dd1..51cf4ed 100644
--- a/analyzer/callout.hpp
+++ b/analyzer/callout.hpp
@@ -110,6 +110,39 @@
inline const Procedure Procedure::NEXTLVL{"NEXTLVL"};
+/** @brief Container class for clock callout service actions. */
+class ClockType
+{
+ public:
+ /** Oscillator reference clock 0. */
+ static const ClockType OSC_REF_CLOCK_0;
+
+ /** Oscillator reference clock 1. */
+ static const ClockType OSC_REF_CLOCK_1;
+
+ private:
+ /**
+ * @brief Constructor from components.
+ * @param i_string The string representation of the procedure used for
+ * callouts.
+ */
+ explicit ClockType(const std::string& i_string) : iv_string(i_string) {}
+
+ private:
+ /** The string representation of the procedure used for callouts. */
+ const std::string iv_string;
+
+ public:
+ /** iv_string accessor */
+ std::string getString() const
+ {
+ return iv_string;
+ }
+};
+
+inline const ClockType ClockType::OSC_REF_CLOCK_0{"OSC_REF_CLOCK_0"};
+inline const ClockType ClockType::OSC_REF_CLOCK_1{"OSC_REF_CLOCK_1"};
+
} // namespace callout
} // namespace analyzer
diff --git a/analyzer/ras-data/data/ras-data-p10-10.json b/analyzer/ras-data/data/ras-data-p10-10.json
index 8bc89bc..e0303ae 100644
--- a/analyzer/ras-data/data/ras-data-p10-10.json
+++ b/analyzer/ras-data/data/ras-data-p10-10.json
@@ -59,11 +59,11 @@
"pau7": [ { "type": "callout_unit", "name": "pau7", "priority": "MED", "guard": true } ],
"rcs_osc_error_0": [
- { "type": "callout_clock", "position": 0, "priority": "HIGH", "guard": true },
+ { "type": "callout_clock", "name": "OSC_REF_CLOCK_0", "priority": "HIGH", "guard": true },
{ "type": "action", "name": "self_L" }
],
"rcs_osc_error_1": [
- { "type": "callout_clock", "position": 1, "priority": "HIGH", "guard": true },
+ { "type": "callout_clock", "name": "OSC_REF_CLOCK_1", "priority": "HIGH", "guard": true },
{ "type": "action", "name": "self_L" }
],
"pll_unlock_0": [
diff --git a/analyzer/ras-data/data/ras-data-p10-20.json b/analyzer/ras-data/data/ras-data-p10-20.json
index 1295ba5..7ae692b 100644
--- a/analyzer/ras-data/data/ras-data-p10-20.json
+++ b/analyzer/ras-data/data/ras-data-p10-20.json
@@ -59,11 +59,11 @@
"pau7": [ { "type": "callout_unit", "name": "pau7", "priority": "MED", "guard": true } ],
"rcs_osc_error_0": [
- { "type": "callout_clock", "position": 0, "priority": "HIGH", "guard": true },
+ { "type": "callout_clock", "name": "OSC_REF_CLOCK_0", "priority": "HIGH", "guard": true },
{ "type": "action", "name": "self_L" }
],
"rcs_osc_error_1": [
- { "type": "callout_clock", "position": 1, "priority": "HIGH", "guard": true },
+ { "type": "callout_clock", "name": "OSC_REF_CLOCK_1", "priority": "HIGH", "guard": true },
{ "type": "action", "name": "self_L" }
],
"pll_unlock_0": [
diff --git a/analyzer/ras-data/ras-data-definition.md b/analyzer/ras-data/ras-data-definition.md
index 6603494..2538230 100644
--- a/analyzer/ras-data/ras-data-definition.md
+++ b/analyzer/ras-data/ras-data-definition.md
@@ -169,10 +169,17 @@
| Keyword | Description |
|----------|-------------------------------------------------------------------|
| type | value (string): `callout_clock` |
-| position | value (integer): 0 or 1 |
+| name | See `clock type` table below. |
| priority | See `priority` table above. |
| guard | See `guard` table above. |
+Supported clock types:
+
+| Clock Type | Description |
+|-----------------|------------------------------------------------------------|
+| OSC_REF_CLOCK_0 | Oscillator reference clock 0 |
+| OSC_REF_CLOCK_1 | Oscillator reference clock 1 |
+
#### 5.1.7) action type `callout_procedure`
This will request to callout a service procedure.
@@ -180,7 +187,7 @@
| Keyword | Description |
|----------|-------------------------------------------------------------------|
| type | value (string): `callout_procedure` |
-| name | The `procedures` table below. |
+| name | See `procedures` table below. |
| priority | See `priority` table above. |
Supported procedures:
@@ -197,7 +204,7 @@
| Keyword | Description |
|----------|-------------------------------------------------------------------|
| type | value (string): `callout_part` |
-| name | The `parts` table below. |
+| name | See `parts` table below. |
| priority | See `priority` table above. |
Supported parts:
diff --git a/analyzer/ras-data/ras-data-parser.cpp b/analyzer/ras-data/ras-data-parser.cpp
index 559a947..d59c289 100644
--- a/analyzer/ras-data/ras-data-parser.cpp
+++ b/analyzer/ras-data/ras-data-parser.cpp
@@ -185,13 +185,20 @@
}
else if ("callout_clock" == type)
{
- auto position = a.at("position").get<unsigned int>();
+ auto name = a.at("name").get<std::string>();
auto priority = a.at("priority").get<std::string>();
auto guard = a.at("guard").get<bool>();
- // TODO
- trace::inf("callout_clock: position=%u priority=%s guard=%c",
- position, priority.c_str(), guard ? 'T' : 'F');
+ // clang-format off
+ static const std::map<std::string, callout::ClockType> m =
+ {
+ {"OSC_REF_CLOCK_0", callout::ClockType::OSC_REF_CLOCK_0},
+ {"OSC_REF_CLOCK_1", callout::ClockType::OSC_REF_CLOCK_1},
+ };
+ // clang-format on
+
+ o_list->push(std::make_shared<ClockCalloutResolution>(
+ m.at(name), getPriority(priority), guard));
}
else if ("callout_procedure" == type)
{
diff --git a/analyzer/ras-data/schema/ras-data-schema-v01.json b/analyzer/ras-data/schema/ras-data-schema-v01.json
index 05f18cc..9ec7150 100644
--- a/analyzer/ras-data/schema/ras-data-schema-v01.json
+++ b/analyzer/ras-data/schema/ras-data-schema-v01.json
@@ -158,13 +158,13 @@
}
},
"then": {
- "required": [ "priority", "guard", "position" ],
- "not": { "required": [ "name" ] },
+ "required": [ "name", "priority", "guard" ],
"properties": {
- "position": {
- "type": "integer",
- "minimum": 0,
- "maximum": 1
+ "name": {
+ "enum": [
+ "OSC_REF_CLOCK_0",
+ "OSC_REF_CLOCK_1"
+ ]
}
}
}
diff --git a/analyzer/resolution.cpp b/analyzer/resolution.cpp
index a20be83..354ccbc 100644
--- a/analyzer/resolution.cpp
+++ b/analyzer/resolution.cpp
@@ -49,6 +49,43 @@
//------------------------------------------------------------------------------
+void ClockCalloutResolution::resolve(ServiceData& io_sd) const
+{
+ // Add the callout to the service data.
+ // TODO: For P10, the callout is simply the backplane. There isn't a devtree
+ // object for this, yet. So will need to hardcode the location code
+ // for now. In the future, we will need a mechanism to make this data
+ // driven.
+ nlohmann::json callout;
+ callout["LocationCode"] = "P0";
+ callout["Priority"] = iv_priority.getUserDataString();
+ io_sd.addCallout(callout);
+
+ // Add the guard info to the service data.
+ // TODO: Still waiting for clock targets to be defined in the device tree.
+ // For get the processor path for the FFDC.
+ // static const std::map<callout::ClockType, std::string> m = {
+ // {callout::ClockType::OSC_REF_CLOCK_0, ""},
+ // {callout::ClockType::OSC_REF_CLOCK_1, ""},
+ // };
+ // auto target = std::string{util::pdbg::getPath(m.at(iv_clockType))};
+ // auto guardPath = util::pdbg::getPhysDevPath(target);
+ // Guard guard = io_sd.addGuard(guardPath, iv_guard);
+ auto target = util::pdbg::getTrgt(io_sd.getRootCause().getChip());
+ auto guardPath = util::pdbg::getPhysDevPath(target);
+
+ // Add the callout FFDC to the service data.
+ nlohmann::json ffdc;
+ ffdc["Callout Type"] = "Clock Callout";
+ ffdc["Clock Type"] = iv_clockType.getString();
+ ffdc["Target"] = guardPath;
+ ffdc["Priority"] = iv_priority.getRegistryString();
+ ffdc["Guard Type"] = ""; // TODO: guard.getString();
+ io_sd.addCalloutFFDC(ffdc);
+}
+
+//------------------------------------------------------------------------------
+
void ProcedureCalloutResolution::resolve(ServiceData& io_sd) const
{
// Add the actual callout to the service data.
diff --git a/analyzer/resolution.hpp b/analyzer/resolution.hpp
index 44638be..1574d04 100644
--- a/analyzer/resolution.hpp
+++ b/analyzer/resolution.hpp
@@ -56,6 +56,36 @@
void resolve(ServiceData& io_sd) const override;
};
+/** @brief Resolves a clock callout service event. */
+class ClockCalloutResolution : public Resolution
+{
+ public:
+ /**
+ * @brief Constructor from components.
+ * @param i_clockType The clock type.
+ * @param i_priority The callout priority.
+ * @param i_guard The guard type for this callout.
+ */
+ ClockCalloutResolution(const callout::ClockType& i_clockType,
+ const callout::Priority& i_priority, bool i_guard) :
+ iv_clockType(i_clockType),
+ iv_priority(i_priority), iv_guard(i_guard)
+ {}
+
+ private:
+ /** The clock type. */
+ const callout::ClockType iv_clockType;
+
+ /** The callout priority. */
+ const callout::Priority iv_priority;
+
+ /** True, if guard is required. False, otherwise. */
+ const bool iv_guard;
+
+ public:
+ void resolve(ServiceData& io_sd) const override;
+};
+
/** @brief Resolves a procedure callout service event. */
class ProcedureCalloutResolution : public Resolution
{
diff --git a/test/resolution_test.cpp b/test/resolution_test.cpp
index 0f1dfcd..7cf95dd 100644
--- a/test/resolution_test.cpp
+++ b/test/resolution_test.cpp
@@ -16,6 +16,8 @@
namespace analyzer
{
+//------------------------------------------------------------------------------
+
void HardwareCalloutResolution::resolve(ServiceData& io_sd) const
{
auto sig = io_sd.getRootCause();
@@ -48,6 +50,27 @@
io_sd.addCallout(callout);
}
+//------------------------------------------------------------------------------
+
+void ClockCalloutResolution::resolve(ServiceData& io_sd) const
+{
+ auto sig = io_sd.getRootCause();
+
+ std::string fru{"P0"};
+ std::string path{(const char*)sig.getChip().getChip()};
+
+ // Add the actual callout to the service data.
+ nlohmann::json callout;
+ callout["LocationCode"] = fru;
+ callout["Priority"] = iv_priority.getUserDataString();
+ io_sd.addCallout(callout);
+
+ // Add the guard info to the service data.
+ io_sd.addGuard(path, iv_guard);
+}
+
+//------------------------------------------------------------------------------
+
} // namespace analyzer
using namespace analyzer;
@@ -67,12 +90,16 @@
auto c4 = std::make_shared<ProcedureCalloutResolution>(
callout::Procedure::NEXTLVL, callout::Priority::LOW);
- // l1 = (c1, c2)
+ auto c5 = std::make_shared<ClockCalloutResolution>(
+ callout::ClockType::OSC_REF_CLOCK_1, callout::Priority::LOW, false);
+
+ // l1 = (c1, c2, c5)
auto l1 = std::make_shared<ResolutionList>();
l1->push(c1);
l1->push(c2);
+ l1->push(c5);
- // l2 = (c4, c3, c1, c2)
+ // l2 = (c4, c3, c1, c2, c5)
auto l2 = std::make_shared<ResolutionList>();
l2->push(c4);
l2->push(c3);
@@ -101,6 +128,10 @@
{
"LocationCode": "/proc0",
"Priority": "A"
+ },
+ {
+ "LocationCode": "P0",
+ "Priority": "L"
}
])";
ASSERT_EQ(s, j.dump(4));
@@ -122,6 +153,10 @@
{
"LocationCode": "/proc0",
"Priority": "A"
+ },
+ {
+ "LocationCode": "P0",
+ "Priority": "L"
}
])";
ASSERT_EQ(s, j.dump(4));