blob: 8415f15d62ef1bcc20b96db7a50dbf2c5c2a9d9b [file] [log] [blame]
Lei YUaf5abc52017-03-07 17:49:17 +08001#include "host_epoch.hpp"
Lei YU7f4fca52017-02-23 15:15:51 +08002#include "utils.hpp"
Lei YUaf5abc52017-03-07 17:49:17 +08003
4#include <phosphor-logging/log.hpp>
5
Lei YUaf5abc52017-03-07 17:49:17 +08006namespace phosphor
7{
8namespace time
9{
10using namespace sdbusplus::xyz::openbmc_project::Time;
11using namespace phosphor::logging;
Lei YU7b218792017-02-09 12:10:13 +080012using namespace std::chrono;
Lei YUaf5abc52017-03-07 17:49:17 +080013
14HostEpoch::HostEpoch(sdbusplus::bus::bus& bus,
15 const char* objPath)
16 : EpochBase(bus, objPath),
Lei YU7f4fca52017-02-23 15:15:51 +080017 offset(utils::readData<decltype(offset)::rep>(offsetFile))
Lei YUaf5abc52017-03-07 17:49:17 +080018{
Lei YU7b218792017-02-09 12:10:13 +080019 // Initialize the diffToSteadyClock
20 auto steadyTime = duration_cast<microseconds>(
21 steady_clock::now().time_since_epoch());
22 diffToSteadyClock = getTime() + offset - steadyTime;
Lei YUaf5abc52017-03-07 17:49:17 +080023}
24
25uint64_t HostEpoch::elapsed() const
26{
Lei YU7b218792017-02-09 12:10:13 +080027 auto ret = getTime();
Lei YUad143542017-07-25 14:27:07 +080028 if (timeOwner == Owner::Split)
Lei YU7b218792017-02-09 12:10:13 +080029 {
30 ret += offset;
31 }
32 return ret.count();
Lei YUaf5abc52017-03-07 17:49:17 +080033}
34
35uint64_t HostEpoch::elapsed(uint64_t value)
36{
Lei YU7b218792017-02-09 12:10:13 +080037 /*
38 Mode | Owner | Set Host Time
39 ----- | ----- | -------------
40 NTP | BMC | Not allowed
41 NTP | HOST | Not allowed
42 NTP | SPLIT | OK, and just save offset
43 NTP | BOTH | Not allowed
44 MANUAL| BMC | Not allowed
45 MANUAL| HOST | OK, and set time to BMC
46 MANUAL| SPLIT | OK, and just save offset
47 MANUAL| BOTH | OK, and set time to BMC
48 */
49 if (timeOwner == Owner::BMC ||
50 (timeMode == Mode::NTP
Lei YUad143542017-07-25 14:27:07 +080051 && (timeOwner == Owner::Host || timeOwner == Owner::Both)))
Lei YUaf5abc52017-03-07 17:49:17 +080052 {
Lei YU7b218792017-02-09 12:10:13 +080053 log<level::ERR>("Setting HostTime is not allowed");
Lei YUaf5abc52017-03-07 17:49:17 +080054 // TODO: throw NotAllowed exception
55 return 0;
56 }
57
Lei YU7b218792017-02-09 12:10:13 +080058 auto time = microseconds(value);
Lei YUad143542017-07-25 14:27:07 +080059 if (timeOwner == Owner::Split)
Lei YU7b218792017-02-09 12:10:13 +080060 {
61 // Calculate the offset between host and bmc time
62 offset = time - getTime();
63 saveOffset();
Lei YUaf5abc52017-03-07 17:49:17 +080064
Lei YU7b218792017-02-09 12:10:13 +080065 // Calculate the diff between host and steady time
66 auto steadyTime = duration_cast<microseconds>(
67 steady_clock::now().time_since_epoch());
68 diffToSteadyClock = time - steadyTime;
69 }
70 else
71 {
72 // Set time to BMC
73 setTime(time);
74 }
Lei YUaf5abc52017-03-07 17:49:17 +080075
76 server::EpochTime::elapsed(value);
77 return value;
78}
79
Lei YU7b218792017-02-09 12:10:13 +080080void HostEpoch::onOwnerChanged(Owner owner)
81{
82 // If timeOwner is changed to SPLIT, the offset shall be preserved
83 // Otherwise it shall be cleared;
84 timeOwner = owner;
Lei YUad143542017-07-25 14:27:07 +080085 if (timeOwner != Owner::Split)
Lei YU7b218792017-02-09 12:10:13 +080086 {
87 offset = microseconds(0);
88 saveOffset();
89 }
Lei YU47263802017-11-08 17:30:04 +080090 else
91 {
92 // In SPLIT, need to re-calculate the diff between
93 // host and steady time
94 auto steadyTime = duration_cast<microseconds>(
95 steady_clock::now().time_since_epoch());
96 diffToSteadyClock = getTime() - steadyTime;
97 }
Lei YU7b218792017-02-09 12:10:13 +080098}
99
100void HostEpoch::saveOffset()
101{
102 // Store the offset to file
103 utils::writeData(offsetFile, offset.count());
104}
105
106void HostEpoch::onBmcTimeChanged(const microseconds& bmcTime)
107{
108 // If owner is split and BMC time is changed,
109 // the offset shall be adjusted
Lei YUad143542017-07-25 14:27:07 +0800110 if (timeOwner == Owner::Split)
Lei YU7b218792017-02-09 12:10:13 +0800111 {
112 auto steadyTime = duration_cast<microseconds>(
113 steady_clock::now().time_since_epoch());
114 auto hostTime = steadyTime + diffToSteadyClock;
115 offset = hostTime - bmcTime;
116
117 saveOffset();
118 }
119}
120
Lei YUaf5abc52017-03-07 17:49:17 +0800121} // namespace time
122} // namespace phosphor
123