blob: 48e6ff347671c1d830415f9bb0d3f05cbf5e7d05 [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
Brad Bishop63508a72020-10-27 18:55:01 -040017#include "registration.hpp"
18
Dhruvaraj Subhashchandran08fc2642020-02-17 01:47:05 -060019#include <libpdbg.h>
Dhruvaraj Subhashchandran285f73e2020-05-15 03:35:02 -050020#include <sys/wait.h>
21#include <unistd.h>
Dhruvaraj Subhashchandran08fc2642020-02-17 01:47:05 -060022
23#include <phosphor-logging/log.hpp>
Brad Bishop63508a72020-10-27 18:55:01 -040024#include <system_error>
Dhruvaraj Subhashchandran08fc2642020-02-17 01:47:05 -060025#include <vector>
26
27namespace openpower
28{
Dhruvaraj Subhashchandran285f73e2020-05-15 03:35:02 -050029namespace misc
Dhruvaraj Subhashchandran08fc2642020-02-17 01:47:05 -060030{
31
32/**
33 * @brief Calls sbe_enter_mpipl on the SBE in the provided target.
34 * @return void
35 */
36void sbeEnterMpReboot(struct pdbg_target* tgt)
37{
38 using namespace phosphor::logging;
39 int error = 0;
40 if ((error = sbe_mpipl_enter(tgt)) < 0)
41 {
42 log<level::ERR>("Failed to initiate memory preserving reboot");
43 // TODO Create a PEL in the future for this failure case.
44 throw std::system_error(error, std::generic_category(),
45 "Failed to initiate memory preserving reboot");
46 }
47}
48
49/**
50 * @brief initiate memory preserving reboot on each SBE.
51 * @return void
52 */
53void enterMpReboot()
54{
55 using namespace phosphor::logging;
56 struct pdbg_target* target;
Dhruvaraj Subhashchandran285f73e2020-05-15 03:35:02 -050057 std::vector<pid_t> pidList;
58 bool failed = false;
Dhruvaraj Subhashchandran08fc2642020-02-17 01:47:05 -060059 pdbg_targets_init(NULL);
60
61 log<level::INFO>("Starting memory preserving reboot");
62 pdbg_for_each_class_target("pib", target)
63 {
64 if (pdbg_target_probe(target) != PDBG_TARGET_ENABLED)
65 {
66 continue;
67 }
Dhruvaraj Subhashchandran285f73e2020-05-15 03:35:02 -050068
69 pid_t pid = fork();
70
71 if (pid < 0)
72 {
73 log<level::ERR>("Fork failed while starting mp reboot");
74 failed = true;
75 }
76 else if (pid == 0)
77 {
78 sbeEnterMpReboot(target);
79 std::exit(EXIT_SUCCESS);
80 }
81 else
82 {
83 pidList.push_back(std::move(pid));
84 }
Dhruvaraj Subhashchandran08fc2642020-02-17 01:47:05 -060085 }
86
Dhruvaraj Subhashchandran285f73e2020-05-15 03:35:02 -050087 for (auto& p : pidList)
Dhruvaraj Subhashchandran08fc2642020-02-17 01:47:05 -060088 {
Dhruvaraj Subhashchandran285f73e2020-05-15 03:35:02 -050089 int status = 0;
90 waitpid(p, &status, 0);
91 if (WEXITSTATUS(status))
92 {
93 log<level::ERR>("Memory preserving reboot failed");
94 failed = true;
95 }
96 }
97
98 if (failed)
99 {
100 std::exit(EXIT_FAILURE);
Dhruvaraj Subhashchandran08fc2642020-02-17 01:47:05 -0600101 }
102}
103
Brad Bishop63508a72020-10-27 18:55:01 -0400104REGISTER_PROCEDURE("enterMpReboot", enterMpReboot)
Dhruvaraj Subhashchandran08fc2642020-02-17 01:47:05 -0600105
Dhruvaraj Subhashchandran285f73e2020-05-15 03:35:02 -0500106} // namespace misc
Dhruvaraj Subhashchandran08fc2642020-02-17 01:47:05 -0600107} // namespace openpower