[kvm-unit-tests PATCH 3/7] riscv: Add ACPI support for timer frequency discovery
Xiang W
wangxiang at iscas.ac.cn
Wed Sep 23 20:39:41 PDT 2026
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();
- 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;
+ 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
More information about the kvm-riscv
mailing list