LoongArch: Adjust time routines for 32BIT/64BIT
Adjust time routines for both 32BIT and 64BIT, including: rdtime_h() /
rdtime_l() definitions for 32BIT and rdtime_d() definition for 64BIT,
get_cycles() and get_cycles64() definitions for 32BIT/64BIT, show time
frequency info ("CPU MHz" and "BogoMIPS") in /proc/cpuinfo, etc.
Use do_div() for division which works on both 32BIT and 64BIT platforms.
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
pull/1354/merge
parent
4ad04e7c7e
commit
ced7814d3a
|
|
@ -1238,7 +1238,35 @@
|
|||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
static __always_inline u64 drdtime(void)
|
||||
#ifdef CONFIG_32BIT
|
||||
|
||||
static __always_inline u32 rdtime_h(void)
|
||||
{
|
||||
u32 val = 0;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"rdtimeh.w %0, $zero\n\t"
|
||||
: "=r"(val)
|
||||
:
|
||||
);
|
||||
return val;
|
||||
}
|
||||
|
||||
static __always_inline u32 rdtime_l(void)
|
||||
{
|
||||
u32 val = 0;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"rdtimel.w %0, $zero\n\t"
|
||||
: "=r"(val)
|
||||
:
|
||||
);
|
||||
return val;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static __always_inline u64 rdtime_d(void)
|
||||
{
|
||||
u64 val = 0;
|
||||
|
||||
|
|
@ -1250,6 +1278,8 @@ static __always_inline u64 drdtime(void)
|
|||
return val;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static inline unsigned int get_csr_cpuid(void)
|
||||
{
|
||||
return csr_read32(LOONGARCH_CSR_CPUID);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,38 @@ typedef unsigned long cycles_t;
|
|||
|
||||
static inline cycles_t get_cycles(void)
|
||||
{
|
||||
return drdtime();
|
||||
#ifdef CONFIG_32BIT
|
||||
return rdtime_l();
|
||||
#else
|
||||
return rdtime_d();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_32BIT
|
||||
|
||||
#define get_cycles_hi get_cycles_hi
|
||||
|
||||
static inline cycles_t get_cycles_hi(void)
|
||||
{
|
||||
return rdtime_h();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static inline u64 get_cycles64(void)
|
||||
{
|
||||
#ifdef CONFIG_32BIT
|
||||
u32 hi, lo;
|
||||
|
||||
do {
|
||||
hi = rdtime_h();
|
||||
lo = rdtime_l();
|
||||
} while (hi != rdtime_h());
|
||||
|
||||
return ((u64)hi << 32) | lo;
|
||||
#else
|
||||
return rdtime_d();
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
|
|
|||
|
|
@ -20,11 +20,14 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
|||
unsigned int prid = cpu_data[n].processor_id;
|
||||
unsigned int version = cpu_data[n].processor_id & 0xff;
|
||||
unsigned int fp_version = cpu_data[n].fpu_vers;
|
||||
u64 freq = cpu_clock_freq, bogomips = lpj_fine * cpu_clock_freq;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
if (!cpu_online(n))
|
||||
return 0;
|
||||
#endif
|
||||
do_div(freq, 10000);
|
||||
do_div(bogomips, const_clock_freq * (5000/HZ));
|
||||
|
||||
/*
|
||||
* For the first processor also print the system type
|
||||
|
|
@ -41,11 +44,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
|||
seq_printf(m, "PRID\t\t\t: %s (%08x)\n", id_to_core_name(prid), prid);
|
||||
seq_printf(m, "CPU Revision\t\t: 0x%02x\n", version);
|
||||
seq_printf(m, "FPU Revision\t\t: 0x%02x\n", fp_version);
|
||||
seq_printf(m, "CPU MHz\t\t\t: %llu.%02llu\n",
|
||||
cpu_clock_freq / 1000000, (cpu_clock_freq / 10000) % 100);
|
||||
seq_printf(m, "BogoMIPS\t\t: %llu.%02llu\n",
|
||||
(lpj_fine * cpu_clock_freq / const_clock_freq) / (500000/HZ),
|
||||
((lpj_fine * cpu_clock_freq / const_clock_freq) / (5000/HZ)) % 100);
|
||||
seq_printf(m, "CPU MHz\t\t\t: %u.%02u\n", (u32)freq / 100, (u32)freq % 100);
|
||||
seq_printf(m, "BogoMIPS\t\t: %u.%02u\n", (u32)bogomips / 100, (u32)bogomips % 100);
|
||||
seq_printf(m, "TLB Entries\t\t: %d\n", cpu_data[n].tlbsize);
|
||||
seq_printf(m, "Address Sizes\t\t: %d bits physical, %d bits virtual\n",
|
||||
cpu_pabits + 1, cpu_vabits + 1);
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ void noinstr __no_stack_protector do_syscall(struct pt_regs *regs)
|
|||
*
|
||||
* The resulting 6 bits of entropy is seen in SP[9:4].
|
||||
*/
|
||||
choose_random_kstack_offset(drdtime());
|
||||
choose_random_kstack_offset(get_cycles());
|
||||
|
||||
syscall_exit_to_user_mode(regs);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include <asm/loongarch.h>
|
||||
#include <asm/paravirt.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/timex.h>
|
||||
|
||||
u64 cpu_clock_freq;
|
||||
EXPORT_SYMBOL(cpu_clock_freq);
|
||||
|
|
@ -62,12 +63,12 @@ static int constant_set_state_oneshot(struct clock_event_device *evt)
|
|||
|
||||
static int constant_set_state_periodic(struct clock_event_device *evt)
|
||||
{
|
||||
unsigned long period;
|
||||
unsigned long timer_config;
|
||||
u64 period = const_clock_freq;
|
||||
|
||||
raw_spin_lock(&state_lock);
|
||||
|
||||
period = const_clock_freq / HZ;
|
||||
do_div(period, HZ);
|
||||
timer_config = period & CSR_TCFG_VAL;
|
||||
timer_config |= (CSR_TCFG_PERIOD | CSR_TCFG_EN);
|
||||
csr_write(timer_config, LOONGARCH_CSR_TCFG);
|
||||
|
|
@ -120,7 +121,7 @@ static int arch_timer_dying(unsigned int cpu)
|
|||
|
||||
static unsigned long get_loops_per_jiffy(void)
|
||||
{
|
||||
unsigned long lpj = (unsigned long)const_clock_freq;
|
||||
u64 lpj = const_clock_freq;
|
||||
|
||||
do_div(lpj, HZ);
|
||||
|
||||
|
|
@ -131,7 +132,7 @@ static long init_offset;
|
|||
|
||||
void save_counter(void)
|
||||
{
|
||||
init_offset = drdtime();
|
||||
init_offset = get_cycles();
|
||||
}
|
||||
|
||||
void sync_counter(void)
|
||||
|
|
@ -197,12 +198,12 @@ int constant_clockevent_init(void)
|
|||
|
||||
static u64 read_const_counter(struct clocksource *clk)
|
||||
{
|
||||
return drdtime();
|
||||
return get_cycles64();
|
||||
}
|
||||
|
||||
static noinstr u64 sched_clock_read(void)
|
||||
{
|
||||
return drdtime();
|
||||
return get_cycles64();
|
||||
}
|
||||
|
||||
static struct clocksource clocksource_const = {
|
||||
|
|
@ -235,7 +236,7 @@ void __init time_init(void)
|
|||
else
|
||||
const_clock_freq = calc_const_freq();
|
||||
|
||||
init_offset = -(drdtime() - csr_read(LOONGARCH_CSR_CNTC));
|
||||
init_offset = -(get_cycles() - csr_read(LOONGARCH_CSR_CNTC));
|
||||
|
||||
constant_clockevent_init();
|
||||
constant_clocksource_init();
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include <asm/loongarch.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/timex.h>
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include "trace.h"
|
||||
|
|
@ -811,7 +812,7 @@ static int kvm_get_one_reg(struct kvm_vcpu *vcpu,
|
|||
case KVM_REG_LOONGARCH_KVM:
|
||||
switch (reg->id) {
|
||||
case KVM_REG_LOONGARCH_COUNTER:
|
||||
*v = drdtime() + vcpu->kvm->arch.time_offset;
|
||||
*v = get_cycles() + vcpu->kvm->arch.time_offset;
|
||||
break;
|
||||
case KVM_REG_LOONGARCH_DEBUG_INST:
|
||||
*v = INSN_HVCL | KVM_HCALL_SWDBG;
|
||||
|
|
@ -906,7 +907,7 @@ static int kvm_set_one_reg(struct kvm_vcpu *vcpu,
|
|||
* only set for the first time for smp system
|
||||
*/
|
||||
if (vcpu->vcpu_id == 0)
|
||||
vcpu->kvm->arch.time_offset = (signed long)(v - drdtime());
|
||||
vcpu->kvm->arch.time_offset = (signed long)(v - get_cycles());
|
||||
break;
|
||||
case KVM_REG_LOONGARCH_VCPU_RESET:
|
||||
vcpu->arch.st.guest_addr = 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue