From c45efb56f226b22b7f177f54962894827018cd63 Mon Sep 17 00:00:00 2001 From: dlg Date: Tue, 28 Aug 2018 00:00:42 +0000 Subject: [PATCH] add support for storing the time of day on OPL based machines. this let's me pull the date back from 2023 to 2018, and have it stay like that after a reboot. ok deraadt@ --- sys/arch/sparc64/dev/prtc.c | 86 ++++++++++++++++++++++---- sys/arch/sparc64/include/sparc64.h | 3 +- sys/arch/sparc64/sparc64/ofw_machdep.c | 23 +------ 3 files changed, 76 insertions(+), 36 deletions(-) diff --git a/sys/arch/sparc64/dev/prtc.c b/sys/arch/sparc64/dev/prtc.c index a44b7a9a913..67932834065 100644 --- a/sys/arch/sparc64/dev/prtc.c +++ b/sys/arch/sparc64/dev/prtc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: prtc.c,v 1.3 2014/05/10 12:36:22 kettenis Exp $ */ +/* $OpenBSD: prtc.c,v 1.4 2018/08/28 00:00:42 dlg Exp $ */ /* * Copyright (c) 2008 Mark Kettenis @@ -49,6 +49,9 @@ struct cfdriver prtc_cd = { int prtc_gettime(todr_chip_handle_t, struct timeval *); int prtc_settime(todr_chip_handle_t, struct timeval *); +int prtc_opl_gettime(todr_chip_handle_t, struct timeval *); +int prtc_opl_settime(todr_chip_handle_t, struct timeval *); + int prtc_match(struct device *parent, void *match, void *aux) { @@ -64,6 +67,14 @@ void prtc_attach(struct device *parent, struct device *self, void *aux) { todr_chip_handle_t handle; + char buf[32]; + int opl; + + opl = OF_getprop(findroot(), "name", buf, sizeof(buf)) > 0 && + strcmp(buf, "SUNW,SPARC-Enterprise") == 0; + + if (opl) + printf(": OPL"); printf("\n"); @@ -72,26 +83,25 @@ prtc_attach(struct device *parent, struct device *self, void *aux) panic("couldn't allocate todr_handle"); handle->cookie = self; - handle->todr_gettime = prtc_gettime; - handle->todr_settime = prtc_settime; + if (opl) { + handle->todr_gettime = prtc_opl_gettime; + handle->todr_settime = prtc_opl_settime; + } else { + handle->todr_gettime = prtc_gettime; + handle->todr_settime = prtc_settime; + } handle->bus_cookie = NULL; handle->todr_setwen = NULL; + todr_handle = handle; } int prtc_gettime(todr_chip_handle_t handle, struct timeval *tv) { - u_int32_t tod = 0; char buf[32]; - - if (OF_getprop(findroot(), "name", buf, sizeof(buf)) > 0 && - strcmp(buf, "SUNW,SPARC-Enterprise") == 0) { - tv->tv_sec = prom_opl_get_tod(); - tv->tv_usec = 0; - return (0); - } + u_int32_t tod = 0; snprintf(buf, sizeof(buf), "h# %08lx unix-gettod", (long)&tod); OF_interpret(buf, 0); @@ -105,4 +115,56 @@ int prtc_settime(todr_chip_handle_t handle, struct timeval *tv) { return (0); -} +} + +int +prtc_opl_gettime(todr_chip_handle_t handle, struct timeval *tv) +{ + struct { + cell_t name; + cell_t nargs; + cell_t nrets; + cell_t stick; + cell_t time; + } args = { + .name = ADR2CELL("FJSV,get-tod"), + .nargs = 0, + .nrets = 2, + }; + + if (openfirmware(&args) == -1) + return (-1); + + tv->tv_sec = args.time; + tv->tv_usec = 0; + + return (0); +} + +int +prtc_opl_settime(todr_chip_handle_t handle, struct timeval *tv) +{ + struct timeval otv; + struct { + cell_t name; + cell_t nargs; + cell_t nrets; + cell_t diff; + } args = { + .name = ADR2CELL("FJSV,set-domain-time"), + .nargs = 1, + .nrets = 0, + }; + + if (prtc_opl_gettime(handle, &otv) == -1) + return (-1); + + args.diff = tv->tv_sec - otv.tv_sec; + if (args.diff == 0) + return (0); + + if (openfirmware(&args) == -1) + return (-1); + + return (0); +} diff --git a/sys/arch/sparc64/include/sparc64.h b/sys/arch/sparc64/include/sparc64.h index 80441390ff2..652715245d7 100644 --- a/sys/arch/sparc64/include/sparc64.h +++ b/sys/arch/sparc64/include/sparc64.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sparc64.h,v 1.13 2008/12/30 00:54:24 kettenis Exp $ */ +/* $OpenBSD: sparc64.h,v 1.14 2018/08/28 00:00:42 dlg Exp $ */ /* $NetBSD: sparc64.h,v 1.3 2000/10/20 05:47:03 mrg Exp $ */ /* @@ -55,7 +55,6 @@ int prom_dtlb_load(int index, u_int64_t data, vaddr_t vaddr); void prom_start_cpu(int cpu, void *func, long arg); void prom_start_cpu_by_cpuid(int cpu, void *func, long arg); const char *prom_serengeti_set_console_input(const char *); -time_t prom_opl_get_tod(void); uint64_t prom_set_sun4v_api_version(uint64_t, uint64_t, uint64_t, uint64_t *); void prom_sun4v_soft_state_supported(void); diff --git a/sys/arch/sparc64/sparc64/ofw_machdep.c b/sys/arch/sparc64/sparc64/ofw_machdep.c index e0bd1913dff..d4ef99a829e 100644 --- a/sys/arch/sparc64/sparc64/ofw_machdep.c +++ b/sys/arch/sparc64/sparc64/ofw_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ofw_machdep.c,v 1.33 2016/03/07 13:21:51 naddy Exp $ */ +/* $OpenBSD: ofw_machdep.c,v 1.34 2018/08/28 00:00:42 dlg Exp $ */ /* $NetBSD: ofw_machdep.c,v 1.16 2001/07/20 00:07:14 eeh Exp $ */ /* @@ -748,27 +748,6 @@ prom_serengeti_set_console_input(const char *new) return (const char *)args.old; } -time_t -prom_opl_get_tod(void) -{ - static struct { - cell_t name; - cell_t nargs; - cell_t nreturns; - cell_t stick; - cell_t time; - } args; - - args.name = ADR2CELL("FJSV,get-tod"); - args.nargs = 0; - args.nreturns = 2; - - if (openfirmware(&args) == -1) - return (time_t)-1; - - return (time_t)args.time; -} - uint64_t prom_set_sun4v_api_version(uint64_t api_group, uint64_t major, uint64_t minor, uint64_t *supported_minor) -- 2.20.1