diff options
author | Alexandru Elisei <alexandru.elisei@arm.com> | 2020-01-31 16:37:21 +0000 |
---|---|---|
committer | Andrew Jones <drjones@redhat.com> | 2020-04-03 09:40:33 +0200 |
commit | 0074eebcb5f40f152b210a9ab6f5394a0ed6e065 (patch) | |
tree | 0794ef432c1ebfdd637e8c81f6dc915f4efa77eb | |
parent | e14e6ba56f6e9597e774ab0e28f9ba9e5f5a06c9 (diff) | |
download | kvm-unit-tests-0074eebcb5f40f152b210a9ab6f5394a0ed6e065.tar.gz |
arm64: timer: Add ISB after register writes
From ARM DDI 0487E.a glossary, the section "Context synchronization
event":
"All direct and indirect writes to System registers that are made before
the Context synchronization event affect any instruction, including a
direct read, that appears in program order after the instruction causing
the Context synchronization event."
The ISB instruction is a context synchronization event [1]. Add an ISB
after all register writes, to make sure that the writes have been
completed when we try to test their effects.
[1] ARM DDI 0487E.a, section C6.2.96
Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com>
Signed-off-by: Andrew Jones <drjones@redhat.com>
-rw-r--r-- | arm/timer.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/arm/timer.c b/arm/timer.c index f390e8e..c6ea108 100644 --- a/arm/timer.c +++ b/arm/timer.c @@ -41,6 +41,7 @@ static u64 read_vtimer_cval(void) static void write_vtimer_cval(u64 val) { write_sysreg(val, cntv_cval_el0); + isb(); } static s32 read_vtimer_tval(void) @@ -51,6 +52,7 @@ static s32 read_vtimer_tval(void) static void write_vtimer_tval(s32 val) { write_sysreg(val, cntv_tval_el0); + isb(); } static u64 read_vtimer_ctl(void) @@ -61,6 +63,7 @@ static u64 read_vtimer_ctl(void) static void write_vtimer_ctl(u64 val) { write_sysreg(val, cntv_ctl_el0); + isb(); } static u64 read_ptimer_counter(void) @@ -76,6 +79,7 @@ static u64 read_ptimer_cval(void) static void write_ptimer_cval(u64 val) { write_sysreg(val, cntp_cval_el0); + isb(); } static s32 read_ptimer_tval(void) @@ -86,6 +90,7 @@ static s32 read_ptimer_tval(void) static void write_ptimer_tval(s32 val) { write_sysreg(val, cntp_tval_el0); + isb(); } static u64 read_ptimer_ctl(void) @@ -96,6 +101,7 @@ static u64 read_ptimer_ctl(void) static void write_ptimer_ctl(u64 val) { write_sysreg(val, cntp_ctl_el0); + isb(); } struct timer_info { @@ -181,7 +187,6 @@ static bool test_cval_10msec(struct timer_info *info) before_timer = info->read_counter(); info->write_cval(before_timer + time_10ms); info->write_ctl(ARCH_TIMER_CTL_ENABLE); - isb(); /* Wait for the timer to fire */ while (!(info->read_ctl() & ARCH_TIMER_CTL_ISTATUS)) @@ -217,11 +222,9 @@ static void test_timer(struct timer_info *info) /* Enable the timer, but schedule it for much later */ info->write_cval(later); info->write_ctl(ARCH_TIMER_CTL_ENABLE); - isb(); report(!gic_timer_pending(info), "not pending before"); info->write_cval(now - 1); - isb(); report(gic_timer_pending(info), "interrupt signal pending"); /* Disable the timer again and prepare to take interrupts */ |