# Copyright (c) 2012-2013, 2015-2017 ARM Limited
# Copyright (c) 2020 Barkhausen Institut
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
# not be construed as granting a license to any other intellectual
# property including but not limited to intellectual property relating
# to a hardware implementation of the functionality of the software
# licensed hereunder.  You may use the software subject to the license
# terms below provided that you ensure that this notice is replicated
# unmodified and in its entirety in all distributions of the software,
# modified or unmodified, in source code or in binary form.
#
# Copyright (c) 2005-2008 The Regents of The University of Michigan
# Copyright (c) 2011 Regents of the University of California
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import sys

from m5.SimObject import *
from m5.defines import buildEnv
from m5.params import *
from m5.proxy import *
from m5.util.fdthelper import *

from m5.objects.ClockedObject import ClockedObject
from m5.objects.XBar import L2XBar
from m5.objects.InstTracer import InstTracer
from m5.objects.CPUTracers import ExeTracer
from m5.objects.SubSystem import SubSystem
from m5.objects.ClockDomain import *
from m5.objects.Platform import Platform

default_tracer = ExeTracer()

if buildEnv['TARGET_ISA'] == 'sparc':
    from m5.objects.SparcMMU import SparcMMU as ArchMMU
    from m5.objects.SparcInterrupts import SparcInterrupts as ArchInterrupts
    from m5.objects.SparcISA import SparcISA as ArchISA
elif buildEnv['TARGET_ISA'] == 'x86':
    from m5.objects.X86MMU import X86MMU as ArchMMU
    from m5.objects.X86LocalApic import X86LocalApic as ArchInterrupts
    from m5.objects.X86ISA import X86ISA as ArchISA
elif buildEnv['TARGET_ISA'] == 'mips':
    from m5.objects.MipsMMU import MipsMMU as ArchMMU
    from m5.objects.MipsInterrupts import MipsInterrupts as ArchInterrupts
    from m5.objects.MipsISA import MipsISA as ArchISA
elif buildEnv['TARGET_ISA'] == 'arm':
    from m5.objects.ArmMMU import ArmMMU as ArchMMU
    from m5.objects.ArmInterrupts import ArmInterrupts as ArchInterrupts
    from m5.objects.ArmISA import ArmISA as ArchISA
elif buildEnv['TARGET_ISA'] == 'power':
    from m5.objects.PowerMMU import PowerMMU as ArchMMU
    from m5.objects.PowerInterrupts import PowerInterrupts as ArchInterrupts
    from m5.objects.PowerISA import PowerISA as ArchISA
elif buildEnv['TARGET_ISA'] == 'riscv':
    from m5.objects.RiscvMMU import RiscvMMU as ArchMMU
    from m5.objects.RiscvInterrupts import RiscvInterrupts as ArchInterrupts
    from m5.objects.RiscvISA import RiscvISA as ArchISA
else:
    print("Don't know what object types to use for ISA %s" %
            buildEnv['TARGET_ISA'])
    sys.exit(1)

class BaseCPU(ClockedObject):
    type = 'BaseCPU'
    abstract = True
    cxx_header = "cpu/base.hh"
    cxx_class = 'gem5::BaseCPU'

    cxx_exports = [
        PyBindMethod("switchOut"),
        PyBindMethod("takeOverFrom"),
        PyBindMethod("switchedOut"),
        PyBindMethod("flushTLBs"),
        PyBindMethod("totalInsts"),
        PyBindMethod("scheduleInstStop"),
        PyBindMethod("getCurrentInstCount"),
    ]

    @classmethod
    def memory_mode(cls):
        """Which memory mode does this CPU require?"""
        return 'invalid'

    @classmethod
    def require_caches(cls):
        """Does the CPU model require caches?

        Some CPU models might make assumptions that require them to
        have caches.
        """
        return False

    @classmethod
    def support_take_over(cls):
        """Does the CPU model support CPU takeOverFrom?"""
        return False

    def takeOverFrom(self, old_cpu):
        self._ccObject.takeOverFrom(old_cpu._ccObject)


    system = Param.System(Parent.any, "system object")
    cpu_id = Param.Int(-1, "CPU identifier")
    socket_id = Param.Unsigned(0, "Physical Socket identifier")
    numThreads = Param.Unsigned(1, "number of HW thread contexts")
    pwr_gating_latency = Param.Cycles(300,
        "Latency to enter power gating state when all contexts are suspended")

    power_gating_on_idle = Param.Bool(False, "Control whether the core goes "\
        "to the OFF power state after all thread are disabled for "\
        "pwr_gating_latency cycles")

    function_trace = Param.Bool(False, "Enable function trace")
    function_trace_start = Param.Tick(0, "Tick to start function trace")

    checker = Param.BaseCPU(NULL, "checker CPU")

    syscallRetryLatency = Param.Cycles(10000, "Cycles to wait until retry")

    do_checkpoint_insts = Param.Bool(True,
        "enable checkpoint pseudo instructions")
    do_statistics_insts = Param.Bool(True,
        "enable statistics pseudo instructions")

    workload = VectorParam.Process([], "processes to run")

    mmu = Param.BaseMMU(ArchMMU(), "CPU memory management unit")
    interrupts = VectorParam.BaseInterrupts([], "Interrupt Controller")
    isa = VectorParam.BaseISA([], "ISA instance")

    max_insts_all_threads = Param.Counter(0,
        "terminate when all threads have reached this inst count")
    max_insts_any_thread = Param.Counter(0,
        "terminate when any thread reaches this inst count")
    simpoint_start_insts = VectorParam.Counter([],
        "starting instruction counts of simpoints")
    progress_interval = Param.Frequency('0Hz',
        "frequency to print out the progress message")

    switched_out = Param.Bool(False,
        "Leave the CPU switched out after startup (used when switching " \
        "between CPU models)")

    tracer = Param.InstTracer(default_tracer, "Instruction tracer")

    icache_port = RequestPort("Instruction Port")
    dcache_port = RequestPort("Data Port")
    _cached_ports = ['icache_port', 'dcache_port']

    _uncached_interrupt_response_ports = []
    _uncached_interrupt_request_ports = []

    def createInterruptController(self):
        self.interrupts = [ArchInterrupts() for i in range(self.numThreads)]

    def connectCachedPorts(self, in_ports):
        for p in self._cached_ports:
            exec('self.%s = in_ports' % p)

    def connectUncachedPorts(self, in_ports, out_ports):
        for p in self._uncached_interrupt_response_ports:
            exec('self.%s = out_ports' % p)
        for p in self._uncached_interrupt_request_ports:
            exec('self.%s = in_ports' % p)

    def connectAllPorts(self, cached_in, uncached_in, uncached_out):
        self.connectCachedPorts(cached_in)
        self.connectUncachedPorts(uncached_in, uncached_out)

    def connectBus(self, bus):
        self.connectAllPorts(bus.cpu_side_ports,
            bus.cpu_side_ports, bus.mem_side_ports)

    def addPrivateSplitL1Caches(self, ic, dc, iwc = None, dwc = None):
        self.icache = ic
        self.dcache = dc
        self.icache_port = ic.cpu_side
        self.dcache_port = dc.cpu_side
        self._cached_ports = ['icache.mem_side', 'dcache.mem_side']
        if iwc and dwc:
            self.itb_walker_cache = iwc
            self.dtb_walker_cache = dwc
            self.mmu.connectWalkerPorts(
                iwc.cpu_side, dwc.cpu_side)
            self._cached_ports += ["itb_walker_cache.mem_side", \
                                   "dtb_walker_cache.mem_side"]
        else:
            self._cached_ports += ArchMMU.walkerPorts()

        # Checker doesn't need its own tlb caches because it does
        # functional accesses only
        if self.checker != NULL:
            self._cached_ports += [ "checker." + port
                for port in ArchMMU.walkerPorts() ]

    def addTwoLevelCacheHierarchy(self, ic, dc, l2c, iwc=None, dwc=None,
                                  xbar=None):
        self.addPrivateSplitL1Caches(ic, dc, iwc, dwc)
        self.toL2Bus = xbar if xbar else L2XBar()
        self.connectCachedPorts(self.toL2Bus.cpu_side_ports)
        self.l2cache = l2c
        self.toL2Bus.mem_side_ports = self.l2cache.cpu_side
        self._cached_ports = ['l2cache.mem_side']

    def createThreads(self):
        # If no ISAs have been created, assume that the user wants the
        # default ISA.
        if len(self.isa) == 0:
            self.isa = [ ArchISA() for i in range(self.numThreads) ]
        else:
            if len(self.isa) != int(self.numThreads):
                raise RuntimeError("Number of ISA instances doesn't "
                                   "match thread count")
        if self.checker != NULL:
            self.checker.createThreads()

    def addCheckerCpu(self):
        pass

    def createPhandleKey(self, thread):
        # This method creates a unique key for this cpu as a function of a
        # certain thread
        return 'CPU-%d-%d-%d' % (self.socket_id, self.cpu_id, thread)

    #Generate simple CPU Device Tree structure
    def generateDeviceTree(self, state):
        """Generate cpu nodes for each thread and the corresponding part of the
        cpu-map node. Note that this implementation does not support clusters
        of clusters. Note that GEM5 is not compatible with the official way of
        numbering cores as defined in the Device Tree documentation. Where the
        cpu_id needs to reset to 0 for each cluster by specification, GEM5
        expects the cpu_id to be globally unique and incremental. This
        generated node adheres the GEM5 way of doing things."""
        if bool(self.switched_out):
            return

        cpus_node = FdtNode('cpus')
        cpus_node.append(state.CPUCellsProperty())
        #Special size override of 0
        cpus_node.append(FdtPropertyWords('#size-cells', [0]))

        # Generate cpu nodes
        for i in range(int(self.numThreads)):
            reg = (int(self.socket_id)<<8) + int(self.cpu_id) + i
            node = FdtNode("cpu@%x" % reg)
            node.append(FdtPropertyStrings("device_type", "cpu"))
            node.appendCompatible(["gem5,arm-cpu"])
            node.append(FdtPropertyWords("reg", state.CPUAddrCells(reg)))
            platform, found = self.system.unproxy(self).find_any(Platform)
            if found:
                platform.annotateCpuDeviceNode(node, state)
            else:
                warn("Platform not found for device tree generation; " \
                     "system or multiple CPUs may not start")

            freq = int(self.clk_domain.unproxy(self).clock[0].frequency)
            node.append(FdtPropertyWords("clock-frequency", freq))

            # Unique key for this CPU
            phandle_key = self.createPhandleKey(i)
            node.appendPhandle(phandle_key)
            cpus_node.append(node)

        yield cpus_node

        # Generate nodes from the BaseCPU children (hence under the root node,
        # and don't add them as subnode). Please note: this is mainly needed
        # for the ISA class, to generate the PMU entry in the DTB.
        for child_node in self.recurseDeviceTree(state):
            yield child_node

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.power_state.possible_states=['ON', 'CLK_GATED', 'OFF']

        self._cached_ports = self._cached_ports + ArchMMU.walkerPorts()

        # Practically speaking, these ports will exist on the x86 interrupt
        # controller class.
        if "pio" in ArchInterrupts._ports:
            self._uncached_interrupt_response_ports = \
                self._uncached_interrupt_response_ports + ["interrupts[0].pio"]
        if "int_responder" in ArchInterrupts._ports:
            self._uncached_interrupt_response_ports = \
                    self._uncached_interrupt_response_ports + [
                    "interrupts[0].int_responder"]
        if "int_requestor" in ArchInterrupts._ports:
            self._uncached_interrupt_request_ports = \
                    self._uncached_interrupt_request_ports + [
                    "interrupts[0].int_requestor"]
