[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 06/32] target/riscv: No need to re-start QEMU timer when timecmp =
From: |
Alistair Francis |
Subject: |
[PULL 06/32] target/riscv: No need to re-start QEMU timer when timecmp == UINT64_MAX |
Date: |
Tue, 7 Feb 2023 17:09:17 +1000 |
From: Anup Patel <apatel@ventanamicro.com>
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>
---
target/riscv/time_helper.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/target/riscv/time_helper.c b/target/riscv/time_helper.c
index 4fb2a471a9..b654f91af9 100644
--- a/target/riscv/time_helper.c
+++ b/target/riscv/time_helper.c
@@ -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) */
--
2.39.1
- [PULL 00/32] riscv-to-apply queue, Alistair Francis, 2023/02/07
- [PULL 02/32] include/hw/riscv/opentitan: update opentitan IRQs, Alistair Francis, 2023/02/07
- [PULL 03/32] hw/riscv: boot: Don't use CSRs if they are disabled, Alistair Francis, 2023/02/07
- [PULL 01/32] target/riscv: update disas.c for xnor/orn/andn and slli.uw, Alistair Francis, 2023/02/07
- [PULL 05/32] target/riscv: Don't clear mask in riscv_cpu_update_mip() for VSTIP, Alistair Francis, 2023/02/07
- [PULL 06/32] target/riscv: No need to re-start QEMU timer when timecmp == UINT64_MAX,
Alistair Francis <=
- [PULL 08/32] hw/riscv/virt.c: calculate socket count once in create_fdt_imsic(), Alistair Francis, 2023/02/07
- [PULL 10/32] hw/riscv/spike.c: rename MachineState 'mc' pointers to' ms', Alistair Francis, 2023/02/07
- [PULL 04/32] target/riscv: Update VS timer whenever htimedelta changes, Alistair Francis, 2023/02/07
- [PULL 11/32] target/riscv: set tval for triggered watchpoints, Alistair Francis, 2023/02/07
- [PULL 07/32] target/riscv: Ensure opcode is saved for all relevant instructions, Alistair Francis, 2023/02/07
- [PULL 12/32] hw/riscv/boot.c: calculate fdt size after fdt_pack(), Alistair Francis, 2023/02/07
- [PULL 09/32] hw/riscv/virt.c: rename MachineState 'mc' pointers to 'ms', Alistair Francis, 2023/02/07
- [PULL 13/32] hw/riscv: split fdt address calculation from fdt load, Alistair Francis, 2023/02/07
- [PULL 14/32] hw/riscv: change riscv_compute_fdt_addr() semantics, Alistair Francis, 2023/02/07
- [PULL 16/32] RISC-V: Adding XTheadSync ISA extension, Alistair Francis, 2023/02/07