1 /**
2  * Copyright © 2020 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 #pragma once
17 
18 #include "device.hpp"
19 #include "id_map.hpp"
20 #include "services.hpp"
21 
22 #include <memory>
23 #include <stdexcept>
24 #include <string>
25 #include <utility>
26 #include <vector>
27 
28 namespace phosphor::power::regulators
29 {
30 
31 // Forward declarations to avoid circular dependencies
32 class System;
33 
34 /**
35  * @class Chassis
36  *
37  * A chassis within the system.
38  *
39  * Chassis are large enclosures that can be independently powered off and on by
40  * the BMC.  Small and mid-sized systems may contain a single chassis.  In a
41  * large rack-mounted system, each drawer may correspond to a chassis.
42  *
43  * A C++ Chassis object only needs to be created if the physical chassis
44  * contains regulators that need to be configured or monitored.
45  */
46 class Chassis
47 {
48   public:
49     // Specify which compiler-generated methods we want
50     Chassis() = delete;
51     Chassis(const Chassis&) = delete;
52     Chassis(Chassis&&) = delete;
53     Chassis& operator=(const Chassis&) = delete;
54     Chassis& operator=(Chassis&&) = delete;
55     ~Chassis() = default;
56 
57     /**
58      * Constructor.
59      *
60      * Throws an exception if any of the input parameters are invalid.
61      *
62      * @param number Chassis number within the system.  Chassis numbers start at
63      *               1 because chassis 0 represents the entire system.
64      * @param inventoryPath D-Bus inventory path for this chassis
65      * @param devices Devices within this chassis, if any.  The vector should
66      *                contain regulator devices and any related devices required
67      *                to perform regulator operations.
68      */
69     explicit Chassis(unsigned int number, const std::string& inventoryPath,
70                      std::vector<std::unique_ptr<Device>> devices =
71                          std::vector<std::unique_ptr<Device>>{}) :
72         number{number},
73         inventoryPath{inventoryPath}, devices{std::move(devices)}
74     {
75         if (number < 1)
76         {
77             throw std::invalid_argument{"Invalid chassis number: " +
78                                         std::to_string(number)};
79         }
80     }
81 
82     /**
83      * Adds the Device and Rail objects in this chassis to the specified IDMap.
84      *
85      * @param idMap mapping from IDs to the associated Device/Rail/Rule objects
86      */
87     void addToIDMap(IDMap& idMap);
88 
89     /**
90      * Clear any cached data about hardware devices.
91      */
92     void clearCache();
93 
94     /**
95      * Clears all error history.
96      *
97      * All data on previously logged errors will be deleted.  If errors occur
98      * again in the future they will be logged again.
99      *
100      * This method is normally called when the system is being powered on.
101      */
102     void clearErrorHistory();
103 
104     /**
105      * Close the devices within this chassis, if any.
106      *
107      * @param services system services like error logging and the journal
108      */
109     void closeDevices(Services& services);
110 
111     /**
112      * Configure the devices within this chassis, if any.
113      *
114      * This method should be called during the boot before regulators are
115      * enabled.
116      *
117      * @param services system services like error logging and the journal
118      * @param system system that contains this chassis
119      */
120     void configure(Services& services, System& system);
121 
122     /**
123      * Detect redundant phase faults in regulator devices in this chassis.
124      *
125      * This method should be called repeatedly based on a timer.
126      *
127      * @param services system services like error logging and the journal
128      * @param system system that contains this chassis
129      */
130     void detectPhaseFaults(Services& services, System& system);
131 
132     /**
133      * Returns the devices within this chassis, if any.
134      *
135      * The vector contains regulator devices and any related devices
136      * required to perform regulator operations.
137      *
138      * @return devices in chassis
139      */
140     const std::vector<std::unique_ptr<Device>>& getDevices() const
141     {
142         return devices;
143     }
144 
145     /**
146      * Returns the D-Bus inventory path for this chassis.
147      *
148      * @return inventory path
149      */
150     const std::string& getInventoryPath() const
151     {
152         return inventoryPath;
153     }
154 
155     /**
156      * Returns the chassis number within the system.
157      *
158      * @return chassis number
159      */
160     unsigned int getNumber() const
161     {
162         return number;
163     }
164 
165     /**
166      * Monitors the sensors for the voltage rails produced by this chassis, if
167      * any.
168      *
169      * This method should be called repeatedly based on a timer.
170      *
171      * @param services system services like error logging and the journal
172      * @param system system that contains the chassis
173      */
174     void monitorSensors(Services& services, System& system);
175 
176   private:
177     /**
178      * Chassis number within the system.
179      *
180      * Chassis numbers start at 1 because chassis 0 represents the entire
181      * system.
182      */
183     const unsigned int number{};
184 
185     /**
186      * D-Bus inventory path for this chassis.
187      */
188     const std::string inventoryPath{};
189 
190     /**
191      * Devices within this chassis, if any.
192      *
193      * The vector contains regulator devices and any related devices
194      * required to perform regulator operations.
195      */
196     std::vector<std::unique_ptr<Device>> devices{};
197 };
198 
199 } // namespace phosphor::power::regulators
200