RealView.py revision 13805
12SN/A# Copyright (c) 2009-2018 ARM Limited
21762SN/A# All rights reserved.
32SN/A#
42SN/A# The license below extends only to copyright in the software and shall
52SN/A# not be construed as granting a license to any other intellectual
62SN/A# property including but not limited to intellectual property relating
72SN/A# to a hardware implementation of the functionality of the software
82SN/A# licensed hereunder.  You may use the software subject to the license
92SN/A# terms below provided that you ensure that this notice is replicated
102SN/A# unmodified and in its entirety in all distributions of the software,
112SN/A# modified or unmodified, in source code or in binary form.
122SN/A#
132SN/A# Copyright (c) 2006-2007 The Regents of The University of Michigan
142SN/A# All rights reserved.
152SN/A#
162SN/A# Redistribution and use in source and binary forms, with or without
172SN/A# modification, are permitted provided that the following conditions are
182SN/A# met: redistributions of source code must retain the above copyright
192SN/A# notice, this list of conditions and the following disclaimer;
202SN/A# redistributions in binary form must reproduce the above copyright
212SN/A# notice, this list of conditions and the following disclaimer in the
222SN/A# documentation and/or other materials provided with the distribution;
232SN/A# neither the name of the copyright holders nor the names of its
242SN/A# contributors may be used to endorse or promote products derived from
252SN/A# this software without specific prior written permission.
262SN/A#
272665Ssaidi@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
282665Ssaidi@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
292665Ssaidi@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
302665Ssaidi@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
312665Ssaidi@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
322SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
332SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
342SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
352SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
363506Ssaidi@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
373506Ssaidi@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
382SN/A#
392973Sgblack@eecs.umich.edu# Authors: Ali Saidi
403584Ssaidi@eecs.umich.edu#          Gabe Black
4156SN/A#          William Wang
423614Sgblack@eecs.umich.edu#          Glenn Bergmans
431717SN/A
442518SN/Afrom m5.defines import buildEnv
4556SN/Afrom m5.params import *
462518SN/Afrom m5.proxy import *
472518SN/Afrom m5.util.fdthelper import *
482SN/Afrom m5.objects.ClockDomain import ClockDomain
493614Sgblack@eecs.umich.edufrom m5.objects.VoltageDomain import VoltageDomain
503614Sgblack@eecs.umich.edufrom m5.objects.Device import \
513614Sgblack@eecs.umich.edu    BasicPioDevice, PioDevice, IsaFake, BadAddr, DmaDevice
523614Sgblack@eecs.umich.edufrom m5.objects.PciHost import *
533065Sgblack@eecs.umich.edufrom m5.objects.Ethernet import NSGigE, IGbE_igb, IGbE_e1000
543065Sgblack@eecs.umich.edufrom m5.objects.Ide import *
553506Ssaidi@eecs.umich.edufrom m5.objects.Platform import Platform
563065Sgblack@eecs.umich.edufrom m5.objects.Terminal import Terminal
572SN/Afrom m5.objects.Uart import Uart
582973Sgblack@eecs.umich.edufrom m5.objects.SimpleMemory import SimpleMemory
592SN/Afrom m5.objects.Gic import *
603840Shsul@eecs.umich.edufrom m5.objects.EnergyCtrl import EnergyCtrl
613825Ssaidi@eecs.umich.edufrom m5.objects.ClockedObject import ClockedObject
623903Ssaidi@eecs.umich.edufrom m5.objects.ClockDomain import SrcClockDomain
633840Shsul@eecs.umich.edufrom m5.objects.SubSystem import SubSystem
643825Ssaidi@eecs.umich.edufrom m5.objects.Graphics import ImageFormat
653506Ssaidi@eecs.umich.edufrom m5.objects.ClockedObject import ClockedObject
663506Ssaidi@eecs.umich.edufrom m5.objects.PS2 import *
673506Ssaidi@eecs.umich.edufrom m5.objects.VirtIOMMIO import MmioVirtIO
683506Ssaidi@eecs.umich.edu
692SN/A# Platforms with KVM support should generally use in-kernel GIC
702SN/A# emulation. Use a GIC model that automatically switches between
712SN/A# gem5's GIC model and KVM's GIC model if KVM is available.
722SN/Atry:
732SN/A    from m5.objects.KvmGic import MuxingKvmGic
743748Sgblack@eecs.umich.edu    kvm_gicv2_class = MuxingKvmGic
753748Sgblack@eecs.umich.eduexcept ImportError:
763748Sgblack@eecs.umich.edu    # KVM support wasn't compiled into gem5. Fallback to a
773748Sgblack@eecs.umich.edu    # software-only GIC.
783748Sgblack@eecs.umich.edu    kvm_gicv2_class = Gic400
793748Sgblack@eecs.umich.edu    pass
803748Sgblack@eecs.umich.edu
813748Sgblack@eecs.umich.educlass AmbaPioDevice(BasicPioDevice):
823748Sgblack@eecs.umich.edu    type = 'AmbaPioDevice'
833748Sgblack@eecs.umich.edu    abstract = True
843748Sgblack@eecs.umich.edu    cxx_header = "dev/arm/amba_device.hh"
853748Sgblack@eecs.umich.edu    amba_id = Param.UInt32("ID of AMBA device for kernel detection")
863748Sgblack@eecs.umich.edu
873748Sgblack@eecs.umich.educlass AmbaIntDevice(AmbaPioDevice):
883748Sgblack@eecs.umich.edu    type = 'AmbaIntDevice'
893748Sgblack@eecs.umich.edu    abstract = True
903748Sgblack@eecs.umich.edu    cxx_header = "dev/arm/amba_device.hh"
913748Sgblack@eecs.umich.edu    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
923748Sgblack@eecs.umich.edu    int_num = Param.UInt32("Interrupt number that connects to GIC")
933748Sgblack@eecs.umich.edu    int_delay = Param.Latency("100ns",
943748Sgblack@eecs.umich.edu            "Time between action and interrupt generation by device")
953748Sgblack@eecs.umich.edu
963748Sgblack@eecs.umich.educlass AmbaDmaDevice(DmaDevice):
973748Sgblack@eecs.umich.edu    type = 'AmbaDmaDevice'
983748Sgblack@eecs.umich.edu    abstract = True
993748Sgblack@eecs.umich.edu    cxx_header = "dev/arm/amba_device.hh"
1003748Sgblack@eecs.umich.edu    pio_addr = Param.Addr("Address for AMBA slave interface")
1013748Sgblack@eecs.umich.edu    pio_latency = Param.Latency("10ns", "Time between action and write/read result by AMBA DMA Device")
1023748Sgblack@eecs.umich.edu    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
1033748Sgblack@eecs.umich.edu    int_num = Param.UInt32("Interrupt number that connects to GIC")
1043748Sgblack@eecs.umich.edu    amba_id = Param.UInt32("ID of AMBA device for kernel detection")
1053748Sgblack@eecs.umich.edu
1063748Sgblack@eecs.umich.educlass A9SCU(BasicPioDevice):
1073748Sgblack@eecs.umich.edu    type = 'A9SCU'
1083748Sgblack@eecs.umich.edu    cxx_header = "dev/arm/a9scu.hh"
1093748Sgblack@eecs.umich.edu
1103748Sgblack@eecs.umich.educlass ArmPciIntRouting(Enum): vals = [
1113748Sgblack@eecs.umich.edu    'ARM_PCI_INT_STATIC',
1123748Sgblack@eecs.umich.edu    'ARM_PCI_INT_DEV',
1133748Sgblack@eecs.umich.edu    'ARM_PCI_INT_PIN',
1143748Sgblack@eecs.umich.edu    ]
1153748Sgblack@eecs.umich.edu
1163748Sgblack@eecs.umich.educlass GenericArmPciHost(GenericPciHost):
1173748Sgblack@eecs.umich.edu    type = 'GenericArmPciHost'
1183748Sgblack@eecs.umich.edu    cxx_header = "dev/arm/pci_host.hh"
1193748Sgblack@eecs.umich.edu
1203748Sgblack@eecs.umich.edu    int_policy = Param.ArmPciIntRouting("PCI interrupt routing policy")
1213748Sgblack@eecs.umich.edu    int_base = Param.Unsigned("PCI interrupt base")
1223748Sgblack@eecs.umich.edu    int_count = Param.Unsigned("Maximum number of interrupts used by this host")
1233748Sgblack@eecs.umich.edu
1242SN/A    # This python parameter can be used in configuration scripts to turn
1252SN/A    # on/off the fdt dma-coherent flag when doing dtb autogeneration
1262SN/A    _dma_coherent = True
1272SN/A
1283903Ssaidi@eecs.umich.edu    def generateDeviceTree(self, state):
1292973Sgblack@eecs.umich.edu        local_state = FdtState(addr_cells=3, size_cells=2, cpu_cells=1)
1302973Sgblack@eecs.umich.edu        intterrupt_cells = 1
1313065Sgblack@eecs.umich.edu
1323380Sgblack@eecs.umich.edu        node = FdtNode("pci")
1333380Sgblack@eecs.umich.edu
1343380Sgblack@eecs.umich.edu        if int(self.conf_device_bits) == 8:
1353380Sgblack@eecs.umich.edu            node.appendCompatible("pci-host-cam-generic")
1363380Sgblack@eecs.umich.edu        elif int(self.conf_device_bits) == 12:
1373380Sgblack@eecs.umich.edu            node.appendCompatible("pci-host-ecam-generic")
1383380Sgblack@eecs.umich.edu        else:
1393380Sgblack@eecs.umich.edu            m5.fatal("No compatibility string for the set conf_device_width")
1403380Sgblack@eecs.umich.edu
1413380Sgblack@eecs.umich.edu        node.append(FdtPropertyStrings("device_type", ["pci"]))
1423380Sgblack@eecs.umich.edu
1433380Sgblack@eecs.umich.edu        # Cell sizes of child nodes/peripherals
1443380Sgblack@eecs.umich.edu        node.append(local_state.addrCellsProperty())
1453380Sgblack@eecs.umich.edu        node.append(local_state.sizeCellsProperty())
1463065Sgblack@eecs.umich.edu        node.append(FdtPropertyWords("#interrupt-cells", intterrupt_cells))
1473588Sgblack@eecs.umich.edu        # PCI address for CPU
1483588Sgblack@eecs.umich.edu        node.append(FdtPropertyWords("reg",
1493588Sgblack@eecs.umich.edu            state.addrCells(self.conf_base) +
1503790Sgblack@eecs.umich.edu            state.sizeCells(self.conf_size) ))
1513790Sgblack@eecs.umich.edu
1523380Sgblack@eecs.umich.edu        # Ranges mapping
1533059Sgblack@eecs.umich.edu        # For now some of this is hard coded, because the PCI module does not
1543588Sgblack@eecs.umich.edu        # have a proper full understanding of the memory map, but adapting the
1553380Sgblack@eecs.umich.edu        # PCI module is beyond the scope of what I'm trying to do here.
1563380Sgblack@eecs.umich.edu        # Values are taken from the VExpress_GEM5_V1 platform.
1573790Sgblack@eecs.umich.edu        ranges = []
1583790Sgblack@eecs.umich.edu        # Pio address range
1593380Sgblack@eecs.umich.edu        ranges += self.pciFdtAddr(space=1, addr=0)
1603380Sgblack@eecs.umich.edu        ranges += state.addrCells(self.pci_pio_base)
1613588Sgblack@eecs.umich.edu        ranges += local_state.sizeCells(0x10000)  # Fixed size
1623380Sgblack@eecs.umich.edu
1633380Sgblack@eecs.umich.edu        # AXI memory address range
1643380Sgblack@eecs.umich.edu        ranges += self.pciFdtAddr(space=2, addr=0)
1653380Sgblack@eecs.umich.edu        ranges += state.addrCells(0x40000000) # Fixed offset
1663380Sgblack@eecs.umich.edu        ranges += local_state.sizeCells(0x40000000) # Fixed size
1673059Sgblack@eecs.umich.edu        node.append(FdtPropertyWords("ranges", ranges))
1683380Sgblack@eecs.umich.edu
1693380Sgblack@eecs.umich.edu        if str(self.int_policy) == 'ARM_PCI_INT_DEV':
1703380Sgblack@eecs.umich.edu            int_phandle = state.phandle(self._parent.unproxy(self).gic)
1713380Sgblack@eecs.umich.edu            # Interrupt mapping
1723588Sgblack@eecs.umich.edu            interrupts = []
1733380Sgblack@eecs.umich.edu            for i in range(int(self.int_count)):
1743380Sgblack@eecs.umich.edu                interrupts += self.pciFdtAddr(device=i, addr=0) + \
1753059Sgblack@eecs.umich.edu                    [0x0, int_phandle, 0, int(self.int_base) - 32 + i, 1]
1763059Sgblack@eecs.umich.edu
1773380Sgblack@eecs.umich.edu            node.append(FdtPropertyWords("interrupt-map", interrupts))
1783380Sgblack@eecs.umich.edu
1793380Sgblack@eecs.umich.edu            int_count = int(self.int_count)
1803380Sgblack@eecs.umich.edu            if int_count & (int_count - 1):
1813380Sgblack@eecs.umich.edu                fatal("PCI interrupt count should be power of 2")
1823588Sgblack@eecs.umich.edu
1833380Sgblack@eecs.umich.edu            intmask = self.pciFdtAddr(device=int_count - 1, addr=0) + [0x0]
1843380Sgblack@eecs.umich.edu            node.append(FdtPropertyWords("interrupt-map-mask", intmask))
1853380Sgblack@eecs.umich.edu        else:
1863588Sgblack@eecs.umich.edu            m5.fatal("Unsupported PCI interrupt policy " +
1873059Sgblack@eecs.umich.edu                     "for Device Tree generation")
1883065Sgblack@eecs.umich.edu
1892973Sgblack@eecs.umich.edu        if self._dma_coherent:
1902973Sgblack@eecs.umich.edu            node.append(FdtProperty("dma-coherent"))
1911968SN/A
1923064Sgblack@eecs.umich.edu        yield node
1931968SN/A
1941968SN/Aclass RealViewCtrl(BasicPioDevice):
1951968SN/A    type = 'RealViewCtrl'
1961968SN/A    cxx_header = "dev/arm/rv_ctrl.hh"
1971967SN/A    proc_id0 = Param.UInt32(0x0C000000, "Processor ID, SYS_PROCID")
1981967SN/A    proc_id1 = Param.UInt32(0x0C000222, "Processor ID, SYS_PROCID1")
1991967SN/A    idreg = Param.UInt32(0x00000000, "ID Register, SYS_ID")
2001967SN/A
2011967SN/A    def generateDeviceTree(self, state):
2021967SN/A        node = FdtNode("sysreg@%x" % long(self.pio_addr))
2031967SN/A        node.appendCompatible("arm,vexpress-sysreg")
2041967SN/A        node.append(FdtPropertyWords("reg",
2051967SN/A            state.addrCells(self.pio_addr) +
2061967SN/A            state.sizeCells(0x1000) ))
2071904SN/A        node.append(FdtProperty("gpio-controller"))
2081904SN/A        node.append(FdtPropertyWords("#gpio-cells", [2]))
2091904SN/A        node.appendPhandle(self)
2101904SN/A
211452SN/A        yield node
2123064Sgblack@eecs.umich.edu
2132SN/Aclass RealViewOsc(ClockDomain):
2141904SN/A    type = 'RealViewOsc'
2151904SN/A    cxx_header = "dev/arm/rv_ctrl.hh"
2162SN/A
2171904SN/A    parent = Param.RealViewCtrl(Parent.any, "RealView controller")
2183064Sgblack@eecs.umich.edu
2192SN/A    # TODO: We currently don't have the notion of a clock source,
2202SN/A    # which means we have to associate oscillators with a voltage
2211904SN/A    # source.
2221904SN/A    voltage_domain = Param.VoltageDomain(Parent.voltage_domain,
2231904SN/A                                         "Voltage domain")
2242299SN/A
2252299SN/A    # See ARM DUI 0447J (ARM Motherboard Express uATX -- V2M-P1) and
2261904SN/A    # the individual core/logic tile reference manuals for details
2271904SN/A    # about the site/position/dcc/device allocation.
2281904SN/A    site = Param.UInt8("Board Site")
2291904SN/A    position = Param.UInt8("Position in device stack")
2301904SN/A    dcc = Param.UInt8("Daughterboard Configuration Controller")
2311904SN/A    device = Param.UInt8("Device ID")
2321904SN/A
233452SN/A    freq = Param.Clock("Default frequency")
2341904SN/A
2351904SN/A    def generateDeviceTree(self, state):
2361904SN/A        phandle = state.phandle(self)
2372SN/A        node = FdtNode("osc@" + format(long(phandle), 'x'))
2382SN/A        node.appendCompatible("arm,vexpress-osc")
2391904SN/A        node.append(FdtPropertyWords("arm,vexpress-sysreg,func",
2401904SN/A                                     [0x1, int(self.device)]))
2411904SN/A        node.append(FdtPropertyWords("#clock-cells", [0]))
2421904SN/A        freq = int(1.0/self.freq.value) # Values are stored as a clock period
2431904SN/A        node.append(FdtPropertyWords("freq-range", [freq, freq]))
2441904SN/A        node.append(FdtPropertyStrings("clock-output-names",
2452SN/A                                       ["oscclk" + str(phandle)]))
2461904SN/A        node.appendPhandle(self)
2472SN/A        yield node
2482SN/A
2491904SN/Aclass RealViewTemperatureSensor(SimObject):
2502SN/A    type = 'RealViewTemperatureSensor'
2511904SN/A    cxx_header = "dev/arm/rv_ctrl.hh"
2521904SN/A
2531904SN/A    parent = Param.RealViewCtrl(Parent.any, "RealView controller")
2541904SN/A
2551904SN/A    system = Param.System(Parent.any, "system")
2561904SN/A
2571904SN/A    # See ARM DUI 0447J (ARM Motherboard Express uATX -- V2M-P1) and
2581904SN/A    # the individual core/logic tile reference manuals for details
2591904SN/A    # about the site/position/dcc/device allocation.
2601904SN/A    site = Param.UInt8("Board Site")
2611904SN/A    position = Param.UInt8("Position in device stack")
2621904SN/A    dcc = Param.UInt8("Daughterboard Configuration Controller")
2631904SN/A    device = Param.UInt8("Device ID")
2641904SN/A
2651904SN/Aclass VExpressMCC(SubSystem):
2661904SN/A    """ARM V2M-P1 Motherboard Configuration Controller
2671904SN/A
2681904SN/AThis subsystem describes a subset of the devices that sit behind the
2691904SN/Amotherboard configuration controller on the the ARM Motherboard
2701904SN/AExpress (V2M-P1) motherboard. See ARM DUI 0447J for details.
2712525SN/A    """
2721904SN/A
2732525SN/A    class Osc(RealViewOsc):
2742525SN/A        site, position, dcc = (0, 0, 0)
2752525SN/A
2761904SN/A    class Temperature(RealViewTemperatureSensor):
2771904SN/A        site, position, dcc = (0, 0, 0)
2781904SN/A
2791904SN/A    osc_mcc = Osc(device=0, freq="50MHz")
2801904SN/A    osc_clcd = Osc(device=1, freq="23.75MHz")
2811904SN/A    osc_peripheral = Osc(device=2, freq="24MHz")
2821904SN/A    osc_system_bus = Osc(device=4, freq="24MHz")
2831904SN/A
2841967SN/A    # See Table 4.19 in ARM DUI 0447J (Motherboard Express uATX TRM).
2851967SN/A    temp_crtl = Temperature(device=0)
2861967SN/A
2871967SN/A    def generateDeviceTree(self, state):
2881967SN/A        node = FdtNode("mcc")
2892SN/A        node.appendCompatible("arm,vexpress,config-bus")
2903817Ssaidi@eecs.umich.edu        node.append(FdtPropertyWords("arm,vexpress,site", [0]))
2913506Ssaidi@eecs.umich.edu
2923506Ssaidi@eecs.umich.edu        for obj in self._children.values():
2933506Ssaidi@eecs.umich.edu            if issubclass(type(obj), SimObject):
2943506Ssaidi@eecs.umich.edu                node.append(obj.generateDeviceTree(state))
2953506Ssaidi@eecs.umich.edu
2963814Ssaidi@eecs.umich.edu        io_phandle = state.phandle(self.osc_mcc.parent.unproxy(self))
2973506Ssaidi@eecs.umich.edu        node.append(FdtPropertyWords("arm,vexpress,config-bridge", io_phandle))
2983931Ssaidi@eecs.umich.edu
2993931Ssaidi@eecs.umich.edu        yield node
3003748Sgblack@eecs.umich.edu
3013748Sgblack@eecs.umich.educlass CoreTile2A15DCC(SubSystem):
3023748Sgblack@eecs.umich.edu    """ARM CoreTile Express A15x2 Daughterboard Configuration Controller
3033748Sgblack@eecs.umich.edu
3043748Sgblack@eecs.umich.eduThis subsystem describes a subset of the devices that sit behind the
3053748Sgblack@eecs.umich.edudaughterboard configuration controller on a CoreTile Express A15x2. See
3063748Sgblack@eecs.umich.eduARM DUI 0604E for details.
3073748Sgblack@eecs.umich.edu    """
3083748Sgblack@eecs.umich.edu
3093748Sgblack@eecs.umich.edu    class Osc(RealViewOsc):
3104001Ssaidi@eecs.umich.edu        site, position, dcc = (1, 0, 0)
3113748Sgblack@eecs.umich.edu
3123748Sgblack@eecs.umich.edu    # See Table 2.8 in ARM DUI 0604E (CoreTile Express A15x2 TRM)
3133748Sgblack@eecs.umich.edu    osc_cpu = Osc(device=0, freq="60MHz")
3143748Sgblack@eecs.umich.edu    osc_hsbm = Osc(device=4, freq="40MHz")
3153748Sgblack@eecs.umich.edu    osc_pxl = Osc(device=5, freq="23.75MHz")
3163748Sgblack@eecs.umich.edu    osc_smb = Osc(device=6, freq="50MHz")
3173748Sgblack@eecs.umich.edu    osc_sys = Osc(device=7, freq="60MHz")
3183748Sgblack@eecs.umich.edu    osc_ddr = Osc(device=8, freq="40MHz")
3193748Sgblack@eecs.umich.edu
3203748Sgblack@eecs.umich.edu    def generateDeviceTree(self, state):
3213880Ssaidi@eecs.umich.edu        node = FdtNode("dcc")
3223603Ssaidi@eecs.umich.edu        node.appendCompatible("arm,vexpress,config-bus")
3233603Ssaidi@eecs.umich.edu
3243903Ssaidi@eecs.umich.edu        for obj in self._children.values():
3253903Ssaidi@eecs.umich.edu            if isinstance(obj, SimObject):
3263903Ssaidi@eecs.umich.edu                node.append(obj.generateDeviceTree(state))
3273903Ssaidi@eecs.umich.edu
3283903Ssaidi@eecs.umich.edu        io_phandle = state.phandle(self.osc_cpu.parent.unproxy(self))
3293903Ssaidi@eecs.umich.edu        node.append(FdtPropertyWords("arm,vexpress,config-bridge", io_phandle))
3303903Ssaidi@eecs.umich.edu
3313903Ssaidi@eecs.umich.edu        yield node
3323903Ssaidi@eecs.umich.edu
3333903Ssaidi@eecs.umich.educlass AmbaFake(AmbaPioDevice):
3343903Ssaidi@eecs.umich.edu    type = 'AmbaFake'
3353903Ssaidi@eecs.umich.edu    cxx_header = "dev/arm/amba_fake.hh"
3363903Ssaidi@eecs.umich.edu    ignore_access = Param.Bool(False, "Ignore reads/writes to this device, (e.g. IsaFake + AMBA)")
3373903Ssaidi@eecs.umich.edu    amba_id = 0;
3383903Ssaidi@eecs.umich.edu
3393903Ssaidi@eecs.umich.educlass Pl011(Uart):
3403903Ssaidi@eecs.umich.edu    type = 'Pl011'
3413903Ssaidi@eecs.umich.edu    cxx_header = "dev/arm/pl011.hh"
3423506Ssaidi@eecs.umich.edu    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
3433584Ssaidi@eecs.umich.edu    int_num = Param.UInt32("Interrupt number that connects to GIC")
3443584Ssaidi@eecs.umich.edu    end_on_eot = Param.Bool(False, "End the simulation when a EOT is received on the UART")
3453584Ssaidi@eecs.umich.edu    int_delay = Param.Latency("100ns", "Time between action and interrupt generation by UART")
3463748Sgblack@eecs.umich.edu
3473928Ssaidi@eecs.umich.edu    def generateDeviceTree(self, state):
3483928Ssaidi@eecs.umich.edu        node = self.generateBasicPioDeviceNode(state, 'uart', self.pio_addr,
3493928Ssaidi@eecs.umich.edu                                               0x1000, [int(self.int_num)])
3503748Sgblack@eecs.umich.edu        node.appendCompatible(["arm,pl011", "arm,primecell"])
3513603Ssaidi@eecs.umich.edu
3523584Ssaidi@eecs.umich.edu        # Hardcoded reference to the realview platform clocks, because the
3533814Ssaidi@eecs.umich.edu        # clk_domain can only store one clock (i.e. it is not a VectorParam)
3543814Ssaidi@eecs.umich.edu        realview = self._parent.unproxy(self)
3553814Ssaidi@eecs.umich.edu        node.append(FdtPropertyWords("clocks",
3563814Ssaidi@eecs.umich.edu            [state.phandle(realview.mcc.osc_peripheral),
3573814Ssaidi@eecs.umich.edu            state.phandle(realview.dcc.osc_smb)]))
3583743Sgblack@eecs.umich.edu        node.append(FdtPropertyStrings("clock-names", ["uartclk", "apb_pclk"]))
3593743Sgblack@eecs.umich.edu        yield node
3603584Ssaidi@eecs.umich.edu
3613743Sgblack@eecs.umich.educlass Sp804(AmbaPioDevice):
3623989Ssaidi@eecs.umich.edu    type = 'Sp804'
3633989Ssaidi@eecs.umich.edu    cxx_header = "dev/arm/timer_sp804.hh"
3643603Ssaidi@eecs.umich.edu    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
3653931Ssaidi@eecs.umich.edu    int_num0 = Param.UInt32("Interrupt number that connects to GIC")
3663603Ssaidi@eecs.umich.edu    clock0 = Param.Clock('1MHz', "Clock speed of the input")
3673584Ssaidi@eecs.umich.edu    int_num1 = Param.UInt32("Interrupt number that connects to GIC")
3683931Ssaidi@eecs.umich.edu    clock1 = Param.Clock('1MHz', "Clock speed of the input")
3693945Ssaidi@eecs.umich.edu    amba_id = 0x00141804
3703931Ssaidi@eecs.umich.edu
3713931Ssaidi@eecs.umich.educlass A9GlobalTimer(BasicPioDevice):
3723931Ssaidi@eecs.umich.edu    type = 'A9GlobalTimer'
3733931Ssaidi@eecs.umich.edu    cxx_header = "dev/arm/timer_a9global.hh"
3743748Sgblack@eecs.umich.edu    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
3753748Sgblack@eecs.umich.edu    int_num = Param.UInt32("Interrrupt number that connects to GIC")
3763748Sgblack@eecs.umich.edu
3773748Sgblack@eecs.umich.educlass CpuLocalTimer(BasicPioDevice):
3783748Sgblack@eecs.umich.edu    type = 'CpuLocalTimer'
3793815Ssaidi@eecs.umich.edu    cxx_header = "dev/arm/timer_cpulocal.hh"
3803748Sgblack@eecs.umich.edu    int_timer = Param.ArmPPI("Interrrupt used per-cpu to GIC")
3813748Sgblack@eecs.umich.edu    int_watchdog = Param.ArmPPI("Interrupt for per-cpu watchdog to GIC")
3823815Ssaidi@eecs.umich.edu
3833748Sgblack@eecs.umich.educlass GenericTimer(ClockedObject):
3843748Sgblack@eecs.umich.edu    type = 'GenericTimer'
3853815Ssaidi@eecs.umich.edu    cxx_header = "dev/arm/generic_timer.hh"
3863748Sgblack@eecs.umich.edu    system = Param.ArmSystem(Parent.any, "system")
3873748Sgblack@eecs.umich.edu    int_phys_s = Param.ArmPPI("Physical (S) timer interrupt")
3883815Ssaidi@eecs.umich.edu    int_phys_ns = Param.ArmPPI("Physical (NS) timer interrupt")
3893748Sgblack@eecs.umich.edu    int_virt = Param.ArmPPI("Virtual timer interrupt")
3903748Sgblack@eecs.umich.edu    int_hyp = Param.ArmPPI("Hypervisor timer interrupt")
3913815Ssaidi@eecs.umich.edu
3923748Sgblack@eecs.umich.edu    def generateDeviceTree(self, state):
3933748Sgblack@eecs.umich.edu        node = FdtNode("timer")
3943748Sgblack@eecs.umich.edu
3953584Ssaidi@eecs.umich.edu        node.appendCompatible(["arm,cortex-a15-timer",
3963748Sgblack@eecs.umich.edu                               "arm,armv7-timer",
3973748Sgblack@eecs.umich.edu                               "arm,armv8-timer"])
3983748Sgblack@eecs.umich.edu        node.append(FdtPropertyWords("interrupts", [
3993748Sgblack@eecs.umich.edu            1, int(self.int_phys_s.num) - 16, 0xf08,
4003748Sgblack@eecs.umich.edu            1, int(self.int_phys_ns.num) - 16, 0xf08,
4013748Sgblack@eecs.umich.edu            1, int(self.int_virt.num) - 16, 0xf08,
4023748Sgblack@eecs.umich.edu            1, int(self.int_hyp.num) - 16, 0xf08,
4033748Sgblack@eecs.umich.edu        ]))
4043748Sgblack@eecs.umich.edu        clock = state.phandle(self.clk_domain.unproxy(self))
4053748Sgblack@eecs.umich.edu        node.append(FdtPropertyWords("clocks", clock))
4063748Sgblack@eecs.umich.edu
4073748Sgblack@eecs.umich.edu        yield node
4083748Sgblack@eecs.umich.edu
4093748Sgblack@eecs.umich.educlass GenericTimerMem(PioDevice):
4103790Sgblack@eecs.umich.edu    type = 'GenericTimerMem'
4113790Sgblack@eecs.umich.edu    cxx_header = "dev/arm/generic_timer.hh"
4123790Sgblack@eecs.umich.edu
4133748Sgblack@eecs.umich.edu    base = Param.Addr(0, "Base address")
4144001Ssaidi@eecs.umich.edu
4154001Ssaidi@eecs.umich.edu    int_phys = Param.ArmSPI("Physical Interrupt")
4163790Sgblack@eecs.umich.edu    int_virt = Param.ArmSPI("Virtual Interrupt")
4173790Sgblack@eecs.umich.edu
4183790Sgblack@eecs.umich.educlass PL031(AmbaIntDevice):
4193748Sgblack@eecs.umich.edu    type = 'PL031'
4203748Sgblack@eecs.umich.edu    cxx_header = "dev/arm/rtc_pl031.hh"
4213748Sgblack@eecs.umich.edu    time = Param.Time('01/01/2009', "System time to use ('Now' for actual time)")
4223748Sgblack@eecs.umich.edu    amba_id = 0x00341031
4233748Sgblack@eecs.umich.edu
4243748Sgblack@eecs.umich.edu    def generateDeviceTree(self, state):
4253748Sgblack@eecs.umich.edu        node = self.generateBasicPioDeviceNode(state, 'rtc', self.pio_addr,
4263748Sgblack@eecs.umich.edu                                               0x1000, [int(self.int_num)])
4273748Sgblack@eecs.umich.edu
4283790Sgblack@eecs.umich.edu        node.appendCompatible(["arm,pl031", "arm,primecell"])
4293790Sgblack@eecs.umich.edu        clock = state.phandle(self.clk_domain.unproxy(self))
4303790Sgblack@eecs.umich.edu        node.append(FdtPropertyWords("clocks", clock))
4313748Sgblack@eecs.umich.edu
4323790Sgblack@eecs.umich.edu        yield node
4333790Sgblack@eecs.umich.edu
4343748Sgblack@eecs.umich.educlass Pl050(AmbaIntDevice):
4353989Ssaidi@eecs.umich.edu    type = 'Pl050'
4363748Sgblack@eecs.umich.edu    cxx_header = "dev/arm/kmi.hh"
4373790Sgblack@eecs.umich.edu    amba_id = 0x00141050
4383790Sgblack@eecs.umich.edu
4393989Ssaidi@eecs.umich.edu    ps2 = Param.PS2Device("PS/2 device")
4403748Sgblack@eecs.umich.edu
4413790Sgblack@eecs.umich.edu    def generateDeviceTree(self, state):
4423790Sgblack@eecs.umich.edu        node = self.generateBasicPioDeviceNode(state, 'kmi', self.pio_addr,
4433989Ssaidi@eecs.umich.edu                                               0x1000, [int(self.int_num)])
4443748Sgblack@eecs.umich.edu
4453748Sgblack@eecs.umich.edu        node.appendCompatible(["arm,pl050", "arm,primecell"])
4463880Ssaidi@eecs.umich.edu        clock = state.phandle(self.clk_domain.unproxy(self))
4473880Ssaidi@eecs.umich.edu        node.append(FdtPropertyWords("clocks", clock))
4483880Ssaidi@eecs.umich.edu
4493880Ssaidi@eecs.umich.edu        yield node
4503880Ssaidi@eecs.umich.edu
4513880Ssaidi@eecs.umich.educlass Pl111(AmbaDmaDevice):
4523880Ssaidi@eecs.umich.edu    type = 'Pl111'
4534008Ssaidi@eecs.umich.edu    cxx_header = "dev/arm/pl111.hh"
4543931Ssaidi@eecs.umich.edu    pixel_clock = Param.Clock('24MHz', "Pixel clock")
4553931Ssaidi@eecs.umich.edu    vnc   = Param.VncInput(Parent.any, "Vnc server for remote frame buffer display")
4564001Ssaidi@eecs.umich.edu    amba_id = 0x00141111
4574001Ssaidi@eecs.umich.edu    enable_capture = Param.Bool(True, "capture frame to system.framebuffer.bmp")
4583931Ssaidi@eecs.umich.edu
4594008Ssaidi@eecs.umich.educlass HDLcd(AmbaDmaDevice):
4603863Ssaidi@eecs.umich.edu    type = 'HDLcd'
4613584Ssaidi@eecs.umich.edu    cxx_header = "dev/arm/hdlcd.hh"
4623584Ssaidi@eecs.umich.edu    vnc = Param.VncInput(Parent.any, "Vnc server for remote frame buffer "
4633584Ssaidi@eecs.umich.edu                                     "display")
4643814Ssaidi@eecs.umich.edu    amba_id = 0x00141000
4653814Ssaidi@eecs.umich.edu    workaround_swap_rb = Param.Bool(False, "Workaround incorrect color "
4663584Ssaidi@eecs.umich.edu                                    "selector order in some kernels")
4673584Ssaidi@eecs.umich.edu    workaround_dma_line_count = Param.Bool(True, "Workaround incorrect "
4683931Ssaidi@eecs.umich.edu                                           "DMA line count (off by 1)")
4693584Ssaidi@eecs.umich.edu    enable_capture = Param.Bool(True, "capture frame to "
4703931Ssaidi@eecs.umich.edu                                      "system.framebuffer.{extension}")
4713931Ssaidi@eecs.umich.edu    frame_format = Param.ImageFormat("Auto",
4723748Sgblack@eecs.umich.edu                                     "image format of the captured frame")
4733748Sgblack@eecs.umich.edu
4743748Sgblack@eecs.umich.edu    pixel_buffer_size = Param.MemorySize32("2kB", "Size of address range")
4753748Sgblack@eecs.umich.edu
4763748Sgblack@eecs.umich.edu    pxl_clk = Param.ClockDomain("Pixel clock source")
4773748Sgblack@eecs.umich.edu    pixel_chunk = Param.Unsigned(32, "Number of pixels to handle in one batch")
4783748Sgblack@eecs.umich.edu    virt_refresh_rate = Param.Frequency("20Hz", "Frame refresh rate "
4793748Sgblack@eecs.umich.edu                                        "in KVM mode")
4803748Sgblack@eecs.umich.edu
4813748Sgblack@eecs.umich.edu    def generateDeviceTree(self, state):
4823748Sgblack@eecs.umich.edu        # Interrupt number is hardcoded; it is not a property of this class
4833748Sgblack@eecs.umich.edu        node = self.generateBasicPioDeviceNode(state, 'hdlcd',
4843748Sgblack@eecs.umich.edu                                               self.pio_addr, 0x1000, [63])
4853748Sgblack@eecs.umich.edu
4863748Sgblack@eecs.umich.edu        node.appendCompatible(["arm,hdlcd"])
4873748Sgblack@eecs.umich.edu        node.append(FdtPropertyWords("clocks", state.phandle(self.pxl_clk)))
4883748Sgblack@eecs.umich.edu        node.append(FdtPropertyStrings("clock-names", ["pxlclk"]))
4893748Sgblack@eecs.umich.edu
4904001Ssaidi@eecs.umich.edu        # This driver is disabled by default since the required DT nodes
4914001Ssaidi@eecs.umich.edu        # haven't been standardized yet. To use it,  override this status to
4923748Sgblack@eecs.umich.edu        # "ok" and add the display configuration nodes required by the driver.
4933748Sgblack@eecs.umich.edu        # See the driver for more information.
4943748Sgblack@eecs.umich.edu        node.append(FdtPropertyStrings("status", ["disabled"]))
4953748Sgblack@eecs.umich.edu
4963748Sgblack@eecs.umich.edu        yield node
4973748Sgblack@eecs.umich.edu
4983748Sgblack@eecs.umich.educlass RealView(Platform):
4993748Sgblack@eecs.umich.edu    type = 'RealView'
5003748Sgblack@eecs.umich.edu    cxx_header = "dev/arm/realview.hh"
5013748Sgblack@eecs.umich.edu    system = Param.System(Parent.any, "system")
5023748Sgblack@eecs.umich.edu    _mem_regions = [ AddrRange(0, size='256MB') ]
5033748Sgblack@eecs.umich.edu
5043748Sgblack@eecs.umich.edu    def _on_chip_devices(self):
5053748Sgblack@eecs.umich.edu        return []
5063748Sgblack@eecs.umich.edu
5073748Sgblack@eecs.umich.edu    def _off_chip_devices(self):
5083748Sgblack@eecs.umich.edu        return []
5093748Sgblack@eecs.umich.edu
5103748Sgblack@eecs.umich.edu    _off_chip_ranges = []
5113748Sgblack@eecs.umich.edu
5123880Ssaidi@eecs.umich.edu    def _attach_device(self, device, bus, dma_ports=None):
5133880Ssaidi@eecs.umich.edu        if hasattr(device, "pio"):
5143603Ssaidi@eecs.umich.edu            device.pio = bus.master
5153584Ssaidi@eecs.umich.edu        if hasattr(device, "dma"):
5163603Ssaidi@eecs.umich.edu            if dma_ports is None:
5173584Ssaidi@eecs.umich.edu                device.dma = bus.slave
5183603Ssaidi@eecs.umich.edu            else:
5193584Ssaidi@eecs.umich.edu                dma_ports.append(device.dma)
5203584Ssaidi@eecs.umich.edu
5213603Ssaidi@eecs.umich.edu    def _attach_io(self, devices, *args, **kwargs):
5223584Ssaidi@eecs.umich.edu        for d in devices:
5233814Ssaidi@eecs.umich.edu            self._attach_device(d, *args, **kwargs)
5243814Ssaidi@eecs.umich.edu
5253814Ssaidi@eecs.umich.edu    def _attach_clk(self, devices, clkdomain):
5263814Ssaidi@eecs.umich.edu        for d in devices:
5273814Ssaidi@eecs.umich.edu            if hasattr(d, "clk_domain"):
5283814Ssaidi@eecs.umich.edu                d.clk_domain = clkdomain
5293814Ssaidi@eecs.umich.edu
5303584Ssaidi@eecs.umich.edu    def attachPciDevices(self):
5313584Ssaidi@eecs.umich.edu        pass
5323584Ssaidi@eecs.umich.edu
5333603Ssaidi@eecs.umich.edu    def enableMSIX(self):
5343584Ssaidi@eecs.umich.edu        pass
5353584Ssaidi@eecs.umich.edu
5363748Sgblack@eecs.umich.edu    def onChipIOClkDomain(self, clkdomain):
5373748Sgblack@eecs.umich.edu        self._attach_clk(self._on_chip_devices(), clkdomain)
5383748Sgblack@eecs.umich.edu
5393584Ssaidi@eecs.umich.edu    def offChipIOClkDomain(self, clkdomain):
5403584Ssaidi@eecs.umich.edu        self._attach_clk(self._off_chip_devices(), clkdomain)
5413584Ssaidi@eecs.umich.edu
5423584Ssaidi@eecs.umich.edu    def attachOnChipIO(self, bus, bridge=None, *args, **kwargs):
5433603Ssaidi@eecs.umich.edu        self._attach_io(self._on_chip_devices(), bus, *args, **kwargs)
5443748Sgblack@eecs.umich.edu        if bridge:
5453584Ssaidi@eecs.umich.edu            bridge.ranges = self._off_chip_ranges
5463748Sgblack@eecs.umich.edu
5473748Sgblack@eecs.umich.edu    def attachIO(self, *args, **kwargs):
5483748Sgblack@eecs.umich.edu        self._attach_io(self._off_chip_devices(), *args, **kwargs)
5493748Sgblack@eecs.umich.edu
5503748Sgblack@eecs.umich.edu    def setupBootLoader(self, mem_bus, cur_sys, loc):
5513748Sgblack@eecs.umich.edu        cur_sys.bootmem = SimpleMemory(
5523748Sgblack@eecs.umich.edu            range = AddrRange('2GB', size = '64MB'),
5533748Sgblack@eecs.umich.edu            conf_table_reported = False)
5543748Sgblack@eecs.umich.edu        if mem_bus is not None:
5553748Sgblack@eecs.umich.edu            cur_sys.bootmem.port = mem_bus.master
5563748Sgblack@eecs.umich.edu        cur_sys.boot_loader = loc('boot.arm')
5573748Sgblack@eecs.umich.edu        cur_sys.atags_addr = 0x100
5583790Sgblack@eecs.umich.edu        cur_sys.load_offset = 0
5593989Ssaidi@eecs.umich.edu
5603748Sgblack@eecs.umich.edu    def generateDeviceTree(self, state):
5614001Ssaidi@eecs.umich.edu        node = FdtNode("/") # Things in this module need to end up in the root
5624001Ssaidi@eecs.umich.edu        node.append(FdtPropertyWords("interrupt-parent",
5634001Ssaidi@eecs.umich.edu                                     state.phandle(self.gic)))
5643748Sgblack@eecs.umich.edu
5653790Sgblack@eecs.umich.edu        for subnode in self.recurseDeviceTree(state):
5663989Ssaidi@eecs.umich.edu            node.append(subnode)
5673748Sgblack@eecs.umich.edu
5683748Sgblack@eecs.umich.edu        yield node
5693748Sgblack@eecs.umich.edu
5703748Sgblack@eecs.umich.edu    def annotateCpuDeviceNode(self, cpu, state):
5713748Sgblack@eecs.umich.edu        cpu.append(FdtPropertyStrings("enable-method", "spin-table"))
5723748Sgblack@eecs.umich.edu        cpu.append(FdtPropertyWords("cpu-release-addr", \
5733748Sgblack@eecs.umich.edu                                    state.addrCells(0x8000fff8)))
5743748Sgblack@eecs.umich.edu
5753748Sgblack@eecs.umich.edu# Reference for memory map and interrupt number
5763748Sgblack@eecs.umich.edu# RealView Platform Baseboard Explore for Cortex-A9 User Guide(ARM DUI 0440A)
5773748Sgblack@eecs.umich.edu# Chapter 4: Programmer's Reference
5783748Sgblack@eecs.umich.educlass RealViewPBX(RealView):
5793748Sgblack@eecs.umich.edu    uart = Pl011(pio_addr=0x10009000, int_num=44)
5803748Sgblack@eecs.umich.edu    realview_io = RealViewCtrl(pio_addr=0x10000000)
5813748Sgblack@eecs.umich.edu    mcc = VExpressMCC()
5823748Sgblack@eecs.umich.edu    dcc = CoreTile2A15DCC()
5833748Sgblack@eecs.umich.edu    gic = Gic400(cpu_addr=0x1f000100, dist_addr=0x1f001000, cpu_size=0x100)
5843790Sgblack@eecs.umich.edu    pci_host = GenericPciHost(
5853790Sgblack@eecs.umich.edu        conf_base=0x30000000, conf_size='256MB', conf_device_bits=16,
5863748Sgblack@eecs.umich.edu        pci_pio_base=0)
5873748Sgblack@eecs.umich.edu    timer0 = Sp804(int_num0=36, int_num1=36, pio_addr=0x10011000)
5883790Sgblack@eecs.umich.edu    timer1 = Sp804(int_num0=37, int_num1=37, pio_addr=0x10012000)
5893790Sgblack@eecs.umich.edu    global_timer = A9GlobalTimer(int_num=27, pio_addr=0x1f000200)
5903748Sgblack@eecs.umich.edu    local_cpu_timer = CpuLocalTimer(int_timer=ArmPPI(num=29),
5913748Sgblack@eecs.umich.edu                                    int_watchdog=ArmPPI(num=30),
5923790Sgblack@eecs.umich.edu                                    pio_addr=0x1f000600)
5933989Ssaidi@eecs.umich.edu    clcd = Pl111(pio_addr=0x10020000, int_num=55)
5943748Sgblack@eecs.umich.edu    kmi0   = Pl050(pio_addr=0x10006000, int_num=52, ps2=PS2Keyboard())
5953748Sgblack@eecs.umich.edu    kmi1   = Pl050(pio_addr=0x10007000, int_num=53, ps2=PS2TouchKit())
5963790Sgblack@eecs.umich.edu    a9scu  = A9SCU(pio_addr=0x1f000000)
5973989Ssaidi@eecs.umich.edu    cf_ctrl = IdeController(disks=[], pci_func=0, pci_dev=7, pci_bus=2,
5983748Sgblack@eecs.umich.edu                            io_shift = 1, ctrl_offset = 2, Command = 0x1,
5993748Sgblack@eecs.umich.edu                            BAR0 = 0x18000000, BAR0Size = '16B',
6003748Sgblack@eecs.umich.edu                            BAR1 = 0x18000100, BAR1Size = '1B',
6013748Sgblack@eecs.umich.edu                            BAR0LegacyIO = True, BAR1LegacyIO = True)
6023748Sgblack@eecs.umich.edu
6033748Sgblack@eecs.umich.edu
6043748Sgblack@eecs.umich.edu    l2x0_fake     = IsaFake(pio_addr=0x1f002000, pio_size=0xfff)
6053748Sgblack@eecs.umich.edu    flash_fake    = IsaFake(pio_addr=0x40000000, pio_size=0x20000000,
6063815Ssaidi@eecs.umich.edu                            fake_mem=True)
6073748Sgblack@eecs.umich.edu    dmac_fake     = AmbaFake(pio_addr=0x10030000)
6083748Sgblack@eecs.umich.edu    uart1_fake    = AmbaFake(pio_addr=0x1000a000)
6093815Ssaidi@eecs.umich.edu    uart2_fake    = AmbaFake(pio_addr=0x1000b000)
6103748Sgblack@eecs.umich.edu    uart3_fake    = AmbaFake(pio_addr=0x1000c000)
6113748Sgblack@eecs.umich.edu    smc_fake      = AmbaFake(pio_addr=0x100e1000)
6123815Ssaidi@eecs.umich.edu    sp810_fake    = AmbaFake(pio_addr=0x10001000, ignore_access=True)
6133748Sgblack@eecs.umich.edu    watchdog_fake = AmbaFake(pio_addr=0x10010000)
6143748Sgblack@eecs.umich.edu    gpio0_fake    = AmbaFake(pio_addr=0x10013000)
6153815Ssaidi@eecs.umich.edu    gpio1_fake    = AmbaFake(pio_addr=0x10014000)
6163748Sgblack@eecs.umich.edu    gpio2_fake    = AmbaFake(pio_addr=0x10015000)
6173748Sgblack@eecs.umich.edu    ssp_fake      = AmbaFake(pio_addr=0x1000d000)
6183815Ssaidi@eecs.umich.edu    sci_fake      = AmbaFake(pio_addr=0x1000e000)
6193748Sgblack@eecs.umich.edu    aaci_fake     = AmbaFake(pio_addr=0x10004000)
6203748Sgblack@eecs.umich.edu    mmc_fake      = AmbaFake(pio_addr=0x10005000)
6213584Ssaidi@eecs.umich.edu    rtc           = PL031(pio_addr=0x10017000, int_num=42)
6223584Ssaidi@eecs.umich.edu    energy_ctrl   = EnergyCtrl(pio_addr=0x1000f000)
6233748Sgblack@eecs.umich.edu
6243584Ssaidi@eecs.umich.edu
6253931Ssaidi@eecs.umich.edu    # Attach I/O devices that are on chip and also set the appropriate
6263931Ssaidi@eecs.umich.edu    # ranges for the bridge
6273748Sgblack@eecs.umich.edu    def attachOnChipIO(self, bus, bridge):
6283748Sgblack@eecs.umich.edu       self.gic.pio = bus.master
6293748Sgblack@eecs.umich.edu       self.l2x0_fake.pio = bus.master
6303748Sgblack@eecs.umich.edu       self.a9scu.pio = bus.master
6313748Sgblack@eecs.umich.edu       self.global_timer.pio = bus.master
6323931Ssaidi@eecs.umich.edu       self.local_cpu_timer.pio = bus.master
6333931Ssaidi@eecs.umich.edu       # Bridge ranges based on excluding what is part of on-chip I/O
6343931Ssaidi@eecs.umich.edu       # (gic, l2x0, a9scu, local_cpu_timer)
6353931Ssaidi@eecs.umich.edu       bridge.ranges = [AddrRange(self.realview_io.pio_addr,
6363931Ssaidi@eecs.umich.edu                                  self.a9scu.pio_addr - 1),
6373931Ssaidi@eecs.umich.edu                        AddrRange(self.flash_fake.pio_addr,
6383931Ssaidi@eecs.umich.edu                                  self.flash_fake.pio_addr + \
6394008Ssaidi@eecs.umich.edu                                  self.flash_fake.pio_size - 1)]
6403931Ssaidi@eecs.umich.edu
6413584Ssaidi@eecs.umich.edu    # Set the clock domain for IO objects that are considered
6423584Ssaidi@eecs.umich.edu    # to be "close" to the cores.
6433903Ssaidi@eecs.umich.edu    def onChipIOClkDomain(self, clkdomain):
6443903Ssaidi@eecs.umich.edu        self.gic.clk_domain             = clkdomain
6453903Ssaidi@eecs.umich.edu        self.l2x0_fake.clk_domain       = clkdomain
6463903Ssaidi@eecs.umich.edu        self.a9scu.clkdomain            = clkdomain
6473903Ssaidi@eecs.umich.edu        self.local_cpu_timer.clk_domain = clkdomain
6483903Ssaidi@eecs.umich.edu
6493903Ssaidi@eecs.umich.edu    # Attach I/O devices to specified bus object.  Can't do this
6503903Ssaidi@eecs.umich.edu    # earlier, since the bus object itself is typically defined at the
6513903Ssaidi@eecs.umich.edu    # System level.
6523903Ssaidi@eecs.umich.edu    def attachIO(self, bus):
6533880Ssaidi@eecs.umich.edu       self.uart.pio          = bus.master
6543903Ssaidi@eecs.umich.edu       self.realview_io.pio   = bus.master
6553903Ssaidi@eecs.umich.edu       self.pci_host.pio      = bus.master
6563903Ssaidi@eecs.umich.edu       self.timer0.pio        = bus.master
6573903Ssaidi@eecs.umich.edu       self.timer1.pio        = bus.master
6583903Ssaidi@eecs.umich.edu       self.clcd.pio          = bus.master
6593903Ssaidi@eecs.umich.edu       self.clcd.dma          = bus.slave
6603903Ssaidi@eecs.umich.edu       self.kmi0.pio          = bus.master
6613903Ssaidi@eecs.umich.edu       self.kmi1.pio          = bus.master
6623903Ssaidi@eecs.umich.edu       self.cf_ctrl.pio       = bus.master
6633903Ssaidi@eecs.umich.edu       self.cf_ctrl.dma       = bus.slave
6643880Ssaidi@eecs.umich.edu       self.dmac_fake.pio     = bus.master
6653826Ssaidi@eecs.umich.edu       self.uart1_fake.pio    = bus.master
6663825Ssaidi@eecs.umich.edu       self.uart2_fake.pio    = bus.master
6673832Ssaidi@eecs.umich.edu       self.uart3_fake.pio    = bus.master
6683825Ssaidi@eecs.umich.edu       self.smc_fake.pio      = bus.master
6693892Ssaidi@eecs.umich.edu       self.sp810_fake.pio    = bus.master
6703892Ssaidi@eecs.umich.edu       self.watchdog_fake.pio = bus.master
6713584Ssaidi@eecs.umich.edu       self.gpio0_fake.pio    = bus.master
6723584Ssaidi@eecs.umich.edu       self.gpio1_fake.pio    = bus.master
6733584Ssaidi@eecs.umich.edu       self.gpio2_fake.pio    = bus.master
6743506Ssaidi@eecs.umich.edu       self.ssp_fake.pio      = bus.master
6753584Ssaidi@eecs.umich.edu       self.sci_fake.pio      = bus.master
6763584Ssaidi@eecs.umich.edu       self.aaci_fake.pio     = bus.master
6773506Ssaidi@eecs.umich.edu       self.mmc_fake.pio      = bus.master
6783584Ssaidi@eecs.umich.edu       self.rtc.pio           = bus.master
6792SN/A       self.flash_fake.pio    = bus.master
6802SN/A       self.energy_ctrl.pio   = bus.master
6812SN/A
6822SN/A    # Set the clock domain for IO objects that are considered
6831967SN/A    # to be "far" away from the cores.
6842SN/A    def offChipIOClkDomain(self, clkdomain):
6852SN/A        self.uart.clk_domain          = clkdomain
6862SN/A        self.realview_io.clk_domain   = clkdomain
6872SN/A        self.timer0.clk_domain        = clkdomain
6882SN/A        self.timer1.clk_domain        = clkdomain
6892SN/A        self.clcd.clk_domain          = clkdomain
6902SN/A        self.kmi0.clk_domain          = clkdomain
6912SN/A        self.kmi1.clk_domain          = clkdomain
6922SN/A        self.cf_ctrl.clk_domain       = clkdomain
6932SN/A        self.dmac_fake.clk_domain     = clkdomain
6942SN/A        self.uart1_fake.clk_domain    = clkdomain
6952SN/A        self.uart2_fake.clk_domain    = clkdomain
6962SN/A        self.uart3_fake.clk_domain    = clkdomain
6972SN/A        self.smc_fake.clk_domain      = clkdomain
6982SN/A        self.sp810_fake.clk_domain    = clkdomain
6992SN/A        self.watchdog_fake.clk_domain = clkdomain
7002SN/A        self.gpio0_fake.clk_domain    = clkdomain
7012SN/A        self.gpio1_fake.clk_domain    = clkdomain
7022SN/A        self.gpio2_fake.clk_domain    = clkdomain
7032SN/A        self.ssp_fake.clk_domain      = clkdomain
7041413SN/A        self.sci_fake.clk_domain      = clkdomain
7052SN/A        self.aaci_fake.clk_domain     = clkdomain
7062SN/A        self.mmc_fake.clk_domain      = clkdomain
7072SN/A        self.rtc.clk_domain           = clkdomain
7082SN/A        self.flash_fake.clk_domain    = clkdomain
7092SN/A        self.energy_ctrl.clk_domain   = clkdomain
7102SN/A
7112SN/Aclass VExpress_EMM(RealView):
7122SN/A    _mem_regions = [ AddrRange('2GB', size='2GB') ]
7132SN/A
7142SN/A    # Ranges based on excluding what is part of on-chip I/O (gic,
7152SN/A    # a9scu)
7162SN/A    _off_chip_ranges = [AddrRange(0x2F000000, size='16MB'),
7172SN/A                        AddrRange(0x30000000, size='256MB'),
7182SN/A                        AddrRange(0x40000000, size='512MB'),
7192SN/A                        AddrRange(0x18000000, size='64MB'),
7202SN/A                        AddrRange(0x1C000000, size='64MB')]
7212SN/A
7222973Sgblack@eecs.umich.edu    # Platform control device (off-chip)
7232973Sgblack@eecs.umich.edu    realview_io = RealViewCtrl(proc_id0=0x14000000, proc_id1=0x14000000,
7242299SN/A                               idreg=0x02250000, pio_addr=0x1C010000)
7252299SN/A
7261904SN/A    mcc = VExpressMCC()
7271904SN/A    dcc = CoreTile2A15DCC()
7283506Ssaidi@eecs.umich.edu
7293506Ssaidi@eecs.umich.edu    ### On-chip devices ###
7303506Ssaidi@eecs.umich.edu    gic = Gic400(dist_addr=0x2C001000, cpu_addr=0x2C002000)
7311967SN/A    vgic   = VGic(vcpu_addr=0x2c006000, hv_addr=0x2c004000, ppint=25)
7321967SN/A
7331967SN/A    local_cpu_timer = CpuLocalTimer(int_timer=ArmPPI(num=29),
7341904SN/A                                    int_watchdog=ArmPPI(num=30),
7352SN/A                                    pio_addr=0x2C080000)
7362SN/A
7372SN/A    hdlcd  = HDLcd(pxl_clk=dcc.osc_pxl,
7382SN/A                   pio_addr=0x2b000000, int_num=117,
7392SN/A                   workaround_swap_rb=True)
7402SN/A
7412SN/A    def _on_chip_devices(self):
7422SN/A        devices = [
7432SN/A            self.gic, self.vgic,
7442SN/A            self.local_cpu_timer
7452SN/A        ]
7462SN/A        if hasattr(self, "gicv2m"):
7472SN/A            devices.append(self.gicv2m)
7482SN/A        devices.append(self.hdlcd)
7492SN/A        return devices
7502SN/A
7512SN/A    ### Off-chip devices ###
7522SN/A    uart = Pl011(pio_addr=0x1c090000, int_num=37)
7532973Sgblack@eecs.umich.edu    pci_host = GenericPciHost(
7542299SN/A        conf_base=0x30000000, conf_size='256MB', conf_device_bits=16,
7551904SN/A        pci_pio_base=0)
7563506Ssaidi@eecs.umich.edu
7571967SN/A    generic_timer = GenericTimer(int_phys_s=ArmPPI(num=29),
7583506Ssaidi@eecs.umich.edu                                 int_phys_ns=ArmPPI(num=30),
7593506Ssaidi@eecs.umich.edu                                 int_virt=ArmPPI(num=27),
7603506Ssaidi@eecs.umich.edu                                 int_hyp=ArmPPI(num=26))
7613506Ssaidi@eecs.umich.edu
7623603Ssaidi@eecs.umich.edu    timer0 = Sp804(int_num0=34, int_num1=34, pio_addr=0x1C110000, clock0='1MHz', clock1='1MHz')
7633506Ssaidi@eecs.umich.edu    timer1 = Sp804(int_num0=35, int_num1=35, pio_addr=0x1C120000, clock0='1MHz', clock1='1MHz')
7643506Ssaidi@eecs.umich.edu    clcd   = Pl111(pio_addr=0x1c1f0000, int_num=46)
7653506Ssaidi@eecs.umich.edu    kmi0   = Pl050(pio_addr=0x1c060000, int_num=44, ps2=PS2Keyboard())
7663506Ssaidi@eecs.umich.edu    kmi1   = Pl050(pio_addr=0x1c070000, int_num=45, ps2=PS2TouchKit())
7673506Ssaidi@eecs.umich.edu    cf_ctrl = IdeController(disks=[], pci_func=0, pci_dev=0, pci_bus=2,
7683506Ssaidi@eecs.umich.edu                            io_shift = 2, ctrl_offset = 2, Command = 0x1,
7693506Ssaidi@eecs.umich.edu                            BAR0 = 0x1C1A0000, BAR0Size = '256B',
7703506Ssaidi@eecs.umich.edu                            BAR1 = 0x1C1A0100, BAR1Size = '4096B',
7713506Ssaidi@eecs.umich.edu                            BAR0LegacyIO = True, BAR1LegacyIO = True)
7723506Ssaidi@eecs.umich.edu
7733506Ssaidi@eecs.umich.edu    vram           = SimpleMemory(range = AddrRange(0x18000000, size='32MB'),
7743506Ssaidi@eecs.umich.edu                                  conf_table_reported = False)
7753506Ssaidi@eecs.umich.edu    rtc            = PL031(pio_addr=0x1C170000, int_num=36)
7763506Ssaidi@eecs.umich.edu
7773603Ssaidi@eecs.umich.edu    l2x0_fake      = IsaFake(pio_addr=0x2C100000, pio_size=0xfff)
7783603Ssaidi@eecs.umich.edu    uart1_fake     = AmbaFake(pio_addr=0x1C0A0000)
7793506Ssaidi@eecs.umich.edu    uart2_fake     = AmbaFake(pio_addr=0x1C0B0000)
7802SN/A    uart3_fake     = AmbaFake(pio_addr=0x1C0C0000)
7812SN/A    sp810_fake     = AmbaFake(pio_addr=0x1C020000, ignore_access=True)
7822SN/A    watchdog_fake  = AmbaFake(pio_addr=0x1C0F0000)
7832SN/A    aaci_fake      = AmbaFake(pio_addr=0x1C040000)
7842SN/A    lan_fake       = IsaFake(pio_addr=0x1A000000, pio_size=0xffff)
7852SN/A    usb_fake       = IsaFake(pio_addr=0x1B000000, pio_size=0x1ffff)
7862SN/A    mmc_fake       = AmbaFake(pio_addr=0x1c050000)
7872SN/A    energy_ctrl    = EnergyCtrl(pio_addr=0x1c080000)
788
789    def _off_chip_devices(self):
790        devices = [
791            self.uart,
792            self.realview_io,
793            self.pci_host,
794            self.timer0,
795            self.timer1,
796            self.clcd,
797            self.kmi0,
798            self.kmi1,
799            self.cf_ctrl,
800            self.rtc,
801            self.vram,
802            self.l2x0_fake,
803            self.uart1_fake,
804            self.uart2_fake,
805            self.uart3_fake,
806            self.sp810_fake,
807            self.watchdog_fake,
808            self.aaci_fake,
809            self.lan_fake,
810            self.usb_fake,
811            self.mmc_fake,
812            self.energy_ctrl,
813        ]
814        # Try to attach the I/O if it exists
815        if hasattr(self, "ide"):
816            devices.append(self.ide)
817        if hasattr(self, "ethernet"):
818            devices.append(self.ethernet)
819        return devices
820
821    # Attach any PCI devices that are supported
822    def attachPciDevices(self):
823        self.ethernet = IGbE_e1000(pci_bus=0, pci_dev=0, pci_func=0,
824                                   InterruptLine=1, InterruptPin=1)
825        self.ide = IdeController(disks = [], pci_bus=0, pci_dev=1, pci_func=0,
826                                 InterruptLine=2, InterruptPin=2)
827
828    def enableMSIX(self):
829        self.gic = Gic400(dist_addr=0x2C001000, cpu_addr=0x2C002000,
830                          it_lines=512)
831        self.gicv2m = Gicv2m()
832        self.gicv2m.frames = [Gicv2mFrame(spi_base=256, spi_len=64, addr=0x2C1C0000)]
833
834    def setupBootLoader(self, mem_bus, cur_sys, loc):
835        cur_sys.bootmem = SimpleMemory(range = AddrRange('64MB'),
836                                       conf_table_reported = False)
837        if mem_bus is not None:
838            cur_sys.bootmem.port = mem_bus.master
839        if not cur_sys.boot_loader:
840            cur_sys.boot_loader = loc('boot_emm.arm')
841        cur_sys.atags_addr = 0x8000000
842        cur_sys.load_offset = 0x80000000
843
844class VExpress_EMM64(VExpress_EMM):
845    # Three memory regions are specified totalling 512GB
846    _mem_regions = [ AddrRange('2GB', size='2GB'),
847                     AddrRange('34GB', size='30GB'),
848                     AddrRange('512GB', size='480GB') ]
849    pci_host = GenericPciHost(
850        conf_base=0x30000000, conf_size='256MB', conf_device_bits=12,
851        pci_pio_base=0x2f000000)
852
853    def setupBootLoader(self, mem_bus, cur_sys, loc):
854        cur_sys.bootmem = SimpleMemory(range=AddrRange(0, size='64MB'),
855                                       conf_table_reported=False)
856        if mem_bus is not None:
857            cur_sys.bootmem.port = mem_bus.master
858        if not cur_sys.boot_loader:
859            cur_sys.boot_loader = loc('boot_emm.arm64')
860        cur_sys.atags_addr = 0x8000000
861        cur_sys.load_offset = 0x80000000
862
863class VExpress_GEM5_Base(RealView):
864    """
865The VExpress gem5 memory map is loosely based on a modified
866Versatile Express RS1 memory map.
867
868The gem5 platform has been designed to implement a subset of the
869original Versatile Express RS1 memory map. Off-chip peripherals should,
870when possible, adhere to the Versatile Express memory map. Non-PCI
871off-chip devices that are gem5-specific should live in the CS5 memory
872space to avoid conflicts with existing devices that we might want to
873model in the future. Such devices should normally have interrupts in
874the gem5-specific SPI range.
875
876On-chip peripherals are loosely modeled after the ARM CoreTile Express
877A15x2 A7x3 memory and interrupt map. In particular, the GIC and
878Generic Timer have the same interrupt lines and base addresses. Other
879on-chip devices are gem5 specific.
880
881Unlike the original Versatile Express RS2 extended platform, gem5 implements a
882large contigious DRAM space, without aliases or holes, starting at the
8832GiB boundary. This means that PCI memory is limited to 1GiB.
884
885Memory map:
886   0x00000000-0x03ffffff: Boot memory (CS0)
887   0x04000000-0x07ffffff: Reserved
888   0x08000000-0x0bffffff: Reserved (CS0 alias)
889   0x0c000000-0x0fffffff: Reserved (Off-chip, CS4)
890   0x10000000-0x13ffffff: gem5-specific peripherals (Off-chip, CS5)
891       0x10000000-0x1000ffff: gem5 energy controller
892       0x10010000-0x1001ffff: gem5 pseudo-ops
893
894   0x14000000-0x17ffffff: Reserved (Off-chip, PSRAM, CS1)
895   0x18000000-0x1bffffff: Reserved (Off-chip, Peripherals, CS2)
896   0x1c000000-0x1fffffff: Peripheral block 1 (Off-chip, CS3):
897       0x1c010000-0x1c01ffff: realview_io (VE system control regs.)
898       0x1c060000-0x1c06ffff: KMI0 (keyboard)
899       0x1c070000-0x1c07ffff: KMI1 (mouse)
900       0x1c090000-0x1c09ffff: UART0
901       0x1c0a0000-0x1c0affff: UART1 (reserved)
902       0x1c0b0000-0x1c0bffff: UART2 (reserved)
903       0x1c0c0000-0x1c0cffff: UART3 (reserved)
904       0x1c130000-0x1c13ffff: VirtIO (gem5/FM extension)
905       0x1c140000-0x1c14ffff: VirtIO (gem5/FM extension)
906       0x1c170000-0x1c17ffff: RTC
907
908   0x20000000-0x3fffffff: On-chip peripherals:
909       0x2b000000-0x2b00ffff: HDLCD
910
911       0x2c001000-0x2c001fff: GIC (distributor)
912       0x2c002000-0x2c003fff: GIC (CPU interface)
913       0x2c004000-0x2c005fff: vGIC (HV)
914       0x2c006000-0x2c007fff: vGIC (VCPU)
915       0x2c1c0000-0x2c1cffff: GICv2m MSI frame 0
916
917       0x2d000000-0x2d00ffff: GPU (reserved)
918
919       0x2f000000-0x2fffffff: PCI IO space
920       0x30000000-0x3fffffff: PCI config space
921
922   0x40000000-0x7fffffff: Ext. AXI: Used as PCI memory
923
924   0x80000000-X: DRAM
925
926Interrupts:
927      0- 15: Software generated interrupts (SGIs)
928     16- 31: On-chip private peripherals (PPIs)
929        25   : vgic
930        26   : generic_timer (hyp)
931        27   : generic_timer (virt)
932        28   : Reserved (Legacy FIQ)
933        29   : generic_timer (phys, sec)
934        30   : generic_timer (phys, non-sec)
935        31   : Reserved (Legacy IRQ)
936    32- 95: Mother board peripherals (SPIs)
937        32   : Reserved (SP805)
938        33   : Reserved (IOFPGA SW int)
939        34-35: Reserved (SP804)
940        36   : RTC
941        37-40: uart0-uart3
942        41-42: Reserved (PL180)
943        43   : Reserved (AACI)
944        44-45: kmi0-kmi1
945        46   : Reserved (CLCD)
946        47   : Reserved (Ethernet)
947        48   : Reserved (USB)
948    95-255: On-chip interrupt sources (we use these for
949            gem5-specific devices, SPIs)
950         74    : VirtIO (gem5/FM extension)
951         75    : VirtIO (gem5/FM extension)
952         95    : HDLCD
953         96- 98: GPU (reserved)
954        100-103: PCI
955   256-319: MSI frame 0 (gem5-specific, SPIs)
956   320-511: Unused
957
958    """
959
960    # Everything above 2GiB is memory
961    _mem_regions = [ AddrRange('2GB', size='510GB') ]
962
963    _off_chip_ranges = [
964        # CS1-CS5
965        AddrRange(0x0c000000, 0x1fffffff),
966        # External AXI interface (PCI)
967        AddrRange(0x2f000000, 0x7fffffff),
968    ]
969
970    # Platform control device (off-chip)
971    realview_io = RealViewCtrl(proc_id0=0x14000000, proc_id1=0x14000000,
972                               idreg=0x02250000, pio_addr=0x1c010000)
973    mcc = VExpressMCC()
974    dcc = CoreTile2A15DCC()
975
976    ### On-chip devices ###
977    generic_timer = GenericTimer(int_phys_s=ArmPPI(num=29),
978                                 int_phys_ns=ArmPPI(num=30),
979                                 int_virt=ArmPPI(num=27),
980                                 int_hyp=ArmPPI(num=26))
981
982    def _on_chip_devices(self):
983        return [
984            self.generic_timer,
985        ]
986
987    ### Off-chip devices ###
988    clock24MHz = SrcClockDomain(clock="24MHz",
989        voltage_domain=VoltageDomain(voltage="3.3V"))
990
991    uart = [
992        Pl011(pio_addr=0x1c090000, int_num=37),
993    ]
994
995    kmi0 = Pl050(pio_addr=0x1c060000, int_num=44, ps2=PS2Keyboard())
996    kmi1 = Pl050(pio_addr=0x1c070000, int_num=45, ps2=PS2TouchKit())
997
998    rtc = PL031(pio_addr=0x1c170000, int_num=36)
999
1000    ### gem5-specific off-chip devices ###
1001    pci_host = GenericArmPciHost(
1002        conf_base=0x30000000, conf_size='256MB', conf_device_bits=12,
1003        pci_pio_base=0x2f000000,
1004        int_policy="ARM_PCI_INT_DEV", int_base=100, int_count=4)
1005
1006    energy_ctrl = EnergyCtrl(pio_addr=0x10000000)
1007
1008    vio = [
1009        MmioVirtIO(pio_addr=0x1c130000, pio_size=0x1000,
1010                   interrupt=ArmSPI(num=74)),
1011        MmioVirtIO(pio_addr=0x1c140000, pio_size=0x1000,
1012                   interrupt=ArmSPI(num=75)),
1013    ]
1014
1015    def _off_chip_devices(self):
1016        return [
1017            self.realview_io,
1018            self.uart[0],
1019            self.kmi0,
1020            self.kmi1,
1021            self.rtc,
1022            self.pci_host,
1023            self.energy_ctrl,
1024            self.clock24MHz,
1025            self.vio[0],
1026            self.vio[1],
1027        ]
1028
1029    def attachPciDevice(self, device, *args, **kwargs):
1030        device.host = self.pci_host
1031        self._attach_device(device, *args, **kwargs)
1032
1033    def setupBootLoader(self, mem_bus, cur_sys, loc):
1034        cur_sys.bootmem = SimpleMemory(range=AddrRange(0, size='64MB'),
1035                                       conf_table_reported=False)
1036        if mem_bus is not None:
1037            cur_sys.bootmem.port = mem_bus.master
1038        if not cur_sys.boot_loader:
1039            cur_sys.boot_loader = [ loc('boot_emm.arm64'), loc('boot_emm.arm') ]
1040        cur_sys.atags_addr = 0x8000000
1041        cur_sys.load_offset = 0x80000000
1042
1043        #  Setup m5ops. It's technically not a part of the boot
1044        #  loader, but this is the only place we can configure the
1045        #  system.
1046        cur_sys.m5ops_base = 0x10010000
1047
1048    def generateDeviceTree(self, state):
1049        # Generate using standard RealView function
1050        dt = list(super(VExpress_GEM5_Base, self).generateDeviceTree(state))
1051        if len(dt) > 1:
1052            raise Exception("System returned too many DT nodes")
1053        node = dt[0]
1054
1055        node.appendCompatible(["arm,vexpress"])
1056        node.append(FdtPropertyStrings("model", ["V2P-CA15"]))
1057        node.append(FdtPropertyWords("arm,hbi", [0x0]))
1058        node.append(FdtPropertyWords("arm,vexpress,site", [0xf]))
1059
1060        yield node
1061
1062class VExpress_GEM5_V1_Base(VExpress_GEM5_Base):
1063    gic = kvm_gicv2_class(dist_addr=0x2c001000, cpu_addr=0x2c002000,
1064                          it_lines=512)
1065    vgic = VGic(vcpu_addr=0x2c006000, hv_addr=0x2c004000, ppint=25)
1066    gicv2m = Gicv2m()
1067    gicv2m.frames = [
1068        Gicv2mFrame(spi_base=256, spi_len=64, addr=0x2c1c0000),
1069    ]
1070
1071    def _on_chip_devices(self):
1072        return super(VExpress_GEM5_V1_Base,self)._on_chip_devices() + [
1073                self.gic, self.vgic, self.gicv2m,
1074            ]
1075
1076class VExpress_GEM5_V1(VExpress_GEM5_V1_Base):
1077    hdlcd  = HDLcd(pxl_clk=VExpress_GEM5_V1_Base.dcc.osc_pxl,
1078                   pio_addr=0x2b000000, int_num=95)
1079
1080    def _on_chip_devices(self):
1081        return super(VExpress_GEM5_V1,self)._on_chip_devices() + [
1082                self.hdlcd,
1083            ]
1084
1085class VExpress_GEM5_V2_Base(VExpress_GEM5_Base):
1086    gic = Gicv3()
1087
1088    def _on_chip_devices(self):
1089        return super(VExpress_GEM5_V2_Base,self)._on_chip_devices() + [
1090                self.gic,
1091            ]
1092
1093    def setupBootLoader(self, mem_bus, cur_sys, loc):
1094        cur_sys.boot_loader = [ loc('boot_emm_v2.arm64') ]
1095        super(VExpress_GEM5_V2_Base,self).setupBootLoader(mem_bus,
1096                cur_sys, loc)
1097
1098class VExpress_GEM5_V2(VExpress_GEM5_V2_Base):
1099    hdlcd  = HDLcd(pxl_clk=VExpress_GEM5_V2_Base.dcc.osc_pxl,
1100                   pio_addr=0x2b000000, int_num=95)
1101
1102    def _on_chip_devices(self):
1103        return super(VExpress_GEM5_V2,self)._on_chip_devices() + [
1104                self.hdlcd,
1105            ]
1106