lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1605169793-10481-1-git-send-email-yangtiezhu@loongson.cn>
Date:   Thu, 12 Nov 2020 16:29:53 +0800
From:   Tiezhu Yang <yangtiezhu@...ngson.cn>
To:     Thomas Bogendoerfer <tsbogend@...ha.franken.de>,
        Huacai Chen <chenhc@...ote.com>,
        Jiaxun Yang <jiaxun.yang@...goat.com>
Cc:     linux-mips@...r.kernel.org, linux-kernel@...r.kernel.org,
        Xuefeng Li <lixuefeng@...ngson.cn>,
        Yinglu Yang <yangyinglu@...ngson.cn>
Subject: [PATCH] MIPS: Loongson64: Add read_persistent_clock64()

Add read_persistent_clock64() to read the time from the battery backed
persistent clock. With this patch, we can fix the wrong time issue due
to the system clock is not consistent with hardware clock after resume
from sleep state S3 (suspend to RAM), at the same time, the system time
can be right instead of "Thu Jan 1 08:00:00 CST 1970" without rtc driver.

start_kernel()
  timekeeping_init()
    read_persistent_wall_and_boot_offset()
      read_persistent_clock64()

timekeeping_resume()
  read_persistent_clock64()

timekeeping_suspend()
  read_persistent_clock64()

Signed-off-by: Yinglu Yang <yangyinglu@...ngson.cn>
Signed-off-by: Tiezhu Yang <yangtiezhu@...ngson.cn>
---
 arch/mips/include/asm/mach-loongson64/loongson.h | 20 +++++++++++++++++
 arch/mips/loongson64/time.c                      | 28 +++++++++++++++++++++++-
 2 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/arch/mips/include/asm/mach-loongson64/loongson.h b/arch/mips/include/asm/mach-loongson64/loongson.h
index fde1b75..448289e 100644
--- a/arch/mips/include/asm/mach-loongson64/loongson.h
+++ b/arch/mips/include/asm/mach-loongson64/loongson.h
@@ -238,4 +238,24 @@ extern u64 loongson_freqctrl[MAX_PACKAGES];
 #define LOONGSON_PCIMAP_WIN(WIN, ADDR)	\
 	((((ADDR)>>26) & LOONGSON_PCIMAP_PCIMAP_LO0) << ((WIN)*6))
 
+/* LS7A RTC */
+#define LS7A_MISC_REG_BASE		0x10080000
+#define LS7A_RTC_ADDR_OFFSET		0x50100
+#define LS7A_RTC_SYS_TOYREAD0_OFFSET	0x2c
+#define LS7A_RTC_SYS_TOYREAD1_OFFSET	0x30
+#define LS7A_RTC_REG_BASE		(LS7A_MISC_REG_BASE + LS7A_RTC_ADDR_OFFSET)
+#define LS7A_RTC_SYS_TOYREAD0_ADDR	(LS7A_RTC_REG_BASE + LS7A_RTC_SYS_TOYREAD0_OFFSET)
+#define LS7A_RTC_SYS_TOYREAD1_ADDR	(LS7A_RTC_REG_BASE + LS7A_RTC_SYS_TOYREAD1_OFFSET)
+#define LS7A_RTC_TOY_MON_MASK		GENMASK(31, 26)
+#define LS7A_RTC_TOY_MON_SHIFT		26
+#define LS7A_RTC_TOY_DAY_MASK		GENMASK(25, 21)
+#define LS7A_RTC_TOY_DAY_SHIFT		21
+#define LS7A_RTC_TOY_HOUR_MASK		GENMASK(20, 16)
+#define LS7A_RTC_TOY_HOUR_SHIFT		16
+#define LS7A_RTC_TOY_MIN_MASK		GENMASK(15, 10)
+#define LS7A_RTC_TOY_MIN_SHIFT		10
+#define LS7A_RTC_TOY_SEC_MASK		GENMASK(9, 4)
+#define LS7A_RTC_TOY_SEC_SHIFT		4
+#define LS7A_RTC_YEAR_BASE		1900
+
 #endif /* __ASM_MACH_LOONGSON64_LOONGSON_H */
diff --git a/arch/mips/loongson64/time.c b/arch/mips/loongson64/time.c
index 91e842b..7f3095546 100644
--- a/arch/mips/loongson64/time.c
+++ b/arch/mips/loongson64/time.c
@@ -9,7 +9,7 @@
 
 #include <asm/time.h>
 #include <asm/hpet.h>
-
+#include <asm/mc146818-time.h>
 #include <loongson.h>
 
 void __init plat_time_init(void)
@@ -21,3 +21,29 @@ void __init plat_time_init(void)
 	setup_hpet_timer();
 #endif
 }
+
+static time64_t ls7a_get_rtc_time(void)
+{
+	unsigned int year, mon, day, hour, min, sec;
+	unsigned int value;
+
+	value = readl((void __iomem *)TO_UNCAC(LS7A_RTC_SYS_TOYREAD0_ADDR));
+	sec = (value & LS7A_RTC_TOY_SEC_MASK) >> LS7A_RTC_TOY_SEC_SHIFT;
+	min = (value & LS7A_RTC_TOY_MIN_MASK) >> LS7A_RTC_TOY_MIN_SHIFT;
+	hour = (value & LS7A_RTC_TOY_HOUR_MASK) >> LS7A_RTC_TOY_HOUR_SHIFT;
+	day = (value & LS7A_RTC_TOY_DAY_MASK) >> LS7A_RTC_TOY_DAY_SHIFT;
+	mon = (value & LS7A_RTC_TOY_MON_MASK) >> LS7A_RTC_TOY_MON_SHIFT;
+	year = readl((void __iomem *)TO_UNCAC(LS7A_RTC_SYS_TOYREAD1_ADDR));
+
+	return mktime64(year + LS7A_RTC_YEAR_BASE, mon, day, hour, min, sec);
+}
+
+void read_persistent_clock64(struct timespec64 *ts)
+{
+	if (loongson_sysconf.bridgetype == LS7A)
+		ts->tv_sec = ls7a_get_rtc_time();
+	else
+		ts->tv_sec = mc146818_get_cmos_time();
+
+	ts->tv_nsec = 0;
+}
-- 
2.1.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