1 /**
2  * Copyright (C) 2017 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 <phosphor-logging/log.hpp>
17 #include "cfam_access.hpp"
18 #include "p9_cfam.hpp"
19 #include "registration.hpp"
20 #include "targeting.hpp"
21 #include "ext_interface.hpp"
22 
23 namespace openpower
24 {
25 namespace p9
26 {
27 
28 using namespace phosphor::logging;
29 using namespace openpower::cfam::access;
30 using namespace openpower::cfam::p9;
31 using namespace openpower::targeting;
32 
33 
34 /**
35  * @brief Starts the self boot engine on P9 position 0 to kick off a boot.
36  * @return void
37  */
38 void startHost()
39 {
40     Targeting targets;
41     const auto& master = *(targets.begin());
42 
43     log<level::INFO>("Running P9 procedure startHost",
44                      entry("NUM_PROCS=%d", targets.size()));
45 
46     //Ensure asynchronous clock mode is set
47     writeReg(master, P9_LL_MODE_REG, 0x00000001);
48 
49     //Clock mux select override
50     for (const auto& t : targets)
51     {
52         writeRegWithMask(t, P9_ROOT_CTRL8,
53                          0x0000000C, 0x0000000C);
54     }
55 
56     //Enable P9 checkstop to be reported to the BMC
57 
58     //Setup FSI2PIB to report checkstop
59     writeReg(master, P9_FSI_A_SI1S, 0x20000000);
60 
61     //Enable Xstop/ATTN interrupt
62     writeReg(master, P9_FSI2PIB_TRUE_MASK, 0x60000000);
63 
64     //Arm it
65     writeReg(master, P9_FSI2PIB_INTERRUPT, 0xFFFFFFFF);
66 
67     //Kick off the SBE to start the boot
68 
69     // Choose seeprom side to boot from
70     cfam_data_t sbeSide = 0;
71     if(getBootCount() > 0)
72     {
73         sbeSide = 0;
74         log<level::INFO>("Setting SBE seeprom side to 0",
75                 entry("SBE_SIDE_SELECT=%d", 0));
76     }
77     else
78     {
79         sbeSide = 0x00004000;
80         log<level::INFO>("Setting SBE seeprom side to 1",
81                 entry("SBE_SIDE_SELECT=%d", 1));
82     }
83     // Bit 17 of the ctrl status reg indicates sbe seeprom boot side
84     // 0 -> Side 0, 1 -> Side 1
85     writeRegWithMask(master, P9_SBE_CTRL_STATUS, sbeSide, 0x00004000);
86 
87     //Ensure ISTEP stepping isn't enabled
88     writeRegWithMask(master, P9_SCRATCH_REGISTER_8, 0x20000000, 0x20000000);
89 
90     //Start the SBE
91     writeRegWithMask(master, P9_CBS_CS, 0x80000000, 0x80000000);
92 }
93 
94 REGISTER_PROCEDURE("startHost", startHost);
95 
96 }
97 }
98