@samitouri / QOSamiQemu / commits / 77b91aca61

target/loongarch: Set timer tick value even if disabled

If constant timer is enabled, its tick value is remained value from the next expired time. However if timer is not enabled, its value should be CONSTANT_TIMER_TICK_MASK or zero. Signed-off-by: Bibo Mao <maobibo@loongson.cn> Reviewed-by: Xianglai Li <lixianglai@loongson.cn>

Bibo Mao committed Jul 14, 2026 at 10:55 UTC 77b91aca6148fafcade41516f12a3309f1e1f552
1 file changed +13 -4
target/loongarch/tcg/constant_timer.c
+13 -4
@@ -22,12 +22,18 @@ uint64_t cpu_loongarch_get_constant_timer_counter(LoongArchCPU *cpu)
22
23 uint64_t cpu_loongarch_get_constant_timer_ticks(LoongArchCPU *cpu)
24 {
25 + CPULoongArchState *env = &cpu->env;
26 + CPUSysState *sys = env_sys(env);
27 uint64_t now, expire;
28
27 - now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
28 - expire = timer_expire_time_ns(&cpu->timer);
29 + if ((sys->CSR_TCFG & CONSTANT_TIMER_ENABLE) &&
30 + (sys->CSR_TVAL < sys->CSR_TCFG)) {
31 + now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
32 + expire = timer_expire_time_ns(&cpu->timer);
33 + sys->CSR_TVAL = (expire - now) / TIMER_PERIOD;
34 + }
35
30 - return (expire - now) / TIMER_PERIOD;
36 + return sys->CSR_TVAL;
37 }
38
39 void cpu_loongarch_store_constant_timer_config(LoongArchCPU *cpu,
@@ -42,8 +48,10 @@ void cpu_loongarch_store_constant_timer_config(LoongArchCPU *cpu,
48 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
49 next = now + (value & CONSTANT_TIMER_TICK_MASK) * TIMER_PERIOD;
50 timer_mod(&cpu->timer, next);
51 + sys->CSR_TVAL = sys->CSR_TCFG & CONSTANT_TIMER_TICK_MASK;
52 } else {
53 timer_del(&cpu->timer);
54 + sys->CSR_TVAL = 0;
55 }
56 }
57
@@ -58,8 +66,9 @@ void loongarch_constant_timer_cb(void *opaque)
66 now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
67 next = now + (sys->CSR_TCFG & CONSTANT_TIMER_TICK_MASK) * TIMER_PERIOD;
68 timer_mod(&cpu->timer, next);
69 + sys->CSR_TVAL = sys->CSR_TCFG & CONSTANT_TIMER_TICK_MASK;
70 } else {
62 - sys->CSR_TCFG = FIELD_DP64(sys->CSR_TCFG, CSR_TCFG, EN, 0);
71 + sys->CSR_TVAL = CONSTANT_TIMER_TICK_MASK;
72 }
73
74 loongarch_cpu_set_irq(opaque, IRQ_TIMER, 1);