qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [RFC PATCH v3 05/27] target/loongarch: Add stabletimer support


From: maobibo
Subject: Re: [RFC PATCH v3 05/27] target/loongarch: Add stabletimer support
Date: Tue, 7 Dec 2021 15:04:56 +0800
User-agent: Mozilla/5.0 (X11; Linux mips64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1


On 12/06/2021 12:38 PM, chen huacai wrote:
> Hi, Xiaojuan,
> 
> Maybe it is better to use "constant timer" instead of "stable timer",
> which is more "native" in English.

Yeap, maybe we need more investigation. On arm platform its name is ArchTimer
rather than "constant timer" in x86. And we will investigate the timer name
across different architecture.

regards
bibo, mao

> 
> Huacai
> 
> On Sat, Dec 4, 2021 at 8:11 PM Xiaojuan Yang <yangxiaojuan@loongson.cn> wrote:
>>
>> Signed-off-by: Xiaojuan Yang <yangxiaojuan@loongson.cn>
>> Signed-off-by: Song Gao <gaosong@loongson.cn>
>> ---
>>  target/loongarch/cpu.c         |  9 +++++
>>  target/loongarch/cpu.h         | 10 ++++++
>>  target/loongarch/meson.build   |  1 +
>>  target/loongarch/stabletimer.c | 63 ++++++++++++++++++++++++++++++++++
>>  4 files changed, 83 insertions(+)
>>  create mode 100644 target/loongarch/stabletimer.c
>>
>> diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
>> index 343632c644..f34e9763af 100644
>> --- a/target/loongarch/cpu.c
>> +++ b/target/loongarch/cpu.c
>> @@ -234,12 +234,21 @@ static void loongarch_cpu_realizefn(DeviceState *dev, 
>> Error **errp)
>>      LoongArchCPUClass *lacc = LOONGARCH_CPU_GET_CLASS(dev);
>>      Error *local_err = NULL;
>>
>> +#ifndef CONFIG_USER_ONLY
>> +    LoongArchCPU *cpu = LOONGARCH_CPU(dev);
>> +#endif
>> +
>>      cpu_exec_realizefn(cs, &local_err);
>>      if (local_err != NULL) {
>>          error_propagate(errp, local_err);
>>          return;
>>      }
>>
>> +#ifndef CONFIG_USER_ONLY
>> +    timer_init_ns(&cpu->timer, QEMU_CLOCK_VIRTUAL,
>> +                  &loongarch_stable_timer_cb, cpu);
>> +#endif
>> +
>>      cpu_reset(cs);
>>      qemu_init_vcpu(cs);
>>
>> diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
>> index a4acd3b285..aeb8a5d397 100644
>> --- a/target/loongarch/cpu.h
>> +++ b/target/loongarch/cpu.h
>> @@ -12,6 +12,7 @@
>>  #include "fpu/softfloat-types.h"
>>  #include "hw/registerfields.h"
>>  #include "cpu-csr.h"
>> +#include "qemu/timer.h"
>>
>>  #define TCG_GUEST_DEFAULT_MO (0)
>>
>> @@ -148,6 +149,9 @@ FIELD(CPUCFG20, L3IU_SIZE, 24, 7)
>>  extern const char * const regnames[];
>>  extern const char * const fregnames[];
>>
>> +#define N_IRQS      14
>> +#define IRQ_TIMER   11
>> +
>>  typedef struct CPULoongArchState CPULoongArchState;
>>  struct CPULoongArchState {
>>      uint64_t gpr[32];
>> @@ -242,6 +246,7 @@ struct LoongArchCPU {
>>
>>      CPUNegativeOffsetState neg;
>>      CPULoongArchState env;
>> +    QEMUTimer timer; /* Internal timer */
>>  };
>>
>>  #define TYPE_LOONGARCH_CPU "loongarch-cpu"
>> @@ -306,4 +311,9 @@ enum {
>>  #define LOONGARCH_CPU_TYPE_NAME(model) model LOONGARCH_CPU_TYPE_SUFFIX
>>  #define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU
>>
>> +void loongarch_stable_timer_cb(void *opaque);
>> +uint64_t cpu_loongarch_get_stable_counter(LoongArchCPU *cpu);
>> +uint64_t cpu_loongarch_get_stable_timer_ticks(LoongArchCPU *cpu);
>> +void cpu_loongarch_store_stable_timer_config(LoongArchCPU *cpu,
>> +                                             uint64_t value);
>>  #endif /* LOONGARCH_CPU_H */
>> diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build
>> index 103f36ee15..bda9f47ae4 100644
>> --- a/target/loongarch/meson.build
>> +++ b/target/loongarch/meson.build
>> @@ -17,6 +17,7 @@ loongarch_tcg_ss.add(zlib)
>>  loongarch_softmmu_ss = ss.source_set()
>>  loongarch_softmmu_ss.add(files(
>>    'machine.c',
>> +  'stabletimer.c',
>>  ))
>>
>>  loongarch_ss.add_all(when: 'CONFIG_TCG', if_true: [loongarch_tcg_ss])
>> diff --git a/target/loongarch/stabletimer.c b/target/loongarch/stabletimer.c
>> new file mode 100644
>> index 0000000000..151f5073f5
>> --- /dev/null
>> +++ b/target/loongarch/stabletimer.c
>> @@ -0,0 +1,63 @@
>> +/* SPDX-License-Identifier: GPL-2.0-or-later */
>> +/*
>> + * QEMU LoongArch timer support
>> + *
>> + * Copyright (c) 2021 Loongson Technology Corporation Limited
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "hw/loongarch/loongarch.h"
>> +#include "qemu/timer.h"
>> +#include "cpu.h"
>> +
>> +#define TIMER_PERIOD                10 /* 10 ns period for 100 Mhz 
>> frequency */
>> +#define STABLETIMER_TICK_MASK       0xfffffffffffcUL
>> +#define STABLETIMER_ENABLE          0x1UL
>> +
>> +/* LoongArch timer */
>> +uint64_t cpu_loongarch_get_stable_counter(LoongArchCPU *cpu)
>> +{
>> +    return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / TIMER_PERIOD;
>> +}
>> +
>> +uint64_t cpu_loongarch_get_stable_timer_ticks(LoongArchCPU *cpu)
>> +{
>> +    uint64_t now, expire;
>> +
>> +    now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
>> +    expire = timer_expire_time_ns(&cpu->timer);
>> +
>> +    return (expire - now) / TIMER_PERIOD;
>> +}
>> +
>> +void cpu_loongarch_store_stable_timer_config(LoongArchCPU *cpu,
>> +                                             uint64_t value)
>> +{
>> +    CPULoongArchState *env = &cpu->env;
>> +    uint64_t now, next;
>> +
>> +    env->CSR_TCFG = value;
>> +    if (value & STABLETIMER_ENABLE) {
>> +        now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
>> +        next = now + (value & STABLETIMER_TICK_MASK) * TIMER_PERIOD;
>> +        timer_mod(&cpu->timer, next);
>> +    }
>> +}
>> +
>> +void loongarch_stable_timer_cb(void *opaque)
>> +{
>> +    LoongArchCPU *cpu  = opaque;
>> +    CPULoongArchState *env = &cpu->env;
>> +    uint64_t now, next;
>> +
>> +    if (FIELD_EX64(env->CSR_TCFG, CSR_TCFG, PERIODIC)) {
>> +        now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
>> +        next = now + (env->CSR_TCFG & STABLETIMER_TICK_MASK) * TIMER_PERIOD;
>> +        timer_mod(&cpu->timer, next);
>> +    } else {
>> +        env->CSR_TCFG = FIELD_DP64(env->CSR_TCFG, CSR_TCFG, EN, 0);
>> +    }
>> +
>> +    env->CSR_ESTAT |= 1 << IRQ_TIMER;
>> +    cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
>> +}
>> --
>> 2.27.0
>>
>>
> 
> 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]