blob: 3c6e2e011fbd1baf5dae0cd5c5b8596f1217f15b [file] [log] [blame]
Dhruvaraj Subhashchandran08fc2642020-02-17 01:47:05 -06001/**
2 * Copyright (C) 2020 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <libpdbg.h>
Dhruvaraj Subhashchandran285f73e2020-05-15 03:35:02 -050018#include <sys/wait.h>
19#include <unistd.h>
Dhruvaraj Subhashchandran08fc2642020-02-17 01:47:05 -060020
21#include <phosphor-logging/log.hpp>
Dhruvaraj Subhashchandran08fc2642020-02-17 01:47:05 -060022#include <vector>
23
24namespace openpower
25{
Dhruvaraj Subhashchandran285f73e2020-05-15 03:35:02 -050026namespace misc
Dhruvaraj Subhashchandran08fc2642020-02-17 01:47:05 -060027{
28
29/**
30 * @brief Calls sbe_enter_mpipl on the SBE in the provided target.
31 * @return void
32 */
33void sbeEnterMpReboot(struct pdbg_target* tgt)
34{
35 using namespace phosphor::logging;
36 int error = 0;
37 if ((error = sbe_mpipl_enter(tgt)) < 0)
38 {
39 log<level::ERR>("Failed to initiate memory preserving reboot");
40 // TODO Create a PEL in the future for this failure case.
41 throw std::system_error(error, std::generic_category(),
42 "Failed to initiate memory preserving reboot");
43 }
44}
45
46/**
47 * @brief initiate memory preserving reboot on each SBE.
48 * @return void
49 */
50void enterMpReboot()
51{
52 using namespace phosphor::logging;
53 struct pdbg_target* target;
Dhruvaraj Subhashchandran285f73e2020-05-15 03:35:02 -050054 std::vector<pid_t> pidList;
55 bool failed = false;
Dhruvaraj Subhashchandran08fc2642020-02-17 01:47:05 -060056 pdbg_targets_init(NULL);
57
58 log<level::INFO>("Starting memory preserving reboot");
59 pdbg_for_each_class_target("pib", target)
60 {
61 if (pdbg_target_probe(target) != PDBG_TARGET_ENABLED)
62 {
63 continue;
64 }
Dhruvaraj Subhashchandran285f73e2020-05-15 03:35:02 -050065
66 pid_t pid = fork();
67
68 if (pid < 0)
69 {
70 log<level::ERR>("Fork failed while starting mp reboot");
71 failed = true;
72 }
73 else if (pid == 0)
74 {
75 sbeEnterMpReboot(target);
76 std::exit(EXIT_SUCCESS);
77 }
78 else
79 {
80 pidList.push_back(std::move(pid));
81 }
Dhruvaraj Subhashchandran08fc2642020-02-17 01:47:05 -060082 }
83
Dhruvaraj Subhashchandran285f73e2020-05-15 03:35:02 -050084 for (auto& p : pidList)
Dhruvaraj Subhashchandran08fc2642020-02-17 01:47:05 -060085 {
Dhruvaraj Subhashchandran285f73e2020-05-15 03:35:02 -050086 int status = 0;
87 waitpid(p, &status, 0);
88 if (WEXITSTATUS(status))
89 {
90 log<level::ERR>("Memory preserving reboot failed");
91 failed = true;
92 }
93 }
94
95 if (failed)
96 {
97 std::exit(EXIT_FAILURE);
Dhruvaraj Subhashchandran08fc2642020-02-17 01:47:05 -060098 }
99}
100
101REGISTER_PROCEDURE("enterMpReboot", enterMpReboot);
102
Dhruvaraj Subhashchandran285f73e2020-05-15 03:35:02 -0500103} // namespace misc
Dhruvaraj Subhashchandran08fc2642020-02-17 01:47:05 -0600104} // namespace openpower