# Copyright (c) 2009-2021 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.
#
# Copyright (c) 2006-2007 The Regents of The University of Michigan
# 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.

from m5.defines import buildEnv
from m5.params import *
from m5.proxy import *
from m5.util.fdthelper import *
from m5.objects.ClockDomain import ClockDomain, SrcClockDomain
from m5.objects.VoltageDomain import VoltageDomain
from m5.objects.Device import \
    BasicPioDevice, PioDevice, IsaFake, BadAddr, DmaDevice
from m5.objects.PciHost import *
from m5.objects.Ethernet import NSGigE, IGbE_igb, IGbE_e1000
from m5.objects.Ide import *
from m5.objects.Platform import Platform
from m5.objects.Terminal import Terminal
from m5.objects.Uart import Uart
from m5.objects.SimpleMemory import SimpleMemory
from m5.objects.GenericTimer import *
from m5.objects.Gic import *
from m5.objects.MHU import MHU, Scp2ApDoorbell, Ap2ScpDoorbell
from m5.objects.EnergyCtrl import EnergyCtrl
from m5.objects.ClockedObject import ClockedObject
from m5.objects.SubSystem import SubSystem
from m5.objects.Graphics import ImageFormat
from m5.objects.ClockedObject import ClockedObject
from m5.objects.PS2 import *
from m5.objects.VirtIOMMIO import MmioVirtIO
from m5.objects.Display import Display, Display1080p
from m5.objects.Scmi import *
from m5.objects.SMMUv3 import SMMUv3
from m5.objects.PciDevice import PciLegacyIoBar, PciIoBar

from m5.objects.CfiMemory import CfiMemory

# Platforms with KVM support should generally use in-kernel GIC
# emulation. Use a GIC model that automatically switches between
# gem5's GIC model and KVM's GIC model if KVM is available.
try:
    from m5.objects.KvmGic import MuxingKvmGic
    kvm_gicv2_class = MuxingKvmGic
except ImportError:
    # KVM support wasn't compiled into gem5. Fallback to a
    # software-only GIC.
    kvm_gicv2_class = Gic400
    pass

class AmbaPioDevice(BasicPioDevice):
    type = 'AmbaPioDevice'
    abstract = True
    cxx_header = "dev/arm/amba_device.hh"
    cxx_class = 'gem5::AmbaPioDevice'
    amba_id = Param.UInt32("ID of AMBA device for kernel detection")

class AmbaIntDevice(AmbaPioDevice):
    type = 'AmbaIntDevice'
    abstract = True
    cxx_header = "dev/arm/amba_device.hh"
    cxx_class = 'gem5::AmbaIntDevice'
    interrupt = Param.ArmInterruptPin("Interrupt that connects to GIC")
    int_delay = Param.Latency("100ns",
            "Time between action and interrupt generation by device")

class AmbaDmaDevice(DmaDevice):
    type = 'AmbaDmaDevice'
    abstract = True
    cxx_header = "dev/arm/amba_device.hh"
    cxx_class = 'gem5::AmbaDmaDevice'
    pio_addr = Param.Addr("Address for AMBA responder interface")
    pio_latency = Param.Latency("10ns", "Time between action and write/read"
                                        "result by AMBA DMA Device")
    interrupt = Param.ArmInterruptPin("Interrupt that connects to GIC")
    amba_id = Param.UInt32("ID of AMBA device for kernel detection")

class A9SCU(BasicPioDevice):
    type = 'A9SCU'
    cxx_header = "dev/arm/a9scu.hh"
    cxx_class = 'gem5::A9SCU'

class ArmPciIntRouting(Enum): vals = [
    'ARM_PCI_INT_STATIC',
    'ARM_PCI_INT_DEV',
    'ARM_PCI_INT_PIN',
    ]

class GenericArmPciHost(GenericPciHost):
    type = 'GenericArmPciHost'
    cxx_header = "dev/arm/pci_host.hh"
    cxx_class = 'gem5::GenericArmPciHost'

    int_policy = Param.ArmPciIntRouting("PCI interrupt routing policy")
    int_base = Param.Unsigned("PCI interrupt base")
    int_count = Param.Unsigned("Maximum number of interrupts used by this host")

    # This python parameter can be used in configuration scripts to turn
    # on/off the fdt dma-coherent flag when doing dtb autogeneration
    _dma_coherent = True

    def generateDeviceTree(self, state):
        local_state = FdtState(
            addr_cells=3, size_cells=2,
            cpu_cells=1, interrupt_cells=1)

        node = FdtNode("pci")

        if int(self.conf_device_bits) == 8:
            node.appendCompatible("pci-host-cam-generic")
        elif int(self.conf_device_bits) == 12:
            node.appendCompatible("pci-host-ecam-generic")
        else:
            m5.fatal("No compatibility string for the set conf_device_width")

        node.append(FdtPropertyStrings("device_type", ["pci"]))

        # Cell sizes of child nodes/peripherals
        node.append(local_state.addrCellsProperty())
        node.append(local_state.sizeCellsProperty())
        node.append(local_state.interruptCellsProperty())
        # PCI address for CPU
        node.append(FdtPropertyWords("reg",
            state.addrCells(self.conf_base) +
            state.sizeCells(self.conf_size) ))

        # Ranges mapping
        # For now some of this is hard coded, because the PCI module does not
        # have a proper full understanding of the memory map, but adapting the
        # PCI module is beyond the scope of what I'm trying to do here.
        # Values are taken from the VExpress_GEM5_V1 platform.
        ranges = []
        # Pio address range
        ranges += self.pciFdtAddr(space=1, addr=0)
        ranges += state.addrCells(self.pci_pio_base)
        ranges += local_state.sizeCells(0x10000)  # Fixed size

        # AXI memory address range
        ranges += self.pciFdtAddr(space=2, addr=0)
        ranges += state.addrCells(self.pci_mem_base)
        ranges += local_state.sizeCells(0x40000000) # Fixed size
        node.append(FdtPropertyWords("ranges", ranges))

        if str(self.int_policy) == 'ARM_PCI_INT_DEV':
            gic = self._parent.unproxy(self).gic
            int_phandle = state.phandle(gic)
            # Interrupt mapping
            interrupts = []

            # child interrupt specifier
            child_interrupt = local_state.interruptCells(0x0)

            # parent unit address
            parent_addr = gic._state.addrCells(0x0)

            for i in range(int(self.int_count)):
                parent_interrupt = gic.interruptCells(0,
                    int(self.int_base) - 32 + i, 1)

                interrupts += self.pciFdtAddr(device=i, addr=0) + \
                    child_interrupt + [int_phandle] + parent_addr + \
                    parent_interrupt

            node.append(FdtPropertyWords("interrupt-map", interrupts))

            int_count = int(self.int_count)
            if int_count & (int_count - 1):
                fatal("PCI interrupt count should be power of 2")

            intmask = self.pciFdtAddr(device=int_count - 1, addr=0) + [0x0]
            node.append(FdtPropertyWords("interrupt-map-mask", intmask))
        else:
            m5.fatal("Unsupported PCI interrupt policy " +
                     "for Device Tree generation")

        if self._dma_coherent:
            node.append(FdtProperty("dma-coherent"))

        yield node

