diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2012-04-06 19:00:50 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2012-04-06 19:00:50 +0000 |
commit | 82df6c03b1a23e5d1ef8fd235d9e1670a28a97d6 (patch) | |
tree | 7196fb1d983b4488e62c91694e055589ee970229 /sys | |
parent | 02e78cbefa8376a5c629fde9f7bb6ee767ba3808 (diff) |
Rework IP22 RTC year base computation, again. It turns out that different
Indy PROM versions use different year bases - after all, using 1970 instead
of the previously used value of 1940 smelled like a bug, and probably was,
so this eventually got fixed in later PROM versions.
Instead of hardcoding a year base depending upon the system, we will now ask
ARCBios for its current year, and compare it to what can be read from the RTC
registers to figure out what year base is in use by the PROM.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/mips64/include/arcbios.h | 15 | ||||
-rw-r--r-- | sys/arch/sgi/hpc/dsclock.c | 37 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/ip22.h | 3 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/ip22_machdep.c | 10 |
4 files changed, 52 insertions, 13 deletions
diff --git a/sys/arch/mips64/include/arcbios.h b/sys/arch/mips64/include/arcbios.h index 112bbaf2f2c..b4d53126202 100644 --- a/sys/arch/mips64/include/arcbios.h +++ b/sys/arch/mips64/include/arcbios.h @@ -1,4 +1,4 @@ -/* $OpenBSD: arcbios.h,v 1.19 2012/03/28 20:44:23 miod Exp $ */ +/* $OpenBSD: arcbios.h,v 1.20 2012/04/06 19:00:49 miod Exp $ */ /*- * Copyright (c) 1996 M. Warner Losh. All rights reserved. * @@ -199,7 +199,15 @@ typedef struct arc_mem64 { u_int64_t PageCount; /* Number of pages */ } arc_mem64_t; -typedef caddr_t arc_time_t; /* XXX */ +typedef struct arc_time { + u_int16_t Year; + u_int16_t Month; + u_int16_t Day; + u_int16_t Hour; + u_int16_t Minutes; + u_int16_t Seconds; + u_int16_t Milliseconds; +} arc_time_t; typedef struct arc_dsp_stat { u_int16_t CursorXPosition; @@ -453,7 +461,7 @@ long Bios_GetComponent(char *); long Bios_SaveConfiguration(void); arc_sid_t *Bios_GetSystemId(void); arc_mem_t *Bios_GetMemoryDescriptor(void *); -long Bios_GetTime(void); +arc_time_t *Bios_GetTime(void); long Bios_GetRelativeTime(void); long Bios_GetDirectoryEntry(u_long, void *, u_long, u_long *); long Bios_Open(char *, int, long *); @@ -470,4 +478,3 @@ long Bios_SetFileInformation(u_long, u_long, u_long); void Bios_FlushAllCaches(void); long Bios_TestUnicodeCharacter(u_long, u_int16_t); arc_dsp_stat_t *Bios_GetDisplayStatus(u_long); - diff --git a/sys/arch/sgi/hpc/dsclock.c b/sys/arch/sgi/hpc/dsclock.c index f1c2d05c20f..4831371da2d 100644 --- a/sys/arch/sgi/hpc/dsclock.c +++ b/sys/arch/sgi/hpc/dsclock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dsclock.c,v 1.2 2012/04/05 21:51:55 miod Exp $ */ +/* $OpenBSD: dsclock.c,v 1.3 2012/04/06 19:00:49 miod Exp $ */ /* $NetBSD: dsclock.c,v 1.5 2011/07/01 18:53:46 dyoung Exp $ */ /* @@ -50,14 +50,13 @@ #include <sgi/hpc/hpcvar.h> #include <sgi/sgi/ip22.h> -#define IRIX_BASE_YEAR \ - (sys_config.system_subtype == IP22_INDY ? POSIX_BASE_YEAR : 1940) - struct dsclock_softc { struct device sc_dev; bus_space_tag_t sc_iot; bus_space_handle_t sc_ioh; + + uint sc_base; }; int dsclock_match(struct device *, void *, void *); @@ -109,6 +108,7 @@ dsclock_attach(struct device *parent, struct device *self, void *aux) { struct dsclock_softc *sc = (void *)self; struct hpc_attach_args *haa = aux; + ds1286_todregs regs; sc->sc_iot = haa->ha_st; if (bus_space_subregion(haa->ha_st, haa->ha_sh, haa->ha_devoff, @@ -122,6 +122,31 @@ dsclock_attach(struct device *parent, struct device *self, void *aux) sys_tod.tod_get = dsclock_gettime; sys_tod.tod_set = dsclock_settime; sys_tod.tod_cookie = self; + + /* + * Try and figure out what year the chip time is relative to. + * Different Indy PROM versions appear to use different base: + * PROM Monitor SGI Version 5.1 Rev B3 IP24 Sep 17, 1993 (BE) + * uses 1970, while + * PROM Monitor SGI Version 5.3 Rev B10 R4X00/R5000 IP24 Feb 12, 1996 (BE) + * uses 1940. + */ + + DS1286_GETTOD(sc, ®s); + sc->sc_base = bios_year - frombcd(regs[DS1286_YEAR]); + /* year might have changed between the ARCBios call and now... */ + if ((sc->sc_base % 10) == 9) + sc->sc_base++; + + /* + * If the data in the chip does not make sense, assume the usual + * IRIX timebase (1940 because it's a leap year). + */ + if (sc->sc_base != 1940 && sc->sc_base != POSIX_BASE_YEAR) + sc->sc_base = 1940; + + /* mips64 clock code expects year relative to 1900 */ + sc->sc_base -= 1900; } /* @@ -158,7 +183,7 @@ dsclock_gettime(void *cookie, time_t base, struct tod_time *ct) ct->day = frombcd(regs[DS1286_DOM]); ct->mon = frombcd(regs[DS1286_MONTH] & DS1286_MONTH_MASK); - ct->year = frombcd(regs[DS1286_YEAR]) + (IRIX_BASE_YEAR - 1900); + ct->year = frombcd(regs[DS1286_YEAR]) + sc->sc_base; } /* @@ -186,7 +211,7 @@ dsclock_settime(void *cookie, struct tod_time *ct) regs[DS1286_MONTH] &= ~DS1286_MONTH_MASK; regs[DS1286_MONTH] |= tobcd(ct->mon) & DS1286_MONTH_MASK; - regs[DS1286_YEAR] = tobcd(ct->year - (IRIX_BASE_YEAR - 1900)); + regs[DS1286_YEAR] = tobcd(ct->year - sc->sc_base); s = splhigh(); DS1286_PUTTOD(sc, ®s); diff --git a/sys/arch/sgi/sgi/ip22.h b/sys/arch/sgi/sgi/ip22.h index c85023486fb..20c6c270a9f 100644 --- a/sys/arch/sgi/sgi/ip22.h +++ b/sys/arch/sgi/sgi/ip22.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip22.h,v 1.2 2012/04/03 21:17:35 miod Exp $ */ +/* $OpenBSD: ip22.h,v 1.3 2012/04/06 19:00:49 miod Exp $ */ /* * Copyright (c) 2012 Miodrag Vallat. @@ -32,3 +32,4 @@ #define INTPRI_L0 (INTPRI_L1 + 1) extern int hpc_old; /* nonzero if at least one HPC 1.x device found */ +extern int bios_year; diff --git a/sys/arch/sgi/sgi/ip22_machdep.c b/sys/arch/sgi/sgi/ip22_machdep.c index 4f187362c3c..ffffcc216ac 100644 --- a/sys/arch/sgi/sgi/ip22_machdep.c +++ b/sys/arch/sgi/sgi/ip22_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip22_machdep.c,v 1.2 2012/04/03 21:17:35 miod Exp $ */ +/* $OpenBSD: ip22_machdep.c,v 1.3 2012/04/06 19:00:49 miod Exp $ */ /* * Copyright (c) 2012 Miodrag Vallat. @@ -41,6 +41,7 @@ extern char *hw_prod; int hpc_old = 0; +int bios_year; void ip22_arcbios_walk(void); int ip22_arcbios_walk_component(arc_config_t *); @@ -126,7 +127,7 @@ ip22_memory_setup() shift = IMC_MEMC_LSHIFT; /* Revision D onwards uses larger units, to allow for more memory */ - if ((imc_read(IMC_SYSID) & IMC_SYSID_REVMASK) >= 5) + if ((imc_read(IMC_SYSID) & IMC_SYSID_REVMASK) >= 5) shift = IMC_MEMC_LSHIFT_HUGE; for (bank = 0; bank < IMC_NREGION; bank++) { @@ -300,6 +301,11 @@ ip22_setup() */ ip22_arcbios_walk(); + /* + * Get ARCBios' current time. + */ + bios_year = Bios_GetTime()->Year; + _device_register = arcs_device_register; } |