i have an m4000 that would come up saying that it was 2023, which is
hard for ntpd to deal with. the rtc in these machines is based on a
value the firmware manages, but we never tell the firmware what we think
the time is.

this diff moves all the opl firwmare handling into the prtc driver, and
adds the todr_settime side of things so the time is kept across reboots.

there's a bunch of dicking around with %sys_tick we could do, but i
can't see what the advantage would be.

ok?

Index: dev/prtc.c
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/dev/prtc.c,v
retrieving revision 1.3
diff -u -p -r1.3 prtc.c
--- dev/prtc.c  10 May 2014 12:36:22 -0000      1.3
+++ dev/prtc.c  27 Aug 2018 07:26:44 -0000
@@ -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, struc
                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 (-1);
+
+       if (openfirmware(&args) == -1)
+               return (-1);
+
+       return (0);
+}
Index: sparc64/ofw_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/sparc64/ofw_machdep.c,v
retrieving revision 1.33
diff -u -p -r1.33 ofw_machdep.c
--- sparc64/ofw_machdep.c       7 Mar 2016 13:21:51 -0000       1.33
+++ sparc64/ofw_machdep.c       27 Aug 2018 07:26:44 -0000
@@ -748,27 +748,6 @@ prom_serengeti_set_console_input(const c
        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)

Reply via email to