由于gem5源代码和一些出版物,我知道ARM PMU是部分实现的。
我有一个二进制文件,该文件使用perf_event在ARM处理器下基于Linux的OS上访问PMU。它可以在ARM ISA下在具有Linux内核的gem5全系统仿真中使用perf_event吗?
到目前为止,我还没有找到正确的方法。如果有人知道,我将不胜感激!

最佳答案

从2020年9月开始,gem5需要打补丁才能使用ARM PMU。
编辑:从2020年11月开始,gem5已被修补,它将包含在下一发行版中。感谢开发人员!
如何修补gem5
这不是一个干净的补丁(非常简单),它更旨在了解其工作原理。尽管如此,这是可用于gem5源存储库中的git apply的补丁:

diff --git i/src/arch/arm/ArmISA.py w/src/arch/arm/ArmISA.py
index 2641ec3fb..3d85c1b75 100644
--- i/src/arch/arm/ArmISA.py
+++ w/src/arch/arm/ArmISA.py
@@ -36,6 +36,7 @@
from m5.params import *
from m5.proxy import *

+from m5.SimObject import SimObject
from m5.objects.ArmPMU import ArmPMU
from m5.objects.ArmSystem import SveVectorLength
from m5.objects.BaseISA import BaseISA
@@ -49,6 +50,8 @@ class ArmISA(BaseISA):
cxx_class = 'ArmISA::ISA'
cxx_header = "arch/arm/isa.hh"

+    generateDeviceTree = SimObject.recurseDeviceTree
+
system = Param.System(Parent.any, "System this ISA object belongs to")

pmu = Param.ArmPMU(NULL, "Performance Monitoring Unit")
diff --git i/src/arch/arm/ArmPMU.py w/src/arch/arm/ArmPMU.py
index 047e908b3..58553fbf9 100644
--- i/src/arch/arm/ArmPMU.py
+++ w/src/arch/arm/ArmPMU.py
@@ -40,6 +40,7 @@ from m5.params import *
from m5.params import isNullPointer
from m5.proxy import *
from m5.objects.Gic import ArmInterruptPin
+from m5.util.fdthelper import *

class ProbeEvent(object):
def __init__(self, pmu, _eventId, obj, *listOfNames):
@@ -76,6 +77,17 @@ class ArmPMU(SimObject):

_events = None

+    def generateDeviceTree(self, state):
+        node = FdtNode("pmu")
+        node.appendCompatible("arm,armv8-pmuv3")
+        # gem5 uses GIC controller interrupt notation, where PPI interrupts
+        # start to 16. However, the Linux kernel start from 0, and used a tag
+        # (set to 1) to indicate the PPI interrupt type.
+        node.append(FdtPropertyWords("interrupts", [
+            1, int(self.interrupt.num) - 16, 0xf04
+        ]))
+        yield node
+
def addEvent(self, newObject):
if not (isinstance(newObject, ProbeEvent)
or isinstance(newObject, SoftwareIncrement)):
diff --git i/src/cpu/BaseCPU.py w/src/cpu/BaseCPU.py
index ab70d1d7f..66a49a038 100644
--- i/src/cpu/BaseCPU.py
+++ w/src/cpu/BaseCPU.py
@@ -302,6 +302,11 @@ class BaseCPU(ClockedObject):
node.appendPhandle(phandle_key)
cpus_node.append(node)

+        # Generate nodes from the BaseCPU children (and don't add them as
+        # subnode). Please note: this is mainly needed for the ISA class.
+        for child_node in self.recurseDeviceTree(state):
+            yield child_node
+
yield cpus_node

def __init__(self, **kwargs):
补丁解决了什么
Linux内核使用设备树Blob(DTB)(这是一个常规文件)来声明运行内核的硬件。这用于使内核在不同体系结构之间可移植,而无需为每个硬件更改重新编译。 DTB遵循设备树引用,并从设备树源(DTS)文件(常规文本文件)进行编译。您可以了解更多herehere
问题在于应该将PMU通过DTB声明给Linux内核。您可以了解更多herehere。在模拟系统中,由于系统是由用户指定的,因此gem5必须自行生成DTB才能传递给内核,因此后者可以识别模拟硬件。但是,问题在于gem5不会为我们的PMU生成DTB条目。
补丁做什么
该修补程序在ISA和CPU文件中添加了一个条目,以启用DTB生成递归来查找PMU。层次结构如下:CPU => ISA => PMU。然后,它将生成函数添加到PMU中,以生成唯一的DTB条目来声明PMU,并在内核中使用适当的符号来声明中断。
使用补丁运行模拟后,我们可以从DTB中看到DTS,如下所示:
cd m5out
# Decompile the DTB to get the DTS.
dtc -I dtb -O dts system.dtb > system.dts
# Find the PMU entry.
head system.dts
dtc是设备树编译器,与sudo apt-get install device-tree-compiler一起安装。我们最终在根节点(pmu)下找到这个/ DTB条目:
/dts-v1/;

/ {
    #address-cells = <0x02>;
    #size-cells = <0x02>;
    interrupt-parent = <0x05>;
    compatible = "arm,vexpress";
    model = "V2P-CA15";
    arm,hbi = <0x00>;
    arm,vexpress,site = <0x0f>;

    memory@80000000 {
        device_type = "memory";
        reg = <0x00 0x80000000 0x01 0x00>;
    };

    pmu {
        compatible = "arm,armv8-pmuv3";
        interrupts = <0x01 0x04 0xf04>;
    };

    cpus {
        #address-cells = <0x01>;
        #size-cells = <0x00>;

        cpu@0 {
            device_type = "cpu";
            compatible = "gem5,arm-cpu";

[...]
interrupts = <0x01 0x04 0xf04>;行中,0x01用来指示0x04编号是PPI中断的编号(gem5中用20编号声明的中断,在补丁代码中解释了16的区别)。 0xf04对应于一个标志(0x4),该标志指示它是“ Activity 的高电平敏感”中断;而一个比特掩码(0xf)则指示该中断应连接至与GIC相连的所有PE。您可以了解更多here
如果补丁程序有效并且您的ArmPMU正确声明,则在引导时应该会看到以下消息:
  [    0.239967] hw perfevents: enabled with armv8_pmuv3 PMU driver, 32 counters available

08-17 19:15