/* * i386 CMOS starts out with 14 bytes clock data alpha has something * similar, but with details depending on the machine type. * * byte 0: seconds 0-59 * byte 2: minutes 0-59 * byte 4: hours 0-23 in 24hr mode, * 1-12 in 12hr mode, with high bit unset/set * if am/pm. * byte 6: weekday 1-7, Sunday=1 * byte 7: day of the month 1-31 * byte 8: month 1-12 * byte 9: year 0-99 * * Numbers are stored in BCD/binary if bit 2 of byte 11 is unset/set The * clock is in 12hr/24hr mode if bit 1 of byte 11 is unset/set The clock is * undefined (being updated) if bit 7 of byte 10 is set. The clock is frozen * (to be updated) by setting bit 7 of byte 11 Bit 7 of byte 14 indicates * whether the CMOS clock is reliable: it is 1 if RTC power has been good * since this bit was last read; it is 0 when the battery is dead and system * power has been off. * * Avoid setting the RTC clock within 2 seconds of the day rollover that * starts a new month or enters daylight saving time. * * The century situation is messy: * * Usually byte 50 (0x32) gives the century (in BCD, so 19 or 20 hex), but * IBM PS/2 has (part of) a checksum there and uses byte 55 (0x37). * Sometimes byte 127 (0x7f) or Bank 1, byte 0x48 gives the century. The * original RTC will not access any century byte; some modern versions will. * If a modern RTC or BIOS increments the century byte it may go from 0x19 * to 0x20, but in some buggy cases 0x1a is produced. */ /* * A struct tm has int fields * tm_sec 0-59, 60 or 61 only for leap seconds * tm_min 0-59 * tm_hour 0-23 * tm_mday 1-31 * tm_mon 0-11 * tm_year number of years since 1900 * tm_wday 0-6, 0=Sunday * tm_yday 0-365 * tm_isdst >0: yes, 0: no, <0: unknown */ #include #include #include #include #include #include #include "c.h" #include "nls.h" #if defined(__i386__) || defined(__x86_64__) # ifdef HAVE_SYS_IO_H # include # elif defined(HAVE_ASM_IO_H) # include /* for inb, outb */ # else /* * Disable cmos access; we can no longer use asm/io.h, since the kernel does * not export that header. */ #undef __i386__ #undef __x86_64__ void outb(int a __attribute__ ((__unused__)), int b __attribute__ ((__unused__))) { } int inb(int c __attribute__ ((__unused__))) { return 0; } #endif /* __i386__ __x86_64__ */ #elif defined(__alpha__) # ifdef HAVE_SYS_IO_H # include # else /* fails to compile, probably because of u8 etc */ extern unsigned int inb(unsigned long port); extern void outb(unsigned char b, unsigned long port); extern int iopl(int level); # endif #else static void outb(int a __attribute__ ((__unused__)), int b __attribute__ ((__unused__))) { } static int inb(int c __attribute__ ((__unused__))) { return 0; } #endif /* __alpha__ */ #include "hwclock.h" #define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10) #define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10) #define IOPL_NOT_IMPLEMENTED -2 /* * The epoch. * * Unix uses 1900 as epoch for a struct tm, and 1970 for a time_t. But what * was written to CMOS? * * Digital DECstations use 1928 - this is on a mips or alpha Digital Unix * uses 1952, e.g. on AXPpxi33. Windows NT uses 1980. The ARC console * expects to boot Windows NT and uses 1980. (But a Ruffian uses 1900, just * like SRM.) It is reported that ALPHA_PRE_V1_2_SRM_CONSOLE uses 1958. */ #define TM_EPOCH 1900 int cmos_epoch = 1900; /* * Martin Ostermann writes: * * The problem with the Jensen is twofold: First, it has the clock at a * different address. Secondly, it has a distinction between "local" and * normal bus addresses. The local ones pertain to the hardware integrated * into the chipset, like serial/parallel ports and of course, the RTC. * Those need to be addressed differently. This is handled fine in the * kernel, and it's not a problem, since this usually gets totally optimized * by the compile. But the i/o routines of (g)libc lack this support so far. * The result of this is, that the old clock program worked only on the * Jensen when USE_DEV_PORT was defined, but not with the normal inb/outb * functions. */ int use_dev_port = 0; /* 1 for Jensen */ int dev_port_fd; unsigned short clock_ctl_addr = 0x70; /* 0x170 for Jensen */ unsigned short clock_data_addr = 0x71; /* 0x171 for Jensen */ int century_byte = 0; /* 0: don't access a century byte * 50 (0x32): usual PC value * 55 (0x37): PS/2 */ #ifdef __alpha__ int funkyTOY = 0; /* 1 for PC164/LX164/SX164 type alpha */ #endif #ifdef __alpha static int is_in_cpuinfo(char *fmt, char *str) { FILE *cpuinfo; char field[256]; char format[256]; int found = 0; sprintf(format, "%s : %s", fmt, "%255s"); cpuinfo = fopen("/proc/cpuinfo", "r"); if (cpuinfo) { do { if (fscanf(cpuinfo, format, field) == 1) { if (strncmp(field, str, strlen(str)) == 0) found = 1; break; } } while (fgets(field, 256, cpuinfo)); fclose(cpuinfo); } return found; } /* * Set cmos_epoch, either from user options, or by asking the kernel, or by * looking at /proc/cpu_info */ void set_cmos_epoch(const struct hwclock_control *ctl) { unsigned long epoch; /* Believe the user */ if (ctl->epoch_option) { cmos_epoch = ctl->epoch_option; return; } if (ctl->ARCconsole) cmos_epoch = 1980; if (ctl->ARCconsole || ctl->SRM) return; #ifdef __linux__ /* * If we can ask the kernel, we don't need guessing from * /proc/cpuinfo */ if (get_epoch_rtc(ctl, &epoch, 1) == 0) { cmos_epoch = epoch; return; } #endif /* * The kernel source today says: read the year. * * If it is in 0-19 then the epoch is 2000. * If it is in 20-47 then the epoch is 1980. * If it is in 48-69 then the epoch is 1952. * If it is in 70-99 then the epoch is 1928. * * Otherwise the epoch is 1900. * TODO: Clearly, this must be changed before 2019. */ /* * See whether we are dealing with SRM or MILO, as they have * different "epoch" ideas. */ if (is_in_cpuinfo("system serial number", "MILO")) { if (ctl->debug) printf(_("booted from MILO\n")); /* * See whether we are dealing with a RUFFIAN aka Alpha PC-164 * UX (or BX), as they have REALLY different TOY (TimeOfYear) * format: BCD, and not an ARC-style epoch. BCD is detected * dynamically, but we must NOT adjust like ARC. */ if (is_in_cpuinfo("system type", "Ruffian")) { if (debug) printf(_("Ruffian BCD clock\n")); return; } } cmos_epoch = 1980; } void set_cmos_access(const struct hwclock_control *ctl) { /* * See whether we're dealing with a Jensen---it has a weird I/O * system. DEC was just learning how to build Alpha PCs. */ if (ctl->Jensen || is_in_cpuinfo("system type", "Jensen")) { use_dev_port = 1; clock_ctl_addr = 0x170; clock_data_addr = 0x171; if (ctl->debug) printf(_("clockport adjusted to 0x%x\n"), clock_ctl_addr); } /* * See whether we are dealing with PC164/LX164/SX164, as they have a * TOY that must be accessed differently to work correctly. */ /* Nautilus stuff reported by Neoklis Kyriazis */ if (ctl->funky_toy || is_in_cpuinfo("system variation", "PC164") || is_in_cpuinfo("system variation", "LX164") || is_in_cpuinfo("system variation", "SX164") || is_in_cpuinfo("system type", "Nautilus")) { funkyTOY = 1; if (ctl->debug) printf(_("funky TOY!\n")); } } #endif /* __alpha */ #ifdef __alpha__ /* * The Alpha doesn't allow user-level code to disable interrupts (for good * reasons). Instead, we ensure atomic operation by performing the operation * and checking whether the high 32 bits of the cycle counter changed. If * they did, a context switch must have occurred and we redo the operation. * As long as the operation is reasonably short, it will complete * atomically, eventually. */ static unsigned long atomic(const char *name, unsigned long (*op) (const struct hwclock_control *ctl, unsigned long), const struct hwclock_control *ctl, unsigned long arg) { unsigned long ts1, ts2, n, v; for (n = 0; n < 1000; ++n) { asm volatile ("rpcc %0":"r=" (ts1)); v = (*op) (ctl, arg); asm volatile ("rpcc %0":"r=" (ts2)); if ((ts1 ^ ts2) >> 32 == 0) { return v; } } errx(EXIT_FAILURE, _("atomic %s failed for 1000 iterations!"), name); } #else /* * Hmmh, this isn't very atomic. Maybe we should force an error instead? * * TODO: optimize the access to CMOS by mlockall(MCL_CURRENT) and SCHED_FIFO */ static unsigned long atomic(const char *name __attribute__ ((__unused__)), unsigned long (*op) (const struct hwclock_control *ctl, unsigned long), const struct hwclock_control *ctl, unsigned long arg) { return (*op) (ctl, arg); } #endif static inline unsigned long cmos_read(const struct hwclock_control *ctl, unsigned long reg) { if (use_dev_port) { unsigned char v = reg | 0x80; lseek(dev_port_fd, clock_ctl_addr, 0); if (write(dev_port_fd, &v, 1) == -1 && ctl->debug) warn(_("cmos_read(): write to control address %X failed"), clock_ctl_addr); lseek(dev_port_fd, clock_data_addr, 0); if (read(dev_port_fd, &v, 1) == -1 && ctl->debug) warn(_("cmos_read(): read from data address %X failed"), clock_data_addr); return v; } else { /* * We only want to read CMOS data, but unfortunately writing * to bit 7 disables (1) or enables (0) NMI; since this bit * is read-only we have to guess the old status. Various * docs suggest that one should disable NMI while * reading/writing CMOS data, and enable it again * afterwards. This would yield the sequence * * outb (reg | 0x80, 0x70); * val = inb(0x71); * outb (0x0d, 0x70); // 0x0d: random read-only location * * Other docs state that "any write to 0x70 should be * followed by an action to 0x71 or the RTC will be left in * an unknown state". Most docs say that it doesn't matter at * all what one does. */ /* * bit 0x80: disable NMI while reading - should we? Let us * follow the kernel and not disable. Called only with 0 <= * reg < 128 */ outb(reg, clock_ctl_addr); return inb(clock_data_addr); } } static inline unsigned long cmos_write(const struct hwclock_control *ctl, unsigned long reg, unsigned long val) { if (use_dev_port) { unsigned char v = reg | 0x80; lseek(dev_port_fd, clock_ctl_addr, 0); if (write(dev_port_fd, &v, 1) == -1 && ctl->debug) warn(_("cmos_write(): write to control address %X failed"), clock_ctl_addr); v = (val & 0xff); lseek(dev_port_fd, clock_data_addr, 0); if (write(dev_port_fd, &v, 1) == -1 && ctl->debug) warn(_("cmos_write(): write to data address %X failed"), clock_data_addr); } else { outb(reg, clock_ctl_addr); outb(val, clock_data_addr); } return 0; } static unsigned long cmos_set_time(const struct hwclock_control *ctl, unsigned long arg) { unsigned char save_control, save_freq_select, pmbit = 0; struct tm tm = *(struct tm *)arg; unsigned int century; /* * CMOS byte 10 (clock status register A) has 3 bitfields: * bit 7: 1 if data invalid, update in progress (read-only bit) * (this is raised 224 us before the actual update starts) * 6-4 select base frequency * 010: 32768 Hz time base (default) * 111: reset * all other combinations are manufacturer-dependent * (e.g.: DS1287: 010 = start oscillator, anything else = stop) * 3-0 rate selection bits for interrupt * 0000 none (may stop RTC) * 0001, 0010 give same frequency as 1000, 1001 * 0011 122 microseconds (minimum, 8192 Hz) * .... each increase by 1 halves the frequency, doubles the period * 1111 500 milliseconds (maximum, 2 Hz) * 0110 976.562 microseconds (default 1024 Hz) */ save_control = cmos_read(ctl, 11); /* tell the clock it's being set */ cmos_write(ctl, 11, (save_control | 0x80)); save_freq_select = cmos_read(ctl, 10); /* stop and reset prescaler */ cmos_write(ctl, 10, (save_freq_select | 0x70)); tm.tm_year += TM_EPOCH; century = tm.tm_year / 100; tm.tm_year -= cmos_epoch; tm.tm_year %= 100; tm.tm_mon += 1; tm.tm_wday += 1; if (!(save_control & 0x02)) { /* 12hr mode; the default is 24hr mode */ if (tm.tm_hour == 0) tm.tm_hour = 24; if (tm.tm_hour > 12) { tm.tm_hour -= 12; pmbit = 0x80; } } if (!(save_control & 0x04)) { /* BCD mode - the default */ BIN_TO_BCD(tm.tm_sec); BIN_TO_BCD(tm.tm_min); BIN_TO_BCD(tm.tm_hour); BIN_TO_BCD(tm.tm_wday); BIN_TO_BCD(tm.tm_mday); BIN_TO_BCD(tm.tm_mon); BIN_TO_BCD(tm.tm_year); BIN_TO_BCD(century); } cmos_write(ctl, 0, tm.tm_sec); cmos_write(ctl, 2, tm.tm_min); cmos_write(ctl, 4, tm.tm_hour | pmbit); cmos_write(ctl, 6, tm.tm_wday); cmos_write(ctl, 7, tm.tm_mday); cmos_write(ctl, 8, tm.tm_mon); cmos_write(ctl, 9, tm.tm_year); if (century_byte) cmos_write(ctl, century_byte, century); /* * The kernel sources, linux/arch/i386/kernel/time.c, have the * following comment: * * The following flags have to be released exactly in this order, * otherwise the DS12887 (popular MC146818A clone with integrated * battery and quartz) will not reset the oscillator and will not * update precisely 500 ms later. You won't find this mentioned in * the Dallas Semiconductor data sheets, but who believes data * sheets anyway ... -- Markus Kuhn */ cmos_write(ctl, 11, save_control); cmos_write(ctl, 10, save_freq_select); return 0; } static int hclock_read(const struct hwclock_control *ctl, unsigned long reg) { return atomic("clock read", cmos_read, ctl, reg); } static void hclock_set_time(const struct hwclock_control *ctl, const struct tm *tm) { atomic("set time", cmos_set_time, ctl, (unsigned long)(tm)); } static inline int cmos_clock_busy(const struct hwclock_control *ctl) { return #ifdef __alpha__ /* poll bit 4 (UF) of Control Register C */ funkyTOY ? (hclock_read(ctl, 12) & 0x10) : #endif /* poll bit 7 (UIP) of Control Register A */ (hclock_read(ctl, 10) & 0x80); } static int synchronize_to_clock_tick_cmos(const struct hwclock_control *ctl __attribute__((__unused__))) { int i; /* * Wait for rise. Should be within a second, but in case something * weird happens, we have a limit on this loop to reduce the impact * of this failure. */ for (i = 0; !cmos_clock_busy(ctl); i++) if (i >= 10000000) return 1; /* Wait for fall. Should be within 2.228 ms. */ for (i = 0; cmos_clock_busy(ctl); i++) if (i >= 1000000) return 1; return 0; } /* * Read the hardware clock and return the current time via argument. * Assume we have an ISA machine and read the clock directly with CPU I/O * instructions. * * This function is not totally reliable. It takes a finite and * unpredictable amount of time to execute the code below. During that time, * the clock may change and we may even read an invalid value in the middle * of an update. We do a few checks to minimize this possibility, but only * the kernel can actually read the clock properly, since it can execute * code in a short and predictable amount of time (by turning of * interrupts). * * In practice, the chance of this function returning the wrong time is * extremely remote. */ static int read_hardware_clock_cmos(const struct hwclock_control *ctl __attribute__((__unused__)), struct tm *tm) { bool got_time = FALSE; unsigned char status, pmbit; status = pmbit = 0; /* just for gcc */ while (!got_time) { /* * Bit 7 of Byte 10 of the Hardware Clock value is the * Update In Progress (UIP) bit, which is on while and 244 * uS before the Hardware Clock updates itself. It updates * the counters individually, so reading them during an * update would produce garbage. The update takes 2mS, so we * could be spinning here that long waiting for this bit to * turn off. * * Furthermore, it is pathologically possible for us to be * in this code so long that even if the UIP bit is not on * at first, the clock has changed while we were running. We * check for that too, and if it happens, we start over. */ if (!cmos_clock_busy(ctl)) { /* No clock update in progress, go ahead and read */ tm->tm_sec = hclock_read(ctl, 0); tm->tm_min = hclock_read(ctl, 2); tm->tm_hour = hclock_read(ctl, 4); tm->tm_wday = hclock_read(ctl, 6); tm->tm_mday = hclock_read(ctl, 7); tm->tm_mon = hclock_read(ctl, 8); tm->tm_year = hclock_read(ctl, 9); status = hclock_read(ctl, 11); #if 0 if (century_byte) century = hclock_read(ctl, century_byte); #endif /* * Unless the clock changed while we were reading, * consider this a good clock read . */ if (tm->tm_sec == hclock_read(ctl, 0)) got_time = TRUE; } /* * Yes, in theory we could have been running for 60 seconds * and the above test wouldn't work! */ } if (!(status & 0x04)) { /* BCD mode - the default */ BCD_TO_BIN(tm->tm_sec); BCD_TO_BIN(tm->tm_min); pmbit = (tm->tm_hour & 0x80); tm->tm_hour &= 0x7f; BCD_TO_BIN(tm->tm_hour); BCD_TO_BIN(tm->tm_wday); BCD_TO_BIN(tm->tm_mday); BCD_TO_BIN(tm->tm_mon); BCD_TO_BIN(tm->tm_year); #if 0 BCD_TO_BIN(century); #endif } /* * We don't use the century byte of the Hardware Clock since we * don't know its address (usually 50 or 55). Here, we follow the * advice of the X/Open Base Working Group: "if century is not * specified, then values in the range [69-99] refer to years in the * twentieth century (1969 to 1999 inclusive), and values in the * range [00-68] refer to years in the twenty-first century (2000 to * 2068 inclusive)." */ tm->tm_wday -= 1; tm->tm_mon -= 1; tm->tm_year += (cmos_epoch - TM_EPOCH); if (tm->tm_year < 69) tm->tm_year += 100; if (pmbit) { tm->tm_hour += 12; if (tm->tm_hour == 24) tm->tm_hour = 0; } tm->tm_isdst = -1; /* don't know whether it's daylight */ return 0; } static int set_hardware_clock_cmos(const struct hwclock_control *ctl __attribute__((__unused__)), const struct tm *new_broken_time) { hclock_set_time(ctl, new_broken_time); return 0; } #if defined(__i386__) || defined(__alpha__) || defined(__x86_64__) # if defined(HAVE_IOPL) static int i386_iopl(const int level) { return iopl(level); } # else static int i386_iopl(const int level __attribute__ ((__unused__))) { extern int ioperm(unsigned long from, unsigned long num, int turn_on); return ioperm(clock_ctl_addr, 2, 1); } # endif #else static int i386_iopl(const int level __attribute__ ((__unused__))) { return IOPL_NOT_IMPLEMENTED; } #endif static int get_permissions_cmos(void) { int rc; if (use_dev_port) { if ((dev_port_fd = open("/dev/port", O_RDWR)) < 0) { warn(_("cannot open %s"), "/dev/port"); rc = 1; } else rc = 0; } else { rc = i386_iopl(3); if (rc == IOPL_NOT_IMPLEMENTED) { warnx(_("I failed to get permission because I didn't try.")); } else if (rc != 0) { rc = errno; warn(_("unable to get I/O port access: " "the iopl(3) call failed.")); if (rc == EPERM && geteuid()) warnx(_("Probably you need root privileges.\n")); } } return rc ? 1 : 0; } static struct clock_ops cmos = { N_("Using direct I/O instructions to ISA clock."), get_permissions_cmos, read_hardware_clock_cmos, set_hardware_clock_cmos, synchronize_to_clock_tick_cmos, }; /* * return &cmos if cmos clock present, NULL otherwise choose this * construction to avoid gcc messages about unused variables */ struct clock_ops *probe_for_cmos_clock(void) { int have_cmos = #if defined(__i386__) || defined(__alpha__) || defined(__x86_64__) TRUE; #else FALSE; #endif return have_cmos ? &cmos : NULL; }