当前位置: 首页 > news >正文

arm32 arm64 读取PMCCNTR cpu cycle counter

ARM 的时钟周期计数保存在PMCCNTR 寄存器,不像x86用户态可以直接读取,需内核态使能,一种是在内核中使能,比如init,比较简单的是在模块中使能。

本来写了两个,arm32一个,arm64一个,方便对比合在了一起。
只测试了32位cortex-a9双核, 还有 个64位a76 a55。
enpmu.c

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/smp.h>

MODULE_AUTHOR("cn");
MODULE_LICENSE("GPL");
MODULE_VERSION("0.0");

#if !defined(__arm__) && !defined(__aarch64__)
#error module only support arm32 arm64.
#endif


#ifdef __aarch64__
typedef unsigned long ulint;  //64
#elif defined __arm__
typedef unsigned int ulint;  //32
#endif

static void en_access(void*)
{
    ulint i=0,tmpvar=0;

#ifdef __aarch64__
    asm volatile("mrs %0, mpidr_el1 ":"=r"(i));
    i =  (i >>8) &0xff;
#else
    asm volatile("mrc p15,0,%0,c0,c0,5 ":"=r"(i));
    i =  i & 3;
#endif  
    asm volatile (  
#ifdef __aarch64__
            "mrs %0,pmuserenr_el0 \n"
            "orr %0, %0,%1 \n"
            "msr pmuserenr_el0,%0"
#else
            "mrc p15, 0, %0, c9, c14, 0 \n"
            "orr %0, %0,%1 \n"
            "mcr p15, 0, %0, c9, c14, 0 \n"
#endif
            :"+r"(tmpvar):"r"(0xf));
    asm volatile(   
#ifdef __aarch64__
            "mrs %0, pmcr_el0 \n"
            "orr %0, %0, %1 \n" //32  0x41
            "bic %0, %0, %2 \n"
            "msr pmcr_el0,%0 \n"
#else
            "mrc p15, 0, %0, c9, c12, 0 \n"
            "orr %0, %0,%1 \n"
            "bic %0, %0, %2 \n"
            "mcr p15, 0, %0, c9, c12, 0 \n"
#endif
            :"+r"(tmpvar):"r"(0x81),"r"(0x28));
    asm volatile(   
#ifdef __aarch64__
            "msr pmcntenset_el0,%1 \n"
            "mrs %0, cntvct_el0 \n"
#else
            "mcr p15, 0, %1, c9, c12, 1 \n"
            "mrc p15, 0, %0, c9, c13, 0 \n"
#endif
            :"=r"(tmpvar) :"r"(0xffffffff));
    printk("core %lu tsc = %lx",(unsigned long)i, (unsigned long)tmpvar );
}

static void restore_access(void*) {
    ulint i,tmpvar=0;
#ifdef __aarch64__
    asm volatile( "mrs %0, mpidr_el1": "=r"(i));
    i =  (i >> 8)&0xff;
#else
    asm volatile("mrc p15,0,%0,c0,c0,5 \n" : "=r"(i));
    i =  i & 3;
#endif

    asm volatile (
#ifdef __aarch64__
            "mrs %0,pmcr_el0 \n"
            "bic %0,%0, %2 \n"
            "msr pmcr_el0,%0\n"
            "msr pmuserenr_el0,%1\n"
            "mrs %0, cntvct_el0 \n"
#else
            "mrc p15, 0, %0, c9, c14, 0 \n"
            "bic %0,%0, %2 \n"
            "mcr p15, 0, %0, c9, c14, 0 \n"
            "mcr p15, 0, %1, c9, c12, 1 \n"
            "mrc p15, 0, %0, c9, c13, 0 \n"
#endif
            :"+r" (tmpvar):"r"(0),"r"(1));
    printk("un core %lx tsc = %lx",(unsigned long)i, (unsigned long)tmpvar );

}
static int __init  start(void) 
{ 
    on_each_cpu(en_access, NULL, 1);
    printk(KERN_INFO "pmu access enabled\n"); 
    return 0; 
} 

static void __exit stop(void) 
{ 
    on_each_cpu(restore_access, NULL, 1);
    printk(KERN_INFO "pmu access disabled\n"); 
} 

module_init(start); 
module_exit(stop); 

Makefile

obj-m = enpmu.o
all:
	make -C /lib/modules/$(shell uname -r)/build/ M=$(PWD) modules
clean:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

直接

make
insmod enpmu.ko
rmmod enpmu

然后就可以读取了 以下arm32 arm64 x86_64读取方法
test.c

#include <stdio.h>
#ifndef __arm__
typedef unsigned long ulint;
#else
typedef unsigned int ulint;
#endif
int main()
{
				ulint ct = 0;
#ifdef __aarch64__
                asm volatile("mrs %0, cntvct_el0" :"=r"(ct));
#elif defined __arm__
				asm volatile("mrc p15,0,%0, c9, c13, 0":"=r"(ct));
#elif defined __x86_64__
                asm volatile("rdtsc ; shl $32, %%rdx ; or %%rdx, %0": "=a"(ct));
#endif
				printf("%lx\n",(unsigned long)ct);
}
gcc test.c
./a.out
taskset -c 1 ./a.out

taskset -c 选择在哪个核上运行。

附录

CNTVCT_EL0

pmcntenset_el0  Performance Monitors Count Enable Set register
 purpose Enables the Cycle Count Register·
C [31]·
0x1 »   PMCCNTR_EL0 enable·
P<m>»   PMEVCNTR<n>_EL0 enable
0xFFFFFFFF

pmuserenr_el0
Performance Monitors User Enable Register
Enable or disables EL0 access to the performance Monitors;
ER [3]                                                                                    
»   Event counters Read enable,
»   1 en rw
CR [2] 
»   Cycle counter Read enable·
»   32 MRC read PMCCNTR  MRRC read PMCCNTR
SW[1]  software increment register Write enable
»   1
En [0] Enable
»   Enables EL0 read/write access to PMU registers
0xF

PMCR_EL0
bit[9] Freeze-on-overflow                                                                 
0
LC [6]  1   aarch32  supported long cycle
»   0x1
DP [5] Disable cycle counter when event counting is prohibited·
	0x0 not affected

D [3] clock divider··
	0 pmccntr_el0 counts every clock cycle
E  [0] enable
	1 Affected counters are enabled by pmcntenset_el0
	
mrc/mcr  Op1 CRm Op2 Name Type Reset Description
0 	c12 0 PMCR RW 0x41093000 Performance Monitor Control Register
		1 PMCNTENSET RW 0x00000000 Count Enable Set Register
		2 PMCNTENCLR RW 0x00000000 Count Enable Clear Register
		3 PMOVSR RW - Overflow Flag Status Register
		4 PMSWINC WO - Software Increment Register
		5 PMSELR RW 0x00000000 Event Counter Selection Register
	c13 0 PMCCNTR RW - Cycle Count Register
		1 PMXEVTYPER RW - Event Type Selection Register
		2 PMXEVCNTR RW - Event Count Registers
	c14 0 PMUSERENR RWa 0x00000000 User Enable Register
		1 PMINTENSET RW 0x00000000 Interrupt Enable Set Register
		2 PMINTENCLR RW 0x00000000 Interrupt Enable Clear Register



相关文章:

  • 【Filament】立方体贴图(6张图)
  • Selenium在vue框架下求生存
  • JavaScript:正则表达式
  • centos 防火墙 设置 LTS
  • k8s持久化存储(NFS-StorageClass)
  • 关于IDEA中Git版本回滚整理
  • FairyGUI-Cocos Creator官方Demo源码解读
  • Vue使用Element table表格格式化GMT时间为Shanghai时间
  • 微机原理12练习题答案
  • 最新AI绘画Midjourney绘画提示词Prompt教程
  • 3D游戏角色建模纹理贴图处理
  • Linux性能优化全景指南
  • web前端开发html/css求职简介/个人简介小白网页设计
  • 智能优化算法应用:基于指数分布算法3D无线传感器网络(WSN)覆盖优化 - 附代码
  • C语言编写Windows程序:组合启用/禁用Telnet客户端,并Telnet指定ip和端口
  • 【Minikube Prometheus】基于Prometheus Grafana监控由Minikube创建的K8S集群
  • lag-llama源码解读(Lag-Llama: Towards Foundation Models for Time Series Forecasting)
  • NSNotificationCenter通知
  • flutter 之proto
  • 深入ArkUI:深入实战组件text和text input
  • 1至4月国家铁路发送货物12.99亿吨,同比增长3.6%
  • 假冒政府机构账号卖假货?“假官号”为何屡禁不绝?媒体调查
  • 因救心梗同学缺席职教高考的姜昭鹏顺利完成补考
  • 南京艺术学院博导、雕塑家尹悟铭病逝,年仅45岁
  • 价格周报|本周猪价继续下探,机构预计今年猪价中枢有支撑
  • 一箭六星,朱雀二号改进型遥二运载火箭发射成功