Skip to content

Commit ced7814

Browse files
committed
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>
1 parent 4ad04e7 commit ced7814

6 files changed

Lines changed: 80 additions & 17 deletions

File tree

arch/loongarch/include/asm/loongarch.h

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1238,7 +1238,35 @@
12381238

12391239
#ifndef __ASSEMBLER__
12401240

1241-
static __always_inline u64 drdtime(void)
1241+
#ifdef CONFIG_32BIT
1242+
1243+
static __always_inline u32 rdtime_h(void)
1244+
{
1245+
u32 val = 0;
1246+
1247+
__asm__ __volatile__(
1248+
"rdtimeh.w %0, $zero\n\t"
1249+
: "=r"(val)
1250+
:
1251+
);
1252+
return val;
1253+
}
1254+
1255+
static __always_inline u32 rdtime_l(void)
1256+
{
1257+
u32 val = 0;
1258+
1259+
__asm__ __volatile__(
1260+
"rdtimel.w %0, $zero\n\t"
1261+
: "=r"(val)
1262+
:
1263+
);
1264+
return val;
1265+
}
1266+
1267+
#else
1268+
1269+
static __always_inline u64 rdtime_d(void)
12421270
{
12431271
u64 val = 0;
12441272

@@ -1250,6 +1278,8 @@ static __always_inline u64 drdtime(void)
12501278
return val;
12511279
}
12521280

1281+
#endif
1282+
12531283
static inline unsigned int get_csr_cpuid(void)
12541284
{
12551285
return csr_read32(LOONGARCH_CSR_CPUID);

arch/loongarch/include/asm/timex.h

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,38 @@ typedef unsigned long cycles_t;
1818

1919
static inline cycles_t get_cycles(void)
2020
{
21-
return drdtime();
21+
#ifdef CONFIG_32BIT
22+
return rdtime_l();
23+
#else
24+
return rdtime_d();
25+
#endif
26+
}
27+
28+
#ifdef CONFIG_32BIT
29+
30+
#define get_cycles_hi get_cycles_hi
31+
32+
static inline cycles_t get_cycles_hi(void)
33+
{
34+
return rdtime_h();
35+
}
36+
37+
#endif
38+
39+
static inline u64 get_cycles64(void)
40+
{
41+
#ifdef CONFIG_32BIT
42+
u32 hi, lo;
43+
44+
do {
45+
hi = rdtime_h();
46+
lo = rdtime_l();
47+
} while (hi != rdtime_h());
48+
49+
return ((u64)hi << 32) | lo;
50+
#else
51+
return rdtime_d();
52+
#endif
2253
}
2354

2455
#endif /* __KERNEL__ */

arch/loongarch/kernel/proc.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,14 @@ static int show_cpuinfo(struct seq_file *m, void *v)
2020
unsigned int prid = cpu_data[n].processor_id;
2121
unsigned int version = cpu_data[n].processor_id & 0xff;
2222
unsigned int fp_version = cpu_data[n].fpu_vers;
23+
u64 freq = cpu_clock_freq, bogomips = lpj_fine * cpu_clock_freq;
2324

2425
#ifdef CONFIG_SMP
2526
if (!cpu_online(n))
2627
return 0;
2728
#endif
29+
do_div(freq, 10000);
30+
do_div(bogomips, const_clock_freq * (5000/HZ));
2831

2932
/*
3033
* For the first processor also print the system type
@@ -41,11 +44,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
4144
seq_printf(m, "PRID\t\t\t: %s (%08x)\n", id_to_core_name(prid), prid);
4245
seq_printf(m, "CPU Revision\t\t: 0x%02x\n", version);
4346
seq_printf(m, "FPU Revision\t\t: 0x%02x\n", fp_version);
44-
seq_printf(m, "CPU MHz\t\t\t: %llu.%02llu\n",
45-
cpu_clock_freq / 1000000, (cpu_clock_freq / 10000) % 100);
46-
seq_printf(m, "BogoMIPS\t\t: %llu.%02llu\n",
47-
(lpj_fine * cpu_clock_freq / const_clock_freq) / (500000/HZ),
48-
((lpj_fine * cpu_clock_freq / const_clock_freq) / (5000/HZ)) % 100);
47+
seq_printf(m, "CPU MHz\t\t\t: %u.%02u\n", (u32)freq / 100, (u32)freq % 100);
48+
seq_printf(m, "BogoMIPS\t\t: %u.%02u\n", (u32)bogomips / 100, (u32)bogomips % 100);
4949
seq_printf(m, "TLB Entries\t\t: %d\n", cpu_data[n].tlbsize);
5050
seq_printf(m, "Address Sizes\t\t: %d bits physical, %d bits virtual\n",
5151
cpu_pabits + 1, cpu_vabits + 1);

arch/loongarch/kernel/syscall.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ void noinstr __no_stack_protector do_syscall(struct pt_regs *regs)
7575
*
7676
* The resulting 6 bits of entropy is seen in SP[9:4].
7777
*/
78-
choose_random_kstack_offset(drdtime());
78+
choose_random_kstack_offset(get_cycles());
7979

8080
syscall_exit_to_user_mode(regs);
8181
}