class RealViewCtrl(BasicPioDevice):
    type = 'RealViewCtrl'
    cxx_header = "dev/arm/rv_ctrl.hh"
    cxx_class = 'gem5::RealViewCtrl'
    proc_id0 = Param.UInt32(0x0C000000, "Processor ID, SYS_PROCID")
    proc_id1 = Param.UInt32(0x0C000222, "Processor ID, SYS_PROCID1")
    idreg = Param.UInt32(0x00000000, "ID Register, SYS_ID")

    def generateDeviceTree(self, state):
        node = FdtNode("sysreg@%x" % int(self.pio_addr))
        node.appendCompatible("arm,vexpress-sysreg")
        node.append(FdtPropertyWords("reg",
            state.addrCells(self.pio_addr) +
            state.sizeCells(0x1000) ))
        node.append(FdtProperty("gpio-controller"))
        node.append(FdtPropertyWords("#gpio-cells", [2]))
        node.appendPhandle(self)

        yield node

class RealViewOsc(ClockDomain):
    type = 'RealViewOsc'
    cxx_header = "dev/arm/rv_ctrl.hh"
    cxx_class = 'gem5::RealViewOsc'

    parent = Param.RealViewCtrl(Parent.any, "RealView controller")

    # TODO: We currently don't have the notion of a clock source,
    # which means we have to associate oscillators with a voltage
    # source.
    voltage_domain = Param.VoltageDomain(Parent.voltage_domain,
                                         "Voltage domain")

    # See ARM DUI 0447J (ARM Motherboard Express uATX -- V2M-P1) and
    # the individual core/logic tile reference manuals for details
    # about the site/position/dcc/device allocation.
    site = Param.UInt8("Board Site")
    position = Param.UInt8("Position in device stack")
    dcc = Param.UInt8("Daughterboard Configuration Controller")
    device = Param.UInt8("Device ID")

    freq = Param.Clock("Default frequency")

    # These are currently only used for the device tree.
    min_freq = Param.Clock("0t", "Minimum frequency")
    max_freq = Param.Clock("0t", "Maximum frequency")

    def generateDeviceTree(self, state):
        phandle = state.phandle(self)
        node = FdtNode("osc@" + format(int(phandle), 'x'))
        node.appendCompatible("arm,vexpress-osc")
        node.append(FdtPropertyWords("arm,vexpress-sysreg,func",
                                     [0x1, int(self.device)]))
        node.append(FdtPropertyWords("#clock-cells", [0]))

        minf = self.min_freq if self.min_freq.value else self.freq
        maxf = self.max_freq if self.max_freq.value else self.freq

        # Values are stored as a clock period.
        def to_freq(prop):
            return int(1.0 / prop.value)

        node.append(FdtPropertyWords("freq-range",
                                     [to_freq(minf), to_freq(maxf)]))
        node.append(FdtPropertyStrings("clock-output-names",
                                       ["oscclk" + str(phandle)]))
        node.appendPhandle(self)
        yield node

class RealViewTemperatureSensor(SimObject):
    type = 'RealViewTemperatureSensor'
    cxx_header = "dev/arm/rv_ctrl.hh"
    cxx_class = 'gem5::RealViewTemperatureSensor'

    parent = Param.RealViewCtrl(Parent.any, "RealView controller")

    system = Param.System(Parent.any, "system")

    # See ARM DUI 0447J (ARM Motherboard Express uATX -- V2M-P1) and
    # the individual core/logic tile reference manuals for details
    # about the site/position/dcc/device allocation.
    site = Param.UInt8("Board Site")
    position = Param.UInt8("Position in device stack")
    dcc = Param.UInt8("Daughterboard Configuration Controller")
    device = Param.UInt8("Device ID")

class VExpressMCC(SubSystem):
    """ARM V2M-P1 Motherboard Configuration Controller

This subsystem describes a subset of the devices that sit behind the
motherboard configuration controller on the the ARM Motherboard
Express (V2M-P1) motherboard. See ARM DUI 0447J for details.
    """

    class Osc(RealViewOsc):
        site, position, dcc = (0, 0, 0)

    class Temperature(RealViewTemperatureSensor):
        site, position, dcc = (0, 0, 0)

    osc_mcc = Osc(device=0, min_freq="25MHz", max_freq="60MHz", freq="50MHz")
    osc_clcd = Osc(device=1, min_freq="23.75MHz", max_freq="63.5MHz",
                   freq="23.75MHz")
    osc_peripheral = Osc(device=2, freq="24MHz")
    osc_system_bus = Osc(device=4, min_freq="2MHz", max_freq="230MHz",
                         freq="24MHz")

    # See Table 4.19 in ARM DUI 0447J (Motherboard Express uATX TRM).
    temp_crtl = Temperature(device=0)

    def generateDeviceTree(self, state):
        node = FdtNode("mcc")
        node.appendCompatible("arm,vexpress,config-bus")
        node.append(FdtPropertyWords("arm,vexpress,site", [0]))

        for obj in self._children.values():
            if issubclass(type(obj), SimObject):
                node.append(obj.generateDeviceTree(state))

        io_phandle = state.phandle(self.osc_mcc.parent.unproxy(self))
        node.append(FdtPropertyWords("arm,vexpress,config-bridge", io_phandle))

        yield node

class CoreTile2A15DCC(SubSystem):
    """ARM CoreTile Express A15x2 Daughterboard Configuration Controller

This subsystem describes a subset of the devices that sit behind the
daughterboard configuration controller on a CoreTile Express A15x2. See
ARM DUI 0604E for details.
    """

    class Osc(RealViewOsc):
        site, position, dcc = (1, 0, 0)

    # See Table 2.8 in ARM DUI 0604E (CoreTile Express A15x2 TRM)
    osc_cpu = Osc(device=0, min_freq="20MHz", max_freq="60MHz", freq="60MHz")
    osc_hsbm = Osc(device=4, min_freq="20MHz", max_freq="40MHz", freq="40MHz")
    osc_pxl = Osc(device=5, min_freq="23.76MHz", max_freq="165MHz",
                  freq="23.75MHz")
    osc_smb = Osc(device=6, min_freq="20MHz", max_freq="50MHz", freq="50MHz")
    osc_sys = Osc(device=7, min_freq="20MHz", max_freq="60MHz", freq="60MHz")
    osc_ddr = Osc(device=8, freq="40MHz")

    def generateDeviceTree(self, state):
        node = FdtNode("dcc")
        node.appendCompatible("arm,vexpress,config-bus")

        for obj in self._children.values():
            if isinstance(obj, SimObject):
                node.append(obj.generateDeviceTree(state))

        io_phandle = state.phandle(self.osc_cpu.parent.unproxy(self))
        node.append(FdtPropertyWords("arm,vexpress,config-bridge", io_phandle))

        yield node

class AmbaFake(AmbaPioDevice):
    type = 'AmbaFake'
    cxx_header = "dev/arm/amba_fake.hh"
    cxx_class = 'gem5::AmbaFake'
    ignore_access = Param.Bool(False,
        "Ignore reads/writes to this device, (e.g. IsaFake + AMBA)")
    amba_id = 0;

# Simple fixed-rate clock source. Intended to be instantiated in Platform
# instances for definition of clock bindings on DTB auto-generation
class FixedClock(SrcClockDomain):
    # Keep track of the number of FixedClock instances in the system
    # to provide unique names
    _index = 0

    def generateDeviceTree(self, state):
        if len(self.clock) > 1:
            fatal('FixedClock configured with multiple frequencies')
        node = FdtNode('clock{}'.format(FixedClock._index))
        node.appendCompatible('fixed-clock')
        node.append(FdtPropertyWords('#clock-cells', 0))
        node.append(FdtPropertyWords('clock-frequency',
                                     self.clock[0].frequency))
        node.appendPhandle(self)
        FixedClock._index += 1

        yield node

class Pl011(Uart):
    type = 'Pl011'
    cxx_header = "dev/arm/pl011.hh"
    cxx_class = 'gem5::Pl011'
    interrupt = Param.ArmInterruptPin("Interrupt that connects to GIC")
    end_on_eot = Param.Bool(False,
        "End the simulation when a EOT is received on the UART")
    int_delay = Param.Latency("100ns",
        "Time between action and interrupt generation by UART")

    def generateDeviceTree(self, state):
        node = self.generateBasicPioDeviceNode(state, 'uart', self.pio_addr,
            0x1000, [ self.interrupt ])
        node.appendCompatible(["arm,pl011", "arm,primecell"])

        # Hardcoded reference to the realview platform clocks, because the
        # clk_domain can only store one clock (i.e. it is not a VectorParam)
        realview = self._parent.unproxy(self)
        node.append(FdtPropertyWords("clocks",
            [state.phandle(realview.mcc.osc_peripheral),
            state.phandle(realview.dcc.osc_smb)]))
        node.append(FdtPropertyStrings("clock-names", ["uartclk", "apb_pclk"]))
        yield node

class Sp804(AmbaPioDevice):
    type = 'Sp804'
    cxx_header = "dev/arm/timer_sp804.hh"
    cxx_class = 'gem5::Sp804'
    int0 = Param.ArmSPI("Interrupt that connects to GIC")
    clock0 = Param.Clock('1MHz', "Clock speed of the input")
    int1 = Param.ArmSPI("Interrupt that connects to GIC")
    clock1 = Param.Clock('1MHz', "Clock speed of the input")
    amba_id = 0x00141804

class Sp805(AmbaIntDevice):
    """
Arm Watchdog Module (SP805)
Reference:
    Arm Watchdog Module (SP805) - Technical Reference Manual - rev. r1p0
    Doc. ID: ARM DDI 0270B
    """

    type = 'Sp805'
    cxx_header = 'dev/arm/watchdog_sp805.hh'
    cxx_class = 'gem5::Sp805'

    amba_id = 0x00141805

    def generateDeviceTree(self, state):
        node = self.generateBasicPioDeviceNode(state, 'watchdog',
            self.pio_addr, 0x1000, [ self.interrupt ])
        node.appendCompatible(['arm,sp805', 'arm,primecell'])
        clocks = [state.phandle(self.clk_domain.unproxy(self))]
        clock_names = ['wdogclk']
        platform = self._parent.unproxy(self)
        if self in platform._off_chip_devices():
            clocks.append(state.phandle(platform.dcc.osc_smb))
            clock_names.append('apb_pclk')
        node.append(FdtPropertyWords('clocks', clocks))
        node.append(FdtPropertyStrings('clock-names', clock_names))

        yield node

class GenericWatchdog(PioDevice):
    type = 'GenericWatchdog'
    cxx_header = 'dev/arm/watchdog_generic.hh'
    cxx_class = 'gem5::GenericWatchdog'

    refresh_start = Param.Addr("Start address for the refresh frame")
    control_start = Param.Addr("Start address for the control frame")
    pio_latency = Param.Latency('10ns', "Delay for PIO r/w")

    ws0 = Param.ArmInterruptPin("WS0 Signal")
    ws1 = Param.ArmInterruptPin("WS1 Signal")

    system_counter = Param.SystemCounter(Parent.any,
        "The Watchdog uses the Generic Timer system counter as the timebase "
        "against which the decision to trigger an interrupt is made.")

class CpuLocalTimer(BasicPioDevice):
    type = 'CpuLocalTimer'
    cxx_header = "dev/arm/timer_cpulocal.hh"
    cxx_class = 'gem5::CpuLocalTimer'
    int_timer = Param.ArmPPI("Interrrupt used per-cpu to GIC")
    int_watchdog = Param.ArmPPI("Interrupt for per-cpu watchdog to GIC")

class PL031(AmbaIntDevice):
    type = 'PL031'
    cxx_header = "dev/arm/rtc_pl031.hh"
    cxx_class = 'gem5::PL031'
    time = Param.Time('01/01/2009',
        "System time to use ('Now' for actual time)")
    amba_id = 0x00041031

    def generateDeviceTree(self, state):
        node = self.generateBasicPioDeviceNode(state, 'rtc', self.pio_addr,
            0x1000, [ self.interrupt ])

        node.appendCompatible(["arm,pl031", "arm,primecell"])
        clock = state.phandle(self.clk_domain.unproxy(self))
        node.append(FdtPropertyWords("clocks", clock))
        node.append(FdtPropertyStrings("clock-names", ["apb_pclk"]))

        yield node

class Pl050(AmbaIntDevice):
    type = 'Pl050'
    cxx_header = "dev/arm/kmi.hh"
    cxx_class = 'gem5::Pl050'
    amba_id = 0x00141050

    ps2 = Param.PS2Device("PS/2 device")

    def generateDeviceTree(self, state):
        node = self.generateBasicPioDeviceNode(state, 'kmi', self.pio_addr,
            0x1000, [ self.interrupt ])

        node.appendCompatible(["arm,pl050", "arm,primecell"])
        clock = state.phandle(self.clk_domain.unproxy(self))
        node.append(FdtPropertyWords("clocks", clock))

        yield node

class Pl111(AmbaDmaDevice):
    type = 'Pl111'
    cxx_header = "dev/arm/pl111.hh"
    cxx_class = 'gem5::Pl111'
    pixel_clock = Param.Clock('24MHz', "Pixel clock")
    vnc   = Param.VncInput(Parent.any,
        "Vnc server for remote frame buffer display")
    amba_id = 0x00141111
    enable_capture = Param.Bool(True,
        "capture frame to system.framebuffer.bmp")

class HDLcd(AmbaDmaDevice):
    type = 'HDLcd'
    cxx_header = "dev/arm/hdlcd.hh"
    cxx_class = 'gem5::HDLcd'
    vnc = Param.VncInput(Parent.any, "Vnc server for remote frame buffer "
                                     "display")
    amba_id = 0x00141000
    workaround_swap_rb = Param.Bool(False, "Workaround incorrect color "
                                    "selector order in some kernels")
    workaround_dma_line_count = Param.Bool(True, "Workaround incorrect "
                                           "DMA line count (off by 1)")
    enable_capture = Param.Bool(True, "capture frame to "
                                      "system.framebuffer.{extension}")
    frame_format = Param.ImageFormat("Auto",
                                     "image format of the captured frame")

    pixel_buffer_size = Param.MemorySize32("2KiB", "Size of address range")

    pxl_clk = Param.ClockDomain("Pixel clock source")
    pixel_chunk = Param.Unsigned(32, "Number of pixels to handle in one batch")
    virt_refresh_rate = Param.Frequency("20Hz", "Frame refresh rate "
                                        "in KVM mode")
    _status = "ok"

    encoder = Param.Display(Display1080p(), "Display encoder")

    def endpointPhandle(self):
        return "hdlcd_endpoint"

    def generateDeviceTree(self, state):
        endpoint_node = FdtNode("endpoint")
        endpoint_node.appendPhandle(self.endpointPhandle())

        for encoder_node in self.encoder.generateDeviceTree(state):
            encoder_endpoint = self.encoder.endpointNode()

            # Endpoint subnode
            endpoint_node.append(FdtPropertyWords("remote-endpoint",
                [ state.phandle(self.encoder.endpointPhandle()) ]))
            encoder_endpoint.append(FdtPropertyWords("remote-endpoint",
                [ state.phandle(self.endpointPhandle()) ]))

            yield encoder_node

        port_node = FdtNode("port")
        port_node.append(endpoint_node)

        node = self.generateBasicPioDeviceNode(state, 'hdlcd',
            self.pio_addr, 0x1000, [ self.interrupt ])

        node.appendCompatible(["arm,hdlcd"])
        node.append(FdtPropertyWords("clocks", state.phandle(self.pxl_clk)))
        node.append(FdtPropertyStrings("clock-names", ["pxlclk"]))

        node.append(FdtPropertyStrings("status", [ self._status ]))

        self.addIommuProperty(state, node)

        node.append(port_node)

        yield node

class ParentMem(SimpleMemory):
    """
    This is a base abstract class for child node generation
    A memory willing to autogenerate child nodes can do that
    directly in the generateDeviceTree method.
    However sometimes portions of memory (child nodes) are tagged
    for specific applications. Hardcoding the child node in the
    parent memory class is not flexible, so we delegate this
    to the application model, which is registering the generator
    helper via the ParentMem interface.
    """
    def __init__(self, *args, **kwargs):
        super(ParentMem, self).__init__(*args, **kwargs)
        self._generators = []

    def addSubnodeGenerator(self, gen):
        """
        This is the method a client application would use to
        register a child generator in the memory object.
        """
        self._generators.append(gen)

    def generateSubnodes(self, node, state):
        """
        This is the method the memory would use to instantiate
        the child nodes via the previously registered generators.
        """
        for subnode_gen in self._generators:
            node.append(subnode_gen(state))

class MmioSRAM(ParentMem):
    def __init__(self, *args, **kwargs):
        super(MmioSRAM, self).__init__(**kwargs)

    def generateDeviceTree(self, state):
        node = FdtNode("sram@%x" % int(self.range.start))
        node.appendCompatible(["mmio-sram"])
        node.append(FdtPropertyWords("reg",
            state.addrCells(self.range.start) +
            state.sizeCells(self.range.size()) ))

        local_state = FdtState(addr_cells=2, size_cells=2, cpu_cells=1)
        node.append(local_state.addrCellsProperty())
        node.append(local_state.sizeCellsProperty())
        node.append(FdtPropertyWords("ranges",
            local_state.addrCells(0) +
            state.addrCells(self.range.start) +
            state.sizeCells(self.range.size()) ))

        self.generateSubnodes(node, state)

        yield node

class FVPBasePwrCtrl(BasicPioDevice):
    """
Based on Fast Models Base_PowerController v11.8
Reference:
    Fast Models Reference Manual - Section 7.7.2 - Version 11.8
    Document ID: 100964_1180_00_en
    """

    type = 'FVPBasePwrCtrl'
    cxx_header = 'dev/arm/fvp_base_pwr_ctrl.hh'
    cxx_class = 'gem5::FVPBasePwrCtrl'

class GenericMHU(MHU):
    lowp_scp2ap = Scp2ApDoorbell(
        set_address=0x10020008, clear_address=0x10020010,
        interrupt=ArmSPI(num=68))
    highp_scp2ap = Scp2ApDoorbell(
        set_address=0x10020028, clear_address=0x10020030,
        interrupt=ArmSPI(num=67))
    sec_scp2ap = Scp2ApDoorbell(
        set_address=0x10020208, clear_address=0x10020210,
        interrupt=ArmSPI(num=69))
    lowp_ap2scp = Ap2ScpDoorbell(
        set_address=0x10020108, clear_address=0x10020110)
    highp_ap2scp = Ap2ScpDoorbell(
        set_address=0x10020128, clear_address=0x10020130)
    sec_ap2scp = Ap2ScpDoorbell(
        set_address=0x10020308, clear_address=0x10020310)

class RealView(Platform):
    type = 'RealView'
    cxx_header = "dev/arm/realview.hh"
    cxx_class = 'gem5::RealView'
    _mem_regions = [ AddrRange(0, size='256MiB') ]
    _num_pci_dev = 0

    def _on_chip_devices(self):
        return []

    def _off_chip_devices(self):
        return []

    def _on_chip_memory(self):
        return []

    def _off_chip_memory(self):
        return []

    _off_chip_ranges = []

    def _attach_memory(self, mem, bus, mem_ports=None):
        if hasattr(mem, "port"):
            if mem_ports is None:
                mem.port = bus.mem_side_ports
            else:
                mem_ports.append(mem.port)

    def _attach_device(self, device, bus, dma_ports=None):
        if hasattr(device, "pio"):
            device.pio = bus.mem_side_ports
        if hasattr(device, "dma"):
            if dma_ports is None:
                device.dma = bus.cpu_side_ports
            else:
                dma_ports.append(device.dma)

    def _attach_io(self, devices, *args, **kwargs):
        for d in devices:
            self._attach_device(d, *args, **kwargs)

    def _attach_mem(self, memories, *args, **kwargs):
        for mem in memories:
            self._attach_memory(mem, *args, **kwargs)

    def _attach_clk(self, devices, clkdomain):
        for d in devices:
            if hasattr(d, "clk_domain"):
                d.clk_domain = clkdomain

    def attachPciDevices(self):
        pass

    def enableMSIX(self):
        pass

    def onChipIOClkDomain(self, clkdomain):
        self._attach_clk(self._on_chip_devices(), clkdomain)

    def offChipIOClkDomain(self, clkdomain):
        self._attach_clk(self._off_chip_devices(), clkdomain)

    def attachOnChipIO(self, bus, bridge=None, dma_ports=None, mem_ports=None):
        self._attach_mem(self._on_chip_memory(), bus, mem_ports)
        self._attach_io(self._on_chip_devices(), bus, dma_ports)
        if bridge:
            bridge.ranges = self._off_chip_ranges

    def attachIO(self, bus, dma_ports=None, mem_ports=None):
        self._attach_mem(self._off_chip_memory(), bus, mem_ports)
        self._attach_io(self._off_chip_devices(), bus, dma_ports)

    def setupBootLoader(self, cur_sys, boot_loader, dtb_addr, load_offset):
        cur_sys.workload.boot_loader = boot_loader
        cur_sys.workload.load_addr_offset = load_offset
        cur_sys.workload.dtb_addr = load_offset + dtb_addr
        cur_sys.workload.cpu_release_addr = cur_sys.workload.dtb_addr - 8

    def generateDeviceTree(self, state):
        node = FdtNode("/") # Things in this module need to end up in the root
        node.append(FdtPropertyWords("interrupt-parent",
                                     state.phandle(self.gic)))

        for subnode in self.recurseDeviceTree(state):
            node.append(subnode)

        yield node

    def annotateCpuDeviceNode(self, cpu, state):
        system = self.system.unproxy(self)
        if system._have_psci:
            cpu.append(FdtPropertyStrings('enable-method', 'psci'))
        else:
            cpu.append(FdtPropertyStrings("enable-method", "spin-table"))
            # The kernel writes the entry addres of secondary CPUs to this
            # address before waking up secondary CPUs.
            # The gem5 bootloader then makes secondary CPUs jump to it.
            cpu.append(FdtPropertyWords("cpu-release-addr", \
                        state.addrCells(system.workload.cpu_release_addr)))

