target/riscv: No need to re-start QEMU timer when timecmp == UINT64_MAX

The time CSR will wrap-around immediately after reaching UINT64_MAX
so we don't need to re-start QEMU timer when timecmp == UINT64_MAX
in riscv_timer_write_timecmp().

Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <20230120125950.2246378-4-apatel@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
Anup Patel 2023-01-20 18:29:49 +05:30 committed by Alistair Francis
parent 14cb78bfaf
commit ae0edf2188
1 changed files with 24 additions and 0 deletions

View File

@ -72,6 +72,30 @@ void riscv_timer_write_timecmp(RISCVCPU *cpu, QEMUTimer *timer,
riscv_cpu_update_mip(cpu, timer_irq, BOOL_TO_MASK(0));
}
/*
* Sstc specification says the following about timer interrupt:
* "A supervisor timer interrupt becomes pending - as reflected in
* the STIP bit in the mip and sip registers - whenever time contains
* a value greater than or equal to stimecmp, treating the values
* as unsigned integers. Writes to stimecmp are guaranteed to be
* reflected in STIP eventually, but not necessarily immediately.
* The interrupt remains posted until stimecmp becomes greater
* than time - typically as a result of writing stimecmp."
*
* When timecmp = UINT64_MAX, the time CSR will eventually reach
* timecmp value but on next timer tick the time CSR will wrap-around
* and become zero which is less than UINT64_MAX. Now, the timer
* interrupt behaves like a level triggered interrupt so it will
* become 1 when time = timecmp = UINT64_MAX and next timer tick
* it will become 0 again because time = 0 < timecmp = UINT64_MAX.
*
* Based on above, we don't re-start the QEMU timer when timecmp
* equals UINT64_MAX.
*/
if (timecmp == UINT64_MAX) {
return;
}
/* otherwise, set up the future timer interrupt */
diff = timecmp - rtc_r;
/* back to ns (note args switched in muldiv64) */