1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2008 Poul-Henning Kamp 5 * Copyright (c) 2010 Alexander Motin <mav@FreeBSD.org> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $FreeBSD$ 30 */ 31 32 #include <sys/cdefs.h> 33 __FBSDID("$FreeBSD$"); 34 35 #include "opt_acpi.h" 36 #include "opt_isa.h" 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/bus.h> 41 #include <sys/clock.h> 42 #include <sys/lock.h> 43 #include <sys/mutex.h> 44 #include <sys/kdb.h> 45 #include <sys/kernel.h> 46 #include <sys/module.h> 47 #include <sys/proc.h> 48 #include <sys/rman.h> 49 #include <sys/timeet.h> 50 51 #include <isa/rtc.h> 52 #ifdef DEV_ISA 53 #include <isa/isareg.h> 54 #include <isa/isavar.h> 55 #endif 56 #include <machine/intr_machdep.h> 57 #include "clock_if.h" 58 59 #ifdef DEV_ACPI 60 #include <contrib/dev/acpica/include/acpi.h> 61 #endif 62 63 /* 64 * atrtc_lock protects low-level access to individual hardware registers. 65 * atrtc_time_lock protects the entire sequence of accessing multiple registers 66 * to read or write the date and time. 67 */ 68 static struct mtx atrtc_lock; 69 MTX_SYSINIT(atrtc_lock_init, &atrtc_lock, "atrtc", MTX_SPIN); 70 71 /* Force RTC enabled/disabled. */ 72 static int atrtc_enabled = -1; 73 TUNABLE_INT("hw.atrtc.enabled", &atrtc_enabled); 74 75 struct mtx atrtc_time_lock; 76 MTX_SYSINIT(atrtc_time_lock_init, &atrtc_time_lock, "atrtc_time", MTX_DEF); 77 78 int atrtcclock_disable = 0; 79 80 static int rtc_reg = -1; 81 static u_char rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF; 82 static u_char rtc_statusb = RTCSB_24HR; 83 84 /* 85 * RTC support routines 86 */ 87 88 static inline u_char 89 rtcin_locked(int reg) 90 { 91 92 if (rtc_reg != reg) { 93 inb(0x84); 94 outb(IO_RTC, reg); 95 rtc_reg = reg; 96 inb(0x84); 97 } 98 return (inb(IO_RTC + 1)); 99 } 100 101 static inline void 102 rtcout_locked(int reg, u_char val) 103 { 104 105 if (rtc_reg != reg) { 106 inb(0x84); 107 outb(IO_RTC, reg); 108 rtc_reg = reg; 109 inb(0x84); 110 } 111 outb(IO_RTC + 1, val); 112 inb(0x84); 113 } 114 115 int 116 rtcin(int reg) 117 { 118 u_char val; 119 120 mtx_lock_spin(&atrtc_lock); 121 val = rtcin_locked(reg); 122 mtx_unlock_spin(&atrtc_lock); 123 return (val); 124 } 125 126 void 127 writertc(int reg, u_char val) 128 { 129 130 mtx_lock_spin(&atrtc_lock); 131 rtcout_locked(reg, val); 132 mtx_unlock_spin(&atrtc_lock); 133 } 134 135 static void 136 atrtc_start(void) 137 { 138 139 mtx_lock_spin(&atrtc_lock); 140 rtcout_locked(RTC_STATUSA, rtc_statusa); 141 rtcout_locked(RTC_STATUSB, RTCSB_24HR); 142 mtx_unlock_spin(&atrtc_lock); 143 } 144 145 static void 146 atrtc_rate(unsigned rate) 147 { 148 149 rtc_statusa = RTCSA_DIVIDER | rate; 150 writertc(RTC_STATUSA, rtc_statusa); 151 } 152 153 static void 154 atrtc_enable_intr(void) 155 { 156 157 rtc_statusb |= RTCSB_PINTR; 158 mtx_lock_spin(&atrtc_lock); 159 rtcout_locked(RTC_STATUSB, rtc_statusb); 160 rtcin_locked(RTC_INTR); 161 mtx_unlock_spin(&atrtc_lock); 162 } 163 164 static void 165 atrtc_disable_intr(void) 166 { 167 168 rtc_statusb &= ~RTCSB_PINTR; 169 mtx_lock_spin(&atrtc_lock); 170 rtcout_locked(RTC_STATUSB, rtc_statusb); 171 rtcin_locked(RTC_INTR); 172 mtx_unlock_spin(&atrtc_lock); 173 } 174 175 void 176 atrtc_restore(void) 177 { 178 179 /* Restore all of the RTC's "status" (actually, control) registers. */ 180 mtx_lock_spin(&atrtc_lock); 181 rtcin_locked(RTC_STATUSA); /* dummy to get rtc_reg set */ 182 rtcout_locked(RTC_STATUSB, RTCSB_24HR); 183 rtcout_locked(RTC_STATUSA, rtc_statusa); 184 rtcout_locked(RTC_STATUSB, rtc_statusb); 185 rtcin_locked(RTC_INTR); 186 mtx_unlock_spin(&atrtc_lock); 187 } 188 189 /********************************************************************** 190 * RTC driver for subr_rtc 191 */ 192 193 struct atrtc_softc { 194 int port_rid, intr_rid; 195 struct resource *port_res; 196 struct resource *intr_res; 197 void *intr_handler; 198 struct eventtimer et; 199 }; 200 201 static int 202 rtc_start(struct eventtimer *et, sbintime_t first, sbintime_t period) 203 { 204 205 atrtc_rate(max(fls(period + (period >> 1)) - 17, 1)); 206 atrtc_enable_intr(); 207 return (0); 208 } 209 210 static int 211 rtc_stop(struct eventtimer *et) 212 { 213 214 atrtc_disable_intr(); 215 return (0); 216 } 217 218 /* 219 * This routine receives statistical clock interrupts from the RTC. 220 * As explained above, these occur at 128 interrupts per second. 221 * When profiling, we receive interrupts at a rate of 1024 Hz. 222 * 223 * This does not actually add as much overhead as it sounds, because 224 * when the statistical clock is active, the hardclock driver no longer 225 * needs to keep (inaccurate) statistics on its own. This decouples 226 * statistics gathering from scheduling interrupts. 227 * 228 * The RTC chip requires that we read status register C (RTC_INTR) 229 * to acknowledge an interrupt, before it will generate the next one. 230 * Under high interrupt load, rtcintr() can be indefinitely delayed and 231 * the clock can tick immediately after the read from RTC_INTR. In this 232 * case, the mc146818A interrupt signal will not drop for long enough 233 * to register with the 8259 PIC. If an interrupt is missed, the stat 234 * clock will halt, considerably degrading system performance. This is 235 * why we use 'while' rather than a more straightforward 'if' below. 236 * Stat clock ticks can still be lost, causing minor loss of accuracy 237 * in the statistics, but the stat clock will no longer stop. 238 */ 239 static int 240 rtc_intr(void *arg) 241 { 242 struct atrtc_softc *sc = (struct atrtc_softc *)arg; 243 int flag = 0; 244 245 while (rtcin(RTC_INTR) & RTCIR_PERIOD) { 246 flag = 1; 247 if (sc->et.et_active) 248 sc->et.et_event_cb(&sc->et, sc->et.et_arg); 249 } 250 return(flag ? FILTER_HANDLED : FILTER_STRAY); 251 } 252 253 /* 254 * Attach to the ISA PnP descriptors for the timer and realtime clock. 255 */ 256 static struct isa_pnp_id atrtc_ids[] = { 257 { 0x000bd041 /* PNP0B00 */, "AT realtime clock" }, 258 { 0 } 259 }; 260 261 static bool 262 atrtc_acpi_disabled(void) 263 { 264 #ifdef DEV_ACPI 265 ACPI_TABLE_FADT *fadt; 266 vm_paddr_t physaddr; 267 uint16_t flags; 268 269 physaddr = acpi_find_table(ACPI_SIG_FADT); 270 if (physaddr == 0) 271 return (false); 272 273 fadt = acpi_map_table(physaddr, ACPI_SIG_FADT); 274 if (fadt == NULL) { 275 printf("at_rtc: unable to map FADT ACPI table\n"); 276 return (false); 277 } 278 279 flags = fadt->BootFlags; 280 acpi_unmap_table(fadt); 281 282 if (flags & ACPI_FADT_NO_CMOS_RTC) 283 return (true); 284 #endif 285 286 return (false); 287 } 288 289 static int 290 atrtc_probe(device_t dev) 291 { 292 int result; 293 294 if ((atrtc_enabled == -1 && atrtc_acpi_disabled()) || 295 (atrtc_enabled == 0)) 296 return (ENXIO); 297 298 result = ISA_PNP_PROBE(device_get_parent(dev), dev, atrtc_ids); 299 /* ENOENT means no PnP-ID, device is hinted. */ 300 if (result == ENOENT) { 301 device_set_desc(dev, "AT realtime clock"); 302 return (BUS_PROBE_LOW_PRIORITY); 303 } 304 return (result); 305 } 306 307 static int 308 atrtc_attach(device_t dev) 309 { 310 struct atrtc_softc *sc; 311 rman_res_t s; 312 int i; 313 314 sc = device_get_softc(dev); 315 sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid, 316 IO_RTC, IO_RTC + 1, 2, RF_ACTIVE); 317 if (sc->port_res == NULL) 318 device_printf(dev, "Warning: Couldn't map I/O.\n"); 319 atrtc_start(); 320 clock_register(dev, 1000000); 321 bzero(&sc->et, sizeof(struct eventtimer)); 322 if (!atrtcclock_disable && 323 (resource_int_value(device_get_name(dev), device_get_unit(dev), 324 "clock", &i) != 0 || i != 0)) { 325 sc->intr_rid = 0; 326 while (bus_get_resource(dev, SYS_RES_IRQ, sc->intr_rid, 327 &s, NULL) == 0 && s != 8) 328 sc->intr_rid++; 329 sc->intr_res = bus_alloc_resource(dev, SYS_RES_IRQ, 330 &sc->intr_rid, 8, 8, 1, RF_ACTIVE); 331 if (sc->intr_res == NULL) { 332 device_printf(dev, "Can't map interrupt.\n"); 333 return (0); 334 } else if ((bus_setup_intr(dev, sc->intr_res, INTR_TYPE_CLK, 335 rtc_intr, NULL, sc, &sc->intr_handler))) { 336 device_printf(dev, "Can't setup interrupt.\n"); 337 return (0); 338 } else { 339 /* Bind IRQ to BSP to avoid live migration. */ 340 bus_bind_intr(dev, sc->intr_res, 0); 341 } 342 sc->et.et_name = "RTC"; 343 sc->et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_POW2DIV; 344 sc->et.et_quality = 0; 345 sc->et.et_frequency = 32768; 346 sc->et.et_min_period = 0x00080000; 347 sc->et.et_max_period = 0x80000000; 348 sc->et.et_start = rtc_start; 349 sc->et.et_stop = rtc_stop; 350 sc->et.et_priv = dev; 351 et_register(&sc->et); 352 } 353 return(0); 354 } 355 356 static int 357 atrtc_resume(device_t dev) 358 { 359 360 atrtc_restore(); 361 return(0); 362 } 363 364 static int 365 atrtc_settime(device_t dev __unused, struct timespec *ts) 366 { 367 struct bcd_clocktime bct; 368 369 clock_ts_to_bcd(ts, &bct, false); 370 clock_dbgprint_bcd(dev, CLOCK_DBG_WRITE, &bct); 371 372 mtx_lock(&atrtc_time_lock); 373 mtx_lock_spin(&atrtc_lock); 374 375 /* Disable RTC updates and interrupts. */ 376 rtcout_locked(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR); 377 378 /* Write all the time registers. */ 379 rtcout_locked(RTC_SEC, bct.sec); 380 rtcout_locked(RTC_MIN, bct.min); 381 rtcout_locked(RTC_HRS, bct.hour); 382 rtcout_locked(RTC_WDAY, bct.dow + 1); 383 rtcout_locked(RTC_DAY, bct.day); 384 rtcout_locked(RTC_MONTH, bct.mon); 385 rtcout_locked(RTC_YEAR, bct.year & 0xff); 386 #ifdef USE_RTC_CENTURY 387 rtcout_locked(RTC_CENTURY, bct.year >> 8); 388 #endif 389 390 /* 391 * Re-enable RTC updates and interrupts. 392 */ 393 rtcout_locked(RTC_STATUSB, rtc_statusb); 394 rtcin_locked(RTC_INTR); 395 396 mtx_unlock_spin(&atrtc_lock); 397 mtx_unlock(&atrtc_time_lock); 398 399 return (0); 400 } 401 402 static int 403 atrtc_gettime(device_t dev, struct timespec *ts) 404 { 405 struct bcd_clocktime bct; 406 407 /* Look if we have a RTC present and the time is valid */ 408 if (!(rtcin(RTC_STATUSD) & RTCSD_PWR)) { 409 device_printf(dev, "WARNING: Battery failure indication\n"); 410 return (EINVAL); 411 } 412 413 /* 414 * wait for time update to complete 415 * If RTCSA_TUP is zero, we have at least 244us before next update. 416 * This is fast enough on most hardware, but a refinement would be 417 * to make sure that no more than 240us pass after we start reading, 418 * and try again if so. 419 */ 420 mtx_lock(&atrtc_time_lock); 421 while (rtcin(RTC_STATUSA) & RTCSA_TUP) 422 continue; 423 mtx_lock_spin(&atrtc_lock); 424 bct.sec = rtcin_locked(RTC_SEC); 425 bct.min = rtcin_locked(RTC_MIN); 426 bct.hour = rtcin_locked(RTC_HRS); 427 bct.day = rtcin_locked(RTC_DAY); 428 bct.mon = rtcin_locked(RTC_MONTH); 429 bct.year = rtcin_locked(RTC_YEAR); 430 #ifdef USE_RTC_CENTURY 431 bct.year |= rtcin_locked(RTC_CENTURY) << 8; 432 #endif 433 mtx_unlock_spin(&atrtc_lock); 434 mtx_unlock(&atrtc_time_lock); 435 /* dow is unused in timespec conversion and we have no nsec info. */ 436 bct.dow = 0; 437 bct.nsec = 0; 438 clock_dbgprint_bcd(dev, CLOCK_DBG_READ, &bct); 439 return (clock_bcd_to_ts(&bct, ts, false)); 440 } 441 442 static device_method_t atrtc_methods[] = { 443 /* Device interface */ 444 DEVMETHOD(device_probe, atrtc_probe), 445 DEVMETHOD(device_attach, atrtc_attach), 446 DEVMETHOD(device_detach, bus_generic_detach), 447 DEVMETHOD(device_shutdown, bus_generic_shutdown), 448 DEVMETHOD(device_suspend, bus_generic_suspend), 449 /* XXX stop statclock? */ 450 DEVMETHOD(device_resume, atrtc_resume), 451 452 /* clock interface */ 453 DEVMETHOD(clock_gettime, atrtc_gettime), 454 DEVMETHOD(clock_settime, atrtc_settime), 455 456 { 0, 0 } 457 }; 458 459 static driver_t atrtc_driver = { 460 "atrtc", 461 atrtc_methods, 462 sizeof(struct atrtc_softc), 463 }; 464 465 static devclass_t atrtc_devclass; 466 467 DRIVER_MODULE(atrtc, isa, atrtc_driver, atrtc_devclass, 0, 0); 468 DRIVER_MODULE(atrtc, acpi, atrtc_driver, atrtc_devclass, 0, 0); 469 ISA_PNP_INFO(atrtc_ids); 470