class VExpress_EMM(RealView):
    _mem_regions = [ AddrRange('2GiB', size='2GiB') ]

    # Ranges based on excluding what is part of on-chip I/O (gic,
    # a9scu)
    _off_chip_ranges = [AddrRange(0x2F000000, size='16MiB'),
                        AddrRange(0x30000000, size='256MiB'),
                        AddrRange(0x40000000, size='512MiB'),
                        AddrRange(0x18000000, size='64MiB'),
                        AddrRange(0x1C000000, size='64MiB')]

    # Platform control device (off-chip)
    realview_io = RealViewCtrl(proc_id0=0x14000000, proc_id1=0x14000000,
                               idreg=0x02250000, pio_addr=0x1C010000)

    mcc = VExpressMCC()
    dcc = CoreTile2A15DCC()

    ### On-chip devices ###
    gic = Gic400(dist_addr=0x2C001000, cpu_addr=0x2C002000)
    vgic   = VGic(vcpu_addr=0x2c006000, hv_addr=0x2c004000, maint_int=25)

    local_cpu_timer = CpuLocalTimer(int_timer=ArmPPI(num=29),
                                    int_watchdog=ArmPPI(num=30),
                                    pio_addr=0x2C080000)

    hdlcd  = HDLcd(pxl_clk=dcc.osc_pxl,
                   pio_addr=0x2b000000, interrupt=ArmSPI(num=117),
                   workaround_swap_rb=True)

    def _on_chip_devices(self):
        devices = [
            self.gic, self.vgic,
            self.local_cpu_timer
        ]
        if hasattr(self, "gicv2m"):
            devices.append(self.gicv2m)
        devices.append(self.hdlcd)
        return devices

    def _on_chip_memory(self):
        memories = [
            self.bootmem,
        ]
        return memories

    ### Off-chip devices ###
    uart = Pl011(pio_addr=0x1c090000, interrupt=ArmSPI(num=37))
    pci_host = GenericPciHost(
        conf_base=0x30000000, conf_size='256MiB', conf_device_bits=16,
        pci_pio_base=0)

    sys_counter = SystemCounter()
    generic_timer = GenericTimer(
        int_phys_s=ArmPPI(num=29, int_type='IRQ_TYPE_LEVEL_LOW'),
        int_phys_ns=ArmPPI(num=30, int_type='IRQ_TYPE_LEVEL_LOW'),
        int_virt=ArmPPI(num=27, int_type='IRQ_TYPE_LEVEL_LOW'),
        int_hyp=ArmPPI(num=26, int_type='IRQ_TYPE_LEVEL_LOW'))

    timer0 = Sp804(int0=ArmSPI(num=34), int1=ArmSPI(num=34),
                   pio_addr=0x1C110000, clock0='1MHz', clock1='1MHz')
    timer1 = Sp804(int0=ArmSPI(num=35), int1=ArmSPI(num=35),
                   pio_addr=0x1C120000, clock0='1MHz', clock1='1MHz')
    clcd   = Pl111(pio_addr=0x1c1f0000, interrupt=ArmSPI(num=46))
    kmi0   = Pl050(pio_addr=0x1c060000, interrupt=ArmSPI(num=44),
                   ps2=PS2Keyboard())
    kmi1   = Pl050(pio_addr=0x1c070000, interrupt=ArmSPI(num=45),
                   ps2=PS2TouchKit())
    cf_ctrl = IdeController(disks=[], pci_func=0, pci_dev=0, pci_bus=2,
                            io_shift = 2, ctrl_offset = 2, Command = 0x1)
    cf_ctrl.BAR0 = PciLegacyIoBar(addr='0x1C1A0000', size='256B')
    cf_ctrl.BAR1 = PciLegacyIoBar(addr='0x1C1A0100', size='4096B')

    bootmem        = SimpleMemory(range = AddrRange('64MiB'),
                                  conf_table_reported = False)
    vram           = SimpleMemory(range = AddrRange(0x18000000, size='32MiB'),
                                  conf_table_reported = False)
    rtc            = PL031(pio_addr=0x1C170000, interrupt=ArmSPI(num=36))

    l2x0_fake      = IsaFake(pio_addr=0x2C100000, pio_size=0xfff)
    uart1_fake     = AmbaFake(pio_addr=0x1C0A0000)
    uart2_fake     = AmbaFake(pio_addr=0x1C0B0000)
    uart3_fake     = AmbaFake(pio_addr=0x1C0C0000)
    sp810_fake     = AmbaFake(pio_addr=0x1C020000, ignore_access=True)
    watchdog_fake  = AmbaFake(pio_addr=0x1C0F0000)
    aaci_fake      = AmbaFake(pio_addr=0x1C040000)
    lan_fake       = IsaFake(pio_addr=0x1A000000, pio_size=0xffff)
    usb_fake       = IsaFake(pio_addr=0x1B000000, pio_size=0x1ffff)
    mmc_fake       = AmbaFake(pio_addr=0x1c050000)
    energy_ctrl    = EnergyCtrl(pio_addr=0x1c080000)

    def _off_chip_devices(self):
        devices = [
            self.uart,
            self.realview_io,
            self.pci_host,
            self.timer0,
            self.timer1,
            self.clcd,
            self.kmi0,
            self.kmi1,
            self.cf_ctrl,
            self.rtc,
            self.vram,
            self.l2x0_fake,
            self.uart1_fake,
            self.uart2_fake,
            self.uart3_fake,
            self.sp810_fake,
            self.watchdog_fake,
            self.aaci_fake,
            self.lan_fake,
            self.usb_fake,
            self.mmc_fake,
            self.energy_ctrl,
        ]
        # Try to attach the I/O if it exists
        if hasattr(self, "ide"):
            devices.append(self.ide)
        if hasattr(self, "ethernet"):
            devices.append(self.ethernet)
        return devices

    # Attach any PCI devices that are supported
    def attachPciDevices(self):
        self.ethernet = IGbE_e1000(pci_bus=0, pci_dev=0, pci_func=0,
                                   InterruptLine=1, InterruptPin=1)
        self.ide = IdeController(disks = [], pci_bus=0, pci_dev=1, pci_func=0,
                                 InterruptLine=2, InterruptPin=2)

    def enableMSIX(self):
        self.gic = Gic400(dist_addr=0x2C001000, cpu_addr=0x2C002000,
                          it_lines=512)
        self.gicv2m = Gicv2m()
        self.gicv2m.frames = [Gicv2mFrame(spi_base=256, spi_len=64, addr=0x2C1C0000)]

    def setupBootLoader(self, cur_sys, loc, boot_loader=None):
        if boot_loader is None:
            boot_loader = loc('boot_emm.arm')
        super(VExpress_EMM, self).setupBootLoader(
                cur_sys, boot_loader, 0x8000000, 0x80000000)

