summaryrefslogtreecommitdiffstats
path: root/tools/testing/selftests/kvm/include/loongarch/pmu.h
blob: 478e6a9bbb2b4301809ad7bf2e5a0e4c98d8ee17 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * LoongArch PMU specific interface
 */
#ifndef SELFTEST_KVM_PMU_H
#define SELFTEST_KVM_PMU_H

#include "processor.h"

#define LOONGARCH_CPUCFG6			0x6
#define  CPUCFG6_PMP				BIT(0)
#define  CPUCFG6_PAMVER				GENMASK(3, 1)
#define  CPUCFG6_PMNUM				GENMASK(7, 4)
#define  CPUCFG6_PMNUM_SHIFT			4
#define  CPUCFG6_PMBITS				GENMASK(13, 8)
#define  CPUCFG6_PMBITS_SHIFT			8
#define  CPUCFG6_UPM				BIT(14)

/* Performance Counter registers */
#define LOONGARCH_CSR_PERFCTRL0			0x200   /* perf event 0 config */
#define LOONGARCH_CSR_PERFCNTR0			0x201   /* perf event 0 count value */
#define LOONGARCH_CSR_PERFCTRL1			0x202   /* perf event 1 config */
#define LOONGARCH_CSR_PERFCNTR1			0x203   /* perf event 1 count value */
#define LOONGARCH_CSR_PERFCTRL2			0x204   /* perf event 2 config */
#define LOONGARCH_CSR_PERFCNTR2			0x205   /* perf event 2 count value */
#define LOONGARCH_CSR_PERFCTRL3			0x206   /* perf event 3 config */
#define LOONGARCH_CSR_PERFCNTR3			0x207   /* perf event 3 count value */
#define  CSR_PERFCTRL_PLV0			BIT(16)
#define  CSR_PERFCTRL_PLV1			BIT(17)
#define  CSR_PERFCTRL_PLV2			BIT(18)
#define  CSR_PERFCTRL_PLV3			BIT(19)
#define  CSR_PERFCTRL_PMIE			BIT(20)
#define PMU_ENVENT_ENABLED	(CSR_PERFCTRL_PLV0 | CSR_PERFCTRL_PLV1 | CSR_PERFCTRL_PLV2 | CSR_PERFCTRL_PLV3)

/* Hardware event codes (from LoongArch perf_event.c */
#define LOONGARCH_PMU_EVENT_CYCLES		0x00  /* CPU cycles */
#define LOONGARCH_PMU_EVENT_INSTR_RETIRED	0x01  /* Instructions retired */
#define PERF_COUNT_HW_BRANCH_INSTRUCTIONS	0x02  /* Branch instructions */
#define PERF_COUNT_HW_BRANCH_MISSES		0x03  /* Branch misses */

#define NUM_LOOPS                               1000
#define EXPECTED_INSTR_MIN                      (NUM_LOOPS + 10)  /* Loop + overhead */
#define EXPECTED_CYCLES_MIN                     NUM_LOOPS       /* At least 1 cycle per iteration */
#define UPPER_BOUND				(10 * NUM_LOOPS)

#define PMU_OVERFLOW				(1ULL << 63)

static inline void pmu_irq_enable(void)
{
	unsigned long val;

	val = csr_read(LOONGARCH_CSR_ECFG);
	val |= ECFGF_PMU;
	csr_write(val, LOONGARCH_CSR_ECFG);
}

static inline void pmu_irq_disable(void)
{
	unsigned long val;

	val = csr_read(LOONGARCH_CSR_ECFG);
	val &= ~ECFGF_PMU;
	csr_write(val, LOONGARCH_CSR_ECFG);
}

#endif