[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 17/18] hw/riscv: clint: Avoid using hard-coded timebase frequ
From: |
Alistair Francis |
Subject: |
Re: [PATCH 17/18] hw/riscv: clint: Avoid using hard-coded timebase frequency |
Date: |
Tue, 25 Aug 2020 11:33:59 -0700 |
On Fri, Aug 14, 2020 at 9:54 AM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> From: Bin Meng <bin.meng@windriver.com>
>
> At present the CLINT timestamp is using a hard-coded timebase
> frequency value SIFIVE_CLINT_TIMEBASE_FREQ. This might not be
> true for all boards.
>
> Add a new 'timebase-freq' property to the CLINT device, and
> update various functions to accept this as a parameter.
>
> Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
>
> hw/riscv/microchip_pfsoc.c | 6 +++++-
> hw/riscv/sifive_clint.c | 25 ++++++++++++++-----------
> hw/riscv/sifive_e.c | 3 ++-
> hw/riscv/sifive_u.c | 3 ++-
> hw/riscv/spike.c | 2 +-
> hw/riscv/virt.c | 3 ++-
> include/hw/riscv/sifive_clint.h | 3 ++-
> target/riscv/cpu.h | 6 ++++--
> target/riscv/cpu_helper.c | 4 +++-
> target/riscv/csr.c | 4 ++--
> 10 files changed, 37 insertions(+), 22 deletions(-)
>
> diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
> index 139284a..e8b7f86 100644
> --- a/hw/riscv/microchip_pfsoc.c
> +++ b/hw/riscv/microchip_pfsoc.c
> @@ -60,6 +60,9 @@
> #define BIOS_FILENAME "hss.bin"
> #define RESET_VECTOR 0x20220000
>
> +/* CLINT timebase frequency */
> +#define CLINT_TIMEBASE_FREQ 1000000
> +
> /* GEM version */
> #define GEM_REVISION 0x0107010c
>
> @@ -189,7 +192,8 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev,
> Error **errp)
> /* CLINT */
> sifive_clint_create(memmap[MICROCHIP_PFSOC_CLINT].base,
> memmap[MICROCHIP_PFSOC_CLINT].size, ms->smp.cpus,
> - SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, false);
> + SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE,
> + CLINT_TIMEBASE_FREQ, false);
>
> /* L2 cache controller */
> create_unimplemented_device("microchip.pfsoc.l2cc",
> diff --git a/hw/riscv/sifive_clint.c b/hw/riscv/sifive_clint.c
> index 669c21a..a568568 100644
> --- a/hw/riscv/sifive_clint.c
> +++ b/hw/riscv/sifive_clint.c
> @@ -29,22 +29,23 @@
> #include "hw/riscv/sifive_clint.h"
> #include "qemu/timer.h"
>
> -static uint64_t cpu_riscv_read_rtc(void)
> +static uint64_t cpu_riscv_read_rtc(uint32_t timebase_freq)
> {
> return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
> - SIFIVE_CLINT_TIMEBASE_FREQ, NANOSECONDS_PER_SECOND);
> + timebase_freq, NANOSECONDS_PER_SECOND);
> }
>
> /*
> * Called when timecmp is written to update the QEMU timer or immediately
> * trigger timer interrupt if mtimecmp <= current timer value.
> */
> -static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value)
> +static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value,
> + uint32_t timebase_freq)
> {
> uint64_t next;
> uint64_t diff;
>
> - uint64_t rtc_r = cpu_riscv_read_rtc();
> + uint64_t rtc_r = cpu_riscv_read_rtc(timebase_freq);
>
> cpu->env.timecmp = value;
> if (cpu->env.timecmp <= rtc_r) {
> @@ -59,7 +60,7 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu,
> uint64_t value)
> diff = cpu->env.timecmp - rtc_r;
> /* back to ns (note args switched in muldiv64) */
> next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
> - muldiv64(diff, NANOSECONDS_PER_SECOND, SIFIVE_CLINT_TIMEBASE_FREQ);
> + muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq);
> timer_mod(cpu->env.timer, next);
> }
>
> @@ -111,10 +112,10 @@ static uint64_t sifive_clint_read(void *opaque, hwaddr
> addr, unsigned size)
> }
> } else if (addr == clint->time_base) {
> /* time_lo */
> - return cpu_riscv_read_rtc() & 0xFFFFFFFF;
> + return cpu_riscv_read_rtc(clint->timebase_freq) & 0xFFFFFFFF;
> } else if (addr == clint->time_base + 4) {
> /* time_hi */
> - return (cpu_riscv_read_rtc() >> 32) & 0xFFFFFFFF;
> + return (cpu_riscv_read_rtc(clint->timebase_freq) >> 32) & 0xFFFFFFFF;
> }
>
> error_report("clint: invalid read: %08x", (uint32_t)addr);
> @@ -151,13 +152,13 @@ static void sifive_clint_write(void *opaque, hwaddr
> addr, uint64_t value,
> /* timecmp_lo */
> uint64_t timecmp_hi = env->timecmp >> 32;
> sifive_clint_write_timecmp(RISCV_CPU(cpu),
> - timecmp_hi << 32 | (value & 0xFFFFFFFF));
> + timecmp_hi << 32 | (value & 0xFFFFFFFF),
> clint->timebase_freq);
> return;
> } else if ((addr & 0x7) == 4) {
> /* timecmp_hi */
> uint64_t timecmp_lo = env->timecmp;
> sifive_clint_write_timecmp(RISCV_CPU(cpu),
> - value << 32 | (timecmp_lo & 0xFFFFFFFF));
> + value << 32 | (timecmp_lo & 0xFFFFFFFF),
> clint->timebase_freq);
> } else {
> error_report("clint: invalid timecmp write: %08x",
> (uint32_t)addr);
> }
> @@ -191,6 +192,7 @@ static Property sifive_clint_properties[] = {
> DEFINE_PROP_UINT32("timecmp-base", SiFiveCLINTState, timecmp_base, 0),
> DEFINE_PROP_UINT32("time-base", SiFiveCLINTState, time_base, 0),
> DEFINE_PROP_UINT32("aperture-size", SiFiveCLINTState, aperture_size, 0),
> + DEFINE_PROP_UINT32("timebase-freq", SiFiveCLINTState, timebase_freq, 0),
> DEFINE_PROP_END_OF_LIST(),
> };
>
> @@ -229,7 +231,7 @@ type_init(sifive_clint_register_types)
> */
> DeviceState *sifive_clint_create(hwaddr addr, hwaddr size, uint32_t
> num_harts,
> uint32_t sip_base, uint32_t timecmp_base, uint32_t time_base,
> - bool provide_rdtime)
> + uint32_t timebase_freq, bool provide_rdtime)
> {
> int i;
> for (i = 0; i < num_harts; i++) {
> @@ -239,7 +241,7 @@ DeviceState *sifive_clint_create(hwaddr addr, hwaddr
> size, uint32_t num_harts,
> continue;
> }
> if (provide_rdtime) {
> - riscv_cpu_set_rdtime_fn(env, cpu_riscv_read_rtc);
> + riscv_cpu_set_rdtime_fn(env, cpu_riscv_read_rtc, timebase_freq);
> }
> env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> &sifive_clint_timer_cb, cpu);
> @@ -252,6 +254,7 @@ DeviceState *sifive_clint_create(hwaddr addr, hwaddr
> size, uint32_t num_harts,
> qdev_prop_set_uint32(dev, "timecmp-base", timecmp_base);
> qdev_prop_set_uint32(dev, "time-base", time_base);
> qdev_prop_set_uint32(dev, "aperture-size", size);
> + qdev_prop_set_uint32(dev, "timebase-freq", timebase_freq);
> sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
> sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
> return dev;
> diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
> index c84d407..e7f6460 100644
> --- a/hw/riscv/sifive_e.c
> +++ b/hw/riscv/sifive_e.c
> @@ -213,7 +213,8 @@ static void sifive_e_soc_realize(DeviceState *dev, Error
> **errp)
> memmap[SIFIVE_E_PLIC].size);
> sifive_clint_create(memmap[SIFIVE_E_CLINT].base,
> memmap[SIFIVE_E_CLINT].size, ms->smp.cpus,
> - SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, false);
> + SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE,
> + SIFIVE_CLINT_TIMEBASE_FREQ, false);
> create_unimplemented_device("riscv.sifive.e.aon",
> memmap[SIFIVE_E_AON].base, memmap[SIFIVE_E_AON].size);
> sifive_e_prci_create(memmap[SIFIVE_E_PRCI].base);
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index e256da2..5ec9fca 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -706,7 +706,8 @@ static void sifive_u_soc_realize(DeviceState *dev, Error
> **errp)
> serial_hd(1), qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_UART1_IRQ));
> sifive_clint_create(memmap[SIFIVE_U_CLINT].base,
> memmap[SIFIVE_U_CLINT].size, ms->smp.cpus,
> - SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, false);
> + SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE,
> + SIFIVE_CLINT_TIMEBASE_FREQ, false);
>
> if (!sysbus_realize(SYS_BUS_DEVICE(&s->prci), errp)) {
> return;
> diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
> index 13958bd..ae8593a 100644
> --- a/hw/riscv/spike.c
> +++ b/hw/riscv/spike.c
> @@ -235,7 +235,7 @@ static void spike_board_init(MachineState *machine)
> /* Core Local Interruptor (timer and IPI) */
> sifive_clint_create(memmap[SPIKE_CLINT].base, memmap[SPIKE_CLINT].size,
> smp_cpus, SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE,
> - false);
> + SIFIVE_CLINT_TIMEBASE_FREQ, false);
> }
>
> static void spike_machine_init(MachineClass *mc)
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 6e91cf1..af0d06a 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -572,7 +572,8 @@ static void virt_machine_init(MachineState *machine)
> memmap[VIRT_PLIC].size);
> sifive_clint_create(memmap[VIRT_CLINT].base,
> memmap[VIRT_CLINT].size, smp_cpus,
> - SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, true);
> + SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE,
> + SIFIVE_CLINT_TIMEBASE_FREQ, true);
> sifive_test_create(memmap[VIRT_TEST].base);
>
> for (i = 0; i < VIRTIO_COUNT; i++) {
> diff --git a/include/hw/riscv/sifive_clint.h b/include/hw/riscv/sifive_clint.h
> index 4a720bf..eb8577a 100644
> --- a/include/hw/riscv/sifive_clint.h
> +++ b/include/hw/riscv/sifive_clint.h
> @@ -38,11 +38,12 @@ typedef struct SiFiveCLINTState {
> uint32_t timecmp_base;
> uint32_t time_base;
> uint32_t aperture_size;
> + uint32_t timebase_freq;
> } SiFiveCLINTState;
>
> DeviceState *sifive_clint_create(hwaddr addr, hwaddr size, uint32_t
> num_harts,
> uint32_t sip_base, uint32_t timecmp_base, uint32_t time_base,
> - bool provide_rdtime);
> + uint32_t timebase_freq, bool provide_rdtime);
>
> enum {
> SIFIVE_SIP_BASE = 0x0,
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index d34bcfa..02486c3 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -219,7 +219,8 @@ struct CPURISCVState {
> pmp_table_t pmp_state;
>
> /* machine specific rdtime callback */
> - uint64_t (*rdtime_fn)(void);
> + uint64_t (*rdtime_fn)(uint32_t);
> + uint32_t rdtime_fn_arg;
>
> /* True if in debugger mode. */
> bool debugger;
> @@ -347,7 +348,8 @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env);
> int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts);
> uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value);
> #define BOOL_TO_MASK(x) (-!!(x)) /* helper for riscv_cpu_update_mip value */
> -void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(void));
> +void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(uint32_t),
> + uint32_t arg);
> #endif
> void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv);
>
> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> index fd1d373..c82a521 100644
> --- a/target/riscv/cpu_helper.c
> +++ b/target/riscv/cpu_helper.c
> @@ -258,9 +258,11 @@ uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t
> mask, uint32_t value)
> return old;
> }
>
> -void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(void))
> +void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(uint32_t),
> + uint32_t arg)
> {
> env->rdtime_fn = fn;
> + env->rdtime_fn_arg = arg;
> }
>
> void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 6a96a01..6cef1ac 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -294,7 +294,7 @@ static int read_time(CPURISCVState *env, int csrno,
> target_ulong *val)
> return -1;
> }
>
> - *val = env->rdtime_fn() + delta;
> + *val = env->rdtime_fn(env->rdtime_fn_arg) + delta;
> return 0;
> }
>
> @@ -307,7 +307,7 @@ static int read_timeh(CPURISCVState *env, int csrno,
> target_ulong *val)
> return -1;
> }
>
> - *val = (env->rdtime_fn() + delta) >> 32;
> + *val = (env->rdtime_fn(env->rdtime_fn_arg) + delta) >> 32;
> return 0;
> }
> #endif
> --
> 2.7.4
>
>
- Re: [PATCH 14/18] hw/net: cadence_gem: Add a new 'phy-addr' property, (continued)
- Re: [PATCH 14/18] hw/net: cadence_gem: Add a new 'phy-addr' property, Bin Meng, 2020/08/16
- Re: [PATCH 14/18] hw/net: cadence_gem: Add a new 'phy-addr' property, Philippe Mathieu-Daudé, 2020/08/16
- Re: [PATCH 14/18] hw/net: cadence_gem: Add a new 'phy-addr' property, Nathan Rossi, 2020/08/16
- Re: [PATCH 14/18] hw/net: cadence_gem: Add a new 'phy-addr' property, Bin Meng, 2020/08/16
- Re: [PATCH 14/18] hw/net: cadence_gem: Add a new 'phy-addr' property, Philippe Mathieu-Daudé, 2020/08/16
[PATCH 15/18] hw/riscv: microchip_pfsoc: Connect 2 Cadence GEMs, Bin Meng, 2020/08/14
[PATCH 16/18] hw/riscv: microchip_pfsoc: Hook GPIO controllers, Bin Meng, 2020/08/14
[PATCH 17/18] hw/riscv: clint: Avoid using hard-coded timebase frequency, Bin Meng, 2020/08/14
- Re: [PATCH 17/18] hw/riscv: clint: Avoid using hard-coded timebase frequency,
Alistair Francis <=
[PATCH 18/18] hw/riscv: microchip_pfsoc: Document the software used for testing, Bin Meng, 2020/08/14
Re: [PATCH 00/18] hw/riscv: Add Microchip PolarFire SoC Icicle Kit board support, Anup Patel, 2020/08/14
- Re: [PATCH 00/18] hw/riscv: Add Microchip PolarFire SoC Icicle Kit board support, Bin Meng, 2020/08/17
- Re: [PATCH 00/18] hw/riscv: Add Microchip PolarFire SoC Icicle Kit board support, Cyril.Jean, 2020/08/17
- Re: [PATCH 00/18] hw/riscv: Add Microchip PolarFire SoC Icicle Kit board support, Alistair Francis, 2020/08/17
- Re: [PATCH 00/18] hw/riscv: Add Microchip PolarFire SoC Icicle Kit board support, Cyril.Jean, 2020/08/17
- Re: [PATCH 00/18] hw/riscv: Add Microchip PolarFire SoC Icicle Kit board support, Anup Patel, 2020/08/18
- Re: [PATCH 00/18] hw/riscv: Add Microchip PolarFire SoC Icicle Kit board support, Cyril.Jean, 2020/08/18
- Re: [PATCH 00/18] hw/riscv: Add Microchip PolarFire SoC Icicle Kit board support, Anup Patel, 2020/08/18