class VExpress_EMM64(VExpress_EMM):
    # Three memory regions are specified totalling 512GiB
    _mem_regions = [ AddrRange('2GiB', size='2GiB'),
                     AddrRange('34GiB', size='30GiB'),
                     AddrRange('512GiB', size='480GiB') ]
    pci_host = GenericPciHost(
        conf_base=0x30000000, conf_size='256MiB', conf_device_bits=12,
        pci_pio_base=0x2f000000)

    def setupBootLoader(self, cur_sys, loc, boot_loader=None):
        if boot_loader is None:
            boot_loader = loc('boot_emm.arm64')
        RealView.setupBootLoader(self, cur_sys, boot_loader,
                0x8000000, 0x80000000)

class VExpress_GEM5_Base(RealView):
    """
The VExpress gem5 memory map is loosely based on a modified
Versatile Express RS1 memory map.

The gem5 platform has been designed to implement a subset of the
original Versatile Express RS1 memory map. Off-chip peripherals should,
when possible, adhere to the Versatile Express memory map. Non-PCI
off-chip devices that are gem5-specific should live in the CS5 memory
space to avoid conflicts with existing devices that we might want to
model in the future. Such devices should normally have interrupts in
the gem5-specific SPI range.

On-chip peripherals are loosely modeled after the ARM CoreTile Express
A15x2 memory and interrupt map. In particular, the GIC and
Generic Timer have the same interrupt lines and base addresses. Other
on-chip devices are gem5 specific.

Unlike the original Versatile Express RS2 extended platform, gem5 implements a
large contigious DRAM space, without aliases or holes, starting at the
2GiB boundary. This means that PCI memory is limited to 1GiB.

References:

    Technical Reference Manuals:
        Arm Motherboard Express uATX (V2M-P1) - ARM DUI 0447J
        Arm CoreTile Express A15x2 (V2P-CA15) - ARM DUI 0604E

    Official Linux device tree specifications:
        V2M-P1   - arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
        V2P-CA15 - arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts

    Memory map:
        Arm CoreTile Express A15x2 (V2P-CA15) - ARM DUI 0604E
        Daughterboard (global)
            Section 3.2.1 - Table 3-1 - Daughterboard memory map
        On-chip
            Section 3.2.3 - Table 3-2 - Cortex-A15 MPCore on-chip peripheral
                                        memory map

    Interrupts:
        Arm CoreTile Express A15x2 (V2P-CA15) - ARM DUI 0604E
        Section 2.8.2 - Test chip interrupts

Memory map:
   0x00000000-0x03ffffff: Boot memory (CS0)
   0x04000000-0x07ffffff: Reserved
   0x08000000-0x0bffffff: NOR FLASH0 (CS0 alias)
   0x0c000000-0x0fffffff: NOR FLASH1 (Off-chip, CS4)
   0x10000000-0x13ffffff: gem5-specific peripherals (Off-chip, CS5)
       0x10000000-0x1000ffff: gem5 energy controller
       0x10010000-0x1001ffff: gem5 pseudo-ops
       0x10020000-0x1002ffff: gem5 MHU

   0x14000000-0x17ffffff: Reserved (Off-chip, PSRAM, CS1)

   0x18000000-0x1bffffff: Off-chip, Peripherals, CS2
       0x18000000-0x19ffffff: VRAM
       0x1a000000-0x1bffffff: Reserved

   0x1c000000-0x1fffffff: Peripheral block 1 (Off-chip, CS3):
       0x1c010000-0x1c01ffff: realview_io (VE system control regs.)
       0x1c060000-0x1c06ffff: KMI0 (keyboard)
       0x1c070000-0x1c07ffff: KMI1 (mouse)
       0x1c090000-0x1c09ffff: UART0
       0x1c0a0000-0x1c0affff: UART1
       0x1c0b0000-0x1c0bffff: UART2
       0x1c0c0000-0x1c0cffff: UART3
       0x1c0f0000-0x1c0fffff: Watchdog (SP805)
       0x1c130000-0x1c13ffff: VirtIO (gem5/FM extension)
       0x1c140000-0x1c14ffff: VirtIO (gem5/FM extension)
       0x1c170000-0x1c17ffff: RTC

   0x20000000-0x3fffffff: On-chip peripherals:
       0x2a430000-0x2a43ffff: System Counter (control)
       0x2a490000-0x2a49ffff: Trusted Watchdog (SP805)
       0x2a800000-0x2a800fff: System Counter (read)
       0x2a810000-0x2a810fff: System Timer (control)

       0x2a820000-0x2a820fff: System Timer (frame 0)
       0x2a830000-0x2a830fff: System Timer (frame 1)

       0x2b000000-0x2b00ffff: HDLCD

       0x2b060000-0x2b060fff: System Watchdog (SP805)

       0x2b400000-0x2b41ffff: SMMUv3

       0x2c001000-0x2c001fff: GIC (distributor)
       0x2c002000-0x2c003fff: GIC (CPU interface)
       0x2c004000-0x2c005fff: vGIC (HV)
       0x2c006000-0x2c007fff: vGIC (VCPU)
       0x2c1c0000-0x2c1cffff: GICv2m MSI frame 0

       0x2d000000-0x2d00ffff: GPU (reserved)

       0x2e000000-0x2e007fff: Non-trusted SRAM

       0x2f000000-0x2fffffff: PCI IO space
       0x30000000-0x3fffffff: PCI config space

   0x40000000-0x7fffffff: Ext. AXI: Used as PCI memory

   0x80000000-X: DRAM

Interrupts:
      0- 15: Software generated interrupts (SGIs)
     16- 31: On-chip private peripherals (PPIs)
        25   : vgic
        26   : generic_timer (hyp)
        27   : generic_timer (virt)
        28   : Reserved (Legacy FIQ)
        29   : generic_timer (phys, sec)
        30   : generic_timer (phys, non-sec)
        31   : Reserved (Legacy IRQ)
    32- 95: Mother board peripherals (SPIs)
        32   : Watchdog (SP805)
        33   : Reserved (IOFPGA SW int)
        34-35: Reserved (SP804)
        36   : RTC
        37-40: uart0-uart3
        41-42: Reserved (PL180)
        43   : Reserved (AACI)
        44-45: kmi0-kmi1
        46   : Reserved (CLCD)
        47   : Reserved (Ethernet)
        48   : Reserved (USB)
        56   : Trusted Watchdog (SP805)
        57   : System timer0 (phys)
        58   : System timer1 (phys)
    95-255: On-chip interrupt sources (we use these for
            gem5-specific devices, SPIs)
         74    : VirtIO (gem5/FM extension)
         75    : VirtIO (gem5/FM extension)
         95    : HDLCD
         96- 98: GPU (reserved)
        100-103: PCI
        130    : System Watchdog (SP805)
   256-319: MSI frame 0 (gem5-specific, SPIs)
   320-511: Unused

    """

    # Everything above 2GiB is memory
    _mem_regions = [ AddrRange('2GiB', size='510GiB') ]

    _off_chip_ranges = [
        # CS1-CS5
        AddrRange(0x0c000000, 0x20000000),
        # External AXI interface (PCI)
        AddrRange(0x2f000000, 0x80000000),
    ]

    bootmem = SimpleMemory(range=AddrRange(0, size='64MiB'),
                           conf_table_reported=False)

    # NOR flash, flash0
    flash0 = SimpleMemory(range=AddrRange(0x08000000, size='64MiB'),
                          conf_table_reported=False)

    # Trusted SRAM
    trusted_sram = SimpleMemory(range=AddrRange(0x04000000, size='256KiB'),
                                conf_table_reported=False)

    # Non-Trusted SRAM
    non_trusted_sram = MmioSRAM(range=AddrRange(0x2e000000, size=0x8000),
                                conf_table_reported=False)

    # Platform control device (off-chip)
    realview_io = RealViewCtrl(proc_id0=0x14000000, proc_id1=0x14000000,
                               idreg=0x30101100, pio_addr=0x1c010000)
    mcc = VExpressMCC()
    dcc = CoreTile2A15DCC()

    ### On-chip devices ###

    el2_watchdog = GenericWatchdog(
        control_start=0x2a440000,
        refresh_start=0x2a450000,
        ws0=ArmSPI(num=59), ws1=ArmSPI(num=60))

    # Trusted Watchdog, SP805
    trusted_watchdog = Sp805(pio_addr=0x2a490000, interrupt=ArmSPI(num=56))

    sys_counter = SystemCounter()
    generic_timer = GenericTimer(
        int_phys_s=ArmPPI(num=29, int_type='IRQ_TYPE_LEVEL_LOW'),
        int_phys_ns=ArmPPI(num=30, int_type='IRQ_TYPE_LEVEL_LOW'),
        int_virt=ArmPPI(num=27, int_type='IRQ_TYPE_LEVEL_LOW'),
        int_hyp=ArmPPI(num=26, int_type='IRQ_TYPE_LEVEL_LOW'))
    generic_timer_mem = GenericTimerMem(cnt_control_base=0x2a430000,
                                        cnt_read_base=0x2a800000,
                                        cnt_ctl_base=0x2a810000,
                                        frames=[
            GenericTimerFrame(cnt_base=0x2a820000,
                int_phys=ArmSPI(num=57), int_virt=ArmSPI(num=133)),
            GenericTimerFrame(cnt_base=0x2a830000,
                int_phys=ArmSPI(num=58), int_virt=ArmSPI(num=134))
    ])

    system_watchdog = Sp805(pio_addr=0x2b060000, interrupt=ArmSPI(num=130))

    def _on_chip_devices(self):
        return [
            self.generic_timer_mem,
            self.el2_watchdog,
            self.trusted_watchdog,
            self.system_watchdog
        ] + self.generic_timer_mem.frames

    def _on_chip_memory(self):
        memories = [
            self.bootmem,
            self.trusted_sram,
            self.non_trusted_sram,
            self.flash0,
        ]
        return memories

    ### Off-chip devices ###
    io_voltage = VoltageDomain(voltage="3.3V")
    clock32KHz = SrcClockDomain(clock="32kHz")
    clock24MHz = SrcClockDomain(clock="24MHz")

    uart = [
        Pl011(pio_addr=0x1c090000,
            interrupt=ArmSPI(num=37)),
        Pl011(pio_addr=0x1c0a0000,
            interrupt=ArmSPI(num=38), device=Terminal()),
        Pl011(pio_addr=0x1c0b0000,
            interrupt=ArmSPI(num=39), device=Terminal()),
        Pl011(pio_addr=0x1c0c0000,
            interrupt=ArmSPI(num=40), device=Terminal())
    ]

    kmi0 = Pl050(pio_addr=0x1c060000, interrupt=ArmSPI(num=44),
                 ps2=PS2Keyboard())
    kmi1 = Pl050(pio_addr=0x1c070000, interrupt=ArmSPI(num=45),
                 ps2=PS2TouchKit())

    watchdog = Sp805(pio_addr=0x1c0f0000, interrupt=ArmSPI(num=32))

    rtc = PL031(pio_addr=0x1C170000, interrupt=ArmSPI(num=36))

    ### gem5-specific off-chip devices ###
    pci_host = GenericArmPciHost(
        conf_base=0x30000000, conf_size='256MiB', conf_device_bits=12,
        pci_pio_base=0x2f000000,
        pci_mem_base=0x40000000,
        int_policy="ARM_PCI_INT_DEV", int_base=100, int_count=4)

    energy_ctrl = EnergyCtrl(pio_addr=0x10000000)

    pwr_ctrl = FVPBasePwrCtrl(pio_addr=0x1c100000)

    vio = [
        MmioVirtIO(pio_addr=0x1c130000, pio_size=0x1000,
                   interrupt=ArmSPI(num=74)),
        MmioVirtIO(pio_addr=0x1c140000, pio_size=0x1000,
                   interrupt=ArmSPI(num=75)),
    ]

    # NOR flash, flash1
    flash1 = CfiMemory(range=AddrRange(0x0c000000, 0x10000000),
                       conf_table_reported=False)

    # VRAM
    vram = SimpleMemory(range=AddrRange(0x18000000, size='32MB'),
                        conf_table_reported=False)

    def _off_chip_devices(self):
        return [
            self.realview_io,
            self.kmi0,
            self.kmi1,
            self.watchdog,
            self.rtc,
            self.pci_host,
            self.energy_ctrl,
            self.pwr_ctrl,
            self.clock32KHz,
            self.clock24MHz,
            self.vio[0],
            self.vio[1],
        ] + self.uart

    def _off_chip_memory(self):
        return [
            self.flash1,
            self.vram,
        ]

    def __init__(self, **kwargs):
        super(VExpress_GEM5_Base, self).__init__(**kwargs)
        self.clock32KHz.voltage_domain = self.io_voltage
        self.clock24MHz.voltage_domain = self.io_voltage
        self.system_watchdog.clk_domain = self.dcc.osc_sys
        self.watchdog.clk_domain = self.clock32KHz

    def attachPciDevice(self, device, *args, **kwargs):
        device.host = self.pci_host
        self._num_pci_dev += 1
        device.pci_bus = 0
        device.pci_dev = self._num_pci_dev
        device.pci_func = 0
        self._attach_device(device, *args, **kwargs)

    def attachSmmu(self, devices, bus):
        """
        Instantiate a single SMMU and attach a group of client devices to it.
        The devices' dma port is wired to the SMMU and the SMMU's dma port
        is attached to the bus. In order to make it work, the list of clients
        shouldn't contain any device part of the _off_chip_devices or
        _on_chip_devices.
        This method should be called only once.

        Parameters:
            devices (list): List of devices which will be using the SMMU
            bus (Bus): The bus downstream of the SMMU. Its response port will
                       receive memory requests from the SMMU, and its request
                       port will forward accesses to the memory mapped devices
        """
        if hasattr(self, 'smmu'):
            m5.fatal("A SMMU has already been instantiated\n")

        self.smmu = SMMUv3(reg_map=AddrRange(0x2b400000, size=0x00020000))

        self.smmu.request = bus.cpu_side_ports
        self.smmu.control = bus.mem_side_ports

        dma_ports = []
        for dev in devices:
            self._attach_device(dev, bus, dma_ports)
            self.smmu.connect(dev)

    def setupBootLoader(self, cur_sys, boot_loader):
        super(VExpress_GEM5_Base, self).setupBootLoader(
                cur_sys, boot_loader, 0x8000000, 0x80000000)

        #  Setup m5ops. It's technically not a part of the boot
        #  loader, but this is the only place we can configure the
        #  system.
        cur_sys.m5ops_base = 0x10010000

    def attachScmi(self, bus):
        # Generate and attach the mailbox
        self.mailbox = GenericMHU(pio_addr=0x10020000)
        self._attach_device(self.mailbox, bus)

        # Generate and attach the SCMI platform
        _scmi_comm = ScmiCommunication(
            agent_channel = ScmiAgentChannel(
                shmem=self.non_trusted_sram,
                shmem_range=AddrRange(0x2e000000, size=0x200),
                doorbell=self.mailbox.highp_ap2scp),
            platform_channel = ScmiPlatformChannel(
                shmem=self.non_trusted_sram,
                shmem_range=AddrRange(0x2e000000, size=0x200),
                doorbell=self.mailbox.highp_scp2ap))

        self.scmi = ScmiPlatform(comms=[ _scmi_comm ])
        self._attach_device(self.scmi, bus)

    def generateDeviceTree(self, state):
        # Generate using standard RealView function
        dt = list(super(VExpress_GEM5_Base, self).generateDeviceTree(state))
        if len(dt) > 1:
            raise Exception("System returned too many DT nodes")
        node = dt[0]

        node.appendCompatible(["arm,vexpress"])
        node.append(FdtPropertyStrings("model", ["V2P-CA15"]))
        node.append(FdtPropertyWords("arm,hbi", [0x0]))
        node.append(FdtPropertyWords("arm,vexpress,site", [0xf]))

        system = self.system.unproxy(self)
        if system._have_psci:
            # PSCI functions exposed to the kernel
            if not system.have_security:
                raise AssertionError("PSCI requires EL3 (have_security)")

            psci_node = FdtNode('psci')
            psci_node.appendCompatible(['arm,psci-1.0', 'arm,psci-0.2',
                                        'arm,psci'])
            method = 'smc'
            psci_node.append(FdtPropertyStrings('method', method))
            psci_node.append(FdtPropertyWords('cpu_suspend', 0xc4000001))
            psci_node.append(FdtPropertyWords('cpu_off', 0x84000002))
            psci_node.append(FdtPropertyWords('cpu_on', 0xc4000003))
            psci_node.append(FdtPropertyWords('sys_poweroff', 0x84000008))
            psci_node.append(FdtPropertyWords('sys_reset', 0x84000009))
            node.append(psci_node)

        yield node

class VExpress_GEM5_V1_Base(VExpress_GEM5_Base):
    gic = kvm_gicv2_class(dist_addr=0x2c001000, cpu_addr=0x2c002000,
                          it_lines=512)
    vgic = VGic(vcpu_addr=0x2c006000, hv_addr=0x2c004000, maint_int=25)
    gicv2m = Gicv2m()
    gicv2m.frames = [
        Gicv2mFrame(spi_base=256, spi_len=64, addr=0x2c1c0000),
    ]

    def setupBootLoader(self, cur_sys, loc, boot_loader=None):
        if boot_loader is None:
            boot_loader = [ loc('boot.arm64'), loc('boot.arm') ]
        super(VExpress_GEM5_V1_Base, self).setupBootLoader(
                cur_sys, boot_loader)

    def _on_chip_devices(self):
        return super(VExpress_GEM5_V1_Base,self)._on_chip_devices() + [
                self.gic, self.vgic, self.gicv2m,
            ]

class VExpress_GEM5_V1(VExpress_GEM5_V1_Base):
    """
    We subclass VExpress_GEM5_V1_Base in order to alias it to
    VExpress_GEM5_V1, which is what gem5 scripts are currently using
    """
    pass

class VExpress_GEM5_V1_HDLcd(VExpress_GEM5_V1_Base):
    hdlcd  = HDLcd(pxl_clk=VExpress_GEM5_V1_Base.dcc.osc_pxl,
                   pio_addr=0x2b000000, interrupt=ArmSPI(num=95))

    def _on_chip_devices(self):
        return super(VExpress_GEM5_V1_HDLcd,self)._on_chip_devices() + [
                self.hdlcd,
            ]

class VExpress_GEM5_V2_Base(VExpress_GEM5_Base):
    gic = Gicv3(dist_addr=0x2c000000, redist_addr=0x2c010000,
                maint_int=ArmPPI(num=25),
                its=Gicv3Its(pio_addr=0x2e010000))

    # Limiting to 128 since it will otherwise overlap with PCI space
    gic.cpu_max = 128

    def _on_chip_devices(self):
        return super(VExpress_GEM5_V2_Base,self)._on_chip_devices() + [
                self.gic, self.gic.its
            ]

    def setupBootLoader(self, cur_sys, loc, boot_loader=None):
        if boot_loader is None:
            boot_loader = [ loc('boot_v2.arm64') ]
        super(VExpress_GEM5_V2_Base, self).setupBootLoader(
                cur_sys, boot_loader)

class VExpress_GEM5_V2(VExpress_GEM5_V2_Base):
    """
    We subclass VExpress_GEM5_V2_Base in order to alias it to
    VExpress_GEM5_V2, which is what gem5 scripts are currently using
    """
    pass

class VExpress_GEM5_V2_HDLcd(VExpress_GEM5_V2_Base):
    hdlcd  = HDLcd(pxl_clk=VExpress_GEM5_V2_Base.dcc.osc_pxl,
                   pio_addr=0x2b000000, interrupt=ArmSPI(num=95))

    def _on_chip_devices(self):
        return super(VExpress_GEM5_V2_HDLcd,self)._on_chip_devices() + [
                self.hdlcd,
            ]

class VExpress_GEM5_Foundation(VExpress_GEM5_Base):
    """
    Based on Armv8-A FVP Foundation platform v11.8
    Reference for memory and interrupt map:
        Armv8-A Foundation Platform - User Guide - Version 11.8
        Document ID: 100961_1180_00_en

    We are adding PCI capabilities to the Armv8-A FVP Foundation
    Platform. We are enabling it by using the PCI memory map
    of the Armv8-A FVP Base Platform:
        Fast Models - Reference Manual - Version 11.8
        Document ID: 100964_1108_00_en
    """
    _off_chip_ranges = [
        # CS1-CS5
        AddrRange(0x0c000000, 0x20000000),
        # External AXI interface (PCI)
        AddrRange(0x40000000, 0x80000000),
        AddrRange(0x4000000000, 0x800000000),
    ]

    sp810_fake = AmbaFake(pio_addr=0x1C020000, ignore_access=True)

    clcd = Pl111(pio_addr=0x1c1f0000, interrupt=ArmSPI(num=46))

    gic = Gicv3(dist_addr=0x2f000000, redist_addr=0x2f100000,
                maint_int=ArmPPI(num=25), gicv4=False,
                its=NULL)

    pci_host = GenericArmPciHost(
        conf_base=0x40000000, conf_size='256MiB', conf_device_bits=12,
        pci_pio_base=0x50000000,
        pci_mem_base=0x4000000000,
        int_policy="ARM_PCI_INT_DEV", int_base=100, int_count=4)

    def _on_chip_devices(self):
        return super(VExpress_GEM5_Foundation, self)._on_chip_devices() + [
                self.gic
            ]

    def _off_chip_devices(self):
        return super(VExpress_GEM5_Foundation, self)._off_chip_devices() + [
                self.clcd,
                self.sp810_fake,
        ]

    def setupBootLoader(self, cur_sys, loc, boot_loader=None):
        if boot_loader is None:
            boot_loader = [ loc('boot_v2.arm64') ]
        super(VExpress_GEM5_Foundation, self).setupBootLoader(
                cur_sys, boot_loader)
