Lei YU | af5abc5 | 2017-03-07 17:49:17 +0800 | [diff] [blame] | 1 | #include "host_epoch.hpp" |
Gunnar Mills | ab4cc6a | 2018-09-14 14:42:39 -0500 | [diff] [blame] | 2 | |
Lei YU | 7f4fca5 | 2017-02-23 15:15:51 +0800 | [diff] [blame] | 3 | #include "utils.hpp" |
Lei YU | af5abc5 | 2017-03-07 17:49:17 +0800 | [diff] [blame] | 4 | |
Lei YU | 33752c7 | 2018-06-07 17:06:58 +0800 | [diff] [blame] | 5 | #include <phosphor-logging/elog-errors.hpp> |
Lei YU | af5abc5 | 2017-03-07 17:49:17 +0800 | [diff] [blame] | 6 | #include <phosphor-logging/log.hpp> |
Lei YU | f6fad82 | 2018-07-13 16:35:45 +0800 | [diff] [blame] | 7 | #include <xyz/openbmc_project/Time/error.hpp> |
Lei YU | af5abc5 | 2017-03-07 17:49:17 +0800 | [diff] [blame] | 8 | |
Lei YU | af5abc5 | 2017-03-07 17:49:17 +0800 | [diff] [blame] | 9 | namespace phosphor |
| 10 | { |
| 11 | namespace time |
| 12 | { |
| 13 | using namespace sdbusplus::xyz::openbmc_project::Time; |
| 14 | using namespace phosphor::logging; |
Lei YU | 7b21879 | 2017-02-09 12:10:13 +0800 | [diff] [blame] | 15 | using namespace std::chrono; |
Lei YU | af5abc5 | 2017-03-07 17:49:17 +0800 | [diff] [blame] | 16 | |
Lei YU | f6fad82 | 2018-07-13 16:35:45 +0800 | [diff] [blame] | 17 | using NotAllowedError = |
| 18 | sdbusplus::xyz::openbmc_project::Time::Error::NotAllowed; |
| 19 | |
Gunnar Mills | ab4cc6a | 2018-09-14 14:42:39 -0500 | [diff] [blame] | 20 | HostEpoch::HostEpoch(sdbusplus::bus::bus& bus, const char* objPath) : |
| 21 | EpochBase(bus, objPath), |
| 22 | offset(utils::readData<decltype(offset)::rep>(offsetFile)) |
Lei YU | af5abc5 | 2017-03-07 17:49:17 +0800 | [diff] [blame] | 23 | { |
Lei YU | 7b21879 | 2017-02-09 12:10:13 +0800 | [diff] [blame] | 24 | // Initialize the diffToSteadyClock |
Gunnar Mills | ab4cc6a | 2018-09-14 14:42:39 -0500 | [diff] [blame] | 25 | auto steadyTime = |
| 26 | duration_cast<microseconds>(steady_clock::now().time_since_epoch()); |
Lei YU | 7b21879 | 2017-02-09 12:10:13 +0800 | [diff] [blame] | 27 | diffToSteadyClock = getTime() + offset - steadyTime; |
Lei YU | af5abc5 | 2017-03-07 17:49:17 +0800 | [diff] [blame] | 28 | } |
| 29 | |
| 30 | uint64_t HostEpoch::elapsed() const |
| 31 | { |
Lei YU | 7b21879 | 2017-02-09 12:10:13 +0800 | [diff] [blame] | 32 | auto ret = getTime(); |
Lei YU | ad14354 | 2017-07-25 14:27:07 +0800 | [diff] [blame] | 33 | if (timeOwner == Owner::Split) |
Lei YU | 7b21879 | 2017-02-09 12:10:13 +0800 | [diff] [blame] | 34 | { |
| 35 | ret += offset; |
| 36 | } |
| 37 | return ret.count(); |
Lei YU | af5abc5 | 2017-03-07 17:49:17 +0800 | [diff] [blame] | 38 | } |
| 39 | |
| 40 | uint64_t HostEpoch::elapsed(uint64_t value) |
| 41 | { |
Lei YU | 7b21879 | 2017-02-09 12:10:13 +0800 | [diff] [blame] | 42 | /* |
| 43 | Mode | Owner | Set Host Time |
| 44 | ----- | ----- | ------------- |
| 45 | NTP | BMC | Not allowed |
| 46 | NTP | HOST | Not allowed |
| 47 | NTP | SPLIT | OK, and just save offset |
| 48 | NTP | BOTH | Not allowed |
| 49 | MANUAL| BMC | Not allowed |
| 50 | MANUAL| HOST | OK, and set time to BMC |
| 51 | MANUAL| SPLIT | OK, and just save offset |
| 52 | MANUAL| BOTH | OK, and set time to BMC |
| 53 | */ |
| 54 | if (timeOwner == Owner::BMC || |
Gunnar Mills | ab4cc6a | 2018-09-14 14:42:39 -0500 | [diff] [blame] | 55 | (timeMode == Mode::NTP && |
| 56 | (timeOwner == Owner::Host || timeOwner == Owner::Both))) |
Lei YU | af5abc5 | 2017-03-07 17:49:17 +0800 | [diff] [blame] | 57 | { |
Lei YU | f6fad82 | 2018-07-13 16:35:45 +0800 | [diff] [blame] | 58 | using namespace xyz::openbmc_project::Time; |
| 59 | elog<NotAllowedError>( |
| 60 | NotAllowed::OWNER(utils::ownerToStr(timeOwner).c_str()), |
| 61 | NotAllowed::SYNC_METHOD(utils::modeToStr(timeMode).c_str()), |
| 62 | NotAllowed::REASON("Setting HostTime is not allowed")); |
Lei YU | af5abc5 | 2017-03-07 17:49:17 +0800 | [diff] [blame] | 63 | } |
| 64 | |
Lei YU | 7b21879 | 2017-02-09 12:10:13 +0800 | [diff] [blame] | 65 | auto time = microseconds(value); |
Lei YU | ad14354 | 2017-07-25 14:27:07 +0800 | [diff] [blame] | 66 | if (timeOwner == Owner::Split) |
Lei YU | 7b21879 | 2017-02-09 12:10:13 +0800 | [diff] [blame] | 67 | { |
| 68 | // Calculate the offset between host and bmc time |
| 69 | offset = time - getTime(); |
| 70 | saveOffset(); |
Lei YU | af5abc5 | 2017-03-07 17:49:17 +0800 | [diff] [blame] | 71 | |
Lei YU | 7b21879 | 2017-02-09 12:10:13 +0800 | [diff] [blame] | 72 | // Calculate the diff between host and steady time |
Gunnar Mills | ab4cc6a | 2018-09-14 14:42:39 -0500 | [diff] [blame] | 73 | auto steadyTime = |
| 74 | duration_cast<microseconds>(steady_clock::now().time_since_epoch()); |
Lei YU | 7b21879 | 2017-02-09 12:10:13 +0800 | [diff] [blame] | 75 | diffToSteadyClock = time - steadyTime; |
| 76 | } |
| 77 | else |
| 78 | { |
| 79 | // Set time to BMC |
| 80 | setTime(time); |
| 81 | } |
Lei YU | af5abc5 | 2017-03-07 17:49:17 +0800 | [diff] [blame] | 82 | |
| 83 | server::EpochTime::elapsed(value); |
| 84 | return value; |
| 85 | } |
| 86 | |
Lei YU | 7b21879 | 2017-02-09 12:10:13 +0800 | [diff] [blame] | 87 | void HostEpoch::onOwnerChanged(Owner owner) |
| 88 | { |
| 89 | // If timeOwner is changed to SPLIT, the offset shall be preserved |
| 90 | // Otherwise it shall be cleared; |
| 91 | timeOwner = owner; |
Lei YU | ad14354 | 2017-07-25 14:27:07 +0800 | [diff] [blame] | 92 | if (timeOwner != Owner::Split) |
Lei YU | 7b21879 | 2017-02-09 12:10:13 +0800 | [diff] [blame] | 93 | { |
| 94 | offset = microseconds(0); |
| 95 | saveOffset(); |
| 96 | } |
Lei YU | 4726380 | 2017-11-08 17:30:04 +0800 | [diff] [blame] | 97 | else |
| 98 | { |
| 99 | // In SPLIT, need to re-calculate the diff between |
| 100 | // host and steady time |
Gunnar Mills | ab4cc6a | 2018-09-14 14:42:39 -0500 | [diff] [blame] | 101 | auto steadyTime = |
| 102 | duration_cast<microseconds>(steady_clock::now().time_since_epoch()); |
Lei YU | 4726380 | 2017-11-08 17:30:04 +0800 | [diff] [blame] | 103 | diffToSteadyClock = getTime() - steadyTime; |
| 104 | } |
Lei YU | 7b21879 | 2017-02-09 12:10:13 +0800 | [diff] [blame] | 105 | } |
| 106 | |
| 107 | void HostEpoch::saveOffset() |
| 108 | { |
| 109 | // Store the offset to file |
| 110 | utils::writeData(offsetFile, offset.count()); |
| 111 | } |
| 112 | |
| 113 | void HostEpoch::onBmcTimeChanged(const microseconds& bmcTime) |
| 114 | { |
| 115 | // If owner is split and BMC time is changed, |
| 116 | // the offset shall be adjusted |
Lei YU | ad14354 | 2017-07-25 14:27:07 +0800 | [diff] [blame] | 117 | if (timeOwner == Owner::Split) |
Lei YU | 7b21879 | 2017-02-09 12:10:13 +0800 | [diff] [blame] | 118 | { |
Gunnar Mills | ab4cc6a | 2018-09-14 14:42:39 -0500 | [diff] [blame] | 119 | auto steadyTime = |
| 120 | duration_cast<microseconds>(steady_clock::now().time_since_epoch()); |
Lei YU | 7b21879 | 2017-02-09 12:10:13 +0800 | [diff] [blame] | 121 | auto hostTime = steadyTime + diffToSteadyClock; |
| 122 | offset = hostTime - bmcTime; |
| 123 | |
| 124 | saveOffset(); |
| 125 | } |
| 126 | } |
| 127 | |
Lei YU | af5abc5 | 2017-03-07 17:49:17 +0800 | [diff] [blame] | 128 | } // namespace time |
| 129 | } // namespace phosphor |