RealView.py revision 13665:9c7fe3811b88
18981Sandreas.hansson@arm.com# Copyright (c) 2009-2018 ARM Limited
213573Ssascha.bischoff@arm.com# All rights reserved.
311804Srjthakur@google.com#
411904Spierre-yves.peneau@lirmm.fr# The license below extends only to copyright in the software and shall
511804Srjthakur@google.com# not be construed as granting a license to any other intellectual
68981Sandreas.hansson@arm.com# property including but not limited to intellectual property relating
78981Sandreas.hansson@arm.com# to a hardware implementation of the functionality of the software
88981Sandreas.hansson@arm.com# licensed hereunder.  You may use the software subject to the license
98981Sandreas.hansson@arm.com# terms below provided that you ensure that this notice is replicated
108981Sandreas.hansson@arm.com# unmodified and in its entirety in all distributions of the software,
118981Sandreas.hansson@arm.com# modified or unmodified, in source code or in binary form.
128981Sandreas.hansson@arm.com#
138981Sandreas.hansson@arm.com# Copyright (c) 2006-2007 The Regents of The University of Michigan
148981Sandreas.hansson@arm.com# All rights reserved.
158981Sandreas.hansson@arm.com#
168981Sandreas.hansson@arm.com# Redistribution and use in source and binary forms, with or without
178981Sandreas.hansson@arm.com# modification, are permitted provided that the following conditions are
188981Sandreas.hansson@arm.com# met: redistributions of source code must retain the above copyright
198981Sandreas.hansson@arm.com# notice, this list of conditions and the following disclaimer;
208981Sandreas.hansson@arm.com# redistributions in binary form must reproduce the above copyright
218981Sandreas.hansson@arm.com# notice, this list of conditions and the following disclaimer in the
228981Sandreas.hansson@arm.com# documentation and/or other materials provided with the distribution;
238981Sandreas.hansson@arm.com# neither the name of the copyright holders nor the names of its
248981Sandreas.hansson@arm.com# contributors may be used to endorse or promote products derived from
258981Sandreas.hansson@arm.com# this software without specific prior written permission.
268981Sandreas.hansson@arm.com#
278981Sandreas.hansson@arm.com# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
288981Sandreas.hansson@arm.com# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
298981Sandreas.hansson@arm.com# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
308981Sandreas.hansson@arm.com# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
318981Sandreas.hansson@arm.com# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
328981Sandreas.hansson@arm.com# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
338981Sandreas.hansson@arm.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
348981Sandreas.hansson@arm.com# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
358981Sandreas.hansson@arm.com# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
368981Sandreas.hansson@arm.com# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
378981Sandreas.hansson@arm.com# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
388981Sandreas.hansson@arm.com#
398981Sandreas.hansson@arm.com# Authors: Ali Saidi
408981Sandreas.hansson@arm.com#          Gabe Black
4111804Srjthakur@google.com#          William Wang
4211904Spierre-yves.peneau@lirmm.fr#          Glenn Bergmans
438981Sandreas.hansson@arm.com
448981Sandreas.hansson@arm.comfrom m5.defines import buildEnv
4511793Sbrandon.potter@amd.comfrom m5.params import *
4611793Sbrandon.potter@amd.comfrom m5.proxy import *
479356Snilay@cs.wisc.edufrom m5.util.fdthelper import *
488981Sandreas.hansson@arm.comfrom m5.objects.ClockDomain import ClockDomain
498981Sandreas.hansson@arm.comfrom m5.objects.VoltageDomain import VoltageDomain
508981Sandreas.hansson@arm.comfrom m5.objects.Device import \
518981Sandreas.hansson@arm.com    BasicPioDevice, PioDevice, IsaFake, BadAddr, DmaDevice
528981Sandreas.hansson@arm.comfrom m5.objects.PciHost import *
538981Sandreas.hansson@arm.comfrom m5.objects.Ethernet import NSGigE, IGbE_igb, IGbE_e1000
548981Sandreas.hansson@arm.comfrom m5.objects.Ide import *
5512084Sspwilson2@wisc.edufrom m5.objects.Platform import Platform
568981Sandreas.hansson@arm.comfrom m5.objects.Terminal import Terminal
5710902Sandreas.sandberg@arm.comfrom m5.objects.Uart import Uart
5810902Sandreas.sandberg@arm.comfrom m5.objects.SimpleMemory import SimpleMemory
598981Sandreas.hansson@arm.comfrom m5.objects.Gic import *
608981Sandreas.hansson@arm.comfrom m5.objects.EnergyCtrl import EnergyCtrl
6110064Sandreas.hansson@arm.comfrom m5.objects.ClockedObject import ClockedObject
6210902Sandreas.sandberg@arm.comfrom m5.objects.ClockDomain import SrcClockDomain
638981Sandreas.hansson@arm.comfrom m5.objects.SubSystem import SubSystem
648981Sandreas.hansson@arm.comfrom m5.objects.Graphics import ImageFormat
658981Sandreas.hansson@arm.comfrom m5.objects.ClockedObject import ClockedObject
668981Sandreas.hansson@arm.comfrom m5.objects.PS2 import *
678981Sandreas.hansson@arm.comfrom m5.objects.VirtIOMMIO import MmioVirtIO
688981Sandreas.hansson@arm.com
698981Sandreas.hansson@arm.com# Platforms with KVM support should generally use in-kernel GIC
708981Sandreas.hansson@arm.com# emulation. Use a GIC model that automatically switches between
718981Sandreas.hansson@arm.com# gem5's GIC model and KVM's GIC model if KVM is available.
728981Sandreas.hansson@arm.comtry:
738981Sandreas.hansson@arm.com    from m5.objects.KvmGic import MuxingKvmGic
748981Sandreas.hansson@arm.com    kvm_gicv2_class = MuxingKvmGic
758981Sandreas.hansson@arm.comexcept ImportError:
768981Sandreas.hansson@arm.com    # KVM support wasn't compiled into gem5. Fallback to a
778981Sandreas.hansson@arm.com    # software-only GIC.
788981Sandreas.hansson@arm.com    kvm_gicv2_class = Gic400
7910994Sandreas.sandberg@arm.com    pass
8010994Sandreas.sandberg@arm.com
8110994Sandreas.sandberg@arm.comclass AmbaPioDevice(BasicPioDevice):
8210994Sandreas.sandberg@arm.com    type = 'AmbaPioDevice'
8310994Sandreas.sandberg@arm.com    abstract = True
8410994Sandreas.sandberg@arm.com    cxx_header = "dev/arm/amba_device.hh"
8510994Sandreas.sandberg@arm.com    amba_id = Param.UInt32("ID of AMBA device for kernel detection")
8613784Sgabeblack@google.com
8713784Sgabeblack@google.comclass AmbaIntDevice(AmbaPioDevice):
888981Sandreas.hansson@arm.com    type = 'AmbaIntDevice'
898981Sandreas.hansson@arm.com    abstract = True
908981Sandreas.hansson@arm.com    cxx_header = "dev/arm/amba_device.hh"
9113784Sgabeblack@google.com    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
928981Sandreas.hansson@arm.com    int_num = Param.UInt32("Interrupt number that connects to GIC")
938981Sandreas.hansson@arm.com    int_delay = Param.Latency("100ns",
9413784Sgabeblack@google.com            "Time between action and interrupt generation by device")
958981Sandreas.hansson@arm.com
968981Sandreas.hansson@arm.comclass AmbaDmaDevice(DmaDevice):
978981Sandreas.hansson@arm.com    type = 'AmbaDmaDevice'
988981Sandreas.hansson@arm.com    abstract = True
998981Sandreas.hansson@arm.com    cxx_header = "dev/arm/amba_device.hh"
1008981Sandreas.hansson@arm.com    pio_addr = Param.Addr("Address for AMBA slave interface")
1018981Sandreas.hansson@arm.com    pio_latency = Param.Latency("10ns", "Time between action and write/read result by AMBA DMA Device")
1028981Sandreas.hansson@arm.com    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
1038981Sandreas.hansson@arm.com    int_num = Param.UInt32("Interrupt number that connects to GIC")
1048981Sandreas.hansson@arm.com    amba_id = Param.UInt32("ID of AMBA device for kernel detection")
1058981Sandreas.hansson@arm.com
1068981Sandreas.hansson@arm.comclass A9SCU(BasicPioDevice):
1078981Sandreas.hansson@arm.com    type = 'A9SCU'
1088981Sandreas.hansson@arm.com    cxx_header = "dev/arm/a9scu.hh"
1098981Sandreas.hansson@arm.com
11011804Srjthakur@google.comclass ArmPciIntRouting(Enum): vals = [
11111804Srjthakur@google.com    'ARM_PCI_INT_STATIC',
11211804Srjthakur@google.com    'ARM_PCI_INT_DEV',
11311804Srjthakur@google.com    'ARM_PCI_INT_PIN',
11411804Srjthakur@google.com    ]
11511804Srjthakur@google.com
11611804Srjthakur@google.comclass GenericArmPciHost(GenericPciHost):
11711804Srjthakur@google.com    type = 'GenericArmPciHost'
11811804Srjthakur@google.com    cxx_header = "dev/arm/pci_host.hh"
11911804Srjthakur@google.com
12011804Srjthakur@google.com    int_policy = Param.ArmPciIntRouting("PCI interrupt routing policy")
12111804Srjthakur@google.com    int_base = Param.Unsigned("PCI interrupt base")
12211804Srjthakur@google.com    int_count = Param.Unsigned("Maximum number of interrupts used by this host")
12311804Srjthakur@google.com
12411804Srjthakur@google.com    def generateDeviceTree(self, state):
12511804Srjthakur@google.com        local_state = FdtState(addr_cells=3, size_cells=2, cpu_cells=1)
12611804Srjthakur@google.com        intterrupt_cells = 1
12711804Srjthakur@google.com
12811804Srjthakur@google.com        node = FdtNode("pci")
12911804Srjthakur@google.com
13011804Srjthakur@google.com        if int(self.conf_device_bits) == 8:
13111804Srjthakur@google.com            node.appendCompatible("pci-host-cam-generic")
13211804Srjthakur@google.com        elif int(self.conf_device_bits) == 12:
13311804Srjthakur@google.com            node.appendCompatible("pci-host-ecam-generic")
13411804Srjthakur@google.com        else:
13511804Srjthakur@google.com            m5.fatal("No compatibility string for the set conf_device_width")
13611804Srjthakur@google.com
13711804Srjthakur@google.com        node.append(FdtPropertyStrings("device_type", ["pci"]))
13811804Srjthakur@google.com
13911804Srjthakur@google.com        # Cell sizes of child nodes/peripherals
14011804Srjthakur@google.com        node.append(local_state.addrCellsProperty())
14111804Srjthakur@google.com        node.append(local_state.sizeCellsProperty())
14211804Srjthakur@google.com        node.append(FdtPropertyWords("#interrupt-cells", intterrupt_cells))
14311804Srjthakur@google.com        # PCI address for CPU
14411804Srjthakur@google.com        node.append(FdtPropertyWords("reg",
14511804Srjthakur@google.com            state.addrCells(self.conf_base) +
14611804Srjthakur@google.com            state.sizeCells(self.conf_size) ))
14711804Srjthakur@google.com
14811804Srjthakur@google.com        # Ranges mapping
14911804Srjthakur@google.com        # For now some of this is hard coded, because the PCI module does not
15011804Srjthakur@google.com        # have a proper full understanding of the memory map, but adapting the
15111804Srjthakur@google.com        # PCI module is beyond the scope of what I'm trying to do here.
15211804Srjthakur@google.com        # Values are taken from the VExpress_GEM5_V1 platform.
15311804Srjthakur@google.com        ranges = []
15411804Srjthakur@google.com        # Pio address range
15511804Srjthakur@google.com        ranges += self.pciFdtAddr(space=1, addr=0)
15611804Srjthakur@google.com        ranges += state.addrCells(self.pci_pio_base)
15711804Srjthakur@google.com        ranges += local_state.sizeCells(0x10000)  # Fixed size
15811804Srjthakur@google.com
15911804Srjthakur@google.com        # AXI memory address range
16011804Srjthakur@google.com        ranges += self.pciFdtAddr(space=2, addr=0)
16111804Srjthakur@google.com        ranges += state.addrCells(0x40000000) # Fixed offset
16211804Srjthakur@google.com        ranges += local_state.sizeCells(0x40000000) # Fixed size
16311804Srjthakur@google.com        node.append(FdtPropertyWords("ranges", ranges))
16411804Srjthakur@google.com
16511804Srjthakur@google.com        if str(self.int_policy) == 'ARM_PCI_INT_DEV':
16611804Srjthakur@google.com            int_phandle = state.phandle(self._parent.unproxy(self).gic)
16711804Srjthakur@google.com            # Interrupt mapping
16811804Srjthakur@google.com            interrupts = []
16911804Srjthakur@google.com            for i in range(int(self.int_count)):
17011804Srjthakur@google.com                interrupts += self.pciFdtAddr(device=i, addr=0) + \
17111804Srjthakur@google.com                    [0x0, int_phandle, 0, int(self.int_base) - 32 + i, 1]
17211804Srjthakur@google.com
17311804Srjthakur@google.com            node.append(FdtPropertyWords("interrupt-map", interrupts))
17411804Srjthakur@google.com
17511804Srjthakur@google.com            int_count = int(self.int_count)
17611804Srjthakur@google.com            if int_count & (int_count - 1):
17711804Srjthakur@google.com                fatal("PCI interrupt count should be power of 2")
17811804Srjthakur@google.com
17911804Srjthakur@google.com            intmask = self.pciFdtAddr(device=int_count - 1, addr=0) + [0x0]
18011804Srjthakur@google.com            node.append(FdtPropertyWords("interrupt-map-mask", intmask))
18111804Srjthakur@google.com        else:
18211804Srjthakur@google.com            m5.fatal("Unsupported PCI interrupt policy " +
18311804Srjthakur@google.com                     "for Device Tree generation")
18411804Srjthakur@google.com
18511804Srjthakur@google.com        node.append(FdtProperty("dma-coherent"))
18611804Srjthakur@google.com
18711804Srjthakur@google.com        yield node
18811804Srjthakur@google.com
18911804Srjthakur@google.comclass RealViewCtrl(BasicPioDevice):
19011804Srjthakur@google.com    type = 'RealViewCtrl'
19111804Srjthakur@google.com    cxx_header = "dev/arm/rv_ctrl.hh"
19211804Srjthakur@google.com    proc_id0 = Param.UInt32(0x0C000000, "Processor ID, SYS_PROCID")
19311804Srjthakur@google.com    proc_id1 = Param.UInt32(0x0C000222, "Processor ID, SYS_PROCID1")
19411804Srjthakur@google.com    idreg = Param.UInt32(0x00000000, "ID Register, SYS_ID")
19511804Srjthakur@google.com
19611804Srjthakur@google.com    def generateDeviceTree(self, state):
19711804Srjthakur@google.com        node = FdtNode("sysreg@%x" % long(self.pio_addr))
19811804Srjthakur@google.com        node.appendCompatible("arm,vexpress-sysreg")
19911804Srjthakur@google.com        node.append(FdtPropertyWords("reg",
20011804Srjthakur@google.com            state.addrCells(self.pio_addr) +
20111804Srjthakur@google.com            state.sizeCells(0x1000) ))
20211804Srjthakur@google.com        node.append(FdtProperty("gpio-controller"))
20311804Srjthakur@google.com        node.append(FdtPropertyWords("#gpio-cells", [2]))
20411804Srjthakur@google.com        node.appendPhandle(self)
20511804Srjthakur@google.com
20611804Srjthakur@google.com        yield node
20711804Srjthakur@google.com
20811804Srjthakur@google.comclass RealViewOsc(ClockDomain):
2098981Sandreas.hansson@arm.com    type = 'RealViewOsc'
2108981Sandreas.hansson@arm.com    cxx_header = "dev/arm/rv_ctrl.hh"
2118981Sandreas.hansson@arm.com
21211804Srjthakur@google.com    parent = Param.RealViewCtrl(Parent.any, "RealView controller")
21311804Srjthakur@google.com
21411139Sandreas.hansson@arm.com    # TODO: We currently don't have the notion of a clock source,
21511139Sandreas.hansson@arm.com    # which means we have to associate oscillators with a voltage
21610994Sandreas.sandberg@arm.com    # source.
21710994Sandreas.sandberg@arm.com    voltage_domain = Param.VoltageDomain(Parent.voltage_domain,
21811804Srjthakur@google.com                                         "Voltage domain")
21911804Srjthakur@google.com
22011804Srjthakur@google.com    # See ARM DUI 0447J (ARM Motherboard Express uATX -- V2M-P1) and
22111804Srjthakur@google.com    # the individual core/logic tile reference manuals for details
22211804Srjthakur@google.com    # about the site/position/dcc/device allocation.
22310994Sandreas.sandberg@arm.com    site = Param.UInt8("Board Site")
22411139Sandreas.hansson@arm.com    position = Param.UInt8("Position in device stack")
22511139Sandreas.hansson@arm.com    dcc = Param.UInt8("Daughterboard Configuration Controller")
22610994Sandreas.sandberg@arm.com    device = Param.UInt8("Device ID")
2278981Sandreas.hansson@arm.com
2288981Sandreas.hansson@arm.com    freq = Param.Clock("Default frequency")
2298981Sandreas.hansson@arm.com
2308981Sandreas.hansson@arm.com    def generateDeviceTree(self, state):
2318981Sandreas.hansson@arm.com        phandle = state.phandle(self)
2328981Sandreas.hansson@arm.com        node = FdtNode("osc@" + format(long(phandle), 'x'))
2338981Sandreas.hansson@arm.com        node.appendCompatible("arm,vexpress-osc")
2348981Sandreas.hansson@arm.com        node.append(FdtPropertyWords("arm,vexpress-sysreg,func",
2358981Sandreas.hansson@arm.com                                     [0x1, int(self.device)]))
2368981Sandreas.hansson@arm.com        node.append(FdtPropertyWords("#clock-cells", [0]))
2378981Sandreas.hansson@arm.com        freq = int(1.0/self.freq.value) # Values are stored as a clock period
2388981Sandreas.hansson@arm.com        node.append(FdtPropertyWords("freq-range", [freq, freq]))
2398981Sandreas.hansson@arm.com        node.append(FdtPropertyStrings("clock-output-names",
2408981Sandreas.hansson@arm.com                                       ["oscclk" + str(phandle)]))
2418981Sandreas.hansson@arm.com        node.appendPhandle(self)
2428981Sandreas.hansson@arm.com        yield node
24311139Sandreas.hansson@arm.com
24411139Sandreas.hansson@arm.comclass RealViewTemperatureSensor(SimObject):
24511804Srjthakur@google.com    type = 'RealViewTemperatureSensor'
24611804Srjthakur@google.com    cxx_header = "dev/arm/rv_ctrl.hh"
2478981Sandreas.hansson@arm.com
2488981Sandreas.hansson@arm.com    parent = Param.RealViewCtrl(Parent.any, "RealView controller")
2498981Sandreas.hansson@arm.com
25011284Sandreas.hansson@arm.com    system = Param.System(Parent.any, "system")
25111284Sandreas.hansson@arm.com
2529785Sandreas.hansson@arm.com    # See ARM DUI 0447J (ARM Motherboard Express uATX -- V2M-P1) and
2539542Sandreas.hansson@arm.com    # the individual core/logic tile reference manuals for details
2548981Sandreas.hansson@arm.com    # about the site/position/dcc/device allocation.
2558981Sandreas.hansson@arm.com    site = Param.UInt8("Board Site")
25611284Sandreas.hansson@arm.com    position = Param.UInt8("Position in device stack")
2578981Sandreas.hansson@arm.com    dcc = Param.UInt8("Daughterboard Configuration Controller")
2588981Sandreas.hansson@arm.com    device = Param.UInt8("Device ID")
2598981Sandreas.hansson@arm.com
2609785Sandreas.hansson@arm.comclass VExpressMCC(SubSystem):
2619542Sandreas.hansson@arm.com    """ARM V2M-P1 Motherboard Configuration Controller
2628981Sandreas.hansson@arm.com
2638981Sandreas.hansson@arm.comThis subsystem describes a subset of the devices that sit behind the
26410994Sandreas.sandberg@arm.commotherboard configuration controller on the the ARM Motherboard
26511139Sandreas.hansson@arm.comExpress (V2M-P1) motherboard. See ARM DUI 0447J for details.
26610994Sandreas.sandberg@arm.com    """
26710994Sandreas.sandberg@arm.com
26811804Srjthakur@google.com    class Osc(RealViewOsc):
26911847Spierre-yves.peneau@lirmm.fr        site, position, dcc = (0, 0, 0)
27011847Spierre-yves.peneau@lirmm.fr
27111804Srjthakur@google.com    class Temperature(RealViewTemperatureSensor):
2728981Sandreas.hansson@arm.com        site, position, dcc = (0, 0, 0)
2738981Sandreas.hansson@arm.com
2748981Sandreas.hansson@arm.com    osc_mcc = Osc(device=0, freq="50MHz")
2758981Sandreas.hansson@arm.com    osc_clcd = Osc(device=1, freq="23.75MHz")
2768981Sandreas.hansson@arm.com    osc_peripheral = Osc(device=2, freq="24MHz")
2778981Sandreas.hansson@arm.com    osc_system_bus = Osc(device=4, freq="24MHz")
2788981Sandreas.hansson@arm.com
2798981Sandreas.hansson@arm.com    # See Table 4.19 in ARM DUI 0447J (Motherboard Express uATX TRM).
2808981Sandreas.hansson@arm.com    temp_crtl = Temperature(device=0)
2818981Sandreas.hansson@arm.com
2828981Sandreas.hansson@arm.com    def generateDeviceTree(self, state):
2838981Sandreas.hansson@arm.com        node = FdtNode("mcc")
28411139Sandreas.hansson@arm.com        node.appendCompatible("arm,vexpress,config-bus")
28511139Sandreas.hansson@arm.com        node.append(FdtPropertyWords("arm,vexpress,site", [0]))
2868981Sandreas.hansson@arm.com
2879785Sandreas.hansson@arm.com        for obj in self._children.values():
2888981Sandreas.hansson@arm.com            if issubclass(type(obj), SimObject):
2898981Sandreas.hansson@arm.com                node.append(obj.generateDeviceTree(state))
2908981Sandreas.hansson@arm.com
2918981Sandreas.hansson@arm.com        io_phandle = state.phandle(self.osc_mcc.parent.unproxy(self))
2929785Sandreas.hansson@arm.com        node.append(FdtPropertyWords("arm,vexpress,config-bridge", io_phandle))
2938981Sandreas.hansson@arm.com
2948981Sandreas.hansson@arm.com        yield node
2958981Sandreas.hansson@arm.com
2969785Sandreas.hansson@arm.comclass CoreTile2A15DCC(SubSystem):
2978981Sandreas.hansson@arm.com    """ARM CoreTile Express A15x2 Daughterboard Configuration Controller
2988981Sandreas.hansson@arm.com
2998981Sandreas.hansson@arm.comThis subsystem describes a subset of the devices that sit behind the
3008981Sandreas.hansson@arm.comdaughterboard configuration controller on a CoreTile Express A15x2. See
3018981Sandreas.hansson@arm.comARM DUI 0604E for details.
3028981Sandreas.hansson@arm.com    """
3038981Sandreas.hansson@arm.com
3048981Sandreas.hansson@arm.com    class Osc(RealViewOsc):
3058981Sandreas.hansson@arm.com        site, position, dcc = (1, 0, 0)
3069785Sandreas.hansson@arm.com
3078981Sandreas.hansson@arm.com    # See Table 2.8 in ARM DUI 0604E (CoreTile Express A15x2 TRM)
3089785Sandreas.hansson@arm.com    osc_cpu = Osc(device=0, freq="60MHz")
3098981Sandreas.hansson@arm.com    osc_hsbm = Osc(device=4, freq="40MHz")
3108981Sandreas.hansson@arm.com    osc_pxl = Osc(device=5, freq="23.75MHz")
3118981Sandreas.hansson@arm.com    osc_smb = Osc(device=6, freq="50MHz")
3129785Sandreas.hansson@arm.com    osc_sys = Osc(device=7, freq="60MHz")
3138981Sandreas.hansson@arm.com    osc_ddr = Osc(device=8, freq="40MHz")
3148981Sandreas.hansson@arm.com
3158981Sandreas.hansson@arm.com    def generateDeviceTree(self, state):
31610994Sandreas.sandberg@arm.com        node = FdtNode("dcc")
31711139Sandreas.hansson@arm.com        node.appendCompatible("arm,vexpress,config-bus")
31811847Spierre-yves.peneau@lirmm.fr
31911847Spierre-yves.peneau@lirmm.fr        for obj in self._children.values():
32011804Srjthakur@google.com            if isinstance(obj, SimObject):
3218981Sandreas.hansson@arm.com                node.append(obj.generateDeviceTree(state))
3228981Sandreas.hansson@arm.com
3238981Sandreas.hansson@arm.com        io_phandle = state.phandle(self.osc_cpu.parent.unproxy(self))
3248981Sandreas.hansson@arm.com        node.append(FdtPropertyWords("arm,vexpress,config-bridge", io_phandle))
3258981Sandreas.hansson@arm.com
3268981Sandreas.hansson@arm.com        yield node
3278981Sandreas.hansson@arm.com
3288981Sandreas.hansson@arm.comclass AmbaFake(AmbaPioDevice):
3298981Sandreas.hansson@arm.com    type = 'AmbaFake'
3308981Sandreas.hansson@arm.com    cxx_header = "dev/arm/amba_fake.hh"
3318981Sandreas.hansson@arm.com    ignore_access = Param.Bool(False, "Ignore reads/writes to this device, (e.g. IsaFake + AMBA)")
3328981Sandreas.hansson@arm.com    amba_id = 0;
3338981Sandreas.hansson@arm.com
3348981Sandreas.hansson@arm.comclass Pl011(Uart):
3358981Sandreas.hansson@arm.com    type = 'Pl011'
3368981Sandreas.hansson@arm.com    cxx_header = "dev/arm/pl011.hh"
33711173Sandreas.hansson@arm.com    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
33811173Sandreas.hansson@arm.com    int_num = Param.UInt32("Interrupt number that connects to GIC")
33911173Sandreas.hansson@arm.com    end_on_eot = Param.Bool(False, "End the simulation when a EOT is received on the UART")
34011173Sandreas.hansson@arm.com    int_delay = Param.Latency("100ns", "Time between action and interrupt generation by UART")
34111173Sandreas.hansson@arm.com
34211173Sandreas.hansson@arm.com    def generateDeviceTree(self, state):
3438981Sandreas.hansson@arm.com        node = self.generateBasicPioDeviceNode(state, 'uart', self.pio_addr,
3448981Sandreas.hansson@arm.com                                               0x1000, [int(self.int_num)])
3458981Sandreas.hansson@arm.com        node.appendCompatible(["arm,pl011", "arm,primecell"])
3469088Sandreas.hansson@arm.com
3479088Sandreas.hansson@arm.com        # Hardcoded reference to the realview platform clocks, because the
3488981Sandreas.hansson@arm.com        # clk_domain can only store one clock (i.e. it is not a VectorParam)
3498981Sandreas.hansson@arm.com        realview = self._parent.unproxy(self)
3508981Sandreas.hansson@arm.com        node.append(FdtPropertyWords("clocks",
3519090Sandreas.hansson@arm.com            [state.phandle(realview.mcc.osc_peripheral),
3528981Sandreas.hansson@arm.com            state.phandle(realview.dcc.osc_smb)]))
3539089Sandreas.hansson@arm.com        node.append(FdtPropertyStrings("clock-names", ["uartclk", "apb_pclk"]))
3549089Sandreas.hansson@arm.com        yield node
3558981Sandreas.hansson@arm.com
3568981Sandreas.hansson@arm.comclass Sp804(AmbaPioDevice):
3578981Sandreas.hansson@arm.com    type = 'Sp804'
35810713Sandreas.hansson@arm.com    cxx_header = "dev/arm/timer_sp804.hh"
3598981Sandreas.hansson@arm.com    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
36010713Sandreas.hansson@arm.com    int_num0 = Param.UInt32("Interrupt number that connects to GIC")
3618981Sandreas.hansson@arm.com    clock0 = Param.Clock('1MHz', "Clock speed of the input")
3628981Sandreas.hansson@arm.com    int_num1 = Param.UInt32("Interrupt number that connects to GIC")
3638981Sandreas.hansson@arm.com    clock1 = Param.Clock('1MHz', "Clock speed of the input")
36410713Sandreas.hansson@arm.com    amba_id = 0x00141804
3658981Sandreas.hansson@arm.com
36610713Sandreas.hansson@arm.comclass A9GlobalTimer(BasicPioDevice):
3678981Sandreas.hansson@arm.com    type = 'A9GlobalTimer'
3688981Sandreas.hansson@arm.com    cxx_header = "dev/arm/timer_a9global.hh"
36913573Ssascha.bischoff@arm.com    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
37013573Ssascha.bischoff@arm.com    int_num = Param.UInt32("Interrrupt number that connects to GIC")
37113573Ssascha.bischoff@arm.com
37213573Ssascha.bischoff@arm.comclass CpuLocalTimer(BasicPioDevice):
37313573Ssascha.bischoff@arm.com    type = 'CpuLocalTimer'
37413573Ssascha.bischoff@arm.com    cxx_header = "dev/arm/timer_cpulocal.hh"
3758981Sandreas.hansson@arm.com    int_timer = Param.ArmPPI("Interrrupt used per-cpu to GIC")
3768981Sandreas.hansson@arm.com    int_watchdog = Param.ArmPPI("Interrupt for per-cpu watchdog to GIC")
3778981Sandreas.hansson@arm.com
3788981Sandreas.hansson@arm.comclass GenericTimer(ClockedObject):
3798981Sandreas.hansson@arm.com    type = 'GenericTimer'
3808981Sandreas.hansson@arm.com    cxx_header = "dev/arm/generic_timer.hh"
3818981Sandreas.hansson@arm.com    system = Param.ArmSystem(Parent.any, "system")
3828981Sandreas.hansson@arm.com    int_phys_s = Param.ArmPPI("Physical (S) timer interrupt")
3838981Sandreas.hansson@arm.com    int_phys_ns = Param.ArmPPI("Physical (NS) timer interrupt")
38411522Sstephan.diestelhorst@arm.com    int_virt = Param.ArmPPI("Virtual timer interrupt")
38511522Sstephan.diestelhorst@arm.com    int_hyp = Param.ArmPPI("Hypervisor timer interrupt")
3868981Sandreas.hansson@arm.com
3878981Sandreas.hansson@arm.com    def generateDeviceTree(self, state):
3888981Sandreas.hansson@arm.com        node = FdtNode("timer")
3898981Sandreas.hansson@arm.com
3908981Sandreas.hansson@arm.com        node.appendCompatible(["arm,cortex-a15-timer",
3918981Sandreas.hansson@arm.com                               "arm,armv7-timer",
3928981Sandreas.hansson@arm.com                               "arm,armv8-timer"])
3938981Sandreas.hansson@arm.com        node.append(FdtPropertyWords("interrupts", [
3948981Sandreas.hansson@arm.com            1, int(self.int_phys_s.num) - 16, 0xf08,
3958981Sandreas.hansson@arm.com            1, int(self.int_phys_ns.num) - 16, 0xf08,
3968981Sandreas.hansson@arm.com            1, int(self.int_virt.num) - 16, 0xf08,
3978981Sandreas.hansson@arm.com            1, int(self.int_hyp.num) - 16, 0xf08,
3988981Sandreas.hansson@arm.com        ]))
3998981Sandreas.hansson@arm.com        clock = state.phandle(self.clk_domain.unproxy(self))
4008981Sandreas.hansson@arm.com        node.append(FdtPropertyWords("clocks", clock))
4018981Sandreas.hansson@arm.com
4028981Sandreas.hansson@arm.com        yield node
4038981Sandreas.hansson@arm.com
4048981Sandreas.hansson@arm.comclass GenericTimerMem(PioDevice):
4058981Sandreas.hansson@arm.com    type = 'GenericTimerMem'
4068981Sandreas.hansson@arm.com    cxx_header = "dev/arm/generic_timer.hh"
4078981Sandreas.hansson@arm.com
4088981Sandreas.hansson@arm.com    base = Param.Addr(0, "Base address")
4098981Sandreas.hansson@arm.com
4108981Sandreas.hansson@arm.com    int_phys = Param.ArmSPI("Physical Interrupt")
4118981Sandreas.hansson@arm.com    int_virt = Param.ArmSPI("Virtual Interrupt")
4128981Sandreas.hansson@arm.com
4138981Sandreas.hansson@arm.comclass PL031(AmbaIntDevice):
4148981Sandreas.hansson@arm.com    type = 'PL031'
4158981Sandreas.hansson@arm.com    cxx_header = "dev/arm/rtc_pl031.hh"
4168981Sandreas.hansson@arm.com    time = Param.Time('01/01/2009', "System time to use ('Now' for actual time)")
4178981Sandreas.hansson@arm.com    amba_id = 0x00341031
4188981Sandreas.hansson@arm.com
4198981Sandreas.hansson@arm.com    def generateDeviceTree(self, state):
4208981Sandreas.hansson@arm.com        node = self.generateBasicPioDeviceNode(state, 'rtc', self.pio_addr,
4218981Sandreas.hansson@arm.com                                               0x1000, [int(self.int_num)])
4228981Sandreas.hansson@arm.com
4238981Sandreas.hansson@arm.com        node.appendCompatible(["arm,pl031", "arm,primecell"])
4248981Sandreas.hansson@arm.com        clock = state.phandle(self.clk_domain.unproxy(self))
4258981Sandreas.hansson@arm.com        node.append(FdtPropertyWords("clocks", clock))
4268981Sandreas.hansson@arm.com
4278981Sandreas.hansson@arm.com        yield node
4288981Sandreas.hansson@arm.com
4298981Sandreas.hansson@arm.comclass Pl050(AmbaIntDevice):
4308981Sandreas.hansson@arm.com    type = 'Pl050'
4318981Sandreas.hansson@arm.com    cxx_header = "dev/arm/kmi.hh"
4328981Sandreas.hansson@arm.com    amba_id = 0x00141050
4338981Sandreas.hansson@arm.com
4348981Sandreas.hansson@arm.com    ps2 = Param.PS2Device("PS/2 device")
4358981Sandreas.hansson@arm.com
4368981Sandreas.hansson@arm.com    def generateDeviceTree(self, state):
4378981Sandreas.hansson@arm.com        node = self.generateBasicPioDeviceNode(state, 'kmi', self.pio_addr,
4388981Sandreas.hansson@arm.com                                               0x1000, [int(self.int_num)])
4398981Sandreas.hansson@arm.com
4408981Sandreas.hansson@arm.com        node.appendCompatible(["arm,pl050", "arm,primecell"])
4418981Sandreas.hansson@arm.com        clock = state.phandle(self.clk_domain.unproxy(self))
4428981Sandreas.hansson@arm.com        node.append(FdtPropertyWords("clocks", clock))
4438981Sandreas.hansson@arm.com
4448981Sandreas.hansson@arm.com        yield node
4458981Sandreas.hansson@arm.com
4468981Sandreas.hansson@arm.comclass Pl111(AmbaDmaDevice):
4478981Sandreas.hansson@arm.com    type = 'Pl111'
4488981Sandreas.hansson@arm.com    cxx_header = "dev/arm/pl111.hh"
4498981Sandreas.hansson@arm.com    pixel_clock = Param.Clock('24MHz', "Pixel clock")
4508981Sandreas.hansson@arm.com    vnc   = Param.VncInput(Parent.any, "Vnc server for remote frame buffer display")
4518981Sandreas.hansson@arm.com    amba_id = 0x00141111
4528981Sandreas.hansson@arm.com    enable_capture = Param.Bool(True, "capture frame to system.framebuffer.bmp")
4538981Sandreas.hansson@arm.com
4548981Sandreas.hansson@arm.comclass HDLcd(AmbaDmaDevice):
4558981Sandreas.hansson@arm.com    type = 'HDLcd'
4568981Sandreas.hansson@arm.com    cxx_header = "dev/arm/hdlcd.hh"
4578981Sandreas.hansson@arm.com    vnc = Param.VncInput(Parent.any, "Vnc server for remote frame buffer "
4588981Sandreas.hansson@arm.com                                     "display")
4598981Sandreas.hansson@arm.com    amba_id = 0x00141000
4608981Sandreas.hansson@arm.com    workaround_swap_rb = Param.Bool(False, "Workaround incorrect color "
4618981Sandreas.hansson@arm.com                                    "selector order in some kernels")
4628981Sandreas.hansson@arm.com    workaround_dma_line_count = Param.Bool(True, "Workaround incorrect "
4638981Sandreas.hansson@arm.com                                           "DMA line count (off by 1)")
4648981Sandreas.hansson@arm.com    enable_capture = Param.Bool(True, "capture frame to "
4658981Sandreas.hansson@arm.com                                      "system.framebuffer.{extension}")
4668981Sandreas.hansson@arm.com    frame_format = Param.ImageFormat("Auto",
4678981Sandreas.hansson@arm.com                                     "image format of the captured frame")
4688981Sandreas.hansson@arm.com
4698981Sandreas.hansson@arm.com    pixel_buffer_size = Param.MemorySize32("2kB", "Size of address range")
4708981Sandreas.hansson@arm.com
4718981Sandreas.hansson@arm.com    pxl_clk = Param.ClockDomain("Pixel clock source")
4728981Sandreas.hansson@arm.com    pixel_chunk = Param.Unsigned(32, "Number of pixels to handle in one batch")
4738981Sandreas.hansson@arm.com    virt_refresh_rate = Param.Frequency("20Hz", "Frame refresh rate "
4748981Sandreas.hansson@arm.com                                        "in KVM mode")
4758981Sandreas.hansson@arm.com
4768981Sandreas.hansson@arm.com    def generateDeviceTree(self, state):
4778981Sandreas.hansson@arm.com        # Interrupt number is hardcoded; it is not a property of this class
4788981Sandreas.hansson@arm.com        node = self.generateBasicPioDeviceNode(state, 'hdlcd',
4798981Sandreas.hansson@arm.com                                               self.pio_addr, 0x1000, [63])
4808981Sandreas.hansson@arm.com
4818981Sandreas.hansson@arm.com        node.appendCompatible(["arm,hdlcd"])
4828981Sandreas.hansson@arm.com        node.append(FdtPropertyWords("clocks", state.phandle(self.pxl_clk)))
4838981Sandreas.hansson@arm.com        node.append(FdtPropertyStrings("clock-names", ["pxlclk"]))
4848981Sandreas.hansson@arm.com
4858981Sandreas.hansson@arm.com        # This driver is disabled by default since the required DT nodes
4868981Sandreas.hansson@arm.com        # haven't been standardized yet. To use it,  override this status to
4878981Sandreas.hansson@arm.com        # "ok" and add the display configuration nodes required by the driver.
4888981Sandreas.hansson@arm.com        # See the driver for more information.
4898981Sandreas.hansson@arm.com        node.append(FdtPropertyStrings("status", ["disabled"]))
4908981Sandreas.hansson@arm.com
4918981Sandreas.hansson@arm.com        yield node
4928981Sandreas.hansson@arm.com
49311848Spierre-yves.peneau@lirmm.frclass RealView(Platform):
4948981Sandreas.hansson@arm.com    type = 'RealView'
4958981Sandreas.hansson@arm.com    cxx_header = "dev/arm/realview.hh"
4968981Sandreas.hansson@arm.com    system = Param.System(Parent.any, "system")
4978981Sandreas.hansson@arm.com    _mem_regions = [ AddrRange(0, size='256MB') ]
4988981Sandreas.hansson@arm.com
4998981Sandreas.hansson@arm.com    def _on_chip_devices(self):
5008981Sandreas.hansson@arm.com        return []
5018981Sandreas.hansson@arm.com
5028981Sandreas.hansson@arm.com    def _off_chip_devices(self):
5038981Sandreas.hansson@arm.com        return []
5048981Sandreas.hansson@arm.com
5058981Sandreas.hansson@arm.com    _off_chip_ranges = []
5068981Sandreas.hansson@arm.com
5078981Sandreas.hansson@arm.com    def _attach_device(self, device, bus, dma_ports=None):
5088981Sandreas.hansson@arm.com        if hasattr(device, "pio"):
5098981Sandreas.hansson@arm.com            device.pio = bus.master
5108981Sandreas.hansson@arm.com        if hasattr(device, "dma"):
5118981Sandreas.hansson@arm.com            if dma_ports is None:
5128981Sandreas.hansson@arm.com                device.dma = bus.slave
5138981Sandreas.hansson@arm.com            else:
5148981Sandreas.hansson@arm.com                dma_ports.append(device.dma)
5158981Sandreas.hansson@arm.com
5168981Sandreas.hansson@arm.com    def _attach_io(self, devices, *args, **kwargs):
5178981Sandreas.hansson@arm.com        for d in devices:
5188981Sandreas.hansson@arm.com            self._attach_device(d, *args, **kwargs)
5198981Sandreas.hansson@arm.com
5208981Sandreas.hansson@arm.com    def _attach_clk(self, devices, clkdomain):
5218981Sandreas.hansson@arm.com        for d in devices:
5228981Sandreas.hansson@arm.com            if hasattr(d, "clk_domain"):
5238981Sandreas.hansson@arm.com                d.clk_domain = clkdomain
5248981Sandreas.hansson@arm.com
5258981Sandreas.hansson@arm.com    def attachPciDevices(self):
5268981Sandreas.hansson@arm.com        pass
5278981Sandreas.hansson@arm.com
5288981Sandreas.hansson@arm.com    def enableMSIX(self):
5298981Sandreas.hansson@arm.com        pass
5308981Sandreas.hansson@arm.com
5318981Sandreas.hansson@arm.com    def onChipIOClkDomain(self, clkdomain):
5328981Sandreas.hansson@arm.com        self._attach_clk(self._on_chip_devices(), clkdomain)
5338981Sandreas.hansson@arm.com
5348981Sandreas.hansson@arm.com    def offChipIOClkDomain(self, clkdomain):
5358981Sandreas.hansson@arm.com        self._attach_clk(self._off_chip_devices(), clkdomain)
5368981Sandreas.hansson@arm.com
5378981Sandreas.hansson@arm.com    def attachOnChipIO(self, bus, bridge=None, *args, **kwargs):
5388981Sandreas.hansson@arm.com        self._attach_io(self._on_chip_devices(), bus, *args, **kwargs)
5398981Sandreas.hansson@arm.com        if bridge:
5408981Sandreas.hansson@arm.com            bridge.ranges = self._off_chip_ranges
5418981Sandreas.hansson@arm.com
5428981Sandreas.hansson@arm.com    def attachIO(self, *args, **kwargs):
5438981Sandreas.hansson@arm.com        self._attach_io(self._off_chip_devices(), *args, **kwargs)
5448981Sandreas.hansson@arm.com
5458981Sandreas.hansson@arm.com    def setupBootLoader(self, mem_bus, cur_sys, loc):
5468981Sandreas.hansson@arm.com        cur_sys.bootmem = SimpleMemory(
5478981Sandreas.hansson@arm.com            range = AddrRange('2GB', size = '64MB'),
5488981Sandreas.hansson@arm.com            conf_table_reported = False)
5498981Sandreas.hansson@arm.com        if mem_bus is not None:
5508981Sandreas.hansson@arm.com            cur_sys.bootmem.port = mem_bus.master
5518981Sandreas.hansson@arm.com        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