HI Everyone,
This is my first time here.
I need help about time measurements on a Cortex-A72 (Arm v8) 64-bit.
I have been trying to read the cycle counter (i have got root privileges on machine), but i can't.
my c code:
#define _GNU_SOURCE#include <stdbool.h>#include <stdio.h>#include <stdlib.h>#include <sched.h>#include <unistd.h>#include <inttypes.h>#include <getopt.h>#include <sched.h>#include <assert.h>#include <sys/stat.h>#include <fcntl.h>#define ARMV8_PMCR_E (1 << 0) /* Enable all counters */#define ARMV8_PMCR_P (1 << 1) /* Reset all counters */#define ARMV8_PMCR_C (1 << 2) /* Cycle counter reset */#define ARMV8_PMUSERENR_EN (1 << 0) /* EL0 access enable */#define ARMV8_PMUSERENR_CR (1 << 2) /* Cycle counter read enable */#define ARMV8_PMUSERENR_ER (1 << 3) /* Event counter read enable */#define ARMV8_PMCNTENSET_EL0_EN (1 << 31) /* Performance Monitors Count Enable Set register */void arm_v8_flush(void* address){ asm volatile ("DC CIVAC, %0" :: "r"(address)); asm volatile ("DSB ISH"); asm volatile ("ISB");}void arm_v8_access_memory(void* pointer){ volatile uint32_t value; asm volatile ("LDR %0, [%1]\n\t" : "=r" (value) : "r" (pointer) );}void arm_v8_memory_barrier(void){ asm volatile ("DSB SY"); asm volatile ("ISB");}void arm_v8_prefetch(void* pointer){ asm volatile ("PRFM PLDL3KEEP, [%x0]" :: "p" (pointer)); asm volatile ("PRFM PLDL2KEEP, [%x0]" :: "p" (pointer)); asm volatile ("PRFM PLDL1KEEP, [%x0]" :: "p" (pointer));}uint64_t arm_v8_get_timing(void) { uint64_t result = 0; asm volatile("MRS %0, PMCCNTR_EL0" : "=r" (result)); return result;}void arm_v8_timing_init(void) { uint32_t value = 0; /* Enable Performance Counter */ asm volatile("MRS %0, PMCR_EL0" : "=r" (value)); value |= ARMV8_PMCR_E; /* Enable */ value |= ARMV8_PMCR_C; /* Cycle counter reset */ value |= ARMV8_PMCR_P; /* Reset all counters */ asm volatile("MSR PMCR_EL0, %0" : : "r" (value)); /* Enable cycle counter register */ asm volatile("MRS %0, PMCNTENSET_EL0" : "=r" (value)); value |= ARMV8_PMCNTENSET_EL0_EN; asm volatile("MSR PMCNTENSET_EL0, %0" : : "r" (value));}void arm_v8_timing_terminate(void){ uint32_t value = 0; uint32_t mask = 0; /* Disable Performance Counter */ asm volatile("MRS %0, PMCR_EL0" : "=r" (value)); mask = 0; mask |= ARMV8_PMCR_E; /* Enable */ mask |= ARMV8_PMCR_C; /* Cycle counter reset */ mask |= ARMV8_PMCR_P; /* Reset all counters */ asm volatile("MSR PMCR_EL0, %0" : : "r" (value & ~mask)); /* Disable cycle counter register */ asm volatile("MRS %0, PMCNTENSET_EL0" : "=r" (value)); mask = 0; mask |= ARMV8_PMCNTENSET_EL0_EN; asm volatile("MSR PMCNTENSET_EL0, %0" : : "r" (value & ~mask));} void arm_v8_reset_timing(void) { uint32_t value = 0; asm volatile("MRS %0, PMCR_EL0" : "=r" (value)); value |= ARMV8_PMCR_C; /* Cycle counter reset */ asm volatile("MSR PMCR_EL0, %0" : : "r" (value));}
int main(){ int x =10; arm_v8_timing_init(); arm_v8_memory_barrier(); uint64_t time = arm_v8_get_timing(); arm_v8_memory_barrier(); arm_v8_access_memory(&x); arm_v8_memory_barrier(); uint64_t time2 = arm_v8_get_timing(); arm_v8_memory_barrier(); uint64_t delta = time2 - time; arm_v8_timing_terminate();
return 0;}
running this code with root privileges the compiler gives me the following error : Illegal Instruction.
trying to fix this problem I realized that MRS instruction gives me that problem.
Why ?
Thank You.
Moving thread to the "Cortex-A / A-Profile" category [1] for better visibility around this topic.
[1]: community.arm.com/.../cortex-a-forum
"root" is a Unix/Linux term which does not imply "supervisor" or EL1 mode. Linux offers access to the performance counters. Just use your favorite search engine.