blob: 5f0f83f98a01e4d4c3f74d6ae040746f8da0512e [file] [log] [blame]
Dhruvaraj Subhashchandran858d1aa2021-10-27 03:26:06 -05001extern "C"
2{
3#include <libpdbg.h>
4#include <libpdbg_sbe.h>
5}
6
7#include "sbe_consts.hpp"
8#include "sbe_dump_collector.hpp"
9
10#include <libphal.H>
11#include <sys/wait.h>
12#include <unistd.h>
13
14#include <phosphor-logging/lg2.hpp>
15#include <phosphor-logging/log.hpp>
16
17#include <format>
18#include <stdexcept>
19
20namespace openpower::dump::sbe_chipop
21{
22
23using namespace phosphor::logging;
24using namespace openpower::dump::SBE;
25
26void SbeDumpCollector::collectDump(uint8_t type, uint32_t id,
27 uint64_t failingUnit,
28 const std::filesystem::path& path)
29{
30 lg2::error("Starting dump collection: type:{TYPE} id:{ID} "
31 "failingUnit:{FAILINGUNIT}, path:{PATH}",
32 "TYPE", type, "ID", id, "FAILINGUNIT", failingUnit, "PATH",
33 path.string());
34
35 initializePdbg();
36
37 std::vector<struct pdbg_target*> targets;
38
39 struct pdbg_target* target = nullptr;
40 pdbg_for_each_class_target("proc", target)
41 {
42 if (pdbg_target_probe(target) != PDBG_TARGET_ENABLED ||
43 !openpower::phal::pdbg::isTgtFunctional(target))
44 {
45 continue;
46 }
47
48 targets.push_back(target);
49 }
50
51 std::vector<uint8_t> clockStates = {SBE_CLOCK_ON, SBE_CLOCK_OFF};
52 for (auto cstate : clockStates)
53 {
54 auto futures = spawnDumpCollectionProcesses(type, id, path, failingUnit,
55 cstate, targets);
56
57 // Wait for all asynchronous tasks to complete
58 for (auto& future : futures)
59 {
60 future.wait();
61 }
62 lg2::info(
63 "Dump collection completed for clock state({CSTATE}): type({TYPE}) "
64 "id({ID}) failingUnit({FAILINGUNIT}), path({PATH})",
65 "CSTATE", cstate, "TYPE", type, "ID", id, "FAILINGUNIT",
66 failingUnit, "PATH", path.string());
67 }
68
69 lg2::info("Dump collection completed");
70}
71
72void SbeDumpCollector::initializePdbg()
73{
74 openpower::phal::pdbg::init();
75}
76
77std::vector<std::future<void>> SbeDumpCollector::spawnDumpCollectionProcesses(
78 uint8_t type, uint32_t id, const std::filesystem::path& path,
79 uint64_t failingUnit, uint8_t cstate,
80 const std::vector<struct pdbg_target*>& targets)
81{
82 std::vector<std::future<void>> futures;
83
84 for (auto target : targets)
85 {
86 if (pdbg_target_probe(target) != PDBG_TARGET_ENABLED ||
87 !openpower::phal::pdbg::isTgtFunctional(target))
88 {
89 continue;
90 }
91
92 // Launch an asynchronous task instead of forking
93 auto future =
94 std::async(std::launch::async,
95 [this, target, path, id, type, cstate, failingUnit]() {
96 this->collectDumpFromSBE(target, path, id, type, cstate,
97 failingUnit);
98 });
99
100 futures.push_back(std::move(future));
101 }
102
103 return futures;
104}
105
106void SbeDumpCollector::collectDumpFromSBE(struct pdbg_target* chip,
107 const std::filesystem::path& path,
108 uint32_t id, uint8_t type,
109 uint8_t clockState,
110 uint64_t failingUnit)
111{
112 auto chipPos = pdbg_target_index(chip);
113 lg2::info(
114 "Collecting dump from proc({PROC}): path({PATH}) id({ID}) "
115 "type({TYPE}) clockState({CLOCKSTATE}) failingUnit({FAILINGUNIT})",
116 "PROC", chipPos, "PATH", path.string(), "ID", id, "TYPE", type,
117 "CLOCKSTATE", clockState, "FAILINGUNIT", failingUnit);
118}
119
120} // namespace openpower::dump::sbe_chipop