arch/loongarch/kernel/time.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <asm/loongarch.h>
1919
#include <asm/paravirt.h>
2020
#include <asm/time.h>
21+
#include <asm/timex.h>
2122

2223
u64 cpu_clock_freq;
2324
EXPORT_SYMBOL(cpu_clock_freq);
@@ -62,12 +63,12 @@ static int constant_set_state_oneshot(struct clock_event_device *evt)
6263

6364
static int constant_set_state_periodic(struct clock_event_device *evt)
6465
{
65-
unsigned long period;
6666
unsigned long timer_config;
67+
u64 period = const_clock_freq;
6768

6869
raw_spin_lock(&state_lock);
6970

70-
period = const_clock_freq / HZ;
71+
do_div(period, HZ);
7172
timer_config = period & CSR_TCFG_VAL;
7273
timer_config |= (CSR_TCFG_PERIOD | CSR_TCFG_EN);
7374
csr_write(timer_config, LOONGARCH_CSR_TCFG);
@@ -120,7 +121,7 @@ static int arch_timer_dying(unsigned int cpu)
120121

121122
static unsigned long get_loops_per_jiffy(void)
122123
{
123-
unsigned long lpj = (unsigned long)const_clock_freq;
124+
u64 lpj = const_clock_freq;
124125

125126
do_div(lpj, HZ);
126127

@@ -131,7 +132,7 @@ static long init_offset;
131132

132133
void save_counter(void)
133134
{
134-
init_offset = drdtime();
135+
init_offset = get_cycles();
135136
}
136137

137138
void sync_counter(void)
@@ -197,12 +198,12 @@ int constant_clockevent_init(void)
197198

198199
static u64 read_const_counter(struct clocksource *clk)
199200
{
200-
return drdtime();
201+
return get_cycles64();
201202
}
202203

203204
static noinstr u64 sched_clock_read(void)
204205
{
205-
return drdtime();
206+
return get_cycles64();
206207
}
207208

208209
static struct clocksource clocksource_const = {
@@ -235,7 +236,7 @@ void __init time_init(void)
235236
else
236237
const_clock_freq = calc_const_freq();
237238

238-
init_offset = -(drdtime() - csr_read(LOONGARCH_CSR_CNTC));
239+
init_offset = -(get_cycles() - csr_read(LOONGARCH_CSR_CNTC));
239240

240241
constant_clockevent_init();
241242
constant_clocksource_init();

arch/loongarch/kvm/vcpu.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <asm/loongarch.h>
1010
#include <asm/setup.h>
1111
#include <asm/time.h>
12+
#include <asm/timex.h>
1213

1314
#define CREATE_TRACE_POINTS
1415
#include "trace.h"
@@ -811,7 +812,7 @@ static int kvm_get_one_reg(struct kvm_vcpu *vcpu,
811812
case KVM_REG_LOONGARCH_KVM:
812813
switch (reg->id) {
813814
case KVM_REG_LOONGARCH_COUNTER:
814-
*v = drdtime() + vcpu->kvm->arch.time_offset;
815+
*v = get_cycles() + vcpu->kvm->arch.time_offset;
815816
break;
816817
case KVM_REG_LOONGARCH_DEBUG_INST:
817818
*v = INSN_HVCL | KVM_HCALL_SWDBG;
@@ -906,7 +907,7 @@ static int kvm_set_one_reg(struct kvm_vcpu *vcpu,
906907
* only set for the first time for smp system
907908
*/
908909
if (vcpu->vcpu_id == 0)
909-
vcpu->kvm->arch.time_offset = (signed long)(v - drdtime());
910+
vcpu->kvm->arch.time_offset = (signed long)(v - get_cycles());
910911
break;
911912
case KVM_REG_LOONGARCH_VCPU_RESET:
912913
vcpu->arch.st.guest_addr = 0;

0 commit comments

Comments
 (0)