# Copyright (c) 2012-2013, 2017-2020 ARM Limited
# 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.
#
# 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.

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

from m5.objects.Device import PioDevice, BasicPioDevice
from m5.objects.Platform import Platform
from m5.objects.IntPin import IntSourcePin

class BaseGic(PioDevice):
    type = 'BaseGic'
    abstract = True
    cxx_header = "dev/arm/base_gic.hh"

    # Used for DTB autogeneration
    _state = FdtState(addr_cells=0, interrupt_cells=3)

    platform = Param.Platform(Parent.any, "Platform this device is part of.")

    gicd_iidr = Param.UInt32(0,
        "Distributor Implementer Identification Register")
    gicd_pidr = Param.UInt32(0,
        "Peripheral Identification Register")
    gicc_iidr = Param.UInt32(0,
        "CPU Interface Identification Register")
    gicv_iidr = Param.UInt32(0,
        "VM CPU Interface Identification Register")

    def interruptCells(self, int_type, int_num, int_trigger, partition=None):
        """
        Interupt cells generation helper:
        Following specifications described in

        Documentation/devicetree/bindings/interrupt-controller/arm,gic.txt
        """
        assert self._state.interrupt_cells == 3

        # Check for affinity in case of PPI. If there is no PPI
        # partitioning, set the affinity to target all CPUs
        # (affinity = 0xf00)
        if partition is None and int_type == ArmPPI._LINUX_ID:
            affinity = 0xf00
        else:
            affinity = 0

        return [ int_type, int_num, affinity | int_trigger ]

class ArmInterruptType(ScopedEnum):
    """
    The values of the scoped enum are matching Linux macroes
    defined in include/linux/irq.h. They are mainly meant
    to be used for DTB autogen
    """
    map = {
        'IRQ_TYPE_EDGE_RISING' : 0x1,
        'IRQ_TYPE_EDGE_FALLING' : 0x2,
        'IRQ_TYPE_LEVEL_HIGH' : 0x4,
        'IRQ_TYPE_LEVEL_LOW' : 0x8
    }

class ArmInterruptPin(SimObject):
    type = 'ArmInterruptPin'
    cxx_header = "dev/arm/base_gic.hh"
    cxx_class = "ArmInterruptPinGen"
    abstract = True

    platform = Param.Platform(Parent.any, "Platform with interrupt controller")
    num = Param.UInt32("Interrupt number in GIC")
    int_type = Param.ArmInterruptType('IRQ_TYPE_LEVEL_HIGH',
        "Interrupt type (level/edge triggered)")

class ArmSPI(ArmInterruptPin):
    type = 'ArmSPI'
    cxx_header = "dev/arm/base_gic.hh"
    cxx_class = "ArmSPIGen"

    _LINUX_ID = 0

    def generateFdtProperty(self, gic):
        """
        Return a list used as an entry for an interrupt FdtProperty

        Subtracting 32 because Linux assumes that SPIs start at 0, while
        gem5 uses the internal GIC numbering (SPIs start at 32)
        """
        return gic.interruptCells(
            self._LINUX_ID, self.num - 32, int(self.int_type.getValue()))

class ArmPPI(ArmInterruptPin):
    type = 'ArmPPI'
    cxx_header = "dev/arm/base_gic.hh"
    cxx_class = "ArmPPIGen"

    _LINUX_ID = 1

    def generateFdtProperty(self, gic):
        """
        Return a list used as an entry for an interrupt FdtProperty

        Subtracting 16 because Linux assumes that PPIs start at 0, while
        gem5 uses the internal GIC numbering (PPIs start at 16)
        """
        return gic.interruptCells(
            self._LINUX_ID, self.num - 16, int(self.int_type.getValue()))

class ArmSigInterruptPin(ArmInterruptPin):
    type = 'ArmSigInterruptPin'
    cxx_header = "dev/arm/base_gic.hh"
    cxx_class = "ArmSigInterruptPinGen"

    irq = IntSourcePin('Interrupt pin')

class GicV2(BaseGic):
    type = 'GicV2'
    cxx_header = "dev/arm/gic_v2.hh"

    dist_addr = Param.Addr("Address for distributor")
    cpu_addr = Param.Addr("Address for cpu")
    cpu_size = Param.Addr(0x2000, "Size of cpu register bank")
    dist_pio_delay = Param.Latency('10ns', "Delay for PIO r/w to distributor")
    cpu_pio_delay = Param.Latency('10ns', "Delay for PIO r/w to cpu interface")
    int_latency = Param.Latency('10ns', "Delay for interrupt to get to CPU")
    it_lines = Param.UInt32(128, "Number of interrupt lines supported (max = 1020)")
    gem5_extensions = Param.Bool(False, "Enable gem5 extensions")

class Gic400(GicV2):
    """
    As defined in:
    "ARM Generic Interrupt Controller Architecture" version 2.0
    "CoreLink GIC-400 Generic Interrupt Controller" revision r0p1
    """
    gicd_pidr = 0x002bb490
    gicd_iidr = 0x0200143B
    gicc_iidr = 0x0202143B

    # gicv_iidr same as gicc_idr
    gicv_iidr = gicc_iidr

class Gicv2mFrame(SimObject):
    type = 'Gicv2mFrame'
    cxx_header = "dev/arm/gic_v2m.hh"
    spi_base = Param.UInt32(0x0, "Frame SPI base number");
    spi_len = Param.UInt32(0x0, "Frame SPI total number");
    addr = Param.Addr("Address for frame PIO")

class Gicv2m(PioDevice):
    type = 'Gicv2m'
    cxx_header = "dev/arm/gic_v2m.hh"

    pio_delay = Param.Latency('10ns', "Delay for PIO r/w")
    gic = Param.BaseGic(Parent.any, "Gic on which to trigger interrupts")
    frames = VectorParam.Gicv2mFrame([], "Power of two number of frames")

class VGic(PioDevice):
    type = 'VGic'
    cxx_header = "dev/arm/vgic.hh"
    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
    platform = Param.Platform(Parent.any, "Platform this device is part of.")
    vcpu_addr = Param.Addr(0, "Address for vcpu interfaces")
    hv_addr = Param.Addr(0, "Address for hv control")
    pio_delay = Param.Latency('10ns', "Delay for PIO r/w")
   # The number of list registers is not currently configurable at runtime.
    maint_int = Param.UInt32("HV maintenance interrupt number")

    # gicv_iidr same as gicc_idr
    gicv_iidr = Param.UInt32(Self.gic.gicc_iidr,
        "VM CPU Interface Identification Register")

    def generateDeviceTree(self, state):
        gic = self.gic.unproxy(self)

        node = FdtNode("interrupt-controller")
        node.appendCompatible(["gem5,gic", "arm,cortex-a15-gic",
                               "arm,cortex-a9-gic"])
        node.append(gic._state.interruptCellsProperty())
        node.append(gic._state.addrCellsProperty())
        node.append(FdtProperty("interrupt-controller"))

        regs = (
            state.addrCells(gic.dist_addr) +
            state.sizeCells(0x1000) +
            state.addrCells(gic.cpu_addr) +
            state.sizeCells(0x1000) +
            state.addrCells(self.hv_addr) +
            state.sizeCells(0x2000) +
            state.addrCells(self.vcpu_addr) +
            state.sizeCells(0x2000) )

        node.append(FdtPropertyWords("reg", regs))
        node.append(FdtPropertyWords("interrupts",
                                     [1, int(self.maint_int)-16, 0xf04]))

        node.appendPhandle(gic)

        yield node

class Gicv3Its(BasicPioDevice):
    type = 'Gicv3Its'
    cxx_header = "dev/arm/gic_v3_its.hh"

    dma = RequestPort("DMA port")
    pio_size = Param.Unsigned(0x20000, "Gicv3Its pio size")

    # CIL [36] = 0: ITS supports 16-bit CollectionID
    # Devbits [17:13] = 0b100011: ITS supports 23 DeviceID bits
    # ID_bits [12:8] = 0b11111: ITS supports 31 EventID bits
    gits_typer = Param.UInt64(0x30023F01, "GITS_TYPER RO value")

    def generateDeviceTree(self, state):
        node = self.generateBasicPioDeviceNode(state, "gic-its", self.pio_addr,
                                               self.pio_size)
        node.appendCompatible(["arm,gic-v3-its"])
        node.append(FdtProperty("msi-controller"))
        node.append(FdtPropertyWords("#msi-cells", [1]))

        return node

class Gicv3(BaseGic):
    type = 'Gicv3'
    cxx_header = "dev/arm/gic_v3.hh"

    # Used for DTB autogeneration
    _state = FdtState(addr_cells=2, size_cells=2, interrupt_cells=3)

    its = Param.Gicv3Its(NULL, "GICv3 Interrupt Translation Service")

    dist_addr = Param.Addr("Address for distributor")
    dist_pio_delay = Param.Latency('10ns', "Delay for PIO r/w to distributor")
    redist_addr = Param.Addr("Address for redistributors")
    redist_pio_delay = Param.Latency('10ns',
            "Delay for PIO r/w to redistributors")
    it_lines = Param.UInt32(1020,
            "Number of interrupt lines supported (max = 1020)")

    maint_int = Param.ArmInterruptPin(
        "HV maintenance interrupt."
        "ARM strongly recommends that maintenance interrupts "
        "are configured to use INTID 25 (PPI Interrupt).")

    cpu_max = Param.Unsigned(256,
        "Maximum number of PE. This is affecting the maximum number of "
        "redistributors")

    gicv4 = Param.Bool(True, "GICv4 extension available")

    def interruptCells(self, int_type, int_num, int_trigger, partition=None):
        """
        Interupt cells generation helper:
        Following specifications described in

        Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt
        """
        prop = self._state.interruptCells(0)
        assert len(prop) >= 3
        prop[0] = int_type
        prop[1] = int_num
        prop[2] = int_trigger
        return prop

    def generateDeviceTree(self, state):
        node = FdtNode("interrupt-controller")
        node.appendCompatible(["arm,gic-v3"])
        node.append(self._state.interruptCellsProperty())
        node.append(self._state.addrCellsProperty())
        node.append(self._state.sizeCellsProperty())
        node.append(FdtProperty("ranges"))
        node.append(FdtProperty("interrupt-controller"))

        redist_stride = 0x40000 if self.gicv4 else 0x20000
        node.append(FdtPropertyWords("redistributor-stride",
            state.sizeCells(redist_stride)))

        regs = (
            state.addrCells(self.dist_addr) +
            state.sizeCells(0x10000) +
            state.addrCells(self.redist_addr) +
            state.sizeCells(0x2000000) )

        node.append(FdtPropertyWords("reg", regs))
        node.append(FdtPropertyWords("interrupts",
            self.interruptCells(1, int(self.maint_int.num)-16, 0x4)))

        node.appendPhandle(self)

        # Generate the ITS device tree if instantiated
        if self.its != NULL:
            node.append(self.its.generateDeviceTree(self._state))

        yield node
