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