diff options
author | Alistair Popple <alistair@popple.id.au> | 2014-08-15 14:31:22 +1000 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-08-15 14:36:38 +1000 |
commit | aa3a45f47b0e85f453a5c2d1414bba668328737e (patch) | |
tree | bac0e10afcbc43c58fedd44ca1af77a953d65971 /core | |
parent | 0890debca7cdd9a78ca2d6d52e07609404412818 (diff) | |
download | skiboot-aa3a45f47b0e85f453a5c2d1414bba668328737e.zip skiboot-aa3a45f47b0e85f453a5c2d1414bba668328737e.tar.gz skiboot-aa3a45f47b0e85f453a5c2d1414bba668328737e.tar.bz2 |
fsp/rtc: Use libc time functions
Our libc now has a proper implementation of mktime, which makes adding
tm structures together easy. This patch makes the FSP RTC functions
use the library functions and removes the generic time calculation
code from the FSP RTC driver.
The OPAL<->tm conversion functions are also made public as they will
be useful for the IPMI RTC implementation.
Signed-off-by: Alistair Popple <alistair@popple.id.au>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'core')
-rw-r--r-- | core/Makefile.inc | 3 | ||||
-rw-r--r-- | core/time-utils.c | 94 |
2 files changed, 95 insertions, 2 deletions
diff --git a/core/Makefile.inc b/core/Makefile.inc index 274318d..714da3a 100644 --- a/core/Makefile.inc +++ b/core/Makefile.inc @@ -6,8 +6,7 @@ CORE_OBJS += malloc.o lock.o cpu.o utils.o fdt.o opal.o interrupts.o CORE_OBJS += timebase.o opal-msg.o pci.o pci-opal.o fast-reboot.o CORE_OBJS += device.o exceptions.o trace.o affinity.o vpd.o CORE_OBJS += hostservices.o platform.o nvram.o flash-nvram.o hmi.o -CORE_OBJS += console-log.o ipmi.o +CORE_OBJS += console-log.o ipmi.o time-utils.o CORE=core/built-in.o $(CORE): $(CORE_OBJS:%=core/%) - diff --git a/core/time-utils.c b/core/time-utils.c new file mode 100644 index 0000000..10a4da4 --- /dev/null +++ b/core/time-utils.c @@ -0,0 +1,94 @@ +/* Copyright 2013-2014 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <time-utils.h> + +/* MSB is byte 3, LSB is byte 0 */ +static unsigned int bcd_byte(uint32_t bcd, int byteno) +{ + bcd >>= byteno * 8; + return (bcd >> 4 & 0xf) * 10 + (bcd & 0xf); +} + +static uint32_t int_to_bcd2(unsigned int x) +{ + return (((x / 10) << 4) & 0xf0) | (x % 10); +} + +static uint32_t int_to_bcd4(unsigned int x) +{ + return int_to_bcd2(x / 100) << 8 | int_to_bcd2(x % 100); +} + +/* + * Converts an OPAL formated datetime into a struct tm. We ignore microseconds + * as Linux doesn't use them anyway. + * + * | year | month | mday | + * +------------------------------------+ + * | hour | minute | secs | reserved | + * +------------------------------------+ + * | microseconds | + */ + +void datetime_to_tm(uint32_t y_m_d, uint64_t h_m_s_m, struct tm *tm) +{ + uint32_t x; + + tm->tm_year = bcd_byte(y_m_d, 3) * 100 + bcd_byte(y_m_d, 2); + tm->tm_mon = bcd_byte(y_m_d, 1) - 1; + tm->tm_mday = bcd_byte(y_m_d, 0); + + x = h_m_s_m >> 32; + tm->tm_hour = bcd_byte(x, 3); + tm->tm_min = bcd_byte(x, 2); + tm->tm_sec = bcd_byte(x, 1); +} + +/* + * The OPAL API is defined as returned a u64 of a similar + * format to the FSP message; the 32-bit date field is + * in the format: + * + * | year | month | mday | + * + * ... and the 64-bit time field is in the format + * + * | hour | minutes | secs | millisec | + * | ------------------------------------- + * | millisec | reserved | + * + * We simply ignore the microseconds/milliseconds for now + * as I don't quite understand why the OPAL API defines that + * it needs 6 digits for the milliseconds :-) I suspect the + * doc got that wrong and it's supposed to be micro but + * let's ignore it. + * + * Note that Linux doesn't use nor set the ms field anyway. + */ +void tm_to_datetime(struct tm *tm, uint32_t *y_m_d, uint64_t *h_m_s_m) +{ + uint64_t h_m_s; + *y_m_d = int_to_bcd4(tm->tm_year) << 16 | + int_to_bcd2(tm->tm_mon + 1) << 8 | + int_to_bcd2(tm->tm_mday); + + h_m_s = int_to_bcd2(tm->tm_hour) << 24 | + int_to_bcd2(tm->tm_min) << 16 | + int_to_bcd2(tm->tm_sec) << 8; + + *h_m_s_m = h_m_s << 32; +} |