summaryrefslogtreecommitdiffstats
path: root/src/include/usr/sbeio/sbe_retry_handler.H
blob: deef15c32c4c48577e00922bd4c7781c5214535a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/include/usr/sbeio/sbe_retry_handler.H $                   */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2017,2018                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
#ifndef __SBE_RETRY_HANDLER_H
#define __SBE_RETRY_HANDLER_H

#include <isteps/hwpisteperror.H>
#include <p9_extract_sbe_rc.H>
#include <p9_get_sbe_msg_register.H>
#include <sys/time.h>

namespace SBEIO
{

class SbeRetryHandler
{
    public:
        enum SBE_REG_RETURN
        {
            FAILED_COLLECTING_REG = 0, // Error returned from HWP
            SBE_AT_RUNTIME        = 1, // SBE is at runtime and booted
            SBE_NOT_AT_RUNTIME    = 2, // SBE has failed to boot
            PROC_DECONFIG         = 3, // Deconfig done on Proc with SBE
        };

        //Possible values of iv_sbeMode
        enum SBE_MODE_OF_OPERATION
        {
            INFORMATIONAL_ONLY = 0, // Get error logs from the SBE HWP's
                                    // This will not attempt an SBE restart
                                    // On FSP systems if informational mode is set we will TI
                                    // On BMC systems we will run extract_rc then bail out
            ATTEMPT_REBOOT     = 1, // Full SBE run, attempt to restart
                                    // This will run all the steps and HWP's to attempt
                                    // an SBE restart on both sides.
        };

        enum SBE_RESTART_METHOD
        {
            START_CBS = 0,  // Use p9_start_cbs to restart the SBE
            HRESET    = 1,  // Use Hreset to restart the SBE
        };

        /**
         * @brief Constructor
         *
         * @param[in] i_sbeMode  Execute the SbeRetryHandler in either
         *                       informational mode, attempt to reboot mode,
         *                       or action set mode.
         *                       (@see sbe_retry_handler.H)
         */
        explicit SbeRetryHandler(SBE_MODE_OF_OPERATION i_sbeMode);

        /**
         * @brief Constructor
         *
         * @param[in] i_sbeMode  Execute the SbeRetryHandler in either
         *                       informational mode, attempt to reboot mode,
         *                       or action set mode.
         *                       (@see sbe_retry_handler.H)
         * @param[in] i_plid     A PLID that is to be propagated down to any
         *                       Error Log Entries that may be created
         */
        SbeRetryHandler(SBE_MODE_OF_OPERATION i_sbeMode, uint32_t i_plid);

        /**
         * @brief Destructor
         */
        ~SbeRetryHandler();

        /**************** Functions to return Class Elements ****************/
        inline bool isSbeAtRuntime()
        {
            return (iv_currentSBEState ==
                        SbeRetryHandler::SBE_REG_RETURN::SBE_AT_RUNTIME);
        }

        inline uint32_t getCallerPLID()
        {
            return iv_callerErrorLogPLID;
        }

        inline uint8_t getSwitchCount()
        {
            return iv_switchSidesCount;
        }

        inline sbeMsgReg_t getSbeRegister()
        {
            return iv_sbeRegister;
        }

        inline P9_EXTRACT_SBE_RC::RETURN_ACTION getCurrentAction()
        {
            return iv_currentAction;
        }

        inline SBE_REG_RETURN getCurrentSBEState()
        {
            return iv_currentSBEState;
        }
        inline SBE_RESTART_METHOD getSbeRestartMethod()
        {
            return iv_sbeRestartMethod;
        }
        inline void setSbeRestartMethod(SBE_RESTART_METHOD i_method)
        {
            iv_sbeRestartMethod = i_method;
        }

        inline SBE_MODE_OF_OPERATION getSBEMode()
        {
            return iv_sbeMode;
        }

        inline void setSBEMode(SBE_MODE_OF_OPERATION i_sbeMode)
        {
            iv_sbeMode = i_sbeMode;
        }

        inline bool getUseSDB()
        {
            return iv_useSDB;
        }

        inline void setUseSDB(bool i_useSDB)
        {
            iv_useSDB = i_useSDB;
        }

        inline bool getSecureModeDisabled()
        {
            return iv_secureModeDisabled;
        }

        inline void setSecureModeDisabled(bool i_secureModeDisabled)
        {
            iv_secureModeDisabled = i_secureModeDisabled;
        }

        inline void setInitialPowerOn(bool i_isInitialPowerOn)
        {
            iv_initialPowerOn = i_isInitialPowerOn;
        }

        /**
         * @brief  This function is the main entry point for all of the
         *         SBE handler functions.
         *
         * @param[in]  i_target    - current proc target
         */

        void main_sbe_handler( TARGETING::Target * i_target);

    private:
#ifndef __HOSTBOOT_RUNTIME
        /**
         * @brief  This function will look at the SBE status register and decide
         *         whether to send the SBEIO_DEAD_SBE or SBEIO_HWSV_COLLECT_SBE_RC
         *         along with the TI depending on if the asyncFFDC bit is set in
         *         the status register
         *
         * @param[in]  i_target    - current proc target we are handling fail for
         *
         * @return - void
         */
        void handleFspIplTimeFail(TARGETING::Target * i_target);
#endif

        /**
         * @brief  This function will look at what iv_currentAction is set to
         *          and take into account how many times we have tried to boot
         *          and how many times we have switched sides.
         *          Note: no_recovery is only an acceptable answer if we have tried
         *                all possibilities. That means that we must have attempted
         *                two boots on both sides. If we have not hit our max attempts
         *                for both sides then this procedure should change iv_currentAction
         *                to either RESTART_SBE or REIPL_BKP_SEEPROM
         *
         *
         * @return - void
         */
        void bestEffortCheck();

        /**
         * @brief  This function handles the SBE timeout and loops
         *         required to start it.
         *
         * @param[in]  i_target       - current proc target
         *
         * @return - error, NULL if no error
         */

        errlHndl_t sbe_poll_status_reg(TARGETING::Target * i_target);

        /**
         * @brief  This function handles getting the SBE FFDC.
         *
         * @param[in]     i_target        - current proc target
         *
         * @return - bool for flow control on return to caller, if false,
         *           caller should go on with the processing flow, if true,
         *           caller should interrupt the processing flow and get out
         *           of loop or current iteration
         */

        void sbe_get_ffdc_handler(TARGETING::Target * i_target);

        /**
         * @brief  This function handles the SBE failed to boot error.
         *
         * @param[in]     i_target        - current proc target
         *
         * @return - bool: true if we need to retry
         *
         * Note: This will default to calling the 2 param version w/ i_hideLog
         *       set to TRUE
         */

        void sbe_run_extract_rc(TARGETING::Target * i_target);

        /**
         * @brief  This function deals with the mask needed to switch
         *         boot side on the SBE for a given proc
         *
         * @param[in] i_target - current proc target
         *
         * @return - error, NULL if no error
         */
        errlHndl_t switch_sbe_sides(TARGETING::Target * i_target);


        /**
         * @brief This is the switch case that identifies the action needed
         *        for the RC value in an SBE FFDC package.
         *
         * @param[in] i_rc            - RC value from SBE FFDC package
         *
         * @return - pass(0) or specific returned SBE action
         */
        uint32_t action_for_ffdc_rc( uint32_t i_rc);

        /**
         * @brief This function handles the call to the p9_get_sbe_msg_handler.
         *        It will read the sbe msg register (Cfam 2809 or Scom 50009)
         *        and update iv_currentSBEState to reflect the state that
         *        the sbe's msg register is telling us
         *
         * @param[in] i_target - current proc target
         *
         * @return - return true if reading the message register was a success
         *           return false if there was an error getting the sbe msg register
         */
        bool sbe_run_extract_msg_reg(TARGETING::Target * i_target);

        /************************** Class Elements **************************/

        /*
        * @brief Bit used to tell if we are in secure debug mode. This means
        *        we are expecting a complete restart so it is safe to perform
        *        some extra operations.
        */
        bool iv_useSDB;

        /*
        * @brief Bit used for testing in the lab with systems that have secure
        *        mode disabled.
        *    NOTE: This bit is only used in the lab when running this HWP with cronus.
        *          We offered to have this bit set in FW based on the security settings of the
        *          system HW people told us it would be safer for us to always assume this bit
        *          is off in FW, so we will leave this bit as 0 until the HW devs tell us to use it.
        */
        bool iv_secureModeDisabled;

        /*
         * @brief PLID of the caller. 0 if caller does not
         *        provide one.  Not to be confused with the
         *        PLID when error log is created in the usage
         *        of this class.
         */
        uint32_t iv_callerErrorLogPLID;

        /*
         * @brief Number of times we switch SBE sides. Max is defined by
         *        MAX_SWITCH_SIDE_COUNT
         */
        uint8_t iv_switchSidesCount;

        /*
         * @brief The current sbe register
         */
        sbeMsgReg_t iv_sbeRegister;

        /*
         * @brief The current SBE return action that has to be taken
         */
        P9_EXTRACT_SBE_RC::RETURN_ACTION iv_currentAction;

        /*
         * @brief The current SBE state - booted, failed, or deconfig
         */
        SBE_REG_RETURN iv_currentSBEState;

        /*
         * @brief Currently there are 3 options for what the shutdownReturnCode
         *        will be. It can be 0 if there is no return code we wish to
         *        send with shutdown. Then it can also be SBEIO_HWSV_COLLECT_SBE_RC
         *        to notify that HWSV should collect FFDC or it can be SBEIO_DEAD_SBE
         *        to tell HWSV that the SBE is dead.
         */
        uint32_t iv_shutdownReturnCode;

        /*
        * @brief This value will keep track of how many times we have attempted
        *        to boot the current side of the SBE's seeprom. In the ctor this
        *        value should be 1, because if the retry handler has been called
        *        that means that we have attempted to boot the current side at
        *        least 1 time. When we switch seeprom sides this value should
        *        drop back to 0. It will be incremeted each time we attempt
        *        to call start_cbs or hreset depending on iv_sbeRestartMethod
        */
        uint8_t iv_currentSideBootAttempts;

        /*
        * @brief If the asyncFFDC bit is found to be set on the status register
        *        this indicates to hostboot that the SBE was able to collect
        *        FFDC about what went wrong in its attempt to boot itself
        *        in this case Hostboot will send a FIFO chip op to the SBE
        *        so the SBE will write the FFDC data out to memory where
        *        Hostboot can parse it. Note that after the SBE writes
        *        the data to memory the asyncFFDC bit on the status register
        *        will be off.
        */
        bool iv_ffdcSetAction;


        /*
         * @brief The mode of operation that needs to be run through the
         *        SbeRetryHandler.  The different modes are specified in the
         *        SBE_MODE_OF_OPERATION enum
         */
        SBE_MODE_OF_OPERATION iv_sbeMode;

        /*
         * @brief This instance variable will instruct the main_sbe_handler
         *        loop on what method to use when attempting to restart the
         *        sbe that we have detected an error on. Currently there are
         *        two options to recover an sbe in a bad state. The first option
         *        is to run "start_cbs", this essentially powers down the proc
         *        and starts the boot sequence from the beginning. This is okay
         *        to use when initially trying to poweron slave processor's sbe
         *        but it is not as useful after that as it will blow away any fabric
         *        initialization we have done on the slave proc chip. The other
         *        option is to use HRESET. HRESET will attempt to restart the
         *        sbe on the fly and does not require us to completely restart
         *        the processor. HRESET can be used during runtime to attempt
         *        to recover an sbe while not disrupting the rest of the proc
         *        chips. Both choices are noted in the SBE_RESTART_METHOD enum
         */
        SBE_RESTART_METHOD iv_sbeRestartMethod;

        /*
        * @brief If true, this tells the retry_hanlder that the caller has recently
        *        attempted to boot the sbe on processor passed to the ctor. This
        *        tells us that the sbe_status register is not stale and that we
        *        can use the curState value on the status register to determine
        *        if the SBE made it to runtime or not
        */
        bool iv_initialPowerOn;

}; // End of class SbeRetryHandler

}  // End of namespace SBEIO
#endif
OpenPOWER on IntegriCloud