ARM Cortex-A7支持多少个事件计数器,如何选择/读取/写入这些计数器?
例如,如果运行:
./perf stat -e L1-dcache-loads,branch-loads sleep 1
它存储事件计数?
Here你可以看到,{c9,c13,0}代表循环计数寄存器而{c9,c13,2}代表事件计数寄存器,所以执行perf命令后哪个寄存器值会改变c9或c13?
如果您看到以下代码:
static inline int armv7_pmnc_select_counter(int idx)
{
u32 counter = ARMV7_IDX_TO_COUNTER(idx);
asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (counter));
return idx;
}
static inline void armv7pmu_write_counter(struct perf_event *event, u32 value)
{
struct arm_pmu *cpu_pmu = to_arm_pmu(event->pmu);
struct hw_perf_event *hwc = &event->hw;
int idx = hwc->idx;
if (!armv7_pmnc_counter_valid(cpu_pmu, idx))
pr_err("CPU%u writing wrong counter %d\n",smp_processor_id(), idx);
else if (idx == ARMV7_IDX_CYCLE_COUNTER)
asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value));
else if (armv7_pmnc_select_counter(idx) == idx)
asm volatile("mcr p15, 0, %0, c9, c13, 2" : : "r" (value));
}
对于每个事件计数器,armv7pmu_write_counter
函数使用idx
设置不同的armv7_pmnc_select_counter
值,但要更新value
,它会调用相同的mcr
指令怎么样?
答案 0 :(得分:1)
因为第二个是数据寄存器,它允许读取和写入 a 计数器值,而第一个是索引寄存器,它选择数据寄存器正在操作的实际计数器。 / p>
具有这种设置的典型原因是不同的实现可以提供不同数量的寄存器而不改变整个寄存器映射。对于ARMv7 PMU,它没有充分利用相对有限的系统寄存器编码空间来拥有32个计数寄存器和32个事件类型寄存器,其中大多数将是未实现的,你当然不会想要寄存器移动,具体取决于此特定CPU实现的计数器数量。
如果有帮助,想象一下这样的事情:
class PMU {
private:
int sel;
int counter[NUMBER];
public:
int num_counters(void) { return NUMBER; };
void select_counter(int i) { sel = i % NUMBER; };
void write_counter(int d) { counter[sel] = d; };
int read_counter(void) { return counter[sel]; };
}