| Vishwanatha Subbanna | 307d80b | 2017-06-28 15:56:09 +0530 | [diff] [blame] | 1 | #include "occ_status.hpp" | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 2 |  | 
| Chris Cain | 1725767 | 2021-10-22 13:41:03 -0500 | [diff] [blame] | 3 | #include "occ_manager.hpp" | 
| Vishwanatha Subbanna | 6add0b8 | 2017-07-21 19:02:37 +0530 | [diff] [blame] | 4 | #include "occ_sensor.hpp" | 
| Chris Cain | 78e8601 | 2021-03-04 16:15:31 -0600 | [diff] [blame] | 5 | #include "powermode.hpp" | 
| Vishwanatha Subbanna | 30e329a | 2017-07-24 23:13:14 +0530 | [diff] [blame] | 6 | #include "utils.hpp" | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 7 |  | 
 | 8 | #include <phosphor-logging/log.hpp> | 
| Chris Cain | 78e8601 | 2021-03-04 16:15:31 -0600 | [diff] [blame] | 9 |  | 
| Chris Cain | e2d0a43 | 2022-03-28 11:08:49 -0500 | [diff] [blame] | 10 | #include <filesystem> | 
| Patrick Williams | 4800249 | 2024-02-13 21:43:32 -0600 | [diff] [blame] | 11 | #include <format> | 
| Chris Cain | e2d0a43 | 2022-03-28 11:08:49 -0500 | [diff] [blame] | 12 |  | 
| Vishwanatha Subbanna | 307d80b | 2017-06-28 15:56:09 +0530 | [diff] [blame] | 13 | namespace open_power | 
 | 14 | { | 
 | 15 | namespace occ | 
 | 16 | { | 
| Chris Cain | 78e8601 | 2021-03-04 16:15:31 -0600 | [diff] [blame] | 17 |  | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 18 | using namespace phosphor::logging; | 
| Vishwanatha Subbanna | 307d80b | 2017-06-28 15:56:09 +0530 | [diff] [blame] | 19 |  | 
| Chris Cain | c86d80f | 2023-05-04 15:49:18 -0500 | [diff] [blame] | 20 | using ThrottleObj = | 
 | 21 |     sdbusplus::xyz::openbmc_project::Control::Power::server::Throttle; | 
 | 22 |  | 
| Vishwanatha Subbanna | 307d80b | 2017-06-28 15:56:09 +0530 | [diff] [blame] | 23 | // Handles updates to occActive property | 
 | 24 | bool Status::occActive(bool value) | 
 | 25 | { | 
| Vishwanatha Subbanna | 32e84e9 | 2017-06-28 19:17:28 +0530 | [diff] [blame] | 26 |     if (value != this->occActive()) | 
 | 27 |     { | 
| Patrick Williams | 4800249 | 2024-02-13 21:43:32 -0600 | [diff] [blame] | 28 |         log<level::INFO>(std::format("Status::occActive OCC{} changed to {}", | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 29 |                                      instance, value) | 
 | 30 |                              .c_str()); | 
| Vishwanatha Subbanna | 32e84e9 | 2017-06-28 19:17:28 +0530 | [diff] [blame] | 31 |         if (value) | 
 | 32 |         { | 
| Chris Cain | c86d80f | 2023-05-04 15:49:18 -0500 | [diff] [blame] | 33 |             // Clear prior throttle reason (before setting device active) | 
 | 34 |             updateThrottle(false, THROTTLED_ALL); | 
 | 35 |  | 
| Eddie James | aced309 | 2022-04-22 16:19:30 -0500 | [diff] [blame] | 36 |             // Set the device active | 
 | 37 |             device.setActive(true); | 
| Vishwanatha Subbanna | ee4d83d | 2017-06-29 18:35:00 +0530 | [diff] [blame] | 38 |  | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 39 |             // Reset last OCC state | 
 | 40 |             lastState = 0; | 
 | 41 |  | 
| Chris Cain | f0295f5 | 2024-09-12 15:41:14 -0500 | [diff] [blame^] | 42 |             // Start watching for errors (throttles, etc) | 
 | 43 |             try | 
 | 44 |             { | 
 | 45 |                 addErrorWatch(); | 
 | 46 |             } | 
 | 47 |             catch (const OpenFailure& e) | 
 | 48 |             { | 
 | 49 |                 // Failed to add watch for throttle events, request reset to try | 
 | 50 |                 // to recover comm | 
 | 51 |                 log<level::ERR>( | 
 | 52 |                     std::format( | 
 | 53 |                         "Status::occActive: Unable to add error watch(s) for OCC{} watch: {}", | 
 | 54 |                         instance, e.what()) | 
 | 55 |                         .c_str()); | 
 | 56 |                 deviceError(Error::Descriptor(OCC_COMM_ERROR_PATH)); | 
 | 57 |                 return Base::Status::occActive(false); | 
 | 58 |             } | 
 | 59 |  | 
 | 60 |             // Update the OCC active sensor | 
 | 61 |             Base::Status::occActive(value); | 
 | 62 |  | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 63 |             if (device.master()) | 
 | 64 |             { | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 65 |                 // Update powercap bounds from OCC | 
| Chris Cain | 40501a2 | 2022-03-14 17:33:27 -0500 | [diff] [blame] | 66 |                 manager.updatePcapBounds(); | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 67 |             } | 
 | 68 |  | 
| Vishwanatha Subbanna | 2dc9b1a | 2017-08-18 18:29:41 +0530 | [diff] [blame] | 69 |             // Call into Manager to let know that we have bound | 
| Chris Cain | 1be4337 | 2021-12-09 19:29:37 -0600 | [diff] [blame] | 70 |             if (this->managerCallBack) | 
| Vishwanatha Subbanna | 2dc9b1a | 2017-08-18 18:29:41 +0530 | [diff] [blame] | 71 |             { | 
| Sheldon Bailey | 373af75 | 2022-02-21 15:14:00 -0600 | [diff] [blame] | 72 |                 this->managerCallBack(instance, value); | 
| Edward A. James | 9fd2bdc | 2017-11-08 16:18:57 -0600 | [diff] [blame] | 73 |             } | 
| Vishwanatha Subbanna | 32e84e9 | 2017-06-28 19:17:28 +0530 | [diff] [blame] | 74 |         } | 
 | 75 |         else | 
 | 76 |         { | 
| Chris Cain | a7b74dc | 2021-11-10 17:03:43 -0600 | [diff] [blame] | 77 | #ifdef POWER10 | 
| Chris Cain | 1be4337 | 2021-12-09 19:29:37 -0600 | [diff] [blame] | 78 |             if (pmode && device.master()) | 
| Chris Cain | 36f9cde | 2021-11-22 11:18:21 -0600 | [diff] [blame] | 79 |             { | 
 | 80 |                 // Prevent mode changes | 
 | 81 |                 pmode->setMasterActive(false); | 
 | 82 |             } | 
| Chris Cain | a7b74dc | 2021-11-10 17:03:43 -0600 | [diff] [blame] | 83 |             if (safeStateDelayTimer.isEnabled()) | 
 | 84 |             { | 
 | 85 |                 // stop safe delay timer | 
 | 86 |                 safeStateDelayTimer.setEnabled(false); | 
 | 87 |             } | 
 | 88 | #endif | 
| Chris Cain | 36f9cde | 2021-11-22 11:18:21 -0600 | [diff] [blame] | 89 |             // Call into Manager to let know that we will unbind. | 
| Chris Cain | 1be4337 | 2021-12-09 19:29:37 -0600 | [diff] [blame] | 90 |             if (this->managerCallBack) | 
| Chris Cain | 36f9cde | 2021-11-22 11:18:21 -0600 | [diff] [blame] | 91 |             { | 
| Sheldon Bailey | 373af75 | 2022-02-21 15:14:00 -0600 | [diff] [blame] | 92 |                 this->managerCallBack(instance, value); | 
| Chris Cain | 36f9cde | 2021-11-22 11:18:21 -0600 | [diff] [blame] | 93 |             } | 
 | 94 |  | 
| Edward A. James | 9fd2bdc | 2017-11-08 16:18:57 -0600 | [diff] [blame] | 95 |             // Stop watching for errors | 
 | 96 |             removeErrorWatch(); | 
| Vishwanatha Subbanna | ee4d83d | 2017-06-29 18:35:00 +0530 | [diff] [blame] | 97 |  | 
| Eddie James | aced309 | 2022-04-22 16:19:30 -0500 | [diff] [blame] | 98 |             // Set the device inactive | 
 | 99 |             device.setActive(false); | 
| Chris Cain | c86d80f | 2023-05-04 15:49:18 -0500 | [diff] [blame] | 100 |  | 
 | 101 |             // Clear throttles (OCC not active after disabling device) | 
 | 102 |             updateThrottle(false, THROTTLED_ALL); | 
| Vishwanatha Subbanna | 32e84e9 | 2017-06-28 19:17:28 +0530 | [diff] [blame] | 103 |         } | 
 | 104 |     } | 
| Eddie James | aced309 | 2022-04-22 16:19:30 -0500 | [diff] [blame] | 105 |     else if (value && !device.active()) | 
| Edward A. James | 5e17797 | 2017-10-25 15:50:31 -0500 | [diff] [blame] | 106 |     { | 
 | 107 |         // Existing error watch is on a dead file descriptor. | 
| Edward A. James | 9fd2bdc | 2017-11-08 16:18:57 -0600 | [diff] [blame] | 108 |         removeErrorWatch(); | 
| Edward A. James | 5e17797 | 2017-10-25 15:50:31 -0500 | [diff] [blame] | 109 |  | 
 | 110 |         /* | 
 | 111 |          * In it's constructor, Status checks Device::bound() to see if OCC is | 
 | 112 |          * active or not. | 
 | 113 |          * Device::bound() checks for occX-dev0 directory. | 
 | 114 |          * We will lose occX-dev0 directories during FSI rescan. | 
 | 115 |          * So, if we start this application (and construct Status), and then | 
 | 116 |          * later do FSI rescan, we will end up with occActive = true and device | 
 | 117 |          * NOT bound. Lets correct that situation here. | 
 | 118 |          */ | 
| Eddie James | aced309 | 2022-04-22 16:19:30 -0500 | [diff] [blame] | 119 |         device.setActive(true); | 
| Edward A. James | 5e17797 | 2017-10-25 15:50:31 -0500 | [diff] [blame] | 120 |  | 
 | 121 |         // Add error watch again | 
| Chris Cain | f0295f5 | 2024-09-12 15:41:14 -0500 | [diff] [blame^] | 122 |         try | 
 | 123 |         { | 
 | 124 |             addErrorWatch(); | 
 | 125 |         } | 
 | 126 |         catch (const OpenFailure& e) | 
 | 127 |         { | 
 | 128 |             // Failed to add watch for throttle events, request reset to try to | 
 | 129 |             // recover comm | 
 | 130 |             log<level::ERR>( | 
 | 131 |                 std::format( | 
 | 132 |                     "Status::occActive: Unable to add error watch(s) again for OCC{} watch: {}", | 
 | 133 |                     instance, e.what()) | 
 | 134 |                     .c_str()); | 
 | 135 |             deviceError(Error::Descriptor(OCC_COMM_ERROR_PATH)); | 
 | 136 |             return Base::Status::occActive(false); | 
 | 137 |         } | 
| Edward A. James | 5e17797 | 2017-10-25 15:50:31 -0500 | [diff] [blame] | 138 |     } | 
| Eddie James | aced309 | 2022-04-22 16:19:30 -0500 | [diff] [blame] | 139 |     else if (!value && device.active()) | 
| Eddie James | 6d6d1b3 | 2019-04-22 10:45:08 -0500 | [diff] [blame] | 140 |     { | 
 | 141 |         removeErrorWatch(); | 
 | 142 |  | 
 | 143 |         // In the event that the application never receives the active signal | 
 | 144 |         // even though the OCC is active (this can occur if the BMC is rebooted | 
 | 145 |         // with the host on, since the initial OCC driver probe will discover | 
 | 146 |         // the OCCs), this application needs to be able to unbind the device | 
 | 147 |         // when we get the OCC inactive signal. | 
| Eddie James | aced309 | 2022-04-22 16:19:30 -0500 | [diff] [blame] | 148 |         device.setActive(false); | 
| Eddie James | 6d6d1b3 | 2019-04-22 10:45:08 -0500 | [diff] [blame] | 149 |     } | 
| Vishwanatha Subbanna | 307d80b | 2017-06-28 15:56:09 +0530 | [diff] [blame] | 150 |     return Base::Status::occActive(value); | 
 | 151 | } | 
 | 152 |  | 
| Vishwanatha Subbanna | ee4d83d | 2017-06-29 18:35:00 +0530 | [diff] [blame] | 153 | // Callback handler when a device error is reported. | 
| Eddie James | 9789e71 | 2022-05-25 15:43:40 -0500 | [diff] [blame] | 154 | void Status::deviceError(Error::Descriptor d) | 
| Vishwanatha Subbanna | ee4d83d | 2017-06-29 18:35:00 +0530 | [diff] [blame] | 155 | { | 
| Chris Cain | 36f9cde | 2021-11-22 11:18:21 -0600 | [diff] [blame] | 156 | #ifdef POWER10 | 
| Chris Cain | 1be4337 | 2021-12-09 19:29:37 -0600 | [diff] [blame] | 157 |     if (pmode && device.master()) | 
 | 158 |     { | 
 | 159 |         // Prevent mode changes | 
 | 160 |         pmode->setMasterActive(false); | 
 | 161 |     } | 
| Chris Cain | 36f9cde | 2021-11-22 11:18:21 -0600 | [diff] [blame] | 162 | #endif | 
 | 163 |  | 
| Eddie James | 9789e71 | 2022-05-25 15:43:40 -0500 | [diff] [blame] | 164 |     if (d.log) | 
 | 165 |     { | 
 | 166 |         FFDC::createOCCResetPEL(instance, d.path, d.err, d.callout); | 
 | 167 |     } | 
 | 168 |  | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 169 |     // This would deem OCC inactive | 
 | 170 |     this->occActive(false); | 
| Vishwanatha Subbanna | 30e329a | 2017-07-24 23:13:14 +0530 | [diff] [blame] | 171 |  | 
| Eddie James | cbad219 | 2021-10-07 09:39:39 -0500 | [diff] [blame] | 172 |     // Reset the OCC | 
 | 173 |     this->resetOCC(); | 
| Vishwanatha Subbanna | 30e329a | 2017-07-24 23:13:14 +0530 | [diff] [blame] | 174 | } | 
 | 175 |  | 
 | 176 | // Sends message to host control command handler to reset OCC | 
 | 177 | void Status::resetOCC() | 
 | 178 | { | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 179 |     log<level::INFO>( | 
| Patrick Williams | 4800249 | 2024-02-13 21:43:32 -0600 | [diff] [blame] | 180 |         std::format(">>Status::resetOCC() - requesting reset for OCC{}", | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 181 |                     instance) | 
 | 182 |             .c_str()); | 
| Chris Cain | f0295f5 | 2024-09-12 15:41:14 -0500 | [diff] [blame^] | 183 |     this->occActive(false); | 
| Tom Joseph | 0032523 | 2020-07-29 17:51:48 +0530 | [diff] [blame] | 184 | #ifdef PLDM | 
 | 185 |     if (resetCallBack) | 
 | 186 |     { | 
 | 187 |         this->resetCallBack(instance); | 
 | 188 |     } | 
 | 189 | #else | 
| Vishwanatha Subbanna | 30e329a | 2017-07-24 23:13:14 +0530 | [diff] [blame] | 190 |     constexpr auto CONTROL_HOST_PATH = "/org/open_power/control/host0"; | 
 | 191 |     constexpr auto CONTROL_HOST_INTF = "org.open_power.Control.Host"; | 
 | 192 |  | 
 | 193 |     // This will throw exception on failure | 
| George Liu | f3b7514 | 2021-06-10 11:22:50 +0800 | [diff] [blame] | 194 |     auto service = utils::getService(CONTROL_HOST_PATH, CONTROL_HOST_INTF); | 
| Vishwanatha Subbanna | 30e329a | 2017-07-24 23:13:14 +0530 | [diff] [blame] | 195 |  | 
| George Liu | f3b7514 | 2021-06-10 11:22:50 +0800 | [diff] [blame] | 196 |     auto& bus = utils::getBus(); | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 197 |     auto method = bus.new_method_call(service.c_str(), CONTROL_HOST_PATH, | 
 | 198 |                                       CONTROL_HOST_INTF, "Execute"); | 
| Vishwanatha Subbanna | 30e329a | 2017-07-24 23:13:14 +0530 | [diff] [blame] | 199 |     // OCC Reset control command | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 200 |     method.append(convertForMessage(Control::Host::Command::OCCReset).c_str()); | 
| Vishwanatha Subbanna | 30e329a | 2017-07-24 23:13:14 +0530 | [diff] [blame] | 201 |  | 
 | 202 |     // OCC Sensor ID for callout reasons | 
| Patrick Williams | e096270 | 2020-05-13 17:50:22 -0500 | [diff] [blame] | 203 |     method.append(std::variant<uint8_t>(std::get<0>(sensorMap.at(instance)))); | 
| Vishwanatha Subbanna | 30e329a | 2017-07-24 23:13:14 +0530 | [diff] [blame] | 204 |     bus.call_noreply(method); | 
 | 205 |     return; | 
| Tom Joseph | 0032523 | 2020-07-29 17:51:48 +0530 | [diff] [blame] | 206 | #endif | 
| Vishwanatha Subbanna | 30e329a | 2017-07-24 23:13:14 +0530 | [diff] [blame] | 207 | } | 
 | 208 |  | 
 | 209 | // Handler called by Host control command handler to convey the | 
 | 210 | // status of the executed command | 
| Patrick Williams | af40808 | 2022-07-22 19:26:54 -0500 | [diff] [blame] | 211 | void Status::hostControlEvent(sdbusplus::message_t& msg) | 
| Vishwanatha Subbanna | 30e329a | 2017-07-24 23:13:14 +0530 | [diff] [blame] | 212 | { | 
| Vishwanatha Subbanna | 30e329a | 2017-07-24 23:13:14 +0530 | [diff] [blame] | 213 |     std::string cmdCompleted{}; | 
 | 214 |     std::string cmdStatus{}; | 
 | 215 |  | 
 | 216 |     msg.read(cmdCompleted, cmdStatus); | 
 | 217 |  | 
 | 218 |     log<level::DEBUG>("Host control signal values", | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 219 |                       entry("COMMAND=%s", cmdCompleted.c_str()), | 
 | 220 |                       entry("STATUS=%s", cmdStatus.c_str())); | 
| Vishwanatha Subbanna | 30e329a | 2017-07-24 23:13:14 +0530 | [diff] [blame] | 221 |  | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 222 |     if (Control::Host::convertResultFromString(cmdStatus) != | 
 | 223 |         Control::Host::Result::Success) | 
| Vishwanatha Subbanna | 30e329a | 2017-07-24 23:13:14 +0530 | [diff] [blame] | 224 |     { | 
| Gunnar Mills | 94df8c9 | 2018-09-14 14:50:03 -0500 | [diff] [blame] | 225 |         if (Control::Host::convertCommandFromString(cmdCompleted) == | 
 | 226 |             Control::Host::Command::OCCReset) | 
| Vishwanatha Subbanna | 30e329a | 2017-07-24 23:13:14 +0530 | [diff] [blame] | 227 |         { | 
| Gunnar Mills | 85e6520 | 2018-04-08 15:01:54 -0500 | [diff] [blame] | 228 |             // Must be a Timeout. Log an Error trace | 
| Alexander Filippov | 1d69e19 | 2019-03-21 18:12:07 +0300 | [diff] [blame] | 229 |             log<level::ERR>( | 
 | 230 |                 "Error resetting the OCC.", entry("PATH=%s", path.c_str()), | 
 | 231 |                 entry("SENSORID=0x%X", std::get<0>(sensorMap.at(instance)))); | 
| Vishwanatha Subbanna | 30e329a | 2017-07-24 23:13:14 +0530 | [diff] [blame] | 232 |         } | 
 | 233 |     } | 
 | 234 |     return; | 
| Vishwanatha Subbanna | ee4d83d | 2017-06-29 18:35:00 +0530 | [diff] [blame] | 235 | } | 
 | 236 |  | 
| Sheldon Bailey | 373af75 | 2022-02-21 15:14:00 -0600 | [diff] [blame] | 237 | // Called from Manager::pollerTimerExpired() in preperation to POLL OCC. | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 238 | void Status::readOccState() | 
 | 239 | { | 
| Chris Cain | f0295f5 | 2024-09-12 15:41:14 -0500 | [diff] [blame^] | 240 |     if (stateValid) | 
 | 241 |     { | 
 | 242 |         // Reset retry count (since state is good) | 
 | 243 |         currentOccReadRetriesCount = occReadRetries; | 
 | 244 |     } | 
| Sheldon Bailey | 373af75 | 2022-02-21 15:14:00 -0600 | [diff] [blame] | 245 |     occReadStateNow(); | 
| Chris Cain | a8857c5 | 2021-01-27 11:53:05 -0600 | [diff] [blame] | 246 | } | 
 | 247 |  | 
| Chris Cain | 78e8601 | 2021-03-04 16:15:31 -0600 | [diff] [blame] | 248 | #ifdef POWER10 | 
| Chris Cain | 78e8601 | 2021-03-04 16:15:31 -0600 | [diff] [blame] | 249 | // Special processing that needs to happen once the OCCs change to ACTIVE state | 
 | 250 | void Status::occsWentActive() | 
 | 251 | { | 
 | 252 |     CmdStatus status = CmdStatus::SUCCESS; | 
 | 253 |  | 
| Chris Cain | 36f9cde | 2021-11-22 11:18:21 -0600 | [diff] [blame] | 254 |     status = pmode->sendModeChange(); | 
| Chris Cain | 78e8601 | 2021-03-04 16:15:31 -0600 | [diff] [blame] | 255 |     if (status != CmdStatus::SUCCESS) | 
 | 256 |     { | 
| George Liu | b5ca101 | 2021-09-10 12:53:11 +0800 | [diff] [blame] | 257 |         log<level::ERR>( | 
| Patrick Williams | 4800249 | 2024-02-13 21:43:32 -0600 | [diff] [blame] | 258 |             std::format( | 
| George Liu | b5ca101 | 2021-09-10 12:53:11 +0800 | [diff] [blame] | 259 |                 "Status::occsWentActive: OCC mode change failed with status {}", | 
 | 260 |                 status) | 
 | 261 |                 .c_str()); | 
| Chris Cain | c567dc8 | 2022-04-01 15:09:17 -0500 | [diff] [blame] | 262 |  | 
 | 263 |         // Disable and reset to try recovering | 
 | 264 |         deviceError(); | 
| Chris Cain | 78e8601 | 2021-03-04 16:15:31 -0600 | [diff] [blame] | 265 |     } | 
 | 266 |  | 
| Chris Cain | 36f9cde | 2021-11-22 11:18:21 -0600 | [diff] [blame] | 267 |     status = pmode->sendIpsData(); | 
| Chris Cain | 78e8601 | 2021-03-04 16:15:31 -0600 | [diff] [blame] | 268 |     if (status != CmdStatus::SUCCESS) | 
 | 269 |     { | 
 | 270 |         log<level::ERR>( | 
| Patrick Williams | 4800249 | 2024-02-13 21:43:32 -0600 | [diff] [blame] | 271 |             std::format( | 
| George Liu | b5ca101 | 2021-09-10 12:53:11 +0800 | [diff] [blame] | 272 |                 "Status::occsWentActive: Sending Idle Power Save Config data failed with status {}", | 
| Chris Cain | 78e8601 | 2021-03-04 16:15:31 -0600 | [diff] [blame] | 273 |                 status) | 
 | 274 |                 .c_str()); | 
| Chris Cain | c567dc8 | 2022-04-01 15:09:17 -0500 | [diff] [blame] | 275 |  | 
 | 276 |         if (status == CmdStatus::COMM_FAILURE) | 
 | 277 |         { | 
 | 278 |             // Disable and reset to try recovering | 
 | 279 |             deviceError(); | 
 | 280 |         } | 
| Chris Cain | 78e8601 | 2021-03-04 16:15:31 -0600 | [diff] [blame] | 281 |     } | 
 | 282 | } | 
 | 283 |  | 
| Chris Cain | 1725767 | 2021-10-22 13:41:03 -0500 | [diff] [blame] | 284 | // Send Ambient and Altitude to the OCC | 
 | 285 | CmdStatus Status::sendAmbient(const uint8_t inTemp, const uint16_t inAltitude) | 
 | 286 | { | 
 | 287 |     CmdStatus status = CmdStatus::FAILURE; | 
 | 288 |     bool ambientValid = true; | 
 | 289 |     uint8_t ambientTemp = inTemp; | 
 | 290 |     uint16_t altitude = inAltitude; | 
 | 291 |  | 
 | 292 |     if (ambientTemp == 0xFF) | 
 | 293 |     { | 
 | 294 |         // Get latest readings from manager | 
 | 295 |         manager.getAmbientData(ambientValid, ambientTemp, altitude); | 
 | 296 |         log<level::DEBUG>( | 
| Patrick Williams | 4800249 | 2024-02-13 21:43:32 -0600 | [diff] [blame] | 297 |             std::format("sendAmbient: valid: {}, Ambient: {}C, altitude: {}m", | 
| Chris Cain | 1725767 | 2021-10-22 13:41:03 -0500 | [diff] [blame] | 298 |                         ambientValid, ambientTemp, altitude) | 
 | 299 |                 .c_str()); | 
 | 300 |     } | 
 | 301 |  | 
 | 302 |     std::vector<std::uint8_t> cmd, rsp; | 
 | 303 |     cmd.reserve(11); | 
 | 304 |     cmd.push_back(uint8_t(CmdType::SEND_AMBIENT)); | 
 | 305 |     cmd.push_back(0x00);                    // Data Length (2 bytes) | 
 | 306 |     cmd.push_back(0x08);                    // | 
 | 307 |     cmd.push_back(0x00);                    // Version | 
 | 308 |     cmd.push_back(ambientValid ? 0 : 0xFF); // Ambient Status | 
 | 309 |     cmd.push_back(ambientTemp);             // Ambient Temperature | 
 | 310 |     cmd.push_back(altitude >> 8);           // Altitude in meters (2 bytes) | 
 | 311 |     cmd.push_back(altitude & 0xFF);         // | 
 | 312 |     cmd.push_back(0x00);                    // Reserved (3 bytes) | 
 | 313 |     cmd.push_back(0x00); | 
 | 314 |     cmd.push_back(0x00); | 
| Patrick Williams | 4800249 | 2024-02-13 21:43:32 -0600 | [diff] [blame] | 315 |     log<level::DEBUG>(std::format("sendAmbient: SEND_AMBIENT " | 
| Chris Cain | 1725767 | 2021-10-22 13:41:03 -0500 | [diff] [blame] | 316 |                                   "command to OCC{} ({} bytes)", | 
 | 317 |                                   instance, cmd.size()) | 
 | 318 |                           .c_str()); | 
 | 319 |     status = occCmd.send(cmd, rsp); | 
 | 320 |     if (status == CmdStatus::SUCCESS) | 
 | 321 |     { | 
 | 322 |         if (rsp.size() == 5) | 
 | 323 |         { | 
 | 324 |             if (RspStatus::SUCCESS != RspStatus(rsp[2])) | 
 | 325 |             { | 
 | 326 |                 log<level::ERR>( | 
| Patrick Williams | 4800249 | 2024-02-13 21:43:32 -0600 | [diff] [blame] | 327 |                     std::format( | 
| Chris Cain | c567dc8 | 2022-04-01 15:09:17 -0500 | [diff] [blame] | 328 |                         "sendAmbient: SEND_AMBIENT failed with rspStatus 0x{:02X}", | 
| Chris Cain | 1725767 | 2021-10-22 13:41:03 -0500 | [diff] [blame] | 329 |                         rsp[2]) | 
 | 330 |                         .c_str()); | 
 | 331 |                 dump_hex(rsp); | 
 | 332 |                 status = CmdStatus::FAILURE; | 
 | 333 |             } | 
 | 334 |         } | 
 | 335 |         else | 
 | 336 |         { | 
| Chris Cain | c567dc8 | 2022-04-01 15:09:17 -0500 | [diff] [blame] | 337 |             log<level::ERR>( | 
| Patrick Williams | 4800249 | 2024-02-13 21:43:32 -0600 | [diff] [blame] | 338 |                 std::format( | 
| Chris Cain | c567dc8 | 2022-04-01 15:09:17 -0500 | [diff] [blame] | 339 |                     "sendAmbient: INVALID SEND_AMBIENT response length:{}", | 
 | 340 |                     rsp.size()) | 
 | 341 |                     .c_str()); | 
| Chris Cain | 1725767 | 2021-10-22 13:41:03 -0500 | [diff] [blame] | 342 |             dump_hex(rsp); | 
 | 343 |             status = CmdStatus::FAILURE; | 
 | 344 |         } | 
 | 345 |     } | 
 | 346 |     else | 
 | 347 |     { | 
| Chris Cain | c567dc8 | 2022-04-01 15:09:17 -0500 | [diff] [blame] | 348 |         log<level::ERR>( | 
| Patrick Williams | 4800249 | 2024-02-13 21:43:32 -0600 | [diff] [blame] | 349 |             std::format( | 
| Chris Cain | c567dc8 | 2022-04-01 15:09:17 -0500 | [diff] [blame] | 350 |                 "sendAmbient: SEND_AMBIENT FAILED! with status 0x{:02X}", | 
 | 351 |                 status) | 
 | 352 |                 .c_str()); | 
 | 353 |  | 
 | 354 |         if (status == CmdStatus::COMM_FAILURE) | 
| Chris Cain | 1725767 | 2021-10-22 13:41:03 -0500 | [diff] [blame] | 355 |         { | 
| Chris Cain | f0295f5 | 2024-09-12 15:41:14 -0500 | [diff] [blame^] | 356 |             // Disable due to OCC comm failure and reset to try recovering | 
 | 357 |             deviceError(Error::Descriptor(OCC_COMM_ERROR_PATH)); | 
| Chris Cain | 1725767 | 2021-10-22 13:41:03 -0500 | [diff] [blame] | 358 |         } | 
 | 359 |     } | 
 | 360 |  | 
 | 361 |     return status; | 
 | 362 | } | 
| Chris Cain | a7b74dc | 2021-11-10 17:03:43 -0600 | [diff] [blame] | 363 |  | 
 | 364 | // Called when safe timer expires to determine if OCCs need to be reset | 
 | 365 | void Status::safeStateDelayExpired() | 
 | 366 | { | 
 | 367 |     if (this->occActive()) | 
 | 368 |     { | 
 | 369 |         log<level::INFO>( | 
| Patrick Williams | 4800249 | 2024-02-13 21:43:32 -0600 | [diff] [blame] | 370 |             std::format( | 
| Chris Cain | f0295f5 | 2024-09-12 15:41:14 -0500 | [diff] [blame^] | 371 |                 "safeStateDelayExpired: OCC{} state missing or not valid, requesting reset", | 
| Chris Cain | a7b74dc | 2021-11-10 17:03:43 -0600 | [diff] [blame] | 372 |                 instance) | 
 | 373 |                 .c_str()); | 
 | 374 |         // Disable and reset to try recovering | 
| Eddie James | 9789e71 | 2022-05-25 15:43:40 -0500 | [diff] [blame] | 375 |         deviceError(Error::Descriptor(SAFE_ERROR_PATH)); | 
| Chris Cain | a7b74dc | 2021-11-10 17:03:43 -0600 | [diff] [blame] | 376 |     } | 
 | 377 | } | 
| Chris Cain | 78e8601 | 2021-03-04 16:15:31 -0600 | [diff] [blame] | 378 | #endif // POWER10 | 
 | 379 |  | 
| Chris Cain | e2d0a43 | 2022-03-28 11:08:49 -0500 | [diff] [blame] | 380 | fs::path Status::getHwmonPath() | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 381 | { | 
 | 382 |     using namespace std::literals::string_literals; | 
 | 383 |  | 
| Chris Cain | e2d0a43 | 2022-03-28 11:08:49 -0500 | [diff] [blame] | 384 |     if (!fs::exists(hwmonPath)) | 
 | 385 |     { | 
 | 386 |         static bool tracedFail[8] = {0}; | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 387 |  | 
| Chris Cain | e2d0a43 | 2022-03-28 11:08:49 -0500 | [diff] [blame] | 388 |         if (!hwmonPath.empty()) | 
 | 389 |         { | 
| Chris Cain | f0295f5 | 2024-09-12 15:41:14 -0500 | [diff] [blame^] | 390 |             log<level::WARNING>( | 
| Patrick Williams | 4800249 | 2024-02-13 21:43:32 -0600 | [diff] [blame] | 391 |                 std::format("Status::getHwmonPath(): path no longer exists: {}", | 
| Chris Cain | e2d0a43 | 2022-03-28 11:08:49 -0500 | [diff] [blame] | 392 |                             hwmonPath.c_str()) | 
 | 393 |                     .c_str()); | 
 | 394 |             hwmonPath.clear(); | 
 | 395 |         } | 
 | 396 |  | 
 | 397 |         // Build the base HWMON path | 
| Patrick Williams | d7542c8 | 2024-08-16 15:20:28 -0400 | [diff] [blame] | 398 |         fs::path prefixPath = | 
 | 399 |             fs::path{OCC_HWMON_PATH + "occ-hwmon."s + | 
 | 400 |                      std::to_string(instance + 1) + "/hwmon/"s}; | 
| Chris Cain | e2d0a43 | 2022-03-28 11:08:49 -0500 | [diff] [blame] | 401 |  | 
 | 402 |         // Get the hwmonXX directory name | 
 | 403 |         try | 
 | 404 |         { | 
 | 405 |             // there should only be one directory | 
 | 406 |             const int numDirs = std::distance( | 
 | 407 |                 fs::directory_iterator(prefixPath), fs::directory_iterator{}); | 
 | 408 |             if (numDirs == 1) | 
 | 409 |             { | 
 | 410 |                 hwmonPath = *fs::directory_iterator(prefixPath); | 
 | 411 |                 tracedFail[instance] = false; | 
 | 412 |             } | 
 | 413 |             else | 
 | 414 |             { | 
 | 415 |                 if (!tracedFail[instance]) | 
 | 416 |                 { | 
 | 417 |                     log<level::ERR>( | 
| Patrick Williams | 4800249 | 2024-02-13 21:43:32 -0600 | [diff] [blame] | 418 |                         std::format( | 
| Chris Cain | e2d0a43 | 2022-03-28 11:08:49 -0500 | [diff] [blame] | 419 |                             "Status::getHwmonPath(): Found multiple ({}) hwmon paths!", | 
 | 420 |                             numDirs) | 
 | 421 |                             .c_str()); | 
 | 422 |                     tracedFail[instance] = true; | 
 | 423 |                 } | 
 | 424 |             } | 
 | 425 |         } | 
 | 426 |         catch (const fs::filesystem_error& e) | 
 | 427 |         { | 
 | 428 |             if (!tracedFail[instance]) | 
 | 429 |             { | 
 | 430 |                 log<level::ERR>( | 
| Patrick Williams | 4800249 | 2024-02-13 21:43:32 -0600 | [diff] [blame] | 431 |                     std::format( | 
| Chris Cain | e2d0a43 | 2022-03-28 11:08:49 -0500 | [diff] [blame] | 432 |                         "Status::getHwmonPath(): error accessing {}: {}", | 
 | 433 |                         prefixPath.c_str(), e.what()) | 
 | 434 |                         .c_str()); | 
 | 435 |                 tracedFail[instance] = true; | 
 | 436 |             } | 
 | 437 |         } | 
 | 438 |     } | 
 | 439 |  | 
 | 440 |     return hwmonPath; | 
| Chris Cain | 5d66a0a | 2022-02-09 08:52:10 -0600 | [diff] [blame] | 441 | } | 
 | 442 |  | 
| Chris Cain | f0295f5 | 2024-09-12 15:41:14 -0500 | [diff] [blame^] | 443 | // Called to read state and handle any errors | 
| Sheldon Bailey | 373af75 | 2022-02-21 15:14:00 -0600 | [diff] [blame] | 444 | void Status::occReadStateNow() | 
 | 445 | { | 
 | 446 |     unsigned int state; | 
 | 447 |     const fs::path filename = | 
 | 448 |         fs::path(DEV_PATH) / | 
 | 449 |         fs::path(sysfsName + "." + std::to_string(instance + 1)) / "occ_state"; | 
 | 450 |  | 
 | 451 |     std::ifstream file; | 
 | 452 |     bool goodFile = false; | 
 | 453 |  | 
 | 454 |     // open file. | 
 | 455 |     file.open(filename, std::ios::in); | 
 | 456 |     const int openErrno = errno; | 
 | 457 |  | 
 | 458 |     // File is open and state can be used. | 
 | 459 |     if (file.is_open() && file.good()) | 
 | 460 |     { | 
 | 461 |         goodFile = true; | 
 | 462 |         file >> state; | 
| Chris Cain | f0295f5 | 2024-09-12 15:41:14 -0500 | [diff] [blame^] | 463 |         // Read the error code (if any) to check status of the read | 
 | 464 |         std::ios_base::iostate readState = file.rdstate(); | 
 | 465 |         if (readState) | 
 | 466 |         { | 
 | 467 |             // There was a failure reading the file | 
 | 468 |             if (lastOccReadStatus != -1) | 
 | 469 |             { | 
 | 470 |                 // Trace error bits | 
 | 471 |                 std::string errorBits = ""; | 
 | 472 |                 if (readState & std::ios_base::eofbit) | 
 | 473 |                 { | 
 | 474 |                     errorBits += " EOF"; | 
 | 475 |                 } | 
 | 476 |                 if (readState & std::ios_base::failbit) | 
 | 477 |                 { | 
 | 478 |                     errorBits += " failbit"; | 
 | 479 |                 } | 
 | 480 |                 if (readState & std::ios_base::badbit) | 
 | 481 |                 { | 
 | 482 |                     errorBits += " badbit"; | 
 | 483 |                 } | 
 | 484 |                 log<level::ERR>( | 
 | 485 |                     std::format( | 
 | 486 |                         "readOccState: Failed to read OCC{} state: Read error on I/O operation -{}", | 
 | 487 |                         instance, errorBits) | 
 | 488 |                         .c_str()); | 
 | 489 |                 lastOccReadStatus = -1; | 
 | 490 |             } | 
 | 491 |             goodFile = false; | 
 | 492 |         } | 
| Sheldon Bailey | 373af75 | 2022-02-21 15:14:00 -0600 | [diff] [blame] | 493 |  | 
| Chris Cain | f0295f5 | 2024-09-12 15:41:14 -0500 | [diff] [blame^] | 494 |         if (goodFile && (state != lastState)) | 
| Sheldon Bailey | 373af75 | 2022-02-21 15:14:00 -0600 | [diff] [blame] | 495 |         { | 
 | 496 |             // Trace OCC state changes | 
 | 497 |             log<level::INFO>( | 
| Patrick Williams | 4800249 | 2024-02-13 21:43:32 -0600 | [diff] [blame] | 498 |                 std::format( | 
| Chris Cain | bd551de | 2022-04-26 13:41:16 -0500 | [diff] [blame] | 499 |                     "Status::readOccState: OCC{} state 0x{:02X} (lastState: 0x{:02X})", | 
 | 500 |                     instance, state, lastState) | 
| Sheldon Bailey | 373af75 | 2022-02-21 15:14:00 -0600 | [diff] [blame] | 501 |                     .c_str()); | 
 | 502 |             lastState = state; | 
 | 503 | #ifdef POWER10 | 
 | 504 |             if (OccState(state) == OccState::ACTIVE) | 
 | 505 |             { | 
 | 506 |                 if (pmode && device.master()) | 
 | 507 |                 { | 
 | 508 |                     // Set the master OCC on the PowerMode object | 
 | 509 |                     pmode->setMasterOcc(path); | 
 | 510 |                     // Enable mode changes | 
 | 511 |                     pmode->setMasterActive(); | 
 | 512 |  | 
 | 513 |                     // Special processing by master OCC when it goes active | 
 | 514 |                     occsWentActive(); | 
 | 515 |                 } | 
 | 516 |  | 
 | 517 |                 CmdStatus status = sendAmbient(); | 
 | 518 |                 if (status != CmdStatus::SUCCESS) | 
 | 519 |                 { | 
 | 520 |                     log<level::ERR>( | 
| Patrick Williams | 4800249 | 2024-02-13 21:43:32 -0600 | [diff] [blame] | 521 |                         std::format( | 
| Sheldon Bailey | 373af75 | 2022-02-21 15:14:00 -0600 | [diff] [blame] | 522 |                             "readOccState: Sending Ambient failed with status {}", | 
 | 523 |                             status) | 
 | 524 |                             .c_str()); | 
 | 525 |                 } | 
 | 526 |             } | 
 | 527 |  | 
 | 528 |             // If OCC in known Good State. | 
 | 529 |             if ((OccState(state) == OccState::ACTIVE) || | 
 | 530 |                 (OccState(state) == OccState::CHARACTERIZATION) || | 
 | 531 |                 (OccState(state) == OccState::OBSERVATION)) | 
 | 532 |             { | 
 | 533 |                 // Good OCC State then sensors valid again | 
 | 534 |                 stateValid = true; | 
 | 535 |  | 
 | 536 |                 if (safeStateDelayTimer.isEnabled()) | 
 | 537 |                 { | 
 | 538 |                     // stop safe delay timer (no longer in SAFE state) | 
 | 539 |                     safeStateDelayTimer.setEnabled(false); | 
 | 540 |                 } | 
 | 541 |             } | 
| Sheldon Bailey | 373af75 | 2022-02-21 15:14:00 -0600 | [diff] [blame] | 542 |             else | 
 | 543 |             { | 
| Chris Cain | f0295f5 | 2024-09-12 15:41:14 -0500 | [diff] [blame^] | 544 |                 // OCC is in SAFE or some other unsupported state | 
| Sheldon Bailey | 373af75 | 2022-02-21 15:14:00 -0600 | [diff] [blame] | 545 |                 if (!safeStateDelayTimer.isEnabled()) | 
 | 546 |                 { | 
| Chris Cain | f0295f5 | 2024-09-12 15:41:14 -0500 | [diff] [blame^] | 547 |                     log<level::ERR>( | 
 | 548 |                         std::format( | 
 | 549 |                             "readOccState: Invalid OCC{} state of {}, starting safe state delay timer", | 
 | 550 |                             instance, state) | 
 | 551 |                             .c_str()); | 
| Sheldon Bailey | 373af75 | 2022-02-21 15:14:00 -0600 | [diff] [blame] | 552 |                     // start safe delay timer (before requesting reset) | 
 | 553 |                     using namespace std::literals::chrono_literals; | 
 | 554 |                     safeStateDelayTimer.restartOnce(60s); | 
 | 555 |                 } | 
| Chris Cain | f0295f5 | 2024-09-12 15:41:14 -0500 | [diff] [blame^] | 556 |                 // Not a supported state (update sensors to NaN and not | 
 | 557 |                 // functional) | 
| Sheldon Bailey | 373af75 | 2022-02-21 15:14:00 -0600 | [diff] [blame] | 558 |                 stateValid = false; | 
 | 559 |             } | 
 | 560 | #else | 
 | 561 |             // Before P10 state not checked, only used good file open. | 
 | 562 |             stateValid = true; | 
 | 563 | #endif | 
 | 564 |         } | 
 | 565 |     } | 
| Chris Cain | f0295f5 | 2024-09-12 15:41:14 -0500 | [diff] [blame^] | 566 | #ifdef POWER10 | 
 | 567 |     else | 
 | 568 |     { | 
 | 569 |         // Unable to read state | 
 | 570 |         stateValid = false; | 
 | 571 |     } | 
 | 572 | #endif | 
| Sheldon Bailey | 373af75 | 2022-02-21 15:14:00 -0600 | [diff] [blame] | 573 |     file.close(); | 
 | 574 |  | 
 | 575 |     // if failed to Read a state or not a valid state -> Attempt retry | 
 | 576 |     // after 1 Second delay if allowed. | 
 | 577 |     if ((!goodFile) || (!stateValid)) | 
 | 578 |     { | 
 | 579 |         if (!goodFile) | 
 | 580 |         { | 
 | 581 |             // If not able to read, OCC may be offline | 
| Chris Cain | f0295f5 | 2024-09-12 15:41:14 -0500 | [diff] [blame^] | 582 |             if (openErrno != lastOccReadStatus) | 
 | 583 |             { | 
 | 584 |                 log<level::ERR>( | 
 | 585 |                     std::format( | 
 | 586 |                         "Status::readOccState: open/read failed trying to read OCC{} state (open errno={})", | 
 | 587 |                         instance, openErrno) | 
 | 588 |                         .c_str()); | 
 | 589 |                 lastOccReadStatus = openErrno; | 
 | 590 |             } | 
| Sheldon Bailey | 373af75 | 2022-02-21 15:14:00 -0600 | [diff] [blame] | 591 |         } | 
 | 592 |         else | 
 | 593 |         { | 
 | 594 |             // else this failed due to state not valid. | 
| Chris Cain | bd551de | 2022-04-26 13:41:16 -0500 | [diff] [blame] | 595 |             if (state != lastState) | 
 | 596 |             { | 
 | 597 |                 log<level::ERR>( | 
| Patrick Williams | 4800249 | 2024-02-13 21:43:32 -0600 | [diff] [blame] | 598 |                     std::format( | 
| Chris Cain | bd551de | 2022-04-26 13:41:16 -0500 | [diff] [blame] | 599 |                         "Status::readOccState: OCC{} Invalid state 0x{:02X} (last state: 0x{:02X})", | 
 | 600 |                         instance, state, lastState) | 
 | 601 |                         .c_str()); | 
 | 602 |             } | 
| Sheldon Bailey | 373af75 | 2022-02-21 15:14:00 -0600 | [diff] [blame] | 603 |         } | 
 | 604 |  | 
 | 605 | #ifdef READ_OCC_SENSORS | 
| Sheldon Bailey | c8dd459 | 2022-05-12 10:15:14 -0500 | [diff] [blame] | 606 |         manager.setSensorValueToNaN(instance); | 
| Sheldon Bailey | 373af75 | 2022-02-21 15:14:00 -0600 | [diff] [blame] | 607 | #endif | 
 | 608 |  | 
 | 609 |         // See occReadRetries for number of retry attempts. | 
 | 610 |         if (currentOccReadRetriesCount > 0) | 
 | 611 |         { | 
 | 612 |             --currentOccReadRetriesCount; | 
| Sheldon Bailey | 373af75 | 2022-02-21 15:14:00 -0600 | [diff] [blame] | 613 |         } | 
 | 614 |         else | 
 | 615 |         { | 
| Chris Cain | f0295f5 | 2024-09-12 15:41:14 -0500 | [diff] [blame^] | 616 |             log<level::ERR>( | 
 | 617 |                 std::format("readOccState: failed to read OCC{} state!", | 
 | 618 |                             instance) | 
 | 619 |                     .c_str()); | 
 | 620 |  | 
| Sheldon Bailey | 373af75 | 2022-02-21 15:14:00 -0600 | [diff] [blame] | 621 |             // State could not be determined, set it to NO State. | 
 | 622 |             lastState = 0; | 
 | 623 |  | 
 | 624 |             // Disable the ability to send Failed actions until OCC is | 
 | 625 |             // Active again. | 
 | 626 |             stateValid = false; | 
 | 627 |  | 
| Chris Cain | f0295f5 | 2024-09-12 15:41:14 -0500 | [diff] [blame^] | 628 |             // Disable due to OCC comm failure and reset to try recovering | 
 | 629 |             deviceError(Error::Descriptor(OCC_COMM_ERROR_PATH)); | 
 | 630 |  | 
 | 631 |             // Reset retry count (for next attempt after recovery) | 
 | 632 |             currentOccReadRetriesCount = occReadRetries; | 
 | 633 |         } | 
 | 634 |     } | 
 | 635 |     else | 
 | 636 |     { | 
 | 637 |         if (lastOccReadStatus != 0) | 
 | 638 |         { | 
 | 639 |             log<level::INFO>( | 
 | 640 |                 std::format( | 
 | 641 |                     "Status::readOccState: successfully read OCC{} state: {}", | 
 | 642 |                     instance, state) | 
 | 643 |                     .c_str()); | 
 | 644 |             lastOccReadStatus = 0; // no error | 
| Sheldon Bailey | 373af75 | 2022-02-21 15:14:00 -0600 | [diff] [blame] | 645 |         } | 
 | 646 |     } | 
 | 647 | } | 
 | 648 |  | 
| Chris Cain | c86d80f | 2023-05-04 15:49:18 -0500 | [diff] [blame] | 649 | // Update processor throttle status on dbus | 
 | 650 | void Status::updateThrottle(const bool isThrottled, const uint8_t newReason) | 
 | 651 | { | 
 | 652 |     if (!throttleHandle) | 
 | 653 |     { | 
 | 654 |         return; | 
 | 655 |     } | 
 | 656 |  | 
 | 657 |     uint8_t newThrottleCause = throttleCause; | 
 | 658 |  | 
 | 659 |     if (isThrottled) // throttled due to newReason | 
 | 660 |     { | 
 | 661 |         if ((newReason & throttleCause) == 0) | 
 | 662 |         { | 
 | 663 |             // set the bit(s) for passed in reason | 
 | 664 |             newThrottleCause |= newReason; | 
 | 665 |         } | 
 | 666 |         // else no change | 
 | 667 |     } | 
 | 668 |     else // no longer throttled due to newReason | 
 | 669 |     { | 
 | 670 |         if ((newReason & throttleCause) != 0) | 
 | 671 |         { | 
 | 672 |             // clear the bit(s) for passed in reason | 
 | 673 |             newThrottleCause &= ~newReason; | 
 | 674 |         } | 
 | 675 |         // else no change | 
 | 676 |     } | 
 | 677 |  | 
 | 678 |     if (newThrottleCause != throttleCause) | 
 | 679 |     { | 
 | 680 |         if (newThrottleCause == THROTTLED_NONE) | 
 | 681 |         { | 
 | 682 |             log<level::DEBUG>( | 
| Patrick Williams | 4800249 | 2024-02-13 21:43:32 -0600 | [diff] [blame] | 683 |                 std::format( | 
| Chris Cain | c86d80f | 2023-05-04 15:49:18 -0500 | [diff] [blame] | 684 |                     "updateThrottle: OCC{} no longer throttled (prior reason: {})", | 
 | 685 |                     instance, throttleCause) | 
 | 686 |                     .c_str()); | 
 | 687 |             throttleCause = THROTTLED_NONE; | 
 | 688 |             throttleHandle->throttled(false); | 
 | 689 |             throttleHandle->throttleCauses({}); | 
 | 690 |         } | 
 | 691 |         else | 
 | 692 |         { | 
 | 693 |             log<level::DEBUG>( | 
| Patrick Williams | 4800249 | 2024-02-13 21:43:32 -0600 | [diff] [blame] | 694 |                 std::format( | 
| Chris Cain | c86d80f | 2023-05-04 15:49:18 -0500 | [diff] [blame] | 695 |                     "updateThrottle: OCC{} is throttled with reason {} (prior reason: {})", | 
 | 696 |                     instance, newThrottleCause, throttleCause) | 
 | 697 |                     .c_str()); | 
 | 698 |             throttleCause = newThrottleCause; | 
 | 699 |  | 
 | 700 |             std::vector<ThrottleObj::ThrottleReasons> updatedCauses; | 
 | 701 |             if (throttleCause & THROTTLED_POWER) | 
 | 702 |             { | 
 | 703 |                 updatedCauses.push_back( | 
 | 704 |                     throttleHandle->ThrottleReasons::PowerLimit); | 
 | 705 |             } | 
 | 706 |             if (throttleCause & THROTTLED_THERMAL) | 
 | 707 |             { | 
 | 708 |                 updatedCauses.push_back( | 
 | 709 |                     throttleHandle->ThrottleReasons::ThermalLimit); | 
 | 710 |             } | 
 | 711 |             if (throttleCause & THROTTLED_SAFE) | 
 | 712 |             { | 
 | 713 |                 updatedCauses.push_back( | 
 | 714 |                     throttleHandle->ThrottleReasons::ManagementDetectedFault); | 
 | 715 |             } | 
 | 716 |             throttleHandle->throttleCauses(updatedCauses); | 
 | 717 |             throttleHandle->throttled(true); | 
 | 718 |         } | 
 | 719 |     } | 
 | 720 |     // else no change to throttle status | 
 | 721 | } | 
 | 722 |  | 
 | 723 | // Get processor path associated with this OCC | 
 | 724 | void Status::readProcAssociation() | 
 | 725 | { | 
 | 726 |     std::string managingPath = path + "/power_managing"; | 
 | 727 |     log<level::DEBUG>( | 
| Patrick Williams | 4800249 | 2024-02-13 21:43:32 -0600 | [diff] [blame] | 728 |         std::format("readProcAssociation: getting endpoints for {} ({})", | 
| Chris Cain | c86d80f | 2023-05-04 15:49:18 -0500 | [diff] [blame] | 729 |                     managingPath, path) | 
 | 730 |             .c_str()); | 
 | 731 |     try | 
 | 732 |     { | 
 | 733 |         utils::PropertyValue procPathProperty{}; | 
 | 734 |         procPathProperty = utils::getProperty( | 
 | 735 |             managingPath, "xyz.openbmc_project.Association", "endpoints"); | 
 | 736 |         auto result = std::get<std::vector<std::string>>(procPathProperty); | 
 | 737 |         if (result.size() > 0) | 
 | 738 |         { | 
 | 739 |             procPath = result[0]; | 
 | 740 |             log<level::INFO>( | 
| Patrick Williams | 4800249 | 2024-02-13 21:43:32 -0600 | [diff] [blame] | 741 |                 std::format("readProcAssociation: OCC{} has proc={}", instance, | 
| Chris Cain | c86d80f | 2023-05-04 15:49:18 -0500 | [diff] [blame] | 742 |                             procPath.c_str()) | 
 | 743 |                     .c_str()); | 
 | 744 |         } | 
 | 745 |         else | 
 | 746 |         { | 
 | 747 |             log<level::ERR>( | 
| Patrick Williams | 4800249 | 2024-02-13 21:43:32 -0600 | [diff] [blame] | 748 |                 std::format( | 
| Chris Cain | c86d80f | 2023-05-04 15:49:18 -0500 | [diff] [blame] | 749 |                     "readProcAssociation: No processor associated with OCC{} / {}", | 
 | 750 |                     instance, path) | 
 | 751 |                     .c_str()); | 
 | 752 |         } | 
 | 753 |     } | 
 | 754 |     catch (const sdbusplus::exception_t& e) | 
 | 755 |     { | 
 | 756 |         log<level::ERR>( | 
| Patrick Williams | 4800249 | 2024-02-13 21:43:32 -0600 | [diff] [blame] | 757 |             std::format( | 
| Chris Cain | c86d80f | 2023-05-04 15:49:18 -0500 | [diff] [blame] | 758 |                 "readProcAssociation: Unable to get proc assocated with {} - {}", | 
 | 759 |                 path, e.what()) | 
 | 760 |                 .c_str()); | 
 | 761 |         procPath = {}; | 
 | 762 |     } | 
 | 763 | } | 
 | 764 |  | 
| Vishwanatha Subbanna | 307d80b | 2017-06-28 15:56:09 +0530 | [diff] [blame] | 765 | } // namespace occ | 
 | 766 | } // namespace open_power |