Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * LoongArch PMU specific interface
4 */
5#ifndef SELFTEST_KVM_PMU_H
6#define SELFTEST_KVM_PMU_H
7
8#include "processor.h"
9
10#define LOONGARCH_CPUCFG6 0x6
11#define CPUCFG6_PMP BIT(0)
12#define CPUCFG6_PAMVER GENMASK(3, 1)
13#define CPUCFG6_PMNUM GENMASK(7, 4)
14#define CPUCFG6_PMNUM_SHIFT 4
15#define CPUCFG6_PMBITS GENMASK(13, 8)
16#define CPUCFG6_PMBITS_SHIFT 8
17#define CPUCFG6_UPM BIT(14)
18
19/* Performance Counter registers */
20#define LOONGARCH_CSR_PERFCTRL0 0x200 /* perf event 0 config */
21#define LOONGARCH_CSR_PERFCNTR0 0x201 /* perf event 0 count value */
22#define LOONGARCH_CSR_PERFCTRL1 0x202 /* perf event 1 config */
23#define LOONGARCH_CSR_PERFCNTR1 0x203 /* perf event 1 count value */
24#define LOONGARCH_CSR_PERFCTRL2 0x204 /* perf event 2 config */
25#define LOONGARCH_CSR_PERFCNTR2 0x205 /* perf event 2 count value */
26#define LOONGARCH_CSR_PERFCTRL3 0x206 /* perf event 3 config */
27#define LOONGARCH_CSR_PERFCNTR3 0x207 /* perf event 3 count value */
28#define CSR_PERFCTRL_PLV0 BIT(16)
29#define CSR_PERFCTRL_PLV1 BIT(17)
30#define CSR_PERFCTRL_PLV2 BIT(18)
31#define CSR_PERFCTRL_PLV3 BIT(19)
32#define CSR_PERFCTRL_PMIE BIT(20)
33#define PMU_ENVENT_ENABLED (CSR_PERFCTRL_PLV0 | CSR_PERFCTRL_PLV1 | CSR_PERFCTRL_PLV2 | CSR_PERFCTRL_PLV3)
34
35/* Hardware event codes (from LoongArch perf_event.c */
36#define LOONGARCH_PMU_EVENT_CYCLES 0x00 /* CPU cycles */
37#define LOONGARCH_PMU_EVENT_INSTR_RETIRED 0x01 /* Instructions retired */
38#define PERF_COUNT_HW_BRANCH_INSTRUCTIONS 0x02 /* Branch instructions */
39#define PERF_COUNT_HW_BRANCH_MISSES 0x03 /* Branch misses */
40
41#define NUM_LOOPS 1000
42#define EXPECTED_INSTR_MIN (NUM_LOOPS + 10) /* Loop + overhead */
43#define EXPECTED_CYCLES_MIN NUM_LOOPS /* At least 1 cycle per iteration */
44#define UPPER_BOUND (10 * NUM_LOOPS)
45
46#define PMU_OVERFLOW (1ULL << 63)
47
48static inline void pmu_irq_enable(void)
49{
50 unsigned long val;
51
52 val = csr_read(LOONGARCH_CSR_ECFG);
53 val |= ECFGF_PMU;
54 csr_write(val, LOONGARCH_CSR_ECFG);
55}
56
57static inline void pmu_irq_disable(void)
58{
59 unsigned long val;
60
61 val = csr_read(LOONGARCH_CSR_ECFG);
62 val &= ~ECFGF_PMU;
63 csr_write(val, LOONGARCH_CSR_ECFG);
64}
65
66#endif