RealView.py revision 13665
12315SN/A# Copyright (c) 2009-2018 ARM Limited
28733Sgeoffrey.blake@arm.com# All rights reserved.
39920Syasuko.eckert@amd.com#
48733Sgeoffrey.blake@arm.com# The license below extends only to copyright in the software and shall
58733Sgeoffrey.blake@arm.com# not be construed as granting a license to any other intellectual
68733Sgeoffrey.blake@arm.com# property including but not limited to intellectual property relating
78733Sgeoffrey.blake@arm.com# to a hardware implementation of the functionality of the software
88733Sgeoffrey.blake@arm.com# licensed hereunder.  You may use the software subject to the license
98733Sgeoffrey.blake@arm.com# terms below provided that you ensure that this notice is replicated
108733Sgeoffrey.blake@arm.com# unmodified and in its entirety in all distributions of the software,
118733Sgeoffrey.blake@arm.com# modified or unmodified, in source code or in binary form.
128733Sgeoffrey.blake@arm.com#
138733Sgeoffrey.blake@arm.com# Copyright (c) 2006-2007 The Regents of The University of Michigan
148733Sgeoffrey.blake@arm.com# All rights reserved.
152332SN/A#
162315SN/A# Redistribution and use in source and binary forms, with or without
172315SN/A# modification, are permitted provided that the following conditions are
182315SN/A# met: redistributions of source code must retain the above copyright
192315SN/A# notice, this list of conditions and the following disclaimer;
202315SN/A# redistributions in binary form must reproduce the above copyright
212315SN/A# notice, this list of conditions and the following disclaimer in the
222315SN/A# documentation and/or other materials provided with the distribution;
232315SN/A# neither the name of the copyright holders nor the names of its
242315SN/A# contributors may be used to endorse or promote products derived from
252315SN/A# this software without specific prior written permission.
262315SN/A#
272315SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
282315SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
292315SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
302315SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
312315SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
322315SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
332315SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
342315SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
352315SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
362315SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
372315SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
382315SN/A#
392315SN/A# Authors: Ali Saidi
402689Sktlim@umich.edu#          Gabe Black
412689Sktlim@umich.edu#          William Wang
422315SN/A#          Glenn Bergmans
432315SN/A
442315SN/Afrom m5.defines import buildEnv
452315SN/Afrom m5.params import *
462315SN/Afrom m5.proxy import *
472315SN/Afrom m5.util.fdthelper import *
488229Snate@binkert.orgfrom m5.objects.ClockDomain import ClockDomain
492315SN/Afrom m5.objects.VoltageDomain import VoltageDomain
502315SN/Afrom m5.objects.Device import \
512669Sktlim@umich.edu    BasicPioDevice, PioDevice, IsaFake, BadAddr, DmaDevice
522315SN/Afrom m5.objects.PciHost import *
532315SN/Afrom m5.objects.Ethernet import NSGigE, IGbE_igb, IGbE_e1000
542315SN/Afrom m5.objects.Ide import *
5510319SAndreas.Sandberg@ARM.comfrom m5.objects.Platform import Platform
568229Snate@binkert.orgfrom m5.objects.Terminal import Terminal
572683Sktlim@umich.edufrom m5.objects.Uart import Uart
582315SN/Afrom m5.objects.SimpleMemory import SimpleMemory
598733Sgeoffrey.blake@arm.comfrom m5.objects.Gic import *
608733Sgeoffrey.blake@arm.comfrom m5.objects.EnergyCtrl import EnergyCtrl
612315SN/Afrom m5.objects.ClockedObject import ClockedObject
622315SN/Afrom m5.objects.ClockDomain import SrcClockDomain
632315SN/Afrom m5.objects.SubSystem import SubSystem
643468Sgblack@eecs.umich.edufrom m5.objects.Graphics import ImageFormat
653468Sgblack@eecs.umich.edufrom m5.objects.ClockedObject import ClockedObject
666022Sgblack@eecs.umich.edufrom m5.objects.PS2 import *
673468Sgblack@eecs.umich.edufrom m5.objects.VirtIOMMIO import MmioVirtIO
682315SN/A
692315SN/A# Platforms with KVM support should generally use in-kernel GIC
702315SN/A# emulation. Use a GIC model that automatically switches between
712680Sktlim@umich.edu# gem5's GIC model and KVM's GIC model if KVM is available.
722669Sktlim@umich.edutry:
732315SN/A    from m5.objects.KvmGic import MuxingKvmGic
742350SN/A    kvm_gicv2_class = MuxingKvmGic
752350SN/Aexcept ImportError:
762350SN/A    # KVM support wasn't compiled into gem5. Fallback to a
772350SN/A    # software-only GIC.
782350SN/A    kvm_gicv2_class = Gic400
792350SN/A    pass
802350SN/A
812350SN/Aclass AmbaPioDevice(BasicPioDevice):
822350SN/A    type = 'AmbaPioDevice'
832350SN/A    abstract = True
842680Sktlim@umich.edu    cxx_header = "dev/arm/amba_device.hh"
852683Sktlim@umich.edu    amba_id = Param.UInt32("ID of AMBA device for kernel detection")
862680Sktlim@umich.edu
872350SN/Aclass AmbaIntDevice(AmbaPioDevice):
882680Sktlim@umich.edu    type = 'AmbaIntDevice'
892350SN/A    abstract = True
9010319SAndreas.Sandberg@ARM.com    cxx_header = "dev/arm/amba_device.hh"
912315SN/A    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
922315SN/A    int_num = Param.UInt32("Interrupt number that connects to GIC")
932315SN/A    int_delay = Param.Latency("100ns",
942669Sktlim@umich.edu            "Time between action and interrupt generation by device")
952669Sktlim@umich.edu
962315SN/Aclass AmbaDmaDevice(DmaDevice):
978832SAli.Saidi@ARM.com    type = 'AmbaDmaDevice'
988832SAli.Saidi@ARM.com    abstract = True
998832SAli.Saidi@ARM.com    cxx_header = "dev/arm/amba_device.hh"
1002315SN/A    pio_addr = Param.Addr("Address for AMBA slave interface")
1012315SN/A    pio_latency = Param.Latency("10ns", "Time between action and write/read result by AMBA DMA Device")
1022315SN/A    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
1035529Snate@binkert.org    int_num = Param.UInt32("Interrupt number that connects to GIC")
1042315SN/A    amba_id = Param.UInt32("ID of AMBA device for kernel detection")
1052315SN/A
1062315SN/Aclass A9SCU(BasicPioDevice):
1072315SN/A    type = 'A9SCU'
1082315SN/A    cxx_header = "dev/arm/a9scu.hh"
1099608Sandreas.hansson@arm.com
1102679Sktlim@umich.educlass ArmPciIntRouting(Enum): vals = [
1119608Sandreas.hansson@arm.com    'ARM_PCI_INT_STATIC',
1122679Sktlim@umich.edu    'ARM_PCI_INT_DEV',
1139608Sandreas.hansson@arm.com    'ARM_PCI_INT_PIN',
1148887Sgeoffrey.blake@arm.com    ]
1159176Sandreas.hansson@arm.com
1169176Sandreas.hansson@arm.comclass GenericArmPciHost(GenericPciHost):
1179176Sandreas.hansson@arm.com    type = 'GenericArmPciHost'
1188887Sgeoffrey.blake@arm.com    cxx_header = "dev/arm/pci_host.hh"
1198887Sgeoffrey.blake@arm.com
1208887Sgeoffrey.blake@arm.com    int_policy = Param.ArmPciIntRouting("PCI interrupt routing policy")
1219608Sandreas.hansson@arm.com    int_base = Param.Unsigned("PCI interrupt base")
1228887Sgeoffrey.blake@arm.com    int_count = Param.Unsigned("Maximum number of interrupts used by this host")
1239176Sandreas.hansson@arm.com
1249176Sandreas.hansson@arm.com    def generateDeviceTree(self, state):
1259176Sandreas.hansson@arm.com        local_state = FdtState(addr_cells=3, size_cells=2, cpu_cells=1)
1268887Sgeoffrey.blake@arm.com        intterrupt_cells = 1
1278887Sgeoffrey.blake@arm.com
1282679Sktlim@umich.edu        node = FdtNode("pci")
1299176Sandreas.hansson@arm.com
1309176Sandreas.hansson@arm.com        if int(self.conf_device_bits) == 8:
1319176Sandreas.hansson@arm.com            node.appendCompatible("pci-host-cam-generic")
1329176Sandreas.hansson@arm.com        elif int(self.conf_device_bits) == 12:
1339176Sandreas.hansson@arm.com            node.appendCompatible("pci-host-ecam-generic")
1349176Sandreas.hansson@arm.com        else:
1359608Sandreas.hansson@arm.com            m5.fatal("No compatibility string for the set conf_device_width")
1369608Sandreas.hansson@arm.com
1372315SN/A        node.append(FdtPropertyStrings("device_type", ["pci"]))
1382680Sktlim@umich.edu
1392315SN/A        # Cell sizes of child nodes/peripherals
1406022Sgblack@eecs.umich.edu        node.append(local_state.addrCellsProperty())
1416022Sgblack@eecs.umich.edu        node.append(local_state.sizeCellsProperty())
1422315SN/A        node.append(FdtPropertyWords("#interrupt-cells", intterrupt_cells))
1432315SN/A        # PCI address for CPU
1442315SN/A        node.append(FdtPropertyWords("reg",
1452315SN/A            state.addrCells(self.conf_base) +
1462315SN/A            state.sizeCells(self.conf_size) ))
1472315SN/A
1488733Sgeoffrey.blake@arm.com        # Ranges mapping
1498733Sgeoffrey.blake@arm.com        # For now some of this is hard coded, because the PCI module does not
1508733Sgeoffrey.blake@arm.com        # have a proper full understanding of the memory map, but adapting the
1518733Sgeoffrey.blake@arm.com        # PCI module is beyond the scope of what I'm trying to do here.
1522315SN/A        # Values are taken from the VExpress_GEM5_V1 platform.
1532315SN/A        ranges = []
1548733Sgeoffrey.blake@arm.com        # Pio address range
1558733Sgeoffrey.blake@arm.com        ranges += self.pciFdtAddr(space=1, addr=0)
1568733Sgeoffrey.blake@arm.com        ranges += state.addrCells(self.pci_pio_base)
1572315SN/A        ranges += local_state.sizeCells(0x10000)  # Fixed size
1582679Sktlim@umich.edu
1592679Sktlim@umich.edu        # AXI memory address range
1602315SN/A        ranges += self.pciFdtAddr(space=2, addr=0)
1612315SN/A        ranges += state.addrCells(0x40000000) # Fixed offset
1628733Sgeoffrey.blake@arm.com        ranges += local_state.sizeCells(0x40000000) # Fixed size
1632315SN/A        node.append(FdtPropertyWords("ranges", ranges))
1642315SN/A
1652315SN/A        if str(self.int_policy) == 'ARM_PCI_INT_DEV':
1662315SN/A            int_phandle = state.phandle(self._parent.unproxy(self).gic)
1672315SN/A            # Interrupt mapping
1682315SN/A            interrupts = []
1692315SN/A            for i in range(int(self.int_count)):
1709176Sandreas.hansson@arm.com                interrupts += self.pciFdtAddr(device=i, addr=0) + \
1719176Sandreas.hansson@arm.com                    [0x0, int_phandle, 0, int(self.int_base) - 32 + i, 1]
1729176Sandreas.hansson@arm.com
1739176Sandreas.hansson@arm.com            node.append(FdtPropertyWords("interrupt-map", interrupts))
1749176Sandreas.hansson@arm.com
1758733Sgeoffrey.blake@arm.com            int_count = int(self.int_count)
1768733Sgeoffrey.blake@arm.com            if int_count & (int_count - 1):
1778733Sgeoffrey.blake@arm.com                fatal("PCI interrupt count should be power of 2")
1788887Sgeoffrey.blake@arm.com
1798887Sgeoffrey.blake@arm.com            intmask = self.pciFdtAddr(device=int_count - 1, addr=0) + [0x0]
1808887Sgeoffrey.blake@arm.com            node.append(FdtPropertyWords("interrupt-map-mask", intmask))
1818887Sgeoffrey.blake@arm.com        else:
1828887Sgeoffrey.blake@arm.com            m5.fatal("Unsupported PCI interrupt policy " +
1838887Sgeoffrey.blake@arm.com                     "for Device Tree generation")
1842315SN/A
1852930Sktlim@umich.edu        node.append(FdtProperty("dma-coherent"))
1862315SN/A
1872315SN/A        yield node
1882315SN/A
1892315SN/Aclass RealViewCtrl(BasicPioDevice):
1902315SN/A    type = 'RealViewCtrl'
1912315SN/A    cxx_header = "dev/arm/rv_ctrl.hh"
19211168Sandreas.hansson@arm.com    proc_id0 = Param.UInt32(0x0C000000, "Processor ID, SYS_PROCID")
19311168Sandreas.hansson@arm.com    proc_id1 = Param.UInt32(0x0C000222, "Processor ID, SYS_PROCID1")
1942315SN/A    idreg = Param.UInt32(0x00000000, "ID Register, SYS_ID")
1952315SN/A
1962315SN/A    def generateDeviceTree(self, state):
1972315SN/A        node = FdtNode("sysreg@%x" % long(self.pio_addr))
19810319SAndreas.Sandberg@ARM.com        node.appendCompatible("arm,vexpress-sysreg")
1992315SN/A        node.append(FdtPropertyWords("reg",
2002315SN/A            state.addrCells(self.pio_addr) +
2012315SN/A            state.sizeCells(0x1000) ))
2022315SN/A        node.append(FdtProperty("gpio-controller"))
2032315SN/A        node.append(FdtPropertyWords("#gpio-cells", [2]))
2042315SN/A        node.appendPhandle(self)
2052315SN/A
2062315SN/A        yield node
2072315SN/A
2082315SN/Aclass RealViewOsc(ClockDomain):
2092315SN/A    type = 'RealViewOsc'
2102315SN/A    cxx_header = "dev/arm/rv_ctrl.hh"
21110319SAndreas.Sandberg@ARM.com
2122315SN/A    parent = Param.RealViewCtrl(Parent.any, "RealView controller")
2132683Sktlim@umich.edu
2142315SN/A    # TODO: We currently don't have the notion of a clock source,
2152315SN/A    # which means we have to associate oscillators with a voltage
2163735Sstever@eecs.umich.edu    # source.
2172315SN/A    voltage_domain = Param.VoltageDomain(Parent.voltage_domain,
2189918Ssteve.reinhardt@amd.com                                         "Voltage domain")
2192683Sktlim@umich.edu
2202315SN/A    # See ARM DUI 0447J (ARM Motherboard Express uATX -- V2M-P1) and
2212315SN/A    # the individual core/logic tile reference manuals for details
2223735Sstever@eecs.umich.edu    # about the site/position/dcc/device allocation.
2232669Sktlim@umich.edu    site = Param.UInt8("Board Site")
2249918Ssteve.reinhardt@amd.com    position = Param.UInt8("Position in device stack")
2252683Sktlim@umich.edu    dcc = Param.UInt8("Daughterboard Configuration Controller")
2262315SN/A    device = Param.UInt8("Device ID")
2272315SN/A
22810319SAndreas.Sandberg@ARM.com    freq = Param.Clock("Default frequency")
2299920Syasuko.eckert@amd.com
2309920Syasuko.eckert@amd.com    def generateDeviceTree(self, state):
2319920Syasuko.eckert@amd.com        phandle = state.phandle(self)
2329920Syasuko.eckert@amd.com        node = FdtNode("osc@" + format(long(phandle), 'x'))
2339920Syasuko.eckert@amd.com        node.appendCompatible("arm,vexpress-osc")
2348733Sgeoffrey.blake@arm.com        node.append(FdtPropertyWords("arm,vexpress-sysreg,func",
2358733Sgeoffrey.blake@arm.com                                     [0x1, int(self.device)]))
2368733Sgeoffrey.blake@arm.com        node.append(FdtPropertyWords("#clock-cells", [0]))
2378733Sgeoffrey.blake@arm.com        freq = int(1.0/self.freq.value) # Values are stored as a clock period
2388733Sgeoffrey.blake@arm.com        node.append(FdtPropertyWords("freq-range", [freq, freq]))
2398733Sgeoffrey.blake@arm.com        node.append(FdtPropertyStrings("clock-output-names",
2408733Sgeoffrey.blake@arm.com                                       ["oscclk" + str(phandle)]))
2418733Sgeoffrey.blake@arm.com        node.appendPhandle(self)
24210319SAndreas.Sandberg@ARM.com        yield node
2432315SN/A
2442683Sktlim@umich.educlass RealViewTemperatureSensor(SimObject):
2458733Sgeoffrey.blake@arm.com    type = 'RealViewTemperatureSensor'
2462315SN/A    cxx_header = "dev/arm/rv_ctrl.hh"
2472315SN/A
2483735Sstever@eecs.umich.edu    parent = Param.RealViewCtrl(Parent.any, "RealView controller")
2492669Sktlim@umich.edu
2509918Ssteve.reinhardt@amd.com    system = Param.System(Parent.any, "system")
2512683Sktlim@umich.edu
2528733Sgeoffrey.blake@arm.com    # See ARM DUI 0447J (ARM Motherboard Express uATX -- V2M-P1) and
2532315SN/A    # the individual core/logic tile reference manuals for details
2542315SN/A    # about the site/position/dcc/device allocation.
2553735Sstever@eecs.umich.edu    site = Param.UInt8("Board Site")
2563735Sstever@eecs.umich.edu    position = Param.UInt8("Position in device stack")
2572315SN/A    dcc = Param.UInt8("Daughterboard Configuration Controller")
2589918Ssteve.reinhardt@amd.com    device = Param.UInt8("Device ID")
2592683Sktlim@umich.edu
2608733Sgeoffrey.blake@arm.comclass VExpressMCC(SubSystem):
2612315SN/A    """ARM V2M-P1 Motherboard Configuration Controller
2622315SN/A
26310319SAndreas.Sandberg@ARM.comThis subsystem describes a subset of the devices that sit behind the
2649920Syasuko.eckert@amd.commotherboard configuration controller on the the ARM Motherboard
2659920Syasuko.eckert@amd.comExpress (V2M-P1) motherboard. See ARM DUI 0447J for details.
2669920Syasuko.eckert@amd.com    """
2679920Syasuko.eckert@amd.com
2689920Syasuko.eckert@amd.com    class Osc(RealViewOsc):
2699920Syasuko.eckert@amd.com        site, position, dcc = (0, 0, 0)
2708733Sgeoffrey.blake@arm.com
2718733Sgeoffrey.blake@arm.com    class Temperature(RealViewTemperatureSensor):
2728733Sgeoffrey.blake@arm.com        site, position, dcc = (0, 0, 0)
2738733Sgeoffrey.blake@arm.com
2748733Sgeoffrey.blake@arm.com    osc_mcc = Osc(device=0, freq="50MHz")
2752669Sktlim@umich.edu    osc_clcd = Osc(device=1, freq="23.75MHz")
27610319SAndreas.Sandberg@ARM.com    osc_peripheral = Osc(device=2, freq="24MHz")
2778733Sgeoffrey.blake@arm.com    osc_system_bus = Osc(device=4, freq="24MHz")
2788733Sgeoffrey.blake@arm.com
2798733Sgeoffrey.blake@arm.com    # See Table 4.19 in ARM DUI 0447J (Motherboard Express uATX TRM).
2808733Sgeoffrey.blake@arm.com    temp_crtl = Temperature(device=0)
2818733Sgeoffrey.blake@arm.com
2828733Sgeoffrey.blake@arm.com    def generateDeviceTree(self, state):
2838733Sgeoffrey.blake@arm.com        node = FdtNode("mcc")
2848733Sgeoffrey.blake@arm.com        node.appendCompatible("arm,vexpress,config-bus")
2858733Sgeoffrey.blake@arm.com        node.append(FdtPropertyWords("arm,vexpress,site", [0]))
2868733Sgeoffrey.blake@arm.com
2872315SN/A        for obj in self._children.values():
28810698Sandreas.hansson@arm.com            if issubclass(type(obj), SimObject):
2894172Ssaidi@eecs.umich.edu                node.append(obj.generateDeviceTree(state))
2904172Ssaidi@eecs.umich.edu
2914172Ssaidi@eecs.umich.edu        io_phandle = state.phandle(self.osc_mcc.parent.unproxy(self))
2924172Ssaidi@eecs.umich.edu        node.append(FdtPropertyWords("arm,vexpress,config-bridge", io_phandle))
2932315SN/A
2942315SN/A        yield node
2952683Sktlim@umich.edu
2962315SN/Aclass CoreTile2A15DCC(SubSystem):
2972315SN/A    """ARM CoreTile Express A15x2 Daughterboard Configuration Controller
2984172Ssaidi@eecs.umich.edu
2992315SN/AThis subsystem describes a subset of the devices that sit behind the
30010034SGeoffrey.Blake@arm.comdaughterboard configuration controller on a CoreTile Express A15x2. See
3014172Ssaidi@eecs.umich.eduARM DUI 0604E for details.
3024172Ssaidi@eecs.umich.edu    """
3032315SN/A
3042315SN/A    class Osc(RealViewOsc):
3053468Sgblack@eecs.umich.edu        site, position, dcc = (1, 0, 0)
3062315SN/A
30710034SGeoffrey.Blake@arm.com    # See Table 2.8 in ARM DUI 0604E (CoreTile Express A15x2 TRM)
3082315SN/A    osc_cpu = Osc(device=0, freq="60MHz")
3092683Sktlim@umich.edu    osc_hsbm = Osc(device=4, freq="40MHz")
3102315SN/A    osc_pxl = Osc(device=5, freq="23.75MHz")
3112315SN/A    osc_smb = Osc(device=6, freq="50MHz")
3128733Sgeoffrey.blake@arm.com    osc_sys = Osc(device=7, freq="60MHz")
3138733Sgeoffrey.blake@arm.com    osc_ddr = Osc(device=8, freq="40MHz")
3149918Ssteve.reinhardt@amd.com
3158733Sgeoffrey.blake@arm.com    def generateDeviceTree(self, state):
3168733Sgeoffrey.blake@arm.com        node = FdtNode("dcc")
3178733Sgeoffrey.blake@arm.com        node.appendCompatible("arm,vexpress,config-bus")
3188733Sgeoffrey.blake@arm.com
3198733Sgeoffrey.blake@arm.com        for obj in self._children.values():
3208733Sgeoffrey.blake@arm.com            if isinstance(obj, SimObject):
3219918Ssteve.reinhardt@amd.com                node.append(obj.generateDeviceTree(state))
32210034SGeoffrey.Blake@arm.com
3238733Sgeoffrey.blake@arm.com        io_phandle = state.phandle(self.osc_cpu.parent.unproxy(self))
3248888Sgeoffrey.blake@arm.com        node.append(FdtPropertyWords("arm,vexpress,config-bridge", io_phandle))
3258888Sgeoffrey.blake@arm.com
32610319SAndreas.Sandberg@ARM.com        yield node
3278888Sgeoffrey.blake@arm.com
3288888Sgeoffrey.blake@arm.comclass AmbaFake(AmbaPioDevice):
3298888Sgeoffrey.blake@arm.com    type = 'AmbaFake'
3308888Sgeoffrey.blake@arm.com    cxx_header = "dev/arm/amba_fake.hh"
3318888Sgeoffrey.blake@arm.com    ignore_access = Param.Bool(False, "Ignore reads/writes to this device, (e.g. IsaFake + AMBA)")
33210319SAndreas.Sandberg@ARM.com    amba_id = 0;
3338888Sgeoffrey.blake@arm.com
3348888Sgeoffrey.blake@arm.comclass Pl011(Uart):
3358888Sgeoffrey.blake@arm.com    type = 'Pl011'
3368888Sgeoffrey.blake@arm.com    cxx_header = "dev/arm/pl011.hh"
3378888Sgeoffrey.blake@arm.com    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
3388733Sgeoffrey.blake@arm.com    int_num = Param.UInt32("Interrupt number that connects to GIC")
3398733Sgeoffrey.blake@arm.com    end_on_eot = Param.Bool(False, "End the simulation when a EOT is received on the UART")
3408733Sgeoffrey.blake@arm.com    int_delay = Param.Latency("100ns", "Time between action and interrupt generation by UART")
3418733Sgeoffrey.blake@arm.com
3428733Sgeoffrey.blake@arm.com    def generateDeviceTree(self, state):
3438733Sgeoffrey.blake@arm.com        node = self.generateBasicPioDeviceNode(state, 'uart', self.pio_addr,
3448733Sgeoffrey.blake@arm.com                                               0x1000, [int(self.int_num)])
3452315SN/A        node.appendCompatible(["arm,pl011", "arm,primecell"])
3465358Sgblack@eecs.umich.edu
3475358Sgblack@eecs.umich.edu        # Hardcoded reference to the realview platform clocks, because the
3485358Sgblack@eecs.umich.edu        # clk_domain can only store one clock (i.e. it is not a VectorParam)
3495358Sgblack@eecs.umich.edu        realview = self._parent.unproxy(self)
3505358Sgblack@eecs.umich.edu        node.append(FdtPropertyWords("clocks",
3515358Sgblack@eecs.umich.edu            [state.phandle(realview.mcc.osc_peripheral),
35210529Smorr@cs.wisc.edu            state.phandle(realview.dcc.osc_smb)]))
35311148Smitch.hayenga@arm.com        node.append(FdtPropertyStrings("clock-names", ["uartclk", "apb_pclk"]))
35411148Smitch.hayenga@arm.com        yield node
35510529Smorr@cs.wisc.edu
35611148Smitch.hayenga@arm.comclass Sp804(AmbaPioDevice):
35711148Smitch.hayenga@arm.com    type = 'Sp804'
35810529Smorr@cs.wisc.edu    cxx_header = "dev/arm/timer_sp804.hh"
3595358Sgblack@eecs.umich.edu    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
3605358Sgblack@eecs.umich.edu    int_num0 = Param.UInt32("Interrupt number that connects to GIC")
3615358Sgblack@eecs.umich.edu    clock0 = Param.Clock('1MHz', "Clock speed of the input")
3625358Sgblack@eecs.umich.edu    int_num1 = Param.UInt32("Interrupt number that connects to GIC")
3635358Sgblack@eecs.umich.edu    clock1 = Param.Clock('1MHz', "Clock speed of the input")
3645358Sgblack@eecs.umich.edu    amba_id = 0x00141804
3655358Sgblack@eecs.umich.edu
3665358Sgblack@eecs.umich.educlass A9GlobalTimer(BasicPioDevice):
3675358Sgblack@eecs.umich.edu    type = 'A9GlobalTimer'
3685358Sgblack@eecs.umich.edu    cxx_header = "dev/arm/timer_a9global.hh"
3698733Sgeoffrey.blake@arm.com    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
3708733Sgeoffrey.blake@arm.com    int_num = Param.UInt32("Interrrupt number that connects to GIC")
3718733Sgeoffrey.blake@arm.com
3728733Sgeoffrey.blake@arm.comclass CpuLocalTimer(BasicPioDevice):
37310319SAndreas.Sandberg@ARM.com    type = 'CpuLocalTimer'
37410319SAndreas.Sandberg@ARM.com    cxx_header = "dev/arm/timer_cpulocal.hh"
37510319SAndreas.Sandberg@ARM.com    int_timer = Param.ArmPPI("Interrrupt used per-cpu to GIC")
37610319SAndreas.Sandberg@ARM.com    int_watchdog = Param.ArmPPI("Interrupt for per-cpu watchdog to GIC")
37710319SAndreas.Sandberg@ARM.com
3788733Sgeoffrey.blake@arm.comclass GenericTimer(ClockedObject):
3798733Sgeoffrey.blake@arm.com    type = 'GenericTimer'
3808733Sgeoffrey.blake@arm.com    cxx_header = "dev/arm/generic_timer.hh"
3815702Ssaidi@eecs.umich.edu    system = Param.ArmSystem(Parent.any, "system")
3825702Ssaidi@eecs.umich.edu    int_phys_s = Param.ArmPPI("Physical (S) timer interrupt")
38311168Sandreas.hansson@arm.com    int_phys_ns = Param.ArmPPI("Physical (NS) timer interrupt")
3842315SN/A    int_virt = Param.ArmPPI("Virtual timer interrupt")
3852332SN/A    int_hyp = Param.ArmPPI("Hypervisor timer interrupt")
38610319SAndreas.Sandberg@ARM.com
3872315SN/A    def generateDeviceTree(self, state):
3882315SN/A        node = FdtNode("timer")
3892315SN/A
3902315SN/A        node.appendCompatible(["arm,cortex-a15-timer",
3912732Sktlim@umich.edu                               "arm,armv7-timer",
3922315SN/A                               "arm,armv8-timer"])
3932732Sktlim@umich.edu        node.append(FdtPropertyWords("interrupts", [
3948733Sgeoffrey.blake@arm.com            1, int(self.int_phys_s.num) - 16, 0xf08,
3958733Sgeoffrey.blake@arm.com            1, int(self.int_phys_ns.num) - 16, 0xf08,
3962315SN/A            1, int(self.int_virt.num) - 16, 0xf08,
3972732Sktlim@umich.edu            1, int(self.int_hyp.num) - 16, 0xf08,
3982732Sktlim@umich.edu        ]))
3992680Sktlim@umich.edu        clock = state.phandle(self.clk_domain.unproxy(self))
4002683Sktlim@umich.edu        node.append(FdtPropertyWords("clocks", clock))
4012315SN/A
4022315SN/A        yield node
4032669Sktlim@umich.edu
4042679Sktlim@umich.educlass GenericTimerMem(PioDevice):
4052315SN/A    type = 'GenericTimerMem'
4062315SN/A    cxx_header = "dev/arm/generic_timer.hh"
4072315SN/A
4088733Sgeoffrey.blake@arm.com    base = Param.Addr(0, "Base address")
4092315SN/A
4102354SN/A    int_phys = Param.ArmSPI("Physical Interrupt")
4112732Sktlim@umich.edu    int_virt = Param.ArmSPI("Virtual Interrupt")
4122315SN/A
4132315SN/Aclass PL031(AmbaIntDevice):
4142315SN/A    type = 'PL031'
4152315SN/A    cxx_header = "dev/arm/rtc_pl031.hh"
4162350SN/A    time = Param.Time('01/01/2009', "System time to use ('Now' for actual time)")
4172350SN/A    amba_id = 0x00341031
4182350SN/A
4192350SN/A    def generateDeviceTree(self, state):
4202350SN/A        node = self.generateBasicPioDeviceNode(state, 'rtc', self.pio_addr,
4212350SN/A                                               0x1000, [int(self.int_num)])
4228733Sgeoffrey.blake@arm.com
4232315SN/A        node.appendCompatible(["arm,pl031", "arm,primecell"])
4242315SN/A        clock = state.phandle(self.clk_domain.unproxy(self))
4258733Sgeoffrey.blake@arm.com        node.append(FdtPropertyWords("clocks", clock))
4268733Sgeoffrey.blake@arm.com
4278733Sgeoffrey.blake@arm.com        yield node
4282315SN/A
4292315SN/Aclass Pl050(AmbaIntDevice):
4309023Sgblack@eecs.umich.edu    type = 'Pl050'
4312315SN/A    cxx_header = "dev/arm/kmi.hh"
4322315SN/A    amba_id = 0x00141050
4332840Sktlim@umich.edu
4342315SN/A    ps2 = Param.PS2Device("PS/2 device")
4352315SN/A
43610379Sandreas.hansson@arm.com    def generateDeviceTree(self, state):
4378733Sgeoffrey.blake@arm.com        node = self.generateBasicPioDeviceNode(state, 'kmi', self.pio_addr,
4382732Sktlim@umich.edu                                               0x1000, [int(self.int_num)])
4392315SN/A
4402315SN/A        node.appendCompatible(["arm,pl050", "arm,primecell"])
4412315SN/A        clock = state.phandle(self.clk_domain.unproxy(self))
4422315SN/A        node.append(FdtPropertyWords("clocks", clock))
4432315SN/A
44410935Snilay@cs.wisc.edu        yield node
4458733Sgeoffrey.blake@arm.com
4462732Sktlim@umich.educlass Pl111(AmbaDmaDevice):
4472732Sktlim@umich.edu    type = 'Pl111'
4482732Sktlim@umich.edu    cxx_header = "dev/arm/pl111.hh"
4492732Sktlim@umich.edu    pixel_clock = Param.Clock('24MHz', "Pixel clock")
4502360SN/A    vnc   = Param.VncInput(Parent.any, "Vnc server for remote frame buffer display")
4512732Sktlim@umich.edu    amba_id = 0x00141111
4522360SN/A    enable_capture = Param.Bool(True, "capture frame to system.framebuffer.bmp")
4532354SN/A
4542360SN/Aclass HDLcd(AmbaDmaDevice):
4552732Sktlim@umich.edu    type = 'HDLcd'
4562732Sktlim@umich.edu    cxx_header = "dev/arm/hdlcd.hh"
4572732Sktlim@umich.edu    vnc = Param.VncInput(Parent.any, "Vnc server for remote frame buffer "
4582732Sktlim@umich.edu                                     "display")
4592354SN/A    amba_id = 0x00141000
4602354SN/A    workaround_swap_rb = Param.Bool(False, "Workaround incorrect color "
4612354SN/A                                    "selector order in some kernels")
4622354SN/A    workaround_dma_line_count = Param.Bool(True, "Workaround incorrect "
4632315SN/A                                           "DMA line count (off by 1)")
4642315SN/A    enable_capture = Param.Bool(True, "capture frame to "
4652315SN/A                                      "system.framebuffer.{extension}")
4662315SN/A    frame_format = Param.ImageFormat("Auto",
4672315SN/A                                     "image format of the captured frame")
4682315SN/A
469    pixel_buffer_size = Param.MemorySize32("2kB", "Size of address range")
470
471    pxl_clk = Param.ClockDomain("Pixel clock source")
472    pixel_chunk = Param.Unsigned(32, "Number of pixels to handle in one batch")
473    virt_refresh_rate = Param.Frequency("20Hz", "Frame refresh rate "
474                                        "in KVM mode")
475
476    def generateDeviceTree(self, state):
477        # Interrupt number is hardcoded; it is not a property of this class
478        node = self.generateBasicPioDeviceNode(state, 'hdlcd',
479                                               self.pio_addr, 0x1000, [63])
480
481        node.appendCompatible(["arm,hdlcd"])
482        node.append(FdtPropertyWords("clocks", state.phandle(self.pxl_clk)))
483        node.append(FdtPropertyStrings("clock-names", ["pxlclk"]))
484
485        # This driver is disabled by default since the required DT nodes
486        # haven't been standardized yet. To use it,  override this status to
487        # "ok" and add the display configuration nodes required by the driver.
488        # See the driver for more information.
489        node.append(FdtPropertyStrings("status", ["disabled"]))
490
491        yield node
492
493class RealView(Platform):
494    type = 'RealView'
495    cxx_header = "dev/arm/realview.hh"
496    system = Param.System(Parent.any, "system")
497    _mem_regions = [ AddrRange(0, size='256MB') ]
498
499    def _on_chip_devices(self):
500        return []
501
502    def _off_chip_devices(self):
503        return []
504
505    _off_chip_ranges = []
506
507    def _attach_device(self, device, bus, dma_ports=None):
508        if hasattr(device, "pio"):
509            device.pio = bus.master
510        if hasattr(device, "dma"):
511            if dma_ports is None:
512                device.dma = bus.slave
513            else:
514                dma_ports.append(device.dma)
515
516    def _attach_io(self, devices, *args, **kwargs):
517        for d in devices:
518            self._attach_device(d, *args, **kwargs)
519
520    def _attach_clk(self, devices, clkdomain):
521        for d in devices:
522            if hasattr(d, "clk_domain"):
523                d.clk_domain = clkdomain
524
525    def attachPciDevices(self):
526        pass
527
528    def enableMSIX(self):
529        pass
530
531    def onChipIOClkDomain(self, clkdomain):
532        self._attach_clk(self._on_chip_devices(), clkdomain)
533
534    def offChipIOClkDomain(self, clkdomain):
535        self._attach_clk(self._off_chip_devices(), clkdomain)
536
537    def attachOnChipIO(self, bus, bridge=None, *args, **kwargs):
538        self._attach_io(self._on_chip_devices(), bus, *args, **kwargs)
539        if bridge:
540            bridge.ranges = self._off_chip_ranges
541
542    def attachIO(self, *args, **kwargs):
543        self._attach_io(self._off_chip_devices(), *args, **kwargs)
544
545    def setupBootLoader(self, mem_bus, cur_sys, loc):
546        cur_sys.bootmem = SimpleMemory(
547            range = AddrRange('2GB', size = '64MB'),
548            conf_table_reported = False)
549        if mem_bus is not None:
550            cur_sys.bootmem.port = mem_bus.master
551        cur_sys.boot_loader = loc('boot.arm')
552        cur_sys.atags_addr = 0x100
553        cur_sys.load_offset = 0
554
555    def generateDeviceTree(self, state):
556        node = FdtNode("/") # Things in this module need to end up in the root
557        node.append(FdtPropertyWords("interrupt-parent",
558                                     state.phandle(self.gic)))
559
560        for subnode in self.recurseDeviceTree(state):
561            node.append(subnode)
562
563        yield node
564
565    def annotateCpuDeviceNode(self, cpu, state):
566        cpu.append(FdtPropertyStrings("enable-method", "spin-table"))
567        cpu.append(FdtPropertyWords("cpu-release-addr", \
568                                    state.addrCells(0x8000fff8)))
569
570# Reference for memory map and interrupt number
571# RealView Platform Baseboard Explore for Cortex-A9 User Guide(ARM DUI 0440A)
572# Chapter 4: Programmer's Reference
573class RealViewPBX(RealView):
574    uart = Pl011(pio_addr=0x10009000, int_num=44)
575    realview_io = RealViewCtrl(pio_addr=0x10000000)
576    mcc = VExpressMCC()
577    dcc = CoreTile2A15DCC()
578    gic = Gic400(cpu_addr=0x1f000100, dist_addr=0x1f001000, cpu_size=0x100)
579    pci_host = GenericPciHost(
580        conf_base=0x30000000, conf_size='256MB', conf_device_bits=16,
581        pci_pio_base=0)
582    timer0 = Sp804(int_num0=36, int_num1=36, pio_addr=0x10011000)
583    timer1 = Sp804(int_num0=37, int_num1=37, pio_addr=0x10012000)
584    global_timer = A9GlobalTimer(int_num=27, pio_addr=0x1f000200)
585    local_cpu_timer = CpuLocalTimer(int_timer=ArmPPI(num=29),
586                                    int_watchdog=ArmPPI(num=30),
587                                    pio_addr=0x1f000600)
588    clcd = Pl111(pio_addr=0x10020000, int_num=55)
589    kmi0   = Pl050(pio_addr=0x10006000, int_num=52, ps2=PS2Keyboard())
590    kmi1   = Pl050(pio_addr=0x10007000, int_num=53, ps2=PS2TouchKit())
591    a9scu  = A9SCU(pio_addr=0x1f000000)
592    cf_ctrl = IdeController(disks=[], pci_func=0, pci_dev=7, pci_bus=2,
593                            io_shift = 1, ctrl_offset = 2, Command = 0x1,
594                            BAR0 = 0x18000000, BAR0Size = '16B',
595                            BAR1 = 0x18000100, BAR1Size = '1B',
596                            BAR0LegacyIO = True, BAR1LegacyIO = True)
597
598
599    l2x0_fake     = IsaFake(pio_addr=0x1f002000, pio_size=0xfff)
600    flash_fake    = IsaFake(pio_addr=0x40000000, pio_size=0x20000000,
601                            fake_mem=True)
602    dmac_fake     = AmbaFake(pio_addr=0x10030000)
603    uart1_fake    = AmbaFake(pio_addr=0x1000a000)
604    uart2_fake    = AmbaFake(pio_addr=0x1000b000)
605    uart3_fake    = AmbaFake(pio_addr=0x1000c000)
606    smc_fake      = AmbaFake(pio_addr=0x100e1000)
607    sp810_fake    = AmbaFake(pio_addr=0x10001000, ignore_access=True)
608    watchdog_fake = AmbaFake(pio_addr=0x10010000)
609    gpio0_fake    = AmbaFake(pio_addr=0x10013000)
610    gpio1_fake    = AmbaFake(pio_addr=0x10014000)
611    gpio2_fake    = AmbaFake(pio_addr=0x10015000)
612    ssp_fake      = AmbaFake(pio_addr=0x1000d000)
613    sci_fake      = AmbaFake(pio_addr=0x1000e000)
614    aaci_fake     = AmbaFake(pio_addr=0x10004000)
615    mmc_fake      = AmbaFake(pio_addr=0x10005000)
616    rtc           = PL031(pio_addr=0x10017000, int_num=42)
617    energy_ctrl   = EnergyCtrl(pio_addr=0x1000f000)
618
619
620    # Attach I/O devices that are on chip and also set the appropriate
621    # ranges for the bridge
622    def attachOnChipIO(self, bus, bridge):
623       self.gic.pio = bus.master
624       self.l2x0_fake.pio = bus.master
625       self.a9scu.pio = bus.master
626       self.global_timer.pio = bus.master
627       self.local_cpu_timer.pio = bus.master
628       # Bridge ranges based on excluding what is part of on-chip I/O
629       # (gic, l2x0, a9scu, local_cpu_timer)
630       bridge.ranges = [AddrRange(self.realview_io.pio_addr,
631                                  self.a9scu.pio_addr - 1),
632                        AddrRange(self.flash_fake.pio_addr,
633                                  self.flash_fake.pio_addr + \
634                                  self.flash_fake.pio_size - 1)]
635
636    # Set the clock domain for IO objects that are considered
637    # to be "close" to the cores.
638    def onChipIOClkDomain(self, clkdomain):
639        self.gic.clk_domain             = clkdomain
640        self.l2x0_fake.clk_domain       = clkdomain
641        self.a9scu.clkdomain            = clkdomain
642        self.local_cpu_timer.clk_domain = clkdomain
643
644    # Attach I/O devices to specified bus object.  Can't do this
645    # earlier, since the bus object itself is typically defined at the
646    # System level.
647    def attachIO(self, bus):
648       self.uart.pio          = bus.master
649       self.realview_io.pio   = bus.master
650       self.pci_host.pio      = bus.master
651       self.timer0.pio        = bus.master
652       self.timer1.pio        = bus.master
653       self.clcd.pio          = bus.master
654       self.clcd.dma          = bus.slave
655       self.kmi0.pio          = bus.master
656       self.kmi1.pio          = bus.master
657       self.cf_ctrl.pio       = bus.master
658       self.cf_ctrl.dma       = bus.slave
659       self.dmac_fake.pio     = bus.master
660       self.uart1_fake.pio    = bus.master
661       self.uart2_fake.pio    = bus.master
662       self.uart3_fake.pio    = bus.master
663       self.smc_fake.pio      = bus.master
664       self.sp810_fake.pio    = bus.master
665       self.watchdog_fake.pio = bus.master
666       self.gpio0_fake.pio    = bus.master
667       self.gpio1_fake.pio    = bus.master
668       self.gpio2_fake.pio    = bus.master
669       self.ssp_fake.pio      = bus.master
670       self.sci_fake.pio      = bus.master
671       self.aaci_fake.pio     = bus.master
672       self.mmc_fake.pio      = bus.master
673       self.rtc.pio           = bus.master
674       self.flash_fake.pio    = bus.master
675       self.energy_ctrl.pio   = bus.master
676
677    # Set the clock domain for IO objects that are considered
678    # to be "far" away from the cores.
679    def offChipIOClkDomain(self, clkdomain):
680        self.uart.clk_domain          = clkdomain
681        self.realview_io.clk_domain   = clkdomain
682        self.timer0.clk_domain        = clkdomain
683        self.timer1.clk_domain        = clkdomain
684        self.clcd.clk_domain          = clkdomain
685        self.kmi0.clk_domain          = clkdomain
686        self.kmi1.clk_domain          = clkdomain
687        self.cf_ctrl.clk_domain       = clkdomain
688        self.dmac_fake.clk_domain     = clkdomain
689        self.uart1_fake.clk_domain    = clkdomain
690        self.uart2_fake.clk_domain    = clkdomain
691        self.uart3_fake.clk_domain    = clkdomain
692        self.smc_fake.clk_domain      = clkdomain
693        self.sp810_fake.clk_domain    = clkdomain
694        self.watchdog_fake.clk_domain = clkdomain
695        self.gpio0_fake.clk_domain    = clkdomain
696        self.gpio1_fake.clk_domain    = clkdomain
697        self.gpio2_fake.clk_domain    = clkdomain
698        self.ssp_fake.clk_domain      = clkdomain
699        self.sci_fake.clk_domain      = clkdomain
700        self.aaci_fake.clk_domain     = clkdomain
701        self.mmc_fake.clk_domain      = clkdomain
702        self.rtc.clk_domain           = clkdomain
703        self.flash_fake.clk_domain    = clkdomain
704        self.energy_ctrl.clk_domain   = clkdomain
705
706class VExpress_EMM(RealView):
707    _mem_regions = [ AddrRange('2GB', size='2GB') ]
708
709    # Ranges based on excluding what is part of on-chip I/O (gic,
710    # a9scu)
711    _off_chip_ranges = [AddrRange(0x2F000000, size='16MB'),
712                        AddrRange(0x30000000, size='256MB'),
713                        AddrRange(0x40000000, size='512MB'),
714                        AddrRange(0x18000000, size='64MB'),
715                        AddrRange(0x1C000000, size='64MB')]
716
717    # Platform control device (off-chip)
718    realview_io = RealViewCtrl(proc_id0=0x14000000, proc_id1=0x14000000,
719                               idreg=0x02250000, pio_addr=0x1C010000)
720
721    mcc = VExpressMCC()
722    dcc = CoreTile2A15DCC()
723
724    ### On-chip devices ###
725    gic = Gic400(dist_addr=0x2C001000, cpu_addr=0x2C002000)
726    vgic   = VGic(vcpu_addr=0x2c006000, hv_addr=0x2c004000, ppint=25)
727
728    local_cpu_timer = CpuLocalTimer(int_timer=ArmPPI(num=29),
729                                    int_watchdog=ArmPPI(num=30),
730                                    pio_addr=0x2C080000)
731
732    hdlcd  = HDLcd(pxl_clk=dcc.osc_pxl,
733                   pio_addr=0x2b000000, int_num=117,
734                   workaround_swap_rb=True)
735
736    def _on_chip_devices(self):
737        devices = [
738            self.gic, self.vgic,
739            self.local_cpu_timer
740        ]
741        if hasattr(self, "gicv2m"):
742            devices.append(self.gicv2m)
743        devices.append(self.hdlcd)
744        return devices
745
746    ### Off-chip devices ###
747    uart = Pl011(pio_addr=0x1c090000, int_num=37)
748    pci_host = GenericPciHost(
749        conf_base=0x30000000, conf_size='256MB', conf_device_bits=16,
750        pci_pio_base=0)
751
752    generic_timer = GenericTimer(int_phys_s=ArmPPI(num=29),
753                                 int_phys_ns=ArmPPI(num=30),
754                                 int_virt=ArmPPI(num=27),
755                                 int_hyp=ArmPPI(num=26))
756
757    timer0 = Sp804(int_num0=34, int_num1=34, pio_addr=0x1C110000, clock0='1MHz', clock1='1MHz')
758    timer1 = Sp804(int_num0=35, int_num1=35, pio_addr=0x1C120000, clock0='1MHz', clock1='1MHz')
759    clcd   = Pl111(pio_addr=0x1c1f0000, int_num=46)
760    kmi0   = Pl050(pio_addr=0x1c060000, int_num=44, ps2=PS2Keyboard())
761    kmi1   = Pl050(pio_addr=0x1c070000, int_num=45, ps2=PS2TouchKit())
762    cf_ctrl = IdeController(disks=[], pci_func=0, pci_dev=0, pci_bus=2,
763                            io_shift = 2, ctrl_offset = 2, Command = 0x1,
764                            BAR0 = 0x1C1A0000, BAR0Size = '256B',
765                            BAR1 = 0x1C1A0100, BAR1Size = '4096B',
766                            BAR0LegacyIO = True, BAR1LegacyIO = True)
767
768    vram           = SimpleMemory(range = AddrRange(0x18000000, size='32MB'),
769                                  conf_table_reported = False)
770    rtc            = PL031(pio_addr=0x1C170000, int_num=36)
771
772    l2x0_fake      = IsaFake(pio_addr=0x2C100000, pio_size=0xfff)
773    uart1_fake     = AmbaFake(pio_addr=0x1C0A0000)
774    uart2_fake     = AmbaFake(pio_addr=0x1C0B0000)
775    uart3_fake     = AmbaFake(pio_addr=0x1C0C0000)
776    sp810_fake     = AmbaFake(pio_addr=0x1C020000, ignore_access=True)
777    watchdog_fake  = AmbaFake(pio_addr=0x1C0F0000)
778    aaci_fake      = AmbaFake(pio_addr=0x1C040000)
779    lan_fake       = IsaFake(pio_addr=0x1A000000, pio_size=0xffff)
780    usb_fake       = IsaFake(pio_addr=0x1B000000, pio_size=0x1ffff)
781    mmc_fake       = AmbaFake(pio_addr=0x1c050000)
782    energy_ctrl    = EnergyCtrl(pio_addr=0x1c080000)
783
784    def _off_chip_devices(self):
785        devices = [
786            self.uart,
787            self.realview_io,
788            self.pci_host,
789            self.timer0,
790            self.timer1,
791            self.clcd,
792            self.kmi0,
793            self.kmi1,
794            self.cf_ctrl,
795            self.rtc,
796            self.vram,
797            self.l2x0_fake,
798            self.uart1_fake,
799            self.uart2_fake,
800            self.uart3_fake,
801            self.sp810_fake,
802            self.watchdog_fake,
803            self.aaci_fake,
804            self.lan_fake,
805            self.usb_fake,
806            self.mmc_fake,
807            self.energy_ctrl,
808        ]
809        # Try to attach the I/O if it exists
810        if hasattr(self, "ide"):
811            devices.append(self.ide)
812        if hasattr(self, "ethernet"):
813            devices.append(self.ethernet)
814        return devices
815
816    # Attach any PCI devices that are supported
817    def attachPciDevices(self):
818        self.ethernet = IGbE_e1000(pci_bus=0, pci_dev=0, pci_func=0,
819                                   InterruptLine=1, InterruptPin=1)
820        self.ide = IdeController(disks = [], pci_bus=0, pci_dev=1, pci_func=0,
821                                 InterruptLine=2, InterruptPin=2)
822
823    def enableMSIX(self):
824        self.gic = Gic400(dist_addr=0x2C001000, cpu_addr=0x2C002000,
825                          it_lines=512)
826        self.gicv2m = Gicv2m()
827        self.gicv2m.frames = [Gicv2mFrame(spi_base=256, spi_len=64, addr=0x2C1C0000)]
828
829    def setupBootLoader(self, mem_bus, cur_sys, loc):
830        cur_sys.bootmem = SimpleMemory(range = AddrRange('64MB'),
831                                       conf_table_reported = False)
832        if mem_bus is not None:
833            cur_sys.bootmem.port = mem_bus.master
834        if not cur_sys.boot_loader:
835            cur_sys.boot_loader = loc('boot_emm.arm')
836        cur_sys.atags_addr = 0x8000000
837        cur_sys.load_offset = 0x80000000
838
839class VExpress_EMM64(VExpress_EMM):
840    # Three memory regions are specified totalling 512GB
841    _mem_regions = [ AddrRange('2GB', size='2GB'),
842                     AddrRange('34GB', size='30GB'),
843                     AddrRange('512GB', size='480GB') ]
844    pci_host = GenericPciHost(
845        conf_base=0x30000000, conf_size='256MB', conf_device_bits=12,
846        pci_pio_base=0x2f000000)
847
848    def setupBootLoader(self, mem_bus, cur_sys, loc):
849        cur_sys.bootmem = SimpleMemory(range=AddrRange(0, size='64MB'),
850                                       conf_table_reported=False)
851        if mem_bus is not None:
852            cur_sys.bootmem.port = mem_bus.master
853        if not cur_sys.boot_loader:
854            cur_sys.boot_loader = loc('boot_emm.arm64')
855        cur_sys.atags_addr = 0x8000000
856        cur_sys.load_offset = 0x80000000
857
858class VExpress_GEM5_Base(RealView):
859    """
860The VExpress gem5 memory map is loosely based on a modified
861Versatile Express RS1 memory map.
862
863The gem5 platform has been designed to implement a subset of the
864original Versatile Express RS1 memory map. Off-chip peripherals should,
865when possible, adhere to the Versatile Express memory map. Non-PCI
866off-chip devices that are gem5-specific should live in the CS5 memory
867space to avoid conflicts with existing devices that we might want to
868model in the future. Such devices should normally have interrupts in
869the gem5-specific SPI range.
870
871On-chip peripherals are loosely modeled after the ARM CoreTile Express
872A15x2 A7x3 memory and interrupt map. In particular, the GIC and
873Generic Timer have the same interrupt lines and base addresses. Other
874on-chip devices are gem5 specific.
875
876Unlike the original Versatile Express RS2 extended platform, gem5 implements a
877large contigious DRAM space, without aliases or holes, starting at the
8782GiB boundary. This means that PCI memory is limited to 1GiB.
879
880Memory map:
881   0x00000000-0x03ffffff: Boot memory (CS0)
882   0x04000000-0x07ffffff: Reserved
883   0x08000000-0x0bffffff: Reserved (CS0 alias)
884   0x0c000000-0x0fffffff: Reserved (Off-chip, CS4)
885   0x10000000-0x13ffffff: gem5-specific peripherals (Off-chip, CS5)
886       0x10000000-0x1000ffff: gem5 energy controller
887       0x10010000-0x1001ffff: gem5 pseudo-ops
888
889   0x14000000-0x17ffffff: Reserved (Off-chip, PSRAM, CS1)
890   0x18000000-0x1bffffff: Reserved (Off-chip, Peripherals, CS2)
891   0x1c000000-0x1fffffff: Peripheral block 1 (Off-chip, CS3):
892       0x1c010000-0x1c01ffff: realview_io (VE system control regs.)
893       0x1c060000-0x1c06ffff: KMI0 (keyboard)
894       0x1c070000-0x1c07ffff: KMI1 (mouse)
895       0x1c090000-0x1c09ffff: UART0
896       0x1c0a0000-0x1c0affff: UART1 (reserved)
897       0x1c0b0000-0x1c0bffff: UART2 (reserved)
898       0x1c0c0000-0x1c0cffff: UART3 (reserved)
899       0x1c130000-0x1c13ffff: VirtIO (gem5/FM extension)
900       0x1c140000-0x1c14ffff: VirtIO (gem5/FM extension)
901       0x1c170000-0x1c17ffff: RTC
902
903   0x20000000-0x3fffffff: On-chip peripherals:
904       0x2b000000-0x2b00ffff: HDLCD
905
906       0x2c001000-0x2c001fff: GIC (distributor)
907       0x2c002000-0x2c003fff: GIC (CPU interface)
908       0x2c004000-0x2c005fff: vGIC (HV)
909       0x2c006000-0x2c007fff: vGIC (VCPU)
910       0x2c1c0000-0x2c1cffff: GICv2m MSI frame 0
911
912       0x2d000000-0x2d00ffff: GPU (reserved)
913
914       0x2f000000-0x2fffffff: PCI IO space
915       0x30000000-0x3fffffff: PCI config space
916
917   0x40000000-0x7fffffff: Ext. AXI: Used as PCI memory
918
919   0x80000000-X: DRAM
920
921Interrupts:
922      0- 15: Software generated interrupts (SGIs)
923     16- 31: On-chip private peripherals (PPIs)
924        25   : vgic
925        26   : generic_timer (hyp)
926        27   : generic_timer (virt)
927        28   : Reserved (Legacy FIQ)
928        29   : generic_timer (phys, sec)
929        30   : generic_timer (phys, non-sec)
930        31   : Reserved (Legacy IRQ)
931    32- 95: Mother board peripherals (SPIs)
932        32   : Reserved (SP805)
933        33   : Reserved (IOFPGA SW int)
934        34-35: Reserved (SP804)
935        36   : RTC
936        37-40: uart0-uart3
937        41-42: Reserved (PL180)
938        43   : Reserved (AACI)
939        44-45: kmi0-kmi1
940        46   : Reserved (CLCD)
941        47   : Reserved (Ethernet)
942        48   : Reserved (USB)
943    95-255: On-chip interrupt sources (we use these for
944            gem5-specific devices, SPIs)
945         74    : VirtIO (gem5/FM extension)
946         75    : VirtIO (gem5/FM extension)
947         95    : HDLCD
948         96- 98: GPU (reserved)
949        100-103: PCI
950   256-319: MSI frame 0 (gem5-specific, SPIs)
951   320-511: Unused
952
953    """
954
955    # Everything above 2GiB is memory
956    _mem_regions = [ AddrRange('2GB', size='510GB') ]
957
958    _off_chip_ranges = [
959        # CS1-CS5
960        AddrRange(0x0c000000, 0x1fffffff),
961        # External AXI interface (PCI)
962        AddrRange(0x2f000000, 0x7fffffff),
963    ]
964
965    # Platform control device (off-chip)
966    realview_io = RealViewCtrl(proc_id0=0x14000000, proc_id1=0x14000000,
967                               idreg=0x02250000, pio_addr=0x1c010000)
968    mcc = VExpressMCC()
969    dcc = CoreTile2A15DCC()
970
971    ### On-chip devices ###
972    generic_timer = GenericTimer(int_phys_s=ArmPPI(num=29),
973                                 int_phys_ns=ArmPPI(num=30),
974                                 int_virt=ArmPPI(num=27),
975                                 int_hyp=ArmPPI(num=26))
976
977    def _on_chip_devices(self):
978        return [
979            self.generic_timer,
980        ]
981
982    ### Off-chip devices ###
983    clock24MHz = SrcClockDomain(clock="24MHz",
984        voltage_domain=VoltageDomain(voltage="3.3V"))
985
986    uart = [
987        Pl011(pio_addr=0x1c090000, int_num=37),
988    ]
989
990    kmi0 = Pl050(pio_addr=0x1c060000, int_num=44, ps2=PS2Keyboard())
991    kmi1 = Pl050(pio_addr=0x1c070000, int_num=45, ps2=PS2TouchKit())
992
993    rtc = PL031(pio_addr=0x1c170000, int_num=36)
994
995    ### gem5-specific off-chip devices ###
996    pci_host = GenericArmPciHost(
997        conf_base=0x30000000, conf_size='256MB', conf_device_bits=12,
998        pci_pio_base=0x2f000000,
999        int_policy="ARM_PCI_INT_DEV", int_base=100, int_count=4)
1000
1001    energy_ctrl = EnergyCtrl(pio_addr=0x10000000)
1002
1003    vio = [
1004        MmioVirtIO(pio_addr=0x1c130000, pio_size=0x1000,
1005                   interrupt=ArmSPI(num=74)),
1006        MmioVirtIO(pio_addr=0x1c140000, pio_size=0x1000,
1007                   interrupt=ArmSPI(num=75)),
1008    ]
1009
1010    def _off_chip_devices(self):
1011        return [
1012            self.realview_io,
1013            self.uart[0],
1014            self.kmi0,
1015            self.kmi1,
1016            self.rtc,
1017            self.pci_host,
1018            self.energy_ctrl,
1019            self.clock24MHz,
1020            self.vio[0],
1021            self.vio[1],
1022        ]
1023
1024    def attachPciDevice(self, device, *args, **kwargs):
1025        device.host = self.pci_host
1026        self._attach_device(device, *args, **kwargs)
1027
1028    def setupBootLoader(self, mem_bus, cur_sys, loc):
1029        cur_sys.bootmem = SimpleMemory(range=AddrRange(0, size='64MB'),
1030                                       conf_table_reported=False)
1031        if mem_bus is not None:
1032            cur_sys.bootmem.port = mem_bus.master
1033        if not cur_sys.boot_loader:
1034            cur_sys.boot_loader = [ loc('boot_emm.arm64'), loc('boot_emm.arm') ]
1035        cur_sys.atags_addr = 0x8000000
1036        cur_sys.load_offset = 0x80000000
1037
1038        #  Setup m5ops. It's technically not a part of the boot
1039        #  loader, but this is the only place we can configure the
1040        #  system.
1041        cur_sys.m5ops_base = 0x10010000
1042
1043    def generateDeviceTree(self, state):
1044        # Generate using standard RealView function
1045        dt = list(super(VExpress_GEM5_Base, self).generateDeviceTree(state))
1046        if len(dt) > 1:
1047            raise Exception("System returned too many DT nodes")
1048        node = dt[0]
1049
1050        node.appendCompatible(["arm,vexpress"])
1051        node.append(FdtPropertyStrings("model", ["V2P-CA15"]))
1052        node.append(FdtPropertyWords("arm,hbi", [0x0]))
1053        node.append(FdtPropertyWords("arm,vexpress,site", [0xf]))
1054
1055        yield node
1056
1057class VExpress_GEM5_V1_Base(VExpress_GEM5_Base):
1058    gic = kvm_gicv2_class(dist_addr=0x2c001000, cpu_addr=0x2c002000,
1059                          it_lines=512)
1060    vgic = VGic(vcpu_addr=0x2c006000, hv_addr=0x2c004000, ppint=25)
1061    gicv2m = Gicv2m()
1062    gicv2m.frames = [
1063        Gicv2mFrame(spi_base=256, spi_len=64, addr=0x2c1c0000),
1064    ]
1065
1066    def _on_chip_devices(self):
1067        return super(VExpress_GEM5_V1_Base,self)._on_chip_devices() + [
1068                self.gic, self.vgic, self.gicv2m,
1069            ]
1070
1071class VExpress_GEM5_V1(VExpress_GEM5_V1_Base):
1072    hdlcd  = HDLcd(pxl_clk=VExpress_GEM5_V1_Base.dcc.osc_pxl,
1073                   pio_addr=0x2b000000, int_num=95)
1074
1075    def _on_chip_devices(self):
1076        return super(VExpress_GEM5_V1,self)._on_chip_devices() + [
1077                self.hdlcd,
1078            ]
1079
1080class VExpress_GEM5_V2_Base(VExpress_GEM5_Base):
1081    gic = Gicv3()
1082
1083    def _on_chip_devices(self):
1084        return super(VExpress_GEM5_V2_Base,self)._on_chip_devices() + [
1085                self.gic,
1086            ]
1087
1088    def setupBootLoader(self, mem_bus, cur_sys, loc):
1089        cur_sys.boot_loader = [ loc('boot_emm_v2.arm64') ]
1090        super(VExpress_GEM5_V2_Base,self).setupBootLoader(mem_bus,
1091                cur_sys, loc)
1092
1093class VExpress_GEM5_V2(VExpress_GEM5_V2_Base):
1094    hdlcd  = HDLcd(pxl_clk=VExpress_GEM5_V2_Base.dcc.osc_pxl,
1095                   pio_addr=0x2b000000, int_num=95)
1096
1097    def _on_chip_devices(self):
1098        return super(VExpress_GEM5_V2,self)._on_chip_devices() + [
1099                self.hdlcd,
1100            ]
1101