# 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 SysSecCtrl(BasicPioDevice):
    """
    System Security Control registers. Taken from:
        Arm Neoverse N1 System Development Platform - TRM - Version 0.0
        Document ID: 101489_0000_02_en
    """

    type = "SysSecCtrl"
    cxx_header = "dev/arm/ssc.hh"
    cxx_class = "gem5::SysSecCtrl"

    ssc_dbgcfg_stat = Param.Unsigned(
        0x00010000, "Debug authentication configuration status"
    )
    ssc_version = Param.Unsigned(0x100417B0, "Version register")
    ssc_pid0 = Param.Unsigned(0x44, "Peripheral ID0 register")
    ssc_pid1 = Param.Unsigned(0xB8, "Peripheral ID1 register")
    ssc_pid2 = Param.Unsigned(0xB, "Peripheral ID2 register")
    ssc_pid4 = Param.Unsigned(0x4, "Peripheral ID4 register")

    compid0 = Param.Unsigned(0x0D, "Component ID0 register")
    compid1 = Param.Unsigned(0xF0, "Component ID1 register")
    compid2 = Param.Unsigned(0x5, "Component ID2 register")
    compid3 = Param.Unsigned(0xB1, "Component ID3 register")


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)
