diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2008-07-20 10:37:44 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2008-07-20 10:37:44 +0000 |
commit | fdc785b49ef0e00a00bb8bed9ddbbdf65af6db14 (patch) | |
tree | bcaf0942c42f2f58a008b1ceb973d17a7e25ac92 /sys/arch | |
parent | a3297c775348f26e4d371a04924ee16c408f89f4 (diff) |
Provide a timecounter based on the UltraSPARC IIe STICK logic.
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/sparc64/dev/psycho.c | 30 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/psychoreg.h | 9 |
2 files changed, 37 insertions, 2 deletions
diff --git a/sys/arch/sparc64/dev/psycho.c b/sys/arch/sparc64/dev/psycho.c index 42baeb77e5e..40c2c8baf38 100644 --- a/sys/arch/sparc64/dev/psycho.c +++ b/sys/arch/sparc64/dev/psycho.c @@ -1,4 +1,4 @@ -/* $OpenBSD: psycho.c,v 1.60 2008/07/12 10:07:25 kettenis Exp $ */ +/* $OpenBSD: psycho.c,v 1.61 2008/07/20 10:37:43 kettenis Exp $ */ /* $NetBSD: psycho.c,v 1.39 2001/10/07 20:30:41 eeh Exp $ */ /* @@ -42,6 +42,7 @@ #include <sys/malloc.h> #include <sys/systm.h> #include <sys/time.h> +#include <sys/timetc.h> #include <sys/reboot.h> #include <uvm/uvm_extern.h> @@ -123,6 +124,12 @@ void psycho_conf_write(pci_chipset_tag_t, pcitag_t, int, pcireg_t); /* base pci_chipset */ extern struct sparc_pci_chipset _sparc_pci_chipset; +u_int stick_get_timecount(struct timecounter *); + +struct timecounter stick_timecounter = { + stick_get_timecount, NULL, ~0u, 0, "stick", 1000, NULL +}; + /* * autoconfiguration */ @@ -238,6 +245,7 @@ psycho_attach(struct device *parent, struct device *self, void *aux) int psycho_br[2], n; struct psycho_type *ptype; char buf[32]; + u_int stick_rate; sc->sc_node = ma->ma_node; sc->sc_bustag = ma->ma_bustag; @@ -557,6 +565,18 @@ psycho_attach(struct device *parent, struct device *self, void *aux) } /* + * The UltraSPARC IIe has new STICK logic that provides a + * timebase counter that doesn't scale with processor + * frequency. Use it to provide a timecounter. + */ + stick_rate = getpropint(findroot(), "stick-frequency", 0); + if (stick_rate > 0 && sc->sc_mode == PSYCHO_MODE_SABRE) { + stick_timecounter.tc_frequency = stick_rate; + stick_timecounter.tc_priv = sc; + tc_init(&stick_timecounter); + } + + /* * attach the pci.. note we pass PCI A tags, etc., for the sabre here. */ pba.pba_busname = "pci"; @@ -1284,3 +1304,11 @@ psycho_sabre_dvmamap_sync(bus_dma_tag_t t, bus_dma_tag_t t0, bus_dmamap_t map, if (ops & (BUS_DMASYNC_POSTREAD | BUS_DMASYNC_PREWRITE)) membar(MemIssue); } + +u_int +stick_get_timecount(struct timecounter *tc) +{ + struct psycho_softc *sc = tc->tc_priv; + + return psycho_psychoreg_read(sc, stick_reg_low); +} diff --git a/sys/arch/sparc64/dev/psychoreg.h b/sys/arch/sparc64/dev/psychoreg.h index 93a01382129..5d174d76702 100644 --- a/sys/arch/sparc64/dev/psychoreg.h +++ b/sys/arch/sparc64/dev/psychoreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: psychoreg.h,v 1.12 2008/07/12 13:08:04 kettenis Exp $ */ +/* $OpenBSD: psychoreg.h,v 1.13 2008/07/20 10:37:43 kettenis Exp $ */ /* $NetBSD: psychoreg.h,v 1.6.4.2 2001/09/13 01:14:40 thorpej Exp $ */ /* @@ -219,6 +219,13 @@ struct psychoreg { u_int64_t pad19[208]; } psy_strbufdiag[2]; /* For PCI a and b */ + u_int64_t pad18[1036]; + + u_int64_t stick_cmp_low; /* STICK comparison low reg */ /* 1fe.0000.f060 */ + u_int64_t stick_cmp_high; /* STICK comparison high reg */ /* 1fe.0000.f068 */ + u_int64_t stick_reg_low; /* STICK counter low reg */ /* 1fe.0000.f070 */ + u_int64_t stick_reg_high; /* STICK counter high reg */ /* 1fe.0000.f078 */ + /* * Here is the rest of the map, which we're not specifying: * |