blob: 192f6caec77b03e9d17d7c5c37e5edb5d74bf326 [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#include "cfam_access.hpp"
17#include "ext_interface.hpp"
18#include "p9_cfam.hpp"
19#include "registration.hpp"
20#include "targeting.hpp"
21
22#include <libpdbg.h>
23
24#include <phosphor-logging/log.hpp>
25namespace openpower
26{
27namespace p9
28{
29
30using namespace openpower::cfam::access;
31using namespace openpower::cfam::p9;
32using namespace openpower::targeting;
33
34/**
35 * @brief Continue with memory preserving reboot.
36 * @return void
37 */
38void startHostMpReboot()
39{
40 using namespace phosphor::logging;
41
42 Targeting targets;
43 const auto& master = *(targets.begin());
44
45 log<level::INFO>("Running P9 procedure startHostMpReboot",
46 entry("NUM_PROCS=%d", targets.size()));
47
48 // Ensure asynchronous clock mode is set
49 writeReg(master, P9_LL_MODE_REG, 0x00000001);
50
51 // Clock mux select override
52 for (const auto& t : targets)
53 {
54 writeRegWithMask(t, P9_ROOT_CTRL8, 0x0000000C, 0x0000000C);
55 }
56
57 // Enable P9 checkstop to be reported to the BMC
58
59 // Setup FSI2PIB to report checkstop
60 writeReg(master, P9_FSI_A_SI1S, 0x20000000);
61
62 // Enable Xstop/ATTN interrupt
63 writeReg(master, P9_FSI2PIB_TRUE_MASK, 0x60000000);
64
65 // Arm it
66 writeReg(master, P9_FSI2PIB_INTERRUPT, 0xFFFFFFFF);
67
68 // Kick off the SBE to start the boot
69
70 // Choose seeprom side to boot from
71 cfam_data_t sbeSide = 0;
72 if (getBootCount() > 0)
73 {
74 sbeSide = 0;
75 log<level::INFO>("Setting SBE seeprom side to 0",
76 entry("SBE_SIDE_SELECT=%d", 0));
77 }
78 else
79 {
80 sbeSide = 0x00004000;
81 log<level::INFO>("Setting SBE seeprom side to 1",
82 entry("SBE_SIDE_SELECT=%d", 1));
83 }
84 // Bit 17 of the ctrl status reg indicates sbe seeprom boot side
85 // 0 -> Side 0, 1 -> Side 1
86 writeRegWithMask(master, P9_SBE_CTRL_STATUS, sbeSide, 0x00004000);
87
88 // Call enter mpipl
89 pdbg_targets_init(NULL);
90 struct pdbg_target* target;
91 pdbg_for_each_class_target("pib", target)
92 {
93 if (pdbg_target_probe(target) != PDBG_TARGET_ENABLED)
94 {
95 continue;
96 }
97
98 int error = 0;
99 if ((error = sbe_mpipl_continue(target)) < 0)
100 {
101 log<level::ERR>("Failed to execute sbe_mpipl_contiue");
102 throw std::system_error(error, std::generic_category(),
103 "Failed to continue with mp reboot");
104 }
105 break;
106 }
107}
108
109REGISTER_PROCEDURE("startHostMpReboot", startHostMpReboot);
110
111} // namespace p9
112} // namespace openpower