# Copyright (c) 2009-2022 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.ArmSystem import ArmExtension
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 MuxingKvmGicV2, MuxingKvmGicV3

    kvm_gicv2_class = MuxingKvmGicV2
    kvm_gicv3_class = MuxingKvmGicV3
except ImportError:
    # KVM support wasn't compiled into gem5. Fallback to a
    # software-only GIC.
    kvm_gicv2_class = Gic400
    kvm_gicv3_class = Gicv3
    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().__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().__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
        # Use 0x200000 as this is the maximum size allowed for a DTB
        cur_sys.workload.initrd_addr = cur_sys.workload.dtb_addr + 0x200000
        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_el3_phys=ArmPPI(num=29, int_type="IRQ_TYPE_LEVEL_LOW"),
        int_el1_phys=ArmPPI(num=30, int_type="IRQ_TYPE_LEVEL_LOW"),
        int_el1_virt=ArmPPI(num=27, int_type="IRQ_TYPE_LEVEL_LOW"),
        int_el2_ns_phys=ArmPPI(num=26, int_type="IRQ_TYPE_LEVEL_LOW"),
        int_el2_ns_virt=ArmPPI(num=28, int_type="IRQ_TYPE_LEVEL_LOW"),
        int_el2_s_phys=ArmPPI(num=20, int_type="IRQ_TYPE_LEVEL_LOW"),
        int_el2_s_virt=ArmPPI(num=19, 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().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:
            Armv8-A Foundation Platform - User Guide - Version 11.8
            Document ID: 100961_1180_00_en

    Memory map:
       0x00000000-0x03ffffff: Boot memory (CS0)
       0x04000000-0x07ffffff: Trusted Memory/Reserved
            0x04000000-0x0403FFFF: 256kB Trusted SRAM
            0x06000000-0x07ffffff: 32MB Trusted DRAM
       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)
            19   : generic_timer (virt sec EL2)
            20   : generic_timer (phys sec EL2)
            25   : vgic
            26   : generic_timer (phys non-sec EL2)
            27   : generic_timer (virt EL1)
            28   : generic_timer (virt non-sec EL2)
            29   : generic_timer (phys EL3)
            30   : generic_timer (phys EL1)
            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
    )
    # Trusted DRAM
    # TODO: preventing access from unsecure world to the trusted RAM
    trusted_dram = SimpleMemory(
        range=AddrRange(0x06000000, size="32MB"), 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_el3_phys=ArmPPI(num=29, int_type="IRQ_TYPE_LEVEL_LOW"),
        int_el1_phys=ArmPPI(num=30, int_type="IRQ_TYPE_LEVEL_LOW"),
        int_el1_virt=ArmPPI(num=27, int_type="IRQ_TYPE_LEVEL_LOW"),
        int_el2_ns_phys=ArmPPI(num=26, int_type="IRQ_TYPE_LEVEL_LOW"),
        int_el2_ns_virt=ArmPPI(num=28, int_type="IRQ_TYPE_LEVEL_LOW"),
        int_el2_s_phys=ArmPPI(num=20, int_type="IRQ_TYPE_LEVEL_LOW"),
        int_el2_s_virt=ArmPPI(num=19, 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.trusted_dram,
            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().__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().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().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.release.has(ArmExtension("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().setupBootLoader(cur_sys, boot_loader)

    def _on_chip_devices(self):
        return super()._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()._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),
        gicv4=True,
        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()._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().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()._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, 0x8000000000),
    ]

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

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

    gic = kvm_gicv3_class(
        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()._on_chip_devices() + [self.gic]

    def _off_chip_devices(self):
        return super()._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_foundation.arm64")]
        super().setupBootLoader(cur_sys, boot_loader)
