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 "cfam_access.hpp"
17 #include "p9_cfam.hpp"
18 #include "registration.hpp"
19 #include "targeting.hpp"
20 
21 #include <phosphor-logging/log.hpp>
22 
23 namespace openpower
24 {
25 namespace p9
26 {
27 namespace debug
28 {
29 // SBE messaging register - cfam 2809
30 union sbeMsgReg_t
31 {
32     uint32_t data32;
33 
34     struct
35     {
36 #if __BYTE_ORDER == __LITTLE_ENDIAN
37         uint32_t reserved2:6;
38         uint32_t minorStep:6;
39         uint32_t majorStep:8;
40         uint32_t currState:4;
41         uint32_t prevState:4;
42         uint32_t reserved1:2;
43         uint32_t asyncFFDC:1;
44         uint32_t sbeBooted:1;
45 #else
46         uint32_t sbeBooted:1;
47         uint32_t asyncFFDC:1;
48         uint32_t reserved1:2;
49         uint32_t prevState:4;
50         uint32_t currState:4;
51         uint32_t majorStep:8;
52         uint32_t minorStep:6;
53         uint32_t reserved2:6;
54 #endif
55     } PACK;
56 };
57 
58 // HB mailbox scratch register 5 - cfam 283C
59 union MboxScratch5_HB_t
60 {
61     uint32_t data32;
62     struct
63     {
64 #if __BYTE_ORDER == __LITTLE_ENDIAN
65         uint32_t minorStep:8;    // 24:31
66         uint32_t majorStep:8;    // 16:23
67         uint32_t internalStep:4; // 12:15
68         uint32_t reserved:2;     // 10:11
69         uint32_t stepFinish:1;   // 9
70         uint32_t stepStart:1;    // 8
71         uint32_t magic:8;        // 0:7
72 #else
73         uint32_t magic:8;        // 0:7
74         uint32_t stepStart:1;    // 8
75         uint32_t stepFinish:1;   // 9
76         uint32_t reserved:2;     // 10:11
77         uint32_t internalStep:4; // 12:15
78         uint32_t majorStep:8;    // 16:23
79         uint32_t minorStep:8;    // 24:31
80 #endif
81     } PACK;
82 };
83 
84 static constexpr uint8_t HB_MBX5_VALID_FLAG = 0xAA;
85 
86 /**
87  * @brief Capture SBE and HB istep information on watchdog timeout
88  * @return void
89  */
collectSBEHBData()90 void collectSBEHBData()
91 {
92     using namespace openpower::targeting;
93     using namespace openpower::cfam::p9;
94     using namespace openpower::cfam::access;
95     using namespace phosphor::logging;
96 
97     Targeting targets;
98 
99     for (const auto& proc : targets)
100     {
101         // Read and parse SBE messaging register
102         try
103         {
104             auto readData = readReg(proc, P9_SBE_MSG_REGISTER);
105             auto msg = reinterpret_cast<const sbeMsgReg_t*>(&readData);
106             log<level::INFO>("SBE status register",
107                              entry("PROC=%d", proc->getPos()),
108                              entry("SBE_MAJOR_ISTEP=%d", msg->PACK.majorStep),
109                              entry("SBE_MINOR_ISTEP=%d", msg->PACK.minorStep),
110                              entry("REG_VAL=0x%08X", msg->data32));
111         }
112         catch (const std::exception& e)
113         {
114             log<level::ERR>(e.what());
115             // We want to continue - capturing as much info as possible
116         }
117     }
118 
119     const auto& master = *(targets.begin());
120     // Read and parse HB messaging register
121     try
122     {
123         auto readData = readReg(master, P9_HB_MBX5_REG);
124         auto msg = reinterpret_cast<const MboxScratch5_HB_t*>(&readData);
125         if (HB_MBX5_VALID_FLAG == msg->PACK.magic)
126         {
127             log<level::INFO>("HB MBOX 5 register",
128                              entry("HB_MAJOR_ISTEP=%d", msg->PACK.majorStep),
129                              entry("HB_MINOR_ISTEP=%d", msg->PACK.minorStep),
130                              entry("REG_VAL=0x%08X", msg->data32));
131         }
132     }
133     catch (const std::exception& e)
134     {
135         log<level::ERR>(e.what());
136         // We want to continue - capturing as much info as possible
137     }
138 }
139 
140 REGISTER_PROCEDURE("collectSBEHBData", collectSBEHBData)
141 
142 } // namespace debug
143 } // namespace p9
144 } // namespace openpower
145