xref: /openbmc/phosphor-logging/extensions/openpower-pels/device_callouts.hpp (revision 9ca4d137ad0f0dd03074652c55186a035fba27d1)
1 #pragma once
2 
3 #include <nlohmann/json.hpp>
4 
5 #include <filesystem>
6 #include <string>
7 #include <tuple>
8 #include <vector>
9 
10 /**
11  * @file device_callouts.hpp
12  *
13  * @brief Looks up FRU callouts, which are D-Bus inventory paths,
14  * in JSON for device sysfs paths.
15  *
16  * The code will extract the search keys from the sysfs path to
17  * use to look up the callout list in the JSON.  The callouts will
18  * be sorted by priority as defined in th PEL spec.
19  *
20  * The JSON is normally generated from the MRW, and contains
21  * sections for the following types of callouts:
22  *   * I2C  (also based on bus/addr as well as the path)
23  *   * FSI
24  *   * FSI-I2C
25  *   * FSI-SPI
26  *
27  * The JSON looks like:
28  *
29  * "I2C":
30  *   "<bus>":
31  *     "<address>":
32  *       "Callouts": [
33  *          {
34  *             "LocationCode": "<location code>",
35  *             "Name": "<inventory path>",
36  *             "Priority": "<priority=H/M/L>",
37  *             "MRU": "<optional MRU name>"
38  *          },
39  *          ...
40  *       ],
41  *       "Dest": "<destination MRW target>"
42  *
43  * "FSI":
44  *   "<fsi link>":
45  *     "Callouts": [
46  *            ...
47  *     ],
48  *     "Dest": "<destination MRW target>"
49  *
50  * "FSI-I2C":
51  *    "<fsi link>":
52  *      "<bus>":
53  *        "<address>":
54  *            "Callouts": [
55  *                   ...
56  *             ],
57  *            "Dest": "<destination MRW target>"
58  *
59  * "FSI-SPI":
60  *    "<fsi link>":
61  *      "<bus>":
62  *         "Callouts": [
63  *                ...
64  *         ],
65  *         "Dest": "<destination MRW target>"
66  *
67  */
68 
69 namespace openpower::pels::device_callouts
70 {
71 
72 /**
73  * @brief Represents a callout in the device JSON.
74  *
75  * The debug field will only be filled in for the first
76  * callout in the list of them and contains additional
77  * information about what happened when looking up the
78  * callouts that is meant to aid in debug.
79  */
80 struct Callout
81 {
82     std::string priority;
83     std::string locationCode;
84     std::string name;
85     std::string mru;
86     std::string debug;
87 };
88 
89 /**
90  * @brief Looks up the callouts in a JSON File to add to a PEL
91  *        for when the path between the BMC and the device specified
92  *        by the passed in device path needs to be called out.
93  *
94  * The path is the path used to access the device in sysfs.  It
95  * can be either a directory path or a file path.
96  *
97  * @param[in] devPath - The device path
98  * @param[in] compatibleList - The list of compatible names for this
99  *                             system.
100  * @return std::vector<Callout> - The list of callouts
101  */
102 std::vector<Callout> getCallouts(
103     const std::string& devPath, const std::vector<std::string>& compatibleList);
104 
105 /**
106  * @brief Looks up the callouts to add to a PEL for when the path
107  *        between the BMC and the device specified by the passed in
108  *        I2C bus and address needs to be called out.
109  *
110  * @param[in] i2cBus - The I2C bus
111  * @param[in] i2cAddress - The I2C address
112  * @param[in] compatibleList - The list of compatible names for this
113  *                             system.
114  * @return std::vector<Callout> - The list of callouts
115  */
116 std::vector<Callout>
117     getI2CCallouts(size_t i2cBus, uint8_t i2cAddress,
118                    const std::vector<std::string>& compatibleList);
119 
120 namespace util
121 {
122 
123 /**
124  * @brief The different callout path types
125  */
126 enum class CalloutType
127 {
128     i2c,
129     fsi,
130     fsii2c,
131     fsispi,
132     unknown
133 };
134 
135 /**
136  * @brief Returns the path to the JSON file to look up callouts in.
137  *
138  * @param[in] compatibleList - The list of compatible names for this
139  *                             system.
140  *
141  * @return path - The path to the file.
142  */
143 std::filesystem::path
144     getJSONFilename(const std::vector<std::string>& compatibleList);
145 
146 /**
147  * @brief Looks up the callouts in the JSON using the I2C keys.
148  *
149  * @param[in] i2cBus - The I2C bus
150  * @param[in] i2cAddress - The I2C address
151  * @param[in] calloutJSON - The JSON containing the callouts
152  *
153  * @return std::vector<Callout> - The callouts
154  */
155 std::vector<device_callouts::Callout> calloutI2C(
156     size_t i2CBus, uint8_t i2cAddress, const nlohmann::json& calloutJSON);
157 
158 /**
159  * @brief Determines the type of the path (FSI, I2C, etc) based
160  *        on tokens in the device path.
161  *
162  * @param[in] devPath - The device path
163  *
164  * @return CalloutType - The callout type
165  */
166 CalloutType getCalloutType(const std::string& devPath);
167 
168 /**
169  * @brief Pulls the fields out of the I2C device path to use as search keys
170  *        in the JSON.
171  *
172  * The keys are the I2C bus and address.
173  *
174  * @param[in] devPath - The device path
175  *
176  * @return std::tuple<size_t, uint8_t> - The I2C bus and address keys
177  */
178 std::tuple<size_t, uint8_t> getI2CSearchKeys(const std::string& devPath);
179 
180 /**
181  * @brief Pulls the fields out of the FSI device path to use as search keys
182  *        in the JSON.
183  *
184  * The key is the FSI link.  For multi-hop paths, the links are
185  * separated by '-'s, like "0-1-2".
186  *
187  * @param[in] devPath - The device path
188  *
189  * @return std::string - The FSI links key
190  */
191 std::string getFSISearchKeys(const std::string& devPath);
192 
193 /**
194  * @brief Pulls the fields out of the FSI-I2C device path to use as
195  *        search keys in the JSON.
196  *
197  * The keys are the FSI link string and the  I2C bus and address.
198  *
199  * @param[in] devPath - The device path
200  *
201  * @return std::tuple<std::string, std::tuple<size_t, uint8_t>>
202  *         - The FSI links key along with the I2C bus/address.
203  */
204 std::tuple<std::string, std::tuple<size_t, uint8_t>>
205     getFSII2CSearchKeys(const std::string& devPath);
206 
207 /**
208  * @brief Pulls the fields out of the SPI device path to use as search keys
209  *        in the JSON.
210  *
211  * The key is the SPI bus number.
212  *
213  * @param[in] devPath - The device path
214  *
215  * @return size_t - The SPI bus key
216  */
217 size_t getSPISearchKeys(const std::string& devPath);
218 
219 /**
220  * @brief Pulls the fields out of the FSI-SPI device path to use as
221  *        search keys in the JSON.
222  *
223  * The keys are the FSI link string and the SPI bus number.
224  *
225  * @param[in] devPath - The device path
226  *
227  * @return std::tuple<std::string, size_t>
228  *         - The FSI links key along with the SPI bus number.
229  */
230 std::tuple<std::string, size_t> getFSISPISearchKeys(const std::string& devPath);
231 
232 } // namespace util
233 } // namespace openpower::pels::device_callouts
234