1 /* $OpenBSD: prtc.c,v 1.5 2018/08/29 02:03:12 dlg Exp $ */ 2 3 /* 4 * Copyright (c) 2008 Mark Kettenis 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /* 20 * Driver to get the time-of-day from the PROM for machines that don't 21 * have a hardware real-time clock, like the Enterprise 10000, 22 * Fire 12K and Fire 15K. 23 */ 24 25 #include <sys/param.h> 26 #include <sys/device.h> 27 #include <sys/malloc.h> 28 #include <sys/systm.h> 29 30 #include <machine/autoconf.h> 31 #include <machine/openfirm.h> 32 #include <machine/sparc64.h> 33 34 #include <dev/clock_subr.h> 35 36 extern todr_chip_handle_t todr_handle; 37 38 struct prtc_softc { 39 struct device sc_dev; 40 struct todr_chip_handle 41 sc_todr_chip; 42 }; 43 44 int prtc_match(struct device *, void *, void *); 45 void prtc_attach(struct device *, struct device *, void *); 46 47 struct cfattach prtc_ca = { 48 sizeof(struct prtc_softc), prtc_match, prtc_attach 49 }; 50 51 struct cfdriver prtc_cd = { 52 NULL, "prtc", DV_DULL 53 }; 54 55 int prtc_gettime(todr_chip_handle_t, struct timeval *); 56 int prtc_settime(todr_chip_handle_t, struct timeval *); 57 58 int prtc_opl_gettime(todr_chip_handle_t, struct timeval *); 59 int prtc_opl_settime(todr_chip_handle_t, struct timeval *); 60 61 int 62 prtc_match(struct device *parent, void *match, void *aux) 63 { 64 struct mainbus_attach_args *ma = aux; 65 66 if (strcmp(ma->ma_name, "prtc") == 0) 67 return (1); 68 69 return (0); 70 } 71 72 void 73 prtc_attach(struct device *parent, struct device *self, void *aux) 74 { 75 struct prtc_softc *sc = (struct prtc_softc *)self; 76 todr_chip_handle_t handle = &sc->sc_todr_chip; 77 char buf[32]; 78 int opl; 79 80 opl = OF_getprop(findroot(), "name", buf, sizeof(buf)) > 0 && 81 strcmp(buf, "SUNW,SPARC-Enterprise") == 0; 82 83 if (opl) 84 printf(": OPL"); 85 86 printf("\n"); 87 88 handle->cookie = sc; 89 if (opl) { 90 handle->todr_gettime = prtc_opl_gettime; 91 handle->todr_settime = prtc_opl_settime; 92 } else { 93 handle->todr_gettime = prtc_gettime; 94 handle->todr_settime = prtc_settime; 95 } 96 97 handle->bus_cookie = NULL; 98 handle->todr_setwen = NULL; 99 100 todr_handle = handle; 101 } 102 103 int 104 prtc_gettime(todr_chip_handle_t handle, struct timeval *tv) 105 { 106 char buf[32]; 107 u_int32_t tod = 0; 108 109 snprintf(buf, sizeof(buf), "h# %08lx unix-gettod", (long)&tod); 110 OF_interpret(buf, 0); 111 112 tv->tv_sec = tod; 113 tv->tv_usec = 0; 114 return (0); 115 } 116 117 int 118 prtc_settime(todr_chip_handle_t handle, struct timeval *tv) 119 { 120 return (0); 121 } 122 123 int 124 prtc_opl_gettime(todr_chip_handle_t handle, struct timeval *tv) 125 { 126 struct { 127 cell_t name; 128 cell_t nargs; 129 cell_t nrets; 130 cell_t stick; 131 cell_t time; 132 } args = { 133 .name = ADR2CELL("FJSV,get-tod"), 134 .nargs = 0, 135 .nrets = 2, 136 }; 137 138 if (openfirmware(&args) == -1) 139 return (-1); 140 141 tv->tv_sec = args.time; 142 tv->tv_usec = 0; 143 144 return (0); 145 } 146 147 int 148 prtc_opl_settime(todr_chip_handle_t handle, struct timeval *tv) 149 { 150 struct timeval otv; 151 struct { 152 cell_t name; 153 cell_t nargs; 154 cell_t nrets; 155 cell_t diff; 156 } args = { 157 .name = ADR2CELL("FJSV,set-domain-time"), 158 .nargs = 1, 159 .nrets = 0, 160 }; 161 162 if (prtc_opl_gettime(handle, &otv) == -1) 163 return (-1); 164 165 args.diff = tv->tv_sec - otv.tv_sec; 166 if (args.diff == 0) 167 return (0); 168 169 if (openfirmware(&args) == -1) 170 return (-1); 171 172 return (0); 173 } 174