110461SAndreas.Sandberg@ARM.com# -*- mode:python -*-
212117Sjose.marinho@arm.com# Copyright (c) 2009-2014, 2017 ARM Limited
310461SAndreas.Sandberg@ARM.com# All rights reserved.
410461SAndreas.Sandberg@ARM.com#
510461SAndreas.Sandberg@ARM.com# The license below extends only to copyright in the software and shall
610461SAndreas.Sandberg@ARM.com# not be construed as granting a license to any other intellectual
710461SAndreas.Sandberg@ARM.com# property including but not limited to intellectual property relating
810461SAndreas.Sandberg@ARM.com# to a hardware implementation of the functionality of the software
910461SAndreas.Sandberg@ARM.com# licensed hereunder.  You may use the software subject to the license
1010461SAndreas.Sandberg@ARM.com# terms below provided that you ensure that this notice is replicated
1110461SAndreas.Sandberg@ARM.com# unmodified and in its entirety in all distributions of the software,
1210461SAndreas.Sandberg@ARM.com# modified or unmodified, in source code or in binary form.
1310461SAndreas.Sandberg@ARM.com#
1410461SAndreas.Sandberg@ARM.com# Redistribution and use in source and binary forms, with or without
1510461SAndreas.Sandberg@ARM.com# modification, are permitted provided that the following conditions are
1610461SAndreas.Sandberg@ARM.com# met: redistributions of source code must retain the above copyright
1710461SAndreas.Sandberg@ARM.com# notice, this list of conditions and the following disclaimer;
1810461SAndreas.Sandberg@ARM.com# redistributions in binary form must reproduce the above copyright
1910461SAndreas.Sandberg@ARM.com# notice, this list of conditions and the following disclaimer in the
2010461SAndreas.Sandberg@ARM.com# documentation and/or other materials provided with the distribution;
2110461SAndreas.Sandberg@ARM.com# neither the name of the copyright holders nor the names of its
2210461SAndreas.Sandberg@ARM.com# contributors may be used to endorse or promote products derived from
2310461SAndreas.Sandberg@ARM.com# this software without specific prior written permission.
2410461SAndreas.Sandberg@ARM.com#
2510461SAndreas.Sandberg@ARM.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2610461SAndreas.Sandberg@ARM.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2710461SAndreas.Sandberg@ARM.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2810461SAndreas.Sandberg@ARM.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2910461SAndreas.Sandberg@ARM.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3010461SAndreas.Sandberg@ARM.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3110461SAndreas.Sandberg@ARM.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3210461SAndreas.Sandberg@ARM.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3310461SAndreas.Sandberg@ARM.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3410461SAndreas.Sandberg@ARM.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3510461SAndreas.Sandberg@ARM.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3610461SAndreas.Sandberg@ARM.com#
3710461SAndreas.Sandberg@ARM.com# Authors: Matt Horsnell
3810461SAndreas.Sandberg@ARM.com#          Andreas Sandberg
3910461SAndreas.Sandberg@ARM.com
4010461SAndreas.Sandberg@ARM.comfrom m5.defines import buildEnv
4111988Sandreas.sandberg@arm.comfrom m5.SimObject import *
4210461SAndreas.Sandberg@ARM.comfrom m5.params import *
4310461SAndreas.Sandberg@ARM.comfrom m5.params import isNullPointer
4410461SAndreas.Sandberg@ARM.comfrom m5.proxy import *
4513665Sandreas.sandberg@arm.comfrom m5.objects.Gic import ArmInterruptPin
4610461SAndreas.Sandberg@ARM.com
4712286Sjose.marinho@arm.comclass ProbeEvent(object):
4812286Sjose.marinho@arm.com    def __init__(self, pmu, _eventId, obj, *listOfNames):
4912286Sjose.marinho@arm.com        self.obj = obj
5012286Sjose.marinho@arm.com        self.names = listOfNames
5112286Sjose.marinho@arm.com        self.eventId = _eventId
5212286Sjose.marinho@arm.com        self.pmu = pmu
5312286Sjose.marinho@arm.com
5412286Sjose.marinho@arm.com    def register(self):
5512286Sjose.marinho@arm.com        if self.obj:
5612286Sjose.marinho@arm.com            for name in self.names:
5712286Sjose.marinho@arm.com                self.pmu.getCCObject().addEventProbe(self.eventId,
5812286Sjose.marinho@arm.com                    self.obj.getCCObject(), name)
5912286Sjose.marinho@arm.com
6012286Sjose.marinho@arm.comclass SoftwareIncrement(object):
6112286Sjose.marinho@arm.com    def __init__(self,pmu, _eventId):
6212286Sjose.marinho@arm.com        self.eventId = _eventId
6312286Sjose.marinho@arm.com        self.pmu = pmu
6412286Sjose.marinho@arm.com
6512286Sjose.marinho@arm.com    def register(self):
6612286Sjose.marinho@arm.com        self.pmu.getCCObject().addSoftwareIncrementEvent(self.eventId)
6712286Sjose.marinho@arm.com
6812286Sjose.marinho@arm.comARCH_EVENT_CORE_CYCLES = 0x11
6912286Sjose.marinho@arm.com
7010461SAndreas.Sandberg@ARM.comclass ArmPMU(SimObject):
7110461SAndreas.Sandberg@ARM.com    type = 'ArmPMU'
7210461SAndreas.Sandberg@ARM.com    cxx_class = 'ArmISA::PMU'
7310461SAndreas.Sandberg@ARM.com    cxx_header = 'arch/arm/pmu.hh'
7410461SAndreas.Sandberg@ARM.com
7511988Sandreas.sandberg@arm.com    cxx_exports = [
7611988Sandreas.sandberg@arm.com        PyBindMethod("addEventProbe"),
7712286Sjose.marinho@arm.com        PyBindMethod("addSoftwareIncrementEvent"),
7811988Sandreas.sandberg@arm.com    ]
7910461SAndreas.Sandberg@ARM.com
8012286Sjose.marinho@arm.com    _events = None
8112286Sjose.marinho@arm.com
8212286Sjose.marinho@arm.com    def addEvent(self, newObject):
8312286Sjose.marinho@arm.com        if not (isinstance(newObject, ProbeEvent)
8412286Sjose.marinho@arm.com            or isinstance(newObject, SoftwareIncrement)):
8512286Sjose.marinho@arm.com            raise TypeError("argument must be of ProbeEvent or "
8612286Sjose.marinho@arm.com                "SoftwareIncrement type")
8712286Sjose.marinho@arm.com
8812286Sjose.marinho@arm.com        if not self._events:
8912286Sjose.marinho@arm.com            self._events = []
9012286Sjose.marinho@arm.com
9112286Sjose.marinho@arm.com        self._events.append(newObject)
9212286Sjose.marinho@arm.com
9310461SAndreas.Sandberg@ARM.com    # Override the normal SimObject::regProbeListeners method and
9410461SAndreas.Sandberg@ARM.com    # register deferred event handlers.
9510461SAndreas.Sandberg@ARM.com    def regProbeListeners(self):
9612286Sjose.marinho@arm.com        for event in self._events:
9712286Sjose.marinho@arm.com           event.register()
9810461SAndreas.Sandberg@ARM.com
9910461SAndreas.Sandberg@ARM.com        self.getCCObject().regProbeListeners()
10010461SAndreas.Sandberg@ARM.com
10110465SAndreas.Sandberg@ARM.com    def addArchEvents(self,
10210465SAndreas.Sandberg@ARM.com                      cpu=None,
10310465SAndreas.Sandberg@ARM.com                      itb=None, dtb=None,
10410465SAndreas.Sandberg@ARM.com                      icache=None, dcache=None,
10510465SAndreas.Sandberg@ARM.com                      l2cache=None):
10610465SAndreas.Sandberg@ARM.com        """Add architected events to the PMU.
10710465SAndreas.Sandberg@ARM.com
10810465SAndreas.Sandberg@ARM.com        This method can be called multiple times with only a subset of
10910465SAndreas.Sandberg@ARM.com        the keyword arguments set. This enables event registration in
11010465SAndreas.Sandberg@ARM.com        configuration scripts to happen closer to the instantiation of
11110465SAndreas.Sandberg@ARM.com        the instrumented objects (e.g., the memory system) instead of
11210465SAndreas.Sandberg@ARM.com        a central point.
11310465SAndreas.Sandberg@ARM.com
11410465SAndreas.Sandberg@ARM.com        CPU events should also be registered once per CPU that is
11510465SAndreas.Sandberg@ARM.com        sharing the PMU (e.g., when switching between CPU models).
11610465SAndreas.Sandberg@ARM.com        """
11710465SAndreas.Sandberg@ARM.com
11812851Sandreas.sandberg@arm.com        bpred = getattr(cpu, "branchPred", None) if cpu else None
11912851Sandreas.sandberg@arm.com        if bpred is not None and isNullPointer(bpred):
12012851Sandreas.sandberg@arm.com            bpred = None
12110465SAndreas.Sandberg@ARM.com
12212286Sjose.marinho@arm.com        self.addEvent(SoftwareIncrement(self,0x00))
12310465SAndreas.Sandberg@ARM.com        # 0x01: L1I_CACHE_REFILL
12412286Sjose.marinho@arm.com        self.addEvent(ProbeEvent(self,0x02, itb, "Refills"))
12512117Sjose.marinho@arm.com        # 0x03: L1D_CACHE_REFILL
12610465SAndreas.Sandberg@ARM.com        # 0x04: L1D_CACHE
12712286Sjose.marinho@arm.com        self.addEvent(ProbeEvent(self,0x05, dtb, "Refills"))
12812286Sjose.marinho@arm.com        self.addEvent(ProbeEvent(self,0x06, cpu, "RetiredLoads"))
12912286Sjose.marinho@arm.com        self.addEvent(ProbeEvent(self,0x07, cpu, "RetiredStores"))
13012286Sjose.marinho@arm.com        self.addEvent(ProbeEvent(self,0x08, cpu, "RetiredInsts"))
13110465SAndreas.Sandberg@ARM.com        # 0x09: EXC_TAKEN
13210465SAndreas.Sandberg@ARM.com        # 0x0A: EXC_RETURN
13310465SAndreas.Sandberg@ARM.com        # 0x0B: CID_WRITE_RETIRED
13412286Sjose.marinho@arm.com        self.addEvent(ProbeEvent(self,0x0C, cpu, "RetiredBranches"))
13510465SAndreas.Sandberg@ARM.com        # 0x0D: BR_IMMED_RETIRED
13610465SAndreas.Sandberg@ARM.com        # 0x0E: BR_RETURN_RETIRED
13710465SAndreas.Sandberg@ARM.com        # 0x0F: UNALIGEND_LDST_RETIRED
13812286Sjose.marinho@arm.com        self.addEvent(ProbeEvent(self,0x10, bpred, "Misses"))
13912286Sjose.marinho@arm.com        self.addEvent(ProbeEvent(self, ARCH_EVENT_CORE_CYCLES, cpu,
14012286Sjose.marinho@arm.com                                 "ActiveCycles"))
14112286Sjose.marinho@arm.com        self.addEvent(ProbeEvent(self,0x12, bpred, "Branches"))
14212286Sjose.marinho@arm.com        self.addEvent(ProbeEvent(self,0x13, cpu, "RetiredLoads",
14312286Sjose.marinho@arm.com                                 "RetiredStores"))
14410465SAndreas.Sandberg@ARM.com        # 0x14: L1I_CACHE
14510465SAndreas.Sandberg@ARM.com        # 0x15: L1D_CACHE_WB
14610465SAndreas.Sandberg@ARM.com        # 0x16: L2D_CACHE
14710465SAndreas.Sandberg@ARM.com        # 0x17: L2D_CACHE_REFILL
14810465SAndreas.Sandberg@ARM.com        # 0x18: L2D_CACHE_WB
14910465SAndreas.Sandberg@ARM.com        # 0x19: BUS_ACCESS
15010465SAndreas.Sandberg@ARM.com        # 0x1A: MEMORY_ERROR
15110465SAndreas.Sandberg@ARM.com        # 0x1B: INST_SPEC
15210465SAndreas.Sandberg@ARM.com        # 0x1C: TTBR_WRITE_RETIRED
15310465SAndreas.Sandberg@ARM.com        # 0x1D: BUS_CYCLES
15410465SAndreas.Sandberg@ARM.com        # 0x1E: CHAIN
15510465SAndreas.Sandberg@ARM.com        # 0x1F: L1D_CACHE_ALLOCATE
15610465SAndreas.Sandberg@ARM.com        # 0x20: L2D_CACHE_ALLOCATE
15712117Sjose.marinho@arm.com        # 0x21: BR_RETIRED
15812117Sjose.marinho@arm.com        # 0x22: BR_MIS_PRED_RETIRED
15912117Sjose.marinho@arm.com        # 0x23: STALL_FRONTEND
16012117Sjose.marinho@arm.com        # 0x24: STALL_BACKEND
16112117Sjose.marinho@arm.com        # 0x25: L1D_TLB
16212117Sjose.marinho@arm.com        # 0x26: L1I_TLB
16312117Sjose.marinho@arm.com        # 0x27: L2I_CACHE
16412117Sjose.marinho@arm.com        # 0x28: L2I_CACHE_REFILL
16512117Sjose.marinho@arm.com        # 0x29: L3D_CACHE_ALLOCATE
16612117Sjose.marinho@arm.com        # 0x2A: L3D_CACHE_REFILL
16712117Sjose.marinho@arm.com        # 0x2B: L3D_CACHE
16812117Sjose.marinho@arm.com        # 0x2C: L3D_CACHE_WB
16912117Sjose.marinho@arm.com        # 0x2D: L2D_TLB_REFILL
17012117Sjose.marinho@arm.com        # 0x2E: L2I_TLB_REFILL
17112117Sjose.marinho@arm.com        # 0x2F: L2D_TLB
17212117Sjose.marinho@arm.com        # 0x30: L2I_TLB
17310465SAndreas.Sandberg@ARM.com
17412286Sjose.marinho@arm.com    cycleEventId = Param.Int(ARCH_EVENT_CORE_CYCLES, "Cycle event id")
17510461SAndreas.Sandberg@ARM.com    platform = Param.Platform(Parent.any, "Platform this device is part of.")
17610461SAndreas.Sandberg@ARM.com    eventCounters = Param.Int(31, "Number of supported PMU counters")
17712973Sandreas.sandberg@arm.com    interrupt = Param.ArmInterruptPin("PMU interrupt")
178