]> xenbits.xensource.com Git - xen.git/commitdiff
xen/riscv: introduce preinit_xen_time()
authorOleksii Kurochko <oleksii.kurochko@gmail.com>
Tue, 1 Apr 2025 10:44:51 +0000 (12:44 +0200)
committerJan Beulich <jbeulich@suse.com>
Tue, 1 Apr 2025 10:44:51 +0000 (12:44 +0200)
preinit_xen_time() does two things:
1. Parse timebase-frequency properpy of /cpus node to initialize cpu_khz
   variable.
2. Initialize boot_clock_cycles with the current time counter value to
   have starting point for Xen.

timebase-frequency is read as a uint32_t because it is unlikely that the
timer will run at more than 4 GHz. If timebase-frequency exceeds 4 GHz,
a panic() is triggered, since dt_property_read_u32() will return 0 if
the size of the timebase-frequency property is greater than the size of
the output variable.

Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
xen/arch/riscv/Makefile
xen/arch/riscv/include/asm/time.h
xen/arch/riscv/setup.c
xen/arch/riscv/stubs.c
xen/arch/riscv/time.c [new file with mode: 0644]

index b0c8270a99473e867dee38fc8ec6688b76cfbb2e..82016a957a9d83c7fa65964d5ade897fe55e51cd 100644 (file)
@@ -9,6 +9,7 @@ obj-y += setup.o
 obj-y += shutdown.o
 obj-y += smp.o
 obj-y += stubs.o
+obj-y += time.o
 obj-y += traps.o
 obj-y += vm_event.o
 
index fc1572e9b43b97aa823bcb4d7803d3d6b04e2d17..e8d9ffec574ca30c29482ab94a0f1699dde0731f 100644 (file)
@@ -3,8 +3,12 @@
 #define ASM__RISCV__TIME_H
 
 #include <xen/bug.h>
+#include <xen/types.h>
 #include <asm/csr.h>
 
+/* Clock cycles count at Xen startup */
+extern uint64_t boot_clock_cycles;
+
 struct vcpu;
 
 static inline void force_update_vcpu_system_time(struct vcpu *v)
@@ -19,6 +23,8 @@ static inline cycles_t get_cycles(void)
     return csr_read(CSR_TIME);
 }
 
+void preinit_xen_time(void);
+
 #endif /* ASM__RISCV__TIME_H */
 
 /*
index b0e587678e3bbd04c87ea866c63243cd9ce66bf0..836ad16fed64e798ed420d3d4d9a136e080560c2 100644 (file)
@@ -126,6 +126,8 @@ void __init noreturn start_xen(unsigned long bootcpu_id,
 
     riscv_fill_hwcap();
 
+    preinit_xen_time();
+
     printk("All set up\n");
 
     machine_halt();
index 5951b0ce91edb0f67348ec01be79d04f5acd213b..caa133de84c5a224341f0d2ed0013fc414311d2b 100644 (file)
@@ -27,8 +27,6 @@ nodemask_t __read_mostly node_online_map = { { [0] = 1UL } };
 
 /* time.c */
 
-unsigned long __ro_after_init cpu_khz;  /* CPU clock frequency in kHz. */
-
 s_time_t get_s_time(void)
 {
     BUG_ON("unimplemented");
diff --git a/xen/arch/riscv/time.c b/xen/arch/riscv/time.c
new file mode 100644 (file)
index 0000000..905bb13
--- /dev/null
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#include <xen/acpi.h>
+#include <xen/device_tree.h>
+#include <xen/init.h>
+#include <xen/lib.h>
+#include <xen/sections.h>
+
+unsigned long __ro_after_init cpu_khz; /* CPU clock frequency in kHz. */
+uint64_t __ro_after_init boot_clock_cycles;
+
+/* Set up the timer on the boot CPU (early init function) */
+static void __init preinit_dt_xen_time(void)
+{
+    static const struct dt_device_match __initconstrel timer_ids[] =
+    {
+        DT_MATCH_PATH("/cpus"),
+        { /* sentinel */ },
+    };
+    struct dt_device_node *timer;
+    uint32_t rate;
+
+    timer = dt_find_matching_node(NULL, timer_ids);
+    if ( !timer )
+        panic("Unable to find a compatible timer in the device tree\n");
+
+    dt_device_set_used_by(timer, DOMID_XEN);
+
+    if ( !dt_property_read_u32(timer, "timebase-frequency", &rate) )
+        panic("Unable to find clock frequency\n");
+
+    cpu_khz = rate / 1000;
+}
+
+void __init preinit_xen_time(void)
+{
+    if ( acpi_disabled )
+        preinit_dt_xen_time();
+    else
+        panic("%s: ACPI isn't supported\n", __func__);
+
+    boot_clock_cycles = get_cycles();
+}