yb_arm/driver/tsc/tsc.c
2023-07-12 14:14:31 +08:00

68 lines
3.8 KiB
C

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/smp.h>
#define ARMV8_PMCR_MASK 0x3f
#define ARMV8_PMCR_E (1 << 0)
#define ARMV8_PMCR_LC (1 << 6)
static inline u32 armv8pmu_pmcr_read(void)
{
u64 val = 0;
asm volatile("mrs %0, pmcr_el0" : "=r" (val));
return (u32)val;
}
static inline void armv8pmu_pmcr_write(u32 val)
{
val &= ARMV8_PMCR_MASK;
isb();
asm volatile("msr pmcr_el0, %0" : : "r" ((u64)val));
}
static inline long long armv8_read_CNTPCT_EL0(void)
{
long long val;
asm volatile("mrs %0, CNTVCT_EL0" : "=r" (val));
return val;
}
static void
enable_cpu_counters(void* data)
{
asm volatile("msr pmuserenr_el0, %0" : : "r"(0xf));
armv8pmu_pmcr_write(ARMV8_PMCR_LC|ARMV8_PMCR_E);
asm volatile("msr PMCNTENSET_EL0, %0" :: "r" ((u32)(1<<31)));
armv8pmu_pmcr_write(armv8pmu_pmcr_read() | ARMV8_PMCR_E|ARMV8_PMCR_LC);
printk("\nCPU:%d ", smp_processor_id());
}
static void
disable_cpu_counters(void* data)
{
printk(KERN_INFO "\ndisabling user-mode PMU access on CPU #%d",
smp_processor_id());
armv8pmu_pmcr_write(armv8pmu_pmcr_read() |~ARMV8_PMCR_E);
asm volatile("msr pmuserenr_el0, %0" : : "r"((u64)0));
}
static int __init init(void)
{
on_each_cpu(enable_cpu_counters, NULL, 1);
printk(KERN_INFO "Enable Access PMU Initialized");
return 0;
}
static void __exit fini(void)
{
on_each_cpu(disable_cpu_counters, NULL, 1);
printk(KERN_INFO "Access PMU Disabled");
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("titan");