mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
xen/riscv: introduce preinit_xen_time()
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>
This commit is contained in:
1 parent
221c66f4f2
commit
025a9858fe
5 files changed
+51
-2
No files matched your search
@@ -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
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
/*
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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();
|
||||
}
|
||||