Commit ced7814d authored by Huacai Chen's avatar Huacai Chen
Browse files

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: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarJiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: default avatarHuacai Chen <chenhuacai@loongson.cn>
parent 4ad04e7c
Loading
Loading
Loading
Loading
+31 −1
Original line number Diff line number Diff line
@@ -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);
+32 −1
Original line number Diff line number Diff line
@@ -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__ */
+5 −5
Original line number Diff line number Diff line
@@ -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);
+1 −1
Original line number Diff line number Diff line
@@ -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);
}
+8 −7
Original line number Diff line number Diff line
@@ -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();
Loading