Zane Shelley | 0b8368c | 2021-03-18 17:33:41 -0500 | [diff] [blame] | 1 | #include <stdio.h> |
| 2 | |
| 3 | #include <analyzer/resolution.hpp> |
| 4 | |
| 5 | #include "gtest/gtest.h" |
| 6 | |
| 7 | // Chip string |
| 8 | constexpr auto chip_str = "/proc0"; |
| 9 | |
| 10 | // Unit paths |
| 11 | constexpr auto proc_str = ""; |
| 12 | constexpr auto omi_str = "pib/perv12/mc0/mi0/mcc0/omi0"; |
| 13 | constexpr auto core_str = "pib/perv39/eq7/fc1/core1"; |
| 14 | |
| 15 | // Local implementation of this function. |
| 16 | namespace analyzer |
| 17 | { |
| 18 | |
Zane Shelley | 84721d9 | 2021-09-08 13:30:27 -0500 | [diff] [blame] | 19 | //------------------------------------------------------------------------------ |
| 20 | |
Zane Shelley | 96d5486 | 2021-09-17 11:16:12 -0500 | [diff] [blame^] | 21 | // Helper function to get the root cause chip target path from the service data. |
| 22 | std::string __getRootCauseChipPath(const ServiceData& i_sd) |
| 23 | { |
| 24 | return std::string{(const char*)i_sd.getRootCause().getChip().getChip()}; |
| 25 | } |
| 26 | |
| 27 | //------------------------------------------------------------------------------ |
| 28 | |
| 29 | // Helper function to get a unit target path from the given unit path, which is |
| 30 | // a devtree path relative the the containing chip. An empty string indicates |
| 31 | // the chip target path should be returned. |
| 32 | std::string __getUnitPath(const std::string& i_chipPath, |
| 33 | const std::string& i_unitPath) |
| 34 | { |
| 35 | auto path = i_chipPath; // default, if i_unitPath is empty |
| 36 | |
| 37 | if (!i_unitPath.empty()) |
| 38 | { |
| 39 | path += "/" + i_unitPath; |
| 40 | } |
| 41 | |
| 42 | return path; |
| 43 | } |
| 44 | |
| 45 | //------------------------------------------------------------------------------ |
| 46 | |
Zane Shelley | 0b8368c | 2021-03-18 17:33:41 -0500 | [diff] [blame] | 47 | void HardwareCalloutResolution::resolve(ServiceData& io_sd) const |
| 48 | { |
Zane Shelley | 96d5486 | 2021-09-17 11:16:12 -0500 | [diff] [blame^] | 49 | // Get the location code and entity path for this target. |
| 50 | auto locCode = __getRootCauseChipPath(io_sd); |
| 51 | auto entityPath = __getUnitPath(locCode, iv_unitPath); |
Zane Shelley | 0b8368c | 2021-03-18 17:33:41 -0500 | [diff] [blame] | 52 | |
Zane Shelley | c85716c | 2021-08-17 10:54:06 -0500 | [diff] [blame] | 53 | // Add the actual callout to the service data. |
| 54 | nlohmann::json callout; |
Zane Shelley | 96d5486 | 2021-09-17 11:16:12 -0500 | [diff] [blame^] | 55 | callout["LocationCode"] = locCode; |
Zane Shelley | c85716c | 2021-08-17 10:54:06 -0500 | [diff] [blame] | 56 | callout["Priority"] = iv_priority.getUserDataString(); |
| 57 | io_sd.addCallout(callout); |
Zane Shelley | 0b8368c | 2021-03-18 17:33:41 -0500 | [diff] [blame] | 58 | |
Zane Shelley | 9513582 | 2021-08-23 09:00:05 -0500 | [diff] [blame] | 59 | // Add the guard info to the service data. |
Zane Shelley | 96d5486 | 2021-09-17 11:16:12 -0500 | [diff] [blame^] | 60 | Guard guard = io_sd.addGuard(entityPath, iv_guard); |
| 61 | |
| 62 | // Add the callout FFDC to the service data. |
| 63 | nlohmann::json ffdc; |
| 64 | ffdc["Callout Type"] = "Hardware Callout"; |
| 65 | ffdc["Target"] = entityPath; |
| 66 | ffdc["Priority"] = iv_priority.getRegistryString(); |
| 67 | ffdc["Guard Type"] = guard.getString(); |
| 68 | io_sd.addCalloutFFDC(ffdc); |
Zane Shelley | 0b8368c | 2021-03-18 17:33:41 -0500 | [diff] [blame] | 69 | } |
| 70 | |
Zane Shelley | c85716c | 2021-08-17 10:54:06 -0500 | [diff] [blame] | 71 | //------------------------------------------------------------------------------ |
| 72 | |
| 73 | void ProcedureCalloutResolution::resolve(ServiceData& io_sd) const |
| 74 | { |
| 75 | // Add the actual callout to the service data. |
| 76 | nlohmann::json callout; |
| 77 | callout["Procedure"] = iv_procedure.getString(); |
| 78 | callout["Priority"] = iv_priority.getUserDataString(); |
| 79 | io_sd.addCallout(callout); |
Zane Shelley | 96d5486 | 2021-09-17 11:16:12 -0500 | [diff] [blame^] | 80 | |
| 81 | // Add the callout FFDC to the service data. |
| 82 | nlohmann::json ffdc; |
| 83 | ffdc["Callout Type"] = "Procedure Callout"; |
| 84 | ffdc["Procedure"] = iv_procedure.getString(); |
| 85 | ffdc["Priority"] = iv_priority.getRegistryString(); |
| 86 | io_sd.addCalloutFFDC(ffdc); |
Zane Shelley | c85716c | 2021-08-17 10:54:06 -0500 | [diff] [blame] | 87 | } |
| 88 | |
Zane Shelley | 84721d9 | 2021-09-08 13:30:27 -0500 | [diff] [blame] | 89 | //------------------------------------------------------------------------------ |
| 90 | |
| 91 | void ClockCalloutResolution::resolve(ServiceData& io_sd) const |
| 92 | { |
Zane Shelley | 96d5486 | 2021-09-17 11:16:12 -0500 | [diff] [blame^] | 93 | // Add the callout to the service data. |
| 94 | // TODO: For P10, the callout is simply the backplane. There isn't a devtree |
| 95 | // object for this, yet. So will need to hardcode the location code |
| 96 | // for now. In the future, we will need a mechanism to make this data |
| 97 | // driven. |
Zane Shelley | 84721d9 | 2021-09-08 13:30:27 -0500 | [diff] [blame] | 98 | nlohmann::json callout; |
Zane Shelley | 96d5486 | 2021-09-17 11:16:12 -0500 | [diff] [blame^] | 99 | callout["LocationCode"] = "P0"; |
Zane Shelley | 84721d9 | 2021-09-08 13:30:27 -0500 | [diff] [blame] | 100 | callout["Priority"] = iv_priority.getUserDataString(); |
| 101 | io_sd.addCallout(callout); |
| 102 | |
| 103 | // Add the guard info to the service data. |
Zane Shelley | 96d5486 | 2021-09-17 11:16:12 -0500 | [diff] [blame^] | 104 | // TODO: Still waiting for clock targets to be defined in the device tree. |
| 105 | // For get the processor path for the FFDC. |
| 106 | // static const std::map<callout::ClockType, std::string> m = { |
| 107 | // {callout::ClockType::OSC_REF_CLOCK_0, ""}, |
| 108 | // {callout::ClockType::OSC_REF_CLOCK_1, ""}, |
| 109 | // }; |
| 110 | // auto target = std::string{util::pdbg::getPath(m.at(iv_clockType))}; |
| 111 | // auto guardPath = util::pdbg::getPhysDevPath(target); |
| 112 | // Guard guard = io_sd.addGuard(guardPath, iv_guard); |
| 113 | auto guardPath = __getRootCauseChipPath(io_sd); |
| 114 | |
| 115 | // Add the callout FFDC to the service data. |
| 116 | nlohmann::json ffdc; |
| 117 | ffdc["Callout Type"] = "Clock Callout"; |
| 118 | ffdc["Clock Type"] = iv_clockType.getString(); |
| 119 | ffdc["Target"] = guardPath; |
| 120 | ffdc["Priority"] = iv_priority.getRegistryString(); |
| 121 | ffdc["Guard Type"] = ""; // TODO: guard.getString(); |
| 122 | io_sd.addCalloutFFDC(ffdc); |
Zane Shelley | 84721d9 | 2021-09-08 13:30:27 -0500 | [diff] [blame] | 123 | } |
| 124 | |
| 125 | //------------------------------------------------------------------------------ |
| 126 | |
Zane Shelley | 0b8368c | 2021-03-18 17:33:41 -0500 | [diff] [blame] | 127 | } // namespace analyzer |
| 128 | |
| 129 | using namespace analyzer; |
| 130 | |
| 131 | TEST(Resolution, TestSet1) |
| 132 | { |
| 133 | // Create a few resolutions |
| 134 | auto c1 = std::make_shared<HardwareCalloutResolution>( |
Zane Shelley | c85716c | 2021-08-17 10:54:06 -0500 | [diff] [blame] | 135 | proc_str, callout::Priority::HIGH, false); |
Zane Shelley | 0b8368c | 2021-03-18 17:33:41 -0500 | [diff] [blame] | 136 | |
| 137 | auto c2 = std::make_shared<HardwareCalloutResolution>( |
Zane Shelley | c85716c | 2021-08-17 10:54:06 -0500 | [diff] [blame] | 138 | omi_str, callout::Priority::MED_A, true); |
Zane Shelley | 0b8368c | 2021-03-18 17:33:41 -0500 | [diff] [blame] | 139 | |
| 140 | auto c3 = std::make_shared<HardwareCalloutResolution>( |
Zane Shelley | c85716c | 2021-08-17 10:54:06 -0500 | [diff] [blame] | 141 | core_str, callout::Priority::MED, true); |
Zane Shelley | 0b8368c | 2021-03-18 17:33:41 -0500 | [diff] [blame] | 142 | |
| 143 | auto c4 = std::make_shared<ProcedureCalloutResolution>( |
Zane Shelley | c85716c | 2021-08-17 10:54:06 -0500 | [diff] [blame] | 144 | callout::Procedure::NEXTLVL, callout::Priority::LOW); |
Zane Shelley | 0b8368c | 2021-03-18 17:33:41 -0500 | [diff] [blame] | 145 | |
Zane Shelley | 84721d9 | 2021-09-08 13:30:27 -0500 | [diff] [blame] | 146 | auto c5 = std::make_shared<ClockCalloutResolution>( |
| 147 | callout::ClockType::OSC_REF_CLOCK_1, callout::Priority::LOW, false); |
| 148 | |
| 149 | // l1 = (c1, c2, c5) |
Zane Shelley | 723fa23 | 2021-08-09 12:02:06 -0500 | [diff] [blame] | 150 | auto l1 = std::make_shared<ResolutionList>(); |
| 151 | l1->push(c1); |
| 152 | l1->push(c2); |
Zane Shelley | 84721d9 | 2021-09-08 13:30:27 -0500 | [diff] [blame] | 153 | l1->push(c5); |
Zane Shelley | 0b8368c | 2021-03-18 17:33:41 -0500 | [diff] [blame] | 154 | |
Zane Shelley | 84721d9 | 2021-09-08 13:30:27 -0500 | [diff] [blame] | 155 | // l2 = (c4, c3, c1, c2, c5) |
Zane Shelley | 723fa23 | 2021-08-09 12:02:06 -0500 | [diff] [blame] | 156 | auto l2 = std::make_shared<ResolutionList>(); |
| 157 | l2->push(c4); |
| 158 | l2->push(c3); |
| 159 | l2->push(l1); |
Zane Shelley | 0b8368c | 2021-03-18 17:33:41 -0500 | [diff] [blame] | 160 | |
| 161 | // Get some ServiceData objects |
| 162 | libhei::Chip chip{chip_str, 0xdeadbeef}; |
| 163 | libhei::Signature sig{chip, 0xabcd, 0, 0, libhei::ATTN_TYPE_CHECKSTOP}; |
Zane Shelley | ca49619 | 2021-08-09 12:05:52 -0500 | [diff] [blame] | 164 | ServiceData sd1{sig, true}; |
| 165 | ServiceData sd2{sig, false}; |
Zane Shelley | 0b8368c | 2021-03-18 17:33:41 -0500 | [diff] [blame] | 166 | |
| 167 | // Resolve |
Zane Shelley | 723fa23 | 2021-08-09 12:02:06 -0500 | [diff] [blame] | 168 | l1->resolve(sd1); |
| 169 | l2->resolve(sd2); |
Zane Shelley | 0b8368c | 2021-03-18 17:33:41 -0500 | [diff] [blame] | 170 | |
| 171 | // Start verifying |
| 172 | nlohmann::json j{}; |
| 173 | std::string s{}; |
| 174 | |
Zane Shelley | c85716c | 2021-08-17 10:54:06 -0500 | [diff] [blame] | 175 | j = sd1.getCalloutList(); |
Zane Shelley | 0b8368c | 2021-03-18 17:33:41 -0500 | [diff] [blame] | 176 | s = R"([ |
| 177 | { |
| 178 | "LocationCode": "/proc0", |
| 179 | "Priority": "H" |
| 180 | }, |
| 181 | { |
| 182 | "LocationCode": "/proc0", |
| 183 | "Priority": "A" |
Zane Shelley | 84721d9 | 2021-09-08 13:30:27 -0500 | [diff] [blame] | 184 | }, |
| 185 | { |
| 186 | "LocationCode": "P0", |
| 187 | "Priority": "L" |
Zane Shelley | 0b8368c | 2021-03-18 17:33:41 -0500 | [diff] [blame] | 188 | } |
| 189 | ])"; |
Zane Shelley | 96d5486 | 2021-09-17 11:16:12 -0500 | [diff] [blame^] | 190 | EXPECT_EQ(s, j.dump(4)); |
Zane Shelley | 0b8368c | 2021-03-18 17:33:41 -0500 | [diff] [blame] | 191 | |
Zane Shelley | c85716c | 2021-08-17 10:54:06 -0500 | [diff] [blame] | 192 | j = sd2.getCalloutList(); |
Zane Shelley | 0b8368c | 2021-03-18 17:33:41 -0500 | [diff] [blame] | 193 | s = R"([ |
| 194 | { |
| 195 | "Priority": "L", |
| 196 | "Procedure": "NEXTLVL" |
| 197 | }, |
| 198 | { |
| 199 | "LocationCode": "/proc0", |
| 200 | "Priority": "M" |
| 201 | }, |
| 202 | { |
| 203 | "LocationCode": "/proc0", |
| 204 | "Priority": "H" |
| 205 | }, |
| 206 | { |
| 207 | "LocationCode": "/proc0", |
| 208 | "Priority": "A" |
Zane Shelley | 84721d9 | 2021-09-08 13:30:27 -0500 | [diff] [blame] | 209 | }, |
| 210 | { |
| 211 | "LocationCode": "P0", |
| 212 | "Priority": "L" |
Zane Shelley | 0b8368c | 2021-03-18 17:33:41 -0500 | [diff] [blame] | 213 | } |
| 214 | ])"; |
Zane Shelley | 96d5486 | 2021-09-17 11:16:12 -0500 | [diff] [blame^] | 215 | EXPECT_EQ(s, j.dump(4)); |
| 216 | } |
| 217 | |
| 218 | TEST(Resolution, HardwareCallout) |
| 219 | { |
| 220 | auto c1 = std::make_shared<HardwareCalloutResolution>( |
| 221 | omi_str, callout::Priority::MED_A, true); |
| 222 | |
| 223 | libhei::Chip chip{chip_str, 0xdeadbeef}; |
| 224 | libhei::Signature sig{chip, 0xabcd, 0, 0, libhei::ATTN_TYPE_CHECKSTOP}; |
| 225 | ServiceData sd{sig, true}; |
| 226 | |
| 227 | c1->resolve(sd); |
| 228 | |
| 229 | nlohmann::json j{}; |
| 230 | std::string s{}; |
| 231 | |
| 232 | // Callout list |
| 233 | j = sd.getCalloutList(); |
| 234 | s = R"([ |
| 235 | { |
| 236 | "LocationCode": "/proc0", |
| 237 | "Priority": "A" |
| 238 | } |
| 239 | ])"; |
| 240 | EXPECT_EQ(s, j.dump(4)); |
| 241 | |
| 242 | // Callout FFDC |
| 243 | j = sd.getCalloutFFDC(); |
| 244 | s = R"([ |
| 245 | { |
| 246 | "Callout Type": "Hardware Callout", |
| 247 | "Guard Type": "FATAL", |
| 248 | "Priority": "medium_group_A", |
| 249 | "Target": "/proc0/pib/perv12/mc0/mi0/mcc0/omi0" |
| 250 | } |
| 251 | ])"; |
| 252 | EXPECT_EQ(s, j.dump(4)); |
| 253 | } |
| 254 | |
| 255 | TEST(Resolution, ClockCallout) |
| 256 | { |
| 257 | auto c1 = std::make_shared<ClockCalloutResolution>( |
| 258 | callout::ClockType::OSC_REF_CLOCK_1, callout::Priority::HIGH, false); |
| 259 | |
| 260 | libhei::Chip chip{chip_str, 0xdeadbeef}; |
| 261 | libhei::Signature sig{chip, 0xabcd, 0, 0, libhei::ATTN_TYPE_CHECKSTOP}; |
| 262 | ServiceData sd{sig, true}; |
| 263 | |
| 264 | c1->resolve(sd); |
| 265 | |
| 266 | nlohmann::json j{}; |
| 267 | std::string s{}; |
| 268 | |
| 269 | // Callout list |
| 270 | j = sd.getCalloutList(); |
| 271 | s = R"([ |
| 272 | { |
| 273 | "LocationCode": "P0", |
| 274 | "Priority": "H" |
| 275 | } |
| 276 | ])"; |
| 277 | EXPECT_EQ(s, j.dump(4)); |
| 278 | |
| 279 | // Callout FFDC |
| 280 | j = sd.getCalloutFFDC(); |
| 281 | s = R"([ |
| 282 | { |
| 283 | "Callout Type": "Clock Callout", |
| 284 | "Clock Type": "OSC_REF_CLOCK_1", |
| 285 | "Guard Type": "", |
| 286 | "Priority": "high", |
| 287 | "Target": "/proc0" |
| 288 | } |
| 289 | ])"; |
| 290 | EXPECT_EQ(s, j.dump(4)); |
| 291 | } |
| 292 | |
| 293 | TEST(Resolution, ProcedureCallout) |
| 294 | { |
| 295 | auto c1 = std::make_shared<ProcedureCalloutResolution>( |
| 296 | callout::Procedure::NEXTLVL, callout::Priority::LOW); |
| 297 | |
| 298 | libhei::Chip chip{chip_str, 0xdeadbeef}; |
| 299 | libhei::Signature sig{chip, 0xabcd, 0, 0, libhei::ATTN_TYPE_CHECKSTOP}; |
| 300 | ServiceData sd{sig, true}; |
| 301 | |
| 302 | c1->resolve(sd); |
| 303 | |
| 304 | nlohmann::json j{}; |
| 305 | std::string s{}; |
| 306 | |
| 307 | // Callout list |
| 308 | j = sd.getCalloutList(); |
| 309 | s = R"([ |
| 310 | { |
| 311 | "Priority": "L", |
| 312 | "Procedure": "NEXTLVL" |
| 313 | } |
| 314 | ])"; |
| 315 | EXPECT_EQ(s, j.dump(4)); |
| 316 | |
| 317 | // Callout FFDC |
| 318 | j = sd.getCalloutFFDC(); |
| 319 | s = R"([ |
| 320 | { |
| 321 | "Callout Type": "Procedure Callout", |
| 322 | "Priority": "low", |
| 323 | "Procedure": "NEXTLVL" |
| 324 | } |
| 325 | ])"; |
| 326 | EXPECT_EQ(s, j.dump(4)); |
Zane Shelley | 0b8368c | 2021-03-18 17:33:41 -0500 | [diff] [blame] | 327 | } |