网站服务器不稳定,做网站推广怎么跟客户沟通,网站推广怎么做与发布,如何自己建设网站ARM 的时钟周期计数保存在PMCCNTR 寄存器#xff0c;不像x86用户态可以直接读取#xff0c;需内核态使能#xff0c;一种是在内核中使能#xff0c;比如init#xff0c;比较简单的是在模块中使能。
本来写了两个#xff0c;arm32一个#xff0c;arm64一个#xff0c;方…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.hMODULE_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
#endifstatic void en_access(void*)
{ulint i0,tmpvar0;#ifdef __aarch64__asm volatile(mrs %0, mpidr_el1 :r(i));i (i 8) 0xff;
#elseasm volatile(mrc p15,0,%0,c0,c0,5 :r(i));i i 3;
#endif asm volatile (
#ifdef __aarch64__mrs %0,pmuserenr_el0 \norr %0, %0,%1 \nmsr pmuserenr_el0,%0
#elsemrc p15, 0, %0, c9, c14, 0 \norr %0, %0,%1 \nmcr p15, 0, %0, c9, c14, 0 \n
#endif:r(tmpvar):r(0xf));asm volatile(
#ifdef __aarch64__mrs %0, pmcr_el0 \norr %0, %0, %1 \n //32 0x41bic %0, %0, %2 \nmsr pmcr_el0,%0 \n
#elsemrc p15, 0, %0, c9, c12, 0 \norr %0, %0,%1 \nbic %0, %0, %2 \nmcr p15, 0, %0, c9, c12, 0 \n
#endif:r(tmpvar):r(0x81),r(0x28));asm volatile(
#ifdef __aarch64__msr pmcntenset_el0,%1 \nmrs %0, cntvct_el0 \n
#elsemcr p15, 0, %1, c9, c12, 1 \nmrc 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,tmpvar0;
#ifdef __aarch64__asm volatile( mrs %0, mpidr_el1: r(i));i (i 8)0xff;
#elseasm volatile(mrc p15,0,%0,c0,c0,5 \n : r(i));i i 3;
#endifasm volatile (
#ifdef __aarch64__mrs %0,pmcr_el0 \nbic %0,%0, %2 \nmsr pmcr_el0,%0\nmsr pmuserenr_el0,%1\nmrs %0, cntvct_el0 \n
#elsemrc p15, 0, %0, c9, c14, 0 \nbic %0,%0, %2 \nmcr p15, 0, %0, c9, c14, 0 \nmcr p15, 0, %1, c9, c12, 1 \nmrc 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直接
makeinsmod 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));
#endifprintf(%lx\n,(unsigned long)ct);
}gcc test.c
./a.out
taskset -c 1 ./a.outtaskset -c 选择在哪个核上运行。
附录
CNTVCT_EL0pmcntenset_el0 Performance Monitors Count Enable Set registerpurpose Enables the Cycle Count Register·
C [31]·
0x1 » PMCCNTR_EL0 enable·
Pm» PMEVCNTRn_EL0 enable
0xFFFFFFFFpmuserenr_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
0xFPMCR_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 affectedD [3] clock divider··0 pmccntr_el0 counts every clock cycle
E [0] enable1 Affected counters are enabled by pmcntenset_el0mrc/mcr Op1 CRm Op2 Name Type Reset Description
0 c12 0 PMCR RW 0x41093000 Performance Monitor Control Register1 PMCNTENSET RW 0x00000000 Count Enable Set Register2 PMCNTENCLR RW 0x00000000 Count Enable Clear Register3 PMOVSR RW - Overflow Flag Status Register4 PMSWINC WO - Software Increment Register5 PMSELR RW 0x00000000 Event Counter Selection Registerc13 0 PMCCNTR RW - Cycle Count Register1 PMXEVTYPER RW - Event Type Selection Register2 PMXEVCNTR RW - Event Count Registersc14 0 PMUSERENR RWa 0x00000000 User Enable Register1 PMINTENSET RW 0x00000000 Interrupt Enable Set Register2 PMINTENCLR RW 0x00000000 Interrupt Enable Clear Register