blob: 96cbfa9d16c5ce3bf3b7c21b0d6bd3701e17652a [file] [log] [blame]
Lei YUaf5abc52017-03-07 17:49:17 +08001#include "host_epoch.hpp"
Gunnar Millsab4cc6a2018-09-14 14:42:39 -05002
Lei YU7f4fca52017-02-23 15:15:51 +08003#include "utils.hpp"
Lei YUaf5abc52017-03-07 17:49:17 +08004
Lei YU33752c72018-06-07 17:06:58 +08005#include <phosphor-logging/elog-errors.hpp>
Lei YUaf5abc52017-03-07 17:49:17 +08006#include <phosphor-logging/log.hpp>
Lei YUf6fad822018-07-13 16:35:45 +08007#include <xyz/openbmc_project/Time/error.hpp>
Lei YUaf5abc52017-03-07 17:49:17 +08008
Lei YUaf5abc52017-03-07 17:49:17 +08009namespace phosphor
10{
11namespace time
12{
13using namespace sdbusplus::xyz::openbmc_project::Time;
14using namespace phosphor::logging;
Lei YU7b218792017-02-09 12:10:13 +080015using namespace std::chrono;
Lei YUaf5abc52017-03-07 17:49:17 +080016
Lei YUf6fad822018-07-13 16:35:45 +080017using NotAllowedError =
18 sdbusplus::xyz::openbmc_project::Time::Error::NotAllowed;
19
Gunnar Millsab4cc6a2018-09-14 14:42:39 -050020HostEpoch::HostEpoch(sdbusplus::bus::bus& bus, const char* objPath) :
21 EpochBase(bus, objPath),
22 offset(utils::readData<decltype(offset)::rep>(offsetFile))
Lei YUaf5abc52017-03-07 17:49:17 +080023{
Lei YU7b218792017-02-09 12:10:13 +080024 // Initialize the diffToSteadyClock
Gunnar Millsab4cc6a2018-09-14 14:42:39 -050025 auto steadyTime =
26 duration_cast<microseconds>(steady_clock::now().time_since_epoch());
Lei YU7b218792017-02-09 12:10:13 +080027 diffToSteadyClock = getTime() + offset - steadyTime;
Lei YUaf5abc52017-03-07 17:49:17 +080028}
29
30uint64_t HostEpoch::elapsed() const
31{
Lei YU7b218792017-02-09 12:10:13 +080032 auto ret = getTime();
Lei YUad143542017-07-25 14:27:07 +080033 if (timeOwner == Owner::Split)
Lei YU7b218792017-02-09 12:10:13 +080034 {
35 ret += offset;
36 }
37 return ret.count();
Lei YUaf5abc52017-03-07 17:49:17 +080038}
39
40uint64_t HostEpoch::elapsed(uint64_t value)
41{
Lei YU7b218792017-02-09 12:10:13 +080042 /*
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 Millsab4cc6a2018-09-14 14:42:39 -050055 (timeMode == Mode::NTP &&
56 (timeOwner == Owner::Host || timeOwner == Owner::Both)))
Lei YUaf5abc52017-03-07 17:49:17 +080057 {
Lei YUf6fad822018-07-13 16:35:45 +080058 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 YUaf5abc52017-03-07 17:49:17 +080063 }
64
Lei YU7b218792017-02-09 12:10:13 +080065 auto time = microseconds(value);
Lei YUad143542017-07-25 14:27:07 +080066 if (timeOwner == Owner::Split)
Lei YU7b218792017-02-09 12:10:13 +080067 {
68 // Calculate the offset between host and bmc time
69 offset = time - getTime();
70 saveOffset();
Lei YUaf5abc52017-03-07 17:49:17 +080071
Lei YU7b218792017-02-09 12:10:13 +080072 // Calculate the diff between host and steady time
Gunnar Millsab4cc6a2018-09-14 14:42:39 -050073 auto steadyTime =
74 duration_cast<microseconds>(steady_clock::now().time_since_epoch());
Lei YU7b218792017-02-09 12:10:13 +080075 diffToSteadyClock = time - steadyTime;
76 }
77 else
78 {
79 // Set time to BMC
80 setTime(time);
81 }
Lei YUaf5abc52017-03-07 17:49:17 +080082
83 server::EpochTime::elapsed(value);
84 return value;
85}
86
Lei YU7b218792017-02-09 12:10:13 +080087void 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 YUad143542017-07-25 14:27:07 +080092 if (timeOwner != Owner::Split)
Lei YU7b218792017-02-09 12:10:13 +080093 {
94 offset = microseconds(0);
95 saveOffset();
96 }
Lei YU47263802017-11-08 17:30:04 +080097 else
98 {
99 // In SPLIT, need to re-calculate the diff between
100 // host and steady time
Gunnar Millsab4cc6a2018-09-14 14:42:39 -0500101 auto steadyTime =
102 duration_cast<microseconds>(steady_clock::now().time_since_epoch());
Lei YU47263802017-11-08 17:30:04 +0800103 diffToSteadyClock = getTime() - steadyTime;
104 }
Lei YU7b218792017-02-09 12:10:13 +0800105}
106
107void HostEpoch::saveOffset()
108{
109 // Store the offset to file
110 utils::writeData(offsetFile, offset.count());
111}
112
113void HostEpoch::onBmcTimeChanged(const microseconds& bmcTime)
114{
115 // If owner is split and BMC time is changed,
116 // the offset shall be adjusted
Lei YUad143542017-07-25 14:27:07 +0800117 if (timeOwner == Owner::Split)
Lei YU7b218792017-02-09 12:10:13 +0800118 {
Gunnar Millsab4cc6a2018-09-14 14:42:39 -0500119 auto steadyTime =
120 duration_cast<microseconds>(steady_clock::now().time_since_epoch());
Lei YU7b218792017-02-09 12:10:13 +0800121 auto hostTime = steadyTime + diffToSteadyClock;
122 offset = hostTime - bmcTime;
123
124 saveOffset();
125 }
126}
127
Lei YUaf5abc52017-03-07 17:49:17 +0800128} // namespace time
129} // namespace phosphor