summaryrefslogtreecommitdiffstats
path: root/src/include/usr/hwas/common/hwas.H
blob: 007eb4ffe911b82aafdc419283d21bfcd1f5c26c (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
/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/include/usr/hwas/common/hwas.H $                          */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2012,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  __HWAS_HWAS_H
#define __HWAS_HWAS_H
/**
 *  @file hwas.H
 *
 *  HardWare Availability Service prototypes.
 *  In trying to keep with C++ tradition, doxygen documentation for functions
 *  are here in the .H file.
 *
 *  All of the following routines are "named isteps" - they are invoked as
 *  tasks by the @ref IStepDispatcher.
 *
 */


/******************************************************************************/
// Includes
/******************************************************************************/
#include <stdint.h>
#include <targeting/common/commontargeting.H>
#include <hwas/common/deconfigGard.H>
#include <hwas/common/hwasError.H>

namespace HWAS
{

/**
 * @brief   initHardware   Common HWAS function to setup the hardware
 *
 *  It will call into the hwas platform-specific platInitHardware()
 *  function to init the FSI hardware.
 *
 * @param  none
 *
 * @return errlHndl_t       valid errlHndl_t handle if there was an error
 *                          NULL if no errors;
 */
errlHndl_t initHardware();

/**
 * @brief   discoverTagets   Common HWAS function to build targeting
 *
 *  This routine will walk through all the targets and initialize HWAS STATE
 *  to a known default value (powered off, etc.)
 *
 *  Then call into the hwas platform-specific platPresenceDetect() function
 *  to read the hardware information, and apply it to the target states,
 *  and call into the hwas platform-specific functions:
 *      platReadIDEC() to get and set the ChipID and EC values.
 *      platReadPartialGood() to get and set the partial good vector.
 *
 * @param  none
 *
 * @return errlHndl_t       valid errlHndl_t handle if there was an error
 *                          NULL if no errors;
 */
errlHndl_t discoverTargets();

/**
 * @brief   restrictECunits   Internal HWAS function to restrict the ECs
 *
 *  This routine will walk through the procs in the list, and turn EC
 *  units to not functional if the number of units is larger than the max
 *  given. This is used for PR keyword and Field Core Override (FCO)
 *  processing.
 *
 * @param[in] i_procRestrict   vector of procRestrict entries
 * @param[in] i_present    boolean for 'present' HWAS value for restricted
 *                          EC units
 * @param[in] i_deconfigReason   DECONFIGURED_BY_ enum or 0
 *
 * @return errlHndl_t       valid errlHndl_t handle if there was an error
 *                          NULL if no errors;
 */

// Maximum number of EXs per proc
#define NUM_EX_PER_EQ     2
#define NUM_EQ_PER_CHIP   6
#define NUM_EX_PER_CHIP   (NUM_EX_PER_EQ * NUM_EQ_PER_CHIP)

// structure used to store proc information for EC restrict processing
typedef struct {
    TARGETING::TargetHandle_t target;      // proc target
    uint32_t group;             // uniq id for this group - ie: FRUID, node
    uint32_t maxECs;            // max EC units for this group
    uint8_t procs;              // number of procs in the group
} procRestrict_t;

errlHndl_t restrictECunits(
    std::vector <procRestrict_t> &i_procRestrict,
    const bool i_present,
    const uint32_t i_deconfigReason);

/**
 * @brief Verifies that the system has enough hardware to proceed through
 *  the IPL.
 *  This function contains checks that are COMMON between HWSV and HB.
 *  platform-specific checks will be called by platCheckMinimimHardware(),
 *  see hwasCommon.H .
 *  If it cannot find minimum hardware, an error will be created and returned.
 *  Error logs will also be created for each hardware module that is not
 *  running.
 *
 * @param[in] i_nodeOrSys Level of HW check node or system
 * @param[out] o_bootable Indicate whether the system is
 *             is bootable with current configuration.
 *             if o_bootable is not NULL an error for
 *             system unavailability will not be logged
 *
 * @return error log handle
 */
errlHndl_t checkMinimumHardware(
    const TARGETING::ConstTargetHandle_t i_nodeOrSys = NULL,
    bool *o_bootable = NULL);

/**
*  @brief  Loop through processors, make sure all have the same EC level
*          create an error log for any slave processor that does not match
*          the master's EC level
*
*
*  @return  errlHndl_t   Error returned will be a summary of all errors that
*                        occurred during the procedure, all PLIDs should match
*/
errlHndl_t validateProcessorEcLevels();

/**
 * @brief Determines if passed in ECs are allowed to be mixed without error
 *
 * Called by validateProcessorEcLevels()
 *
 * @param[in] i_model:    Cumulus or Nimbus
 * @param[in] i_baseEC:   EC level of primary chip
 * @param[in] i_compareEC:  EC level of to check against mixing allowed
 *
 * @return bool -- true if mixing allowed, otherwise false
 *                 note that same EC is not mixed, thus returns false
 */
bool mixedECsAllowed(TARGETING::ATTR_MODEL_type i_model,
                     TARGETING::ATTR_EC_type i_baseEC,
                     TARGETING::ATTR_EC_type i_compareEC);


/**
 * @brief  Struct representing a particular target.  Used by
 * invokePresentByAssoc to populate a vector of TargetInfo's for subsequent
 * use by deconfigPresentByAssoc
 */
struct TargetInfo
{
    TARGETING::ATTR_AFFINITY_PATH_type affinityPath;
    TARGETING::Target * pThisTarget;
    TARGETING::ATTR_TYPE_type type;
    HWAS::DeconfigGard::DeconfiguredByReason reason;
};

// Structure populated in invokePresentByAssoc() for use in presentByAssoc()
typedef std::vector<TargetInfo> TargetInfoVector;

/**
 * @brief Invokes presentByAssoc
 *
 * Called by discoverTargets(). This function queries the system and populates
 * a vector of structs representing functional MCS, MEMBUFS, MBAs, MCAs,DIMMS.
 * This vector is then passed to presentByAssoc() which systematically adds
 * targets to another vector to be deconfigured based on their related targets
 * Upon completion of presentByAssoc(), this function iterates
 * through the returned vector and deconfigures any targets marked
 * for deconfiguration.
 */
void invokePresentByAssoc();

/**
 * @brief Algorithm to validate the memory target structure.
 *
 * For non direct memory, check if a MCS has a MEMBUF, a MEMBUF has a MBA,
 * and the MBA has a DIMM.
 *
 * For direct memory, check if a MCS has a MCA, and a MCA has a DIMM.
 *
 * The vector o_funcTargets is sorted by affinity path to allow a single pass
 * with some backtracking to check every scenario more efficiently.
 * These checks are needed because of scenarios where targets are non-present
 * and their related targets are not marked as deconfigured
 *
 * @param[in/out] io_funcTargets    A vector of functional memory targets
 * @param[out]    o_targToDeconfig  A vector of targets to deconfigure, done
 *                                  this way to allow unit tests
 */
void presentByAssoc(TargetInfoVector& io_funcTargets,
                    TargetInfoVector& o_targToDeconfig);

/**
* @brief Algorithm to set up the EQ_GARD and EC_GARD attributes on the proc
*
* @param[in] i_procTarget    Proccesor target to set attributes on
*/
void setChipletGardsOnProc(TARGETING::Target * i_procTarget);


/**
 * @brief Find the ATTR_EC for all processors and calculate the EFFECTIVE_EC
 *        (the lowest EC found)
 *
 */
void calculateEffectiveEC();


/**
 * @brief Mark any MCA units that are present but have a disabled port as
 *        non-functional
 *
 * @return error log handle
 */
errlHndl_t markDisabledMcas();


/*
 * @brief: This function calls check_for_missing_memory and set
 *         ATTR_PROC_MEM_TO_USE to the processor that we should use
 *         in case of missing memory behind master proc
 *
 * @note:  Only applicable for PHYP based system
 *
 * @param[in]: i_node: Node target to operate on
 *
 * @retval: error log handle
 */
errlHndl_t update_proc_mem_to_use (const TARGETING::Target* i_node);

/*
 * @brief: checks whether we are missing memory behind master proc
 *
 * If there is no memory behind the master proc, then we iterate
 * through all the other procs and figure out a proc that has
 * memory. We figure out the proc with memory and
 * return that to the user as io_proc_mem_to_use. User can update
 * ATTR_PROC_MEM_TO_USE as needed.
 *
 * @note:  Only applicable for PHYP based system
 *
 * @param[in]: i_node: Node target to operate on
 * @param[in/out]: io_proc_mem_to_use: Value of ATTR_PROC_MEM_TO_USE
 *                  the value is changed only if we find missing
 *                  memory
 * @param[out]: o_found_missing_mem: indicated whether we found missing
 *                  memory behind master proc or not
 * @retval error log handle
 */
errlHndl_t check_for_missing_memory (const TARGETING::Target* i_node,
                                     uint8_t & io_proc_mem_to_use,
                                     bool & o_found_missing_mem);

/*
 * @brief  This function takes in proc target and returns group/chip id
 *         in the following bit format: GGGG CCC
 *         where G = Group Id and C = Chip Id
 *
 * @param[in] i_proc: proc target
 * @retval: chip info including group and chip id
 */
uint64_t getGroupChipIdInfo (TARGETING::TargetHandle_t i_proc);

/*
 * @brief  This function takes in the value of ATTR_PROC_MEM_TO_USE
 *         and extract out group and chip id
 *         in the following bit format: GGGG CCC
 *         where G = Group Id and C = Chip Id
 *
 * @param[in] i_proc_mem_to_use: Value of ATTR_PROC_MEM_TO_USE
 * @param[out] o_grp_id: group id
 * @param[out] o_chip_id: chip id
 */
void parseProcMemToUseIntoGrpChipId (uint8_t i_proc_mem_to_use,
                                     uint8_t & o_grp_id,
                                     uint8_t & o_chip_id);

/*
 * @brief This function computes whether current value of
 *        PROC_MEM_TO_USE matches with the expected value.
 *        The expected value can change through the IPL because
 *        we might end up deconfiguring dimms.
 *
 * @param[out] o_valid: true, if current and expected values are the same
 */
errlHndl_t check_current_proc_mem_to_use_is_still_valid (bool o_valid);

};   // end namespace

#endif
OpenPOWER on IntegriCloud