summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2020-06-05 22:14:26 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2020-06-05 22:14:26 +0000
commitbb47463e44ba95db5a0ce64649ba085ef8c18638 (patch)
tree1ba9f5987bfffc89a7befdcfb3b35223ae7fad91 /sys/arch
parent659b80aba7ce97881c95c78858f7f1e214ecd458 (diff)
Allow userland access to the virtual counter.
ok patrick@, deraadt@
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/arm64/dev/agtimer.c16
-rw-r--r--sys/arch/arm64/include/armreg.h5
2 files changed, 16 insertions, 5 deletions
diff --git a/sys/arch/arm64/dev/agtimer.c b/sys/arch/arm64/dev/agtimer.c
index 29394141ad5..11196b5c60d 100644
--- a/sys/arch/arm64/dev/agtimer.c
+++ b/sys/arch/arm64/dev/agtimer.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: agtimer.c,v 1.11 2019/10/05 11:27:02 kettenis Exp $ */
+/* $OpenBSD: agtimer.c,v 1.12 2020/06/05 22:14:25 kettenis Exp $ */
/*
* Copyright (c) 2011 Dale Rahn <drahn@openbsd.org>
* Copyright (c) 2013 Patrick Wildt <patrick@blueri.se>
@@ -169,8 +169,6 @@ agtimer_attach(struct device *parent, struct device *self, void *aux)
printf(": tick rate %d KHz\n", sc->sc_ticks_per_second /1000);
- /* XXX: disable user access */
-
#ifdef AMPTIMER_DEBUG
evcount_attach(&sc->sc_clk_count, "clock", NULL);
evcount_attach(&sc->sc_stat_count, "stat", NULL);
@@ -281,12 +279,13 @@ agtimer_set_clockrate(int32_t new_frequency)
}
void
-agtimer_cpu_initclocks()
+agtimer_cpu_initclocks(void)
{
struct agtimer_softc *sc = agtimer_cd.cd_devs[0];
struct agtimer_pcpu_softc *pc = &sc->sc_pstat[CPU_INFO_UNIT(curcpu())];
uint32_t reg;
uint64_t next;
+ uint64_t kctl;
stathz = hz;
profhz = hz * 10;
@@ -313,6 +312,10 @@ agtimer_cpu_initclocks()
reg |= GTIMER_CNTV_CTL_ENABLE;
agtimer_set_tval(sc->sc_ticks_per_second);
agtimer_set_ctrl(reg);
+
+ /* enable userland access to virtual counter */
+ kctl = READ_SPECIALREG(CNTKCTL_EL1);
+ WRITE_SPECIALREG(CNTKCTL_EL1, kctl | CNTKCTL_EL0VCTEN);
}
void
@@ -378,6 +381,7 @@ agtimer_startclock(void)
struct agtimer_softc *sc = agtimer_cd.cd_devs[0];
struct agtimer_pcpu_softc *pc = &sc->sc_pstat[CPU_INFO_UNIT(curcpu())];
uint64_t nextevent;
+ uint64_t kctl;
uint32_t reg;
nextevent = agtimer_readcnt64() + sc->sc_ticks_per_intr;
@@ -390,6 +394,10 @@ agtimer_startclock(void)
reg |= GTIMER_CNTV_CTL_ENABLE;
agtimer_set_tval(sc->sc_ticks_per_second);
agtimer_set_ctrl(reg);
+
+ /* enable userland access to virtual counter */
+ kctl = READ_SPECIALREG(CNTKCTL_EL1);
+ WRITE_SPECIALREG(CNTKCTL_EL1, kctl | CNTKCTL_EL0VCTEN);
}
void
diff --git a/sys/arch/arm64/include/armreg.h b/sys/arch/arm64/include/armreg.h
index f79e32c9311..54a02384510 100644
--- a/sys/arch/arm64/include/armreg.h
+++ b/sys/arch/arm64/include/armreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: armreg.h,v 1.10 2019/10/17 15:38:56 drahn Exp $ */
+/* $OpenBSD: armreg.h,v 1.11 2020/06/05 22:14:25 kettenis Exp $ */
/*-
* Copyright (c) 2013, 2014 Andrew Turner
* Copyright (c) 2015 The FreeBSD Foundation
@@ -69,6 +69,9 @@
#define CNTHCTL_EL1PCEN (1 << 1) /* Allow EL0/1 physical timer access */
#define CNTHCTL_EL1PCTEN (1 << 0) /*Allow EL0/1 physical counter access*/
+/* CNTKCTL_EL1 - Counter-timer Kernel Control Register */
+#define CNTKCTL_EL0VCTEN (1 << 1) /* Allow EL0 virtual counter access */
+
/* CPACR_EL1 */
#define CPACR_FPEN_MASK (0x3 << 20)
#define CPACR_FPEN_TRAP_ALL1 (0x0 << 20) /* Traps from EL0 and EL1 */