[kvm-unit-tests PATCH 3/7] riscv: Add ACPI support for timer frequency discovery
Andrew Jones
andrew.jones at linux.dev
Wed Sep 30 02:43:46 PDT 2026
On Thu, Sep 24, 2026 at 11:39:41AM +0800, Xiang W wrote:
> When a DT is not provided, read the system time base frequency from
> the RHCT instead of aborting in timer_get_frequency().
>
> RHCT Time Base Frequency is the ACPI equivalent of the DT
> /cpus timebase-frequency property and is the same for all harts.
> Keep DT as the preferred path when one is available.
>
> Signed-off-by: Xiang W <wangxiang at iscas.ac.cn>
> ---
> lib/acpi.h | 9 +++++++++
> lib/riscv/timer.c | 37 +++++++++++++++++++++++++------------
> 2 files changed, 34 insertions(+), 12 deletions(-)
>
> diff --git a/lib/acpi.h b/lib/acpi.h
> index a905807d..2597e8ce 100644
> --- a/lib/acpi.h
> +++ b/lib/acpi.h
> @@ -20,6 +20,7 @@
> #define MADT_SIGNATURE ACPI_SIGNATURE('A','P','I','C')
> #define SPCR_SIGNATURE ACPI_SIGNATURE('S','P','C','R')
> #define GTDT_SIGNATURE ACPI_SIGNATURE('G','T','D','T')
> +#define RHCT_SIGNATURE ACPI_SIGNATURE('R','H','C','T')
>
> #define ACPI_SIGNATURE_8BYTE(c1, c2, c3, c4, c5, c6, c7, c8) \
> (((uint64_t)(ACPI_SIGNATURE(c1, c2, c3, c4))) | \
> @@ -328,6 +329,14 @@ struct acpi_table_gtdt {
> u32 virtual_el2_timer_flags;
> };
>
> +struct acpi_table_rhct {
> + ACPI_TABLE_HEADER_DEF
> + u32 flags;
> + u64 timebase_frequency;
> + u32 node_count;
> + u32 node_offset;
> +};
> +
> /* Reset to default packing */
> #pragma pack()
>
> diff --git a/lib/riscv/timer.c b/lib/riscv/timer.c
> index 18063b7e..2a18f0e0 100644
> --- a/lib/riscv/timer.c
> +++ b/lib/riscv/timer.c
> @@ -13,24 +13,37 @@
> #include <asm/smp.h>
> #include <asm/timer.h>
>
> +#ifdef CONFIG_EFI
> +#include <acpi.h>
> +#endif
> +
> void timer_get_frequency(void)
> {
> - const struct fdt_property *prop;
> - u32 *data;
> - int cpus, len;
> -
> - assert_msg(dt_available(), "ACPI not yet supported");
> + if (dt_available()) {
> + const struct fdt_property *prop;
> + u32 *data;
> + int cpus, len;
>
> - const void *fdt = dt_fdt();
> + const void *fdt = dt_fdt();
This should be put above 'u32 *data'
>
> - cpus = fdt_path_offset(fdt, "/cpus");
> - assert(cpus >= 0);
> + cpus = fdt_path_offset(fdt, "/cpus");
> + assert(cpus >= 0);
>
> - prop = fdt_get_property(fdt, cpus, "timebase-frequency", &len);
> - assert(prop != NULL && len == 4);
> + prop = fdt_get_property(fdt, cpus, "timebase-frequency", &len);
> + assert(prop != NULL && len == 4);
>
> - data = (u32 *)prop->data;
> - timebase_frequency = fdt32_to_cpu(*data);
> + data = (u32 *)prop->data;
> + timebase_frequency = fdt32_to_cpu(*data);
> + } else {
> +#ifdef CONFIG_EFI
> + struct acpi_table_rhct *rhct;
Need a blank line here, or just do the find call on the same line.
> + rhct = find_acpi_table_addr(RHCT_SIGNATURE);
> + assert_msg(rhct, "Cannot find ACPI RHCT");
> + timebase_frequency = rhct->timebase_frequency;
> +#else
> + assert_msg(false, "ACPI not available");
> +#endif
> + }
> }
>
> void timer_start(unsigned long duration_us)
> --
> 2.47.3
>
Thanks,
drew
More information about the kvm-riscv
mailing list