summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.H
blob: 9463db39a94609519dd71006953dc4d6cc746ac2 (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
/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/eff_config/plug_rules.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2019                        */
/* [+] 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                                                     */

///
/// @file plug_rules.H
/// @brief Enforcement of rules for plugging in DIMM
///
// *HWP HWP Owner: Stephen Glancy <sglancy@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: FSP:HB

#ifndef _MSS_PLUG_RULES_H_
#define _MSS_PLUG_RULES_H_

#include <fapi2.H>
#include <cstdint>
#include <generic/memory/lib/utils/dimm/kind.H>

namespace mss
{

namespace plug_rule
{

///
/// @brief Helper function to determine if a given DIMM slot can support an NVDIMM
/// @param[in] const ref to the DIMM target
/// @param[out] o_is_capable true if the DIMM slot is NVDIMM capable
/// @return bool FAPI2_RC_SUCCESS iff we pass without errors
///
fapi2::ReturnCode dimm_slot_is_nv_capable(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
        bool& o_is_capable);


///
/// @brief Enforce the plug-rules per MCS
/// @param[in] i_target FAPI2 target (MCS)
/// @return fapi2::FAPI2_RC_SUCCESS if okay, otherwise a MSS_PLUG_RULE error code
///
fapi2::ReturnCode enforce_plug_rules(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target);

///
/// @brief Enforce the plug-rules per MCA
/// @param[in] i_target FAPI2 target (MCA)
/// @return fapi2::FAPI2_RC_SUCCESS if okay, otherwise a MSS_PLUG_RULE error code
///
fapi2::ReturnCode enforce_plug_rules(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target);

///
/// @brief Helper to evaluate the unsupported rank config override attribute
/// @param[in] i_dimm0_ranks count of the ranks on DIMM in slot 0
/// @param[in] i_dimm1_ranks count of the ranks on DIMM in slot 1
/// @param[in] i_attr value of the attribute containing the unsupported rank configs
/// @return true iff this rank config is supported according to the unsupported attribute
/// @note not to be used to enforce populated/unpopulated - e.g., 0 ranks in both slots is ignored
///
bool unsupported_rank_helper(const uint64_t i_dimm0_ranks,
                             const uint64_t i_dimm1_ranks,
                             const fapi2::buffer<uint64_t>& i_attr);
///
/// @brief Enforces the DEAD LOAD rules
/// @tparam T fapi2::Target, either MCA or MCS
/// @param[in] i_target the MCA/ port target
/// @return fapi2::FAPI2_RC_SUCCESS if okay
/// @note This function will deconfigure the port if it's dual drop and one of the dimms is deconfigured
///
template<fapi2::TargetType T>
fapi2::ReturnCode check_dead_load( const fapi2::Target<T>& i_target);

///
/// @brief Enforce having one solitary DIMM plugged into slot 0
/// @tparam T fapi2::Target, either MCA or MCS
/// @param[in] i_target port target
/// @return fapi2::FAPI2_RC_SUCCESS if okay
///
template<fapi2::TargetType T>
fapi2::ReturnCode empty_slot_zero(const fapi2::Target<T>& i_target);

///
/// @brief Helper to find the best represented DIMM type in a vector of dimm::kind
/// @param[in, out] io_kinds a vector of dimm::kind
/// @return std::pair representing the type and the count.
/// @note the vector of kinds comes back sorted by DIMM type.
///
std::pair<uint8_t, uint64_t> dimm_type_helper(std::vector<dimm::kind<>>& io_kinds);

///
/// @brief Rank violation helper
/// Used to record a rank configuration violation. Broken out from other checking
/// so that we can throw a rank violation directly from VPD processing.
/// @tparam T target type for the error log
/// @param[in] i_target the target which constrains the rank violation checking
/// @param[in] l_dimm0_ranks the number of ranks on the DIMM in slot 0
/// @param[in] l_dimm1_ranks the number of ranks on the DIMM in slot 1
/// @note Commits the proper error log; does little else
/// @note Not presently used, but also not compiled in - left here because I think we're
/// gonna need it eventually.
///
template< fapi2::TargetType T >
inline void rank_violation(const fapi2::Target<T>& i_target, const uint8_t l_dimm0_ranks, const uint8_t l_dimm1_ranks)
{
    // fapi2::current_err will NOT be set which is important for the caller - they can return
    // the original ReturnCode which got us here.
    FAPI_ERR("Rank config on %s violates the rank configuration rules. DIMM0 ranks: %d DIMM1 ranks: %d",
             mss::c_str(i_target), l_dimm0_ranks, l_dimm1_ranks);

    fapi2::MSS_PLUG_RULES_INVALID_RANK_CONFIG()
    .set_RANKS_ON_DIMM0(l_dimm0_ranks)
    .set_RANKS_ON_DIMM1(l_dimm1_ranks)
    .set_TARGET(i_target).execute(fapi2::FAPI2_ERRL_SEV_UNDEFINED, true);
}

///
/// @brief Enforce no mixing DIMM types
/// @param[in] i_target the port to check
/// @param[in] i_kinds a vector of DIMM (sorted while procesing)
/// @return fapi2::FAPI2_RC_SUCCESS if okay, otherwise a MSS_PLUG_RULE error code
/// @note This function will commit error logs representing the mixing failure
///
fapi2::ReturnCode dimm_type_mixing(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
                                   const std::vector<dimm::kind<>>& i_kinds);

///
/// @brief Enforce rank configs
/// Enforces rank configurations which are not part of the VPD/rank config thing.
/// @note Reads an MRW attribute to further limit rank configs.
/// @param[in] i_target the port
/// @param[in] i_kinds a vector of DIMM (sorted while processing)
/// @param[in] i_ranks_override value of mrw_unsupported_rank_config attribute
/// @return fapi2::FAPI2_RC_SUCCESS if okay
/// @note Expects the kind array to represent the DIMM on the port.
///
fapi2::ReturnCode check_rank_config(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
                                    const std::vector<dimm::kind<>>& i_kinds,
                                    const uint64_t i_ranks_override);

///
/// @brief Enforce DRAM width system support checks
/// @param[in] i_target the port
/// @param[in] i_kind a DIMM kind
/// @param[in] i_mrw_supported_list the MRW bitmap's value
/// @return fapi2::FAPI2_RC_SUCCESS if okay
/// @note The DIMM kind should be a DIMM on the MCA
///
fapi2::ReturnCode check_system_supported_dram_width(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
        const dimm::kind<>& i_kind,
        const fapi2::buffer<uint8_t>& i_mrw_supported_list);

///
/// @brief Enforce DRAM width system support checks
/// @param[in] i_target the port
/// @param[in] i_kinds a vector of DIMM (sorted while processing)
/// @return fapi2::FAPI2_RC_SUCCESS if okay
/// @note Expects the kind array to represent the DIMM on the port.
/// This function will commit error logs if a DIMM has an unsupported DRAM width
///
fapi2::ReturnCode check_system_supported_dram_width(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
        const std::vector<dimm::kind<>>& i_kinds);

///
/// @brief Enforce DRAM width checks
/// @note DIMM0's width needs to equal DIMM1's width
/// @param[in] i_target the port
/// @param[in] i_kinds a vector of DIMM (sorted while processing)
/// @return fapi2::FAPI2_RC_SUCCESS if okay
/// @note Expects the kind array to represent the DIMM on the port.
///
fapi2::ReturnCode check_dram_width(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
                                   const std::vector<dimm::kind<>>& i_kinds);

///
/// @brief Enforce DRAM stack type checks
/// @note No 3DS and non-3DS DIMM's can mix
/// @param[in] i_target the port
/// @param[in] i_kinds a vector of DIMM (sorted while processing)
/// @return fapi2::FAPI2_RC_SUCCESS if okay
/// @note Expects the kind array to represent the DIMM on the port.
///
fapi2::ReturnCode check_stack_type(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
                                   const std::vector<dimm::kind<>>& i_kinds);

///
/// @brief Enforce hybrid DIMM checks
/// @note No hybrid/non-hybrid and no different hybrid types
/// @param[in] i_target the port
/// @param[in] i_kinds a vector of DIMM (sorted while processing)
/// @return fapi2::FAPI2_RC_SUCCESS if okay
/// @note Expects the kind array to represent the DIMM on the port.
///
fapi2::ReturnCode check_hybrid(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
                               const std::vector<dimm::kind<>>& i_kinds);

///
/// @brief Enforces that NVDIMM are plugged in the proper location
/// @note NVDIMM can only be plugged in locations where the MRW attribute bitmap is set
/// @param[in] i_target the port
/// @param[in] i_kinds a vector of DIMM (sorted while processing)
/// @return fapi2::FAPI2_RC_SUCCESS if okay
/// @note Expects the kind array to represent the DIMM on the port.
///
fapi2::ReturnCode check_nvdimm(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
                               const std::vector<dimm::kind<>>& i_kinds);

///
/// @brief Enforce the NVDIMM pairing per MCS
/// @param[in] i_target FAPI2 target (MCS)
/// @param[in] i_kinds a vector of DIMM
/// @return fapi2::FAPI2_RC_SUCCESS if okay, otherwise a MSS_PLUG_RULE error code
///
fapi2::ReturnCode check_nvdimm_pairing(const fapi2::Target<fapi2::TARGET_TYPE_MCS> i_target,
                                       const std::vector<dimm::kind<>>& l_kinds);

// Adding in code based plug rules - as supporting code gets added, the following checks can be deleted
namespace code
{

///
/// @brief Checks for invalid LRDIMM plug combinations
/// @param[in] i_kinds a vector of DIMM (sorted while procesing)
/// @return fapi2::FAPI2_RC_SUCCESS if no LRDIMM, otherwise a MSS_PLUG_RULE error code
/// @note This function will commit error logs representing the mixing failure
///
fapi2::ReturnCode check_lrdimm( const std::vector<dimm::kind<>>& i_kinds );

///
/// @brief Enforce equivalent rank and row configs
/// Enforces configurations which will produce equivalent xlate register settings
/// @param[in] i_target the port
/// @param[in] i_kinds a vector of DIMM
/// @return fapi2::FAPI2_RC_SUCCESS if okay
/// @note Expects the kind array to represent the DIMM on the port.
///
fapi2::ReturnCode check_xlate_config(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
                                     const std::vector<dimm::kind<>>& i_kinds);

} // code

} // plug_rule
} // mss

#endif // _MSS_PLUG_RULES_H_
OpenPOWER on IntegriCloud