RealView.py revision 14283:b02cde4661e1
1# Copyright (c) 2009-2019 ARM Limited
2# All rights reserved.
3#
4# The license below extends only to copyright in the software and shall
5# not be construed as granting a license to any other intellectual
6# property including but not limited to intellectual property relating
7# to a hardware implementation of the functionality of the software
8# licensed hereunder.  You may use the software subject to the license
9# terms below provided that you ensure that this notice is replicated
10# unmodified and in its entirety in all distributions of the software,
11# modified or unmodified, in source code or in binary form.
12#
13# Copyright (c) 2006-2007 The Regents of The University of Michigan
14# All rights reserved.
15#
16# Redistribution and use in source and binary forms, with or without
17# modification, are permitted provided that the following conditions are
18# met: redistributions of source code must retain the above copyright
19# notice, this list of conditions and the following disclaimer;
20# redistributions in binary form must reproduce the above copyright
21# notice, this list of conditions and the following disclaimer in the
22# documentation and/or other materials provided with the distribution;
23# neither the name of the copyright holders nor the names of its
24# contributors may be used to endorse or promote products derived from
25# this software without specific prior written permission.
26#
27# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38#
39# Authors: Ali Saidi
40#          Gabe Black
41#          William Wang
42#          Glenn Bergmans
43
44from m5.defines import buildEnv
45from m5.params import *
46from m5.proxy import *
47from m5.util.fdthelper import *
48from m5.objects.ClockDomain import ClockDomain
49from m5.objects.VoltageDomain import VoltageDomain
50from m5.objects.Device import \
51    BasicPioDevice, PioDevice, IsaFake, BadAddr, DmaDevice
52from m5.objects.PciHost import *
53from m5.objects.Ethernet import NSGigE, IGbE_igb, IGbE_e1000
54from m5.objects.Ide import *
55from m5.objects.Platform import Platform
56from m5.objects.Terminal import Terminal
57from m5.objects.Uart import Uart
58from m5.objects.SimpleMemory import SimpleMemory
59from m5.objects.Gic import *
60from m5.objects.EnergyCtrl import EnergyCtrl
61from m5.objects.ClockedObject import ClockedObject
62from m5.objects.ClockDomain import SrcClockDomain
63from m5.objects.SubSystem import SubSystem
64from m5.objects.Graphics import ImageFormat
65from m5.objects.ClockedObject import ClockedObject
66from m5.objects.PS2 import *
67from m5.objects.VirtIOMMIO import MmioVirtIO
68from m5.objects.Display import Display, Display1080p
69
70# Platforms with KVM support should generally use in-kernel GIC
71# emulation. Use a GIC model that automatically switches between
72# gem5's GIC model and KVM's GIC model if KVM is available.
73try:
74    from m5.objects.KvmGic import MuxingKvmGic
75    kvm_gicv2_class = MuxingKvmGic
76except ImportError:
77    # KVM support wasn't compiled into gem5. Fallback to a
78    # software-only GIC.
79    kvm_gicv2_class = Gic400
80    pass
81
82class AmbaPioDevice(BasicPioDevice):
83    type = 'AmbaPioDevice'
84    abstract = True
85    cxx_header = "dev/arm/amba_device.hh"
86    amba_id = Param.UInt32("ID of AMBA device for kernel detection")
87
88class AmbaIntDevice(AmbaPioDevice):
89    type = 'AmbaIntDevice'
90    abstract = True
91    cxx_header = "dev/arm/amba_device.hh"
92    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
93    int_num = Param.UInt32("Interrupt number that connects to GIC")
94    int_delay = Param.Latency("100ns",
95            "Time between action and interrupt generation by device")
96
97class AmbaDmaDevice(DmaDevice):
98    type = 'AmbaDmaDevice'
99    abstract = True
100    cxx_header = "dev/arm/amba_device.hh"
101    pio_addr = Param.Addr("Address for AMBA slave interface")
102    pio_latency = Param.Latency("10ns", "Time between action and write/read result by AMBA DMA Device")
103    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
104    int_num = Param.UInt32("Interrupt number that connects to GIC")
105    amba_id = Param.UInt32("ID of AMBA device for kernel detection")
106
107class A9SCU(BasicPioDevice):
108    type = 'A9SCU'
109    cxx_header = "dev/arm/a9scu.hh"
110
111class ArmPciIntRouting(Enum): vals = [
112    'ARM_PCI_INT_STATIC',
113    'ARM_PCI_INT_DEV',
114    'ARM_PCI_INT_PIN',
115    ]
116
117class GenericArmPciHost(GenericPciHost):
118    type = 'GenericArmPciHost'
119    cxx_header = "dev/arm/pci_host.hh"
120
121    int_policy = Param.ArmPciIntRouting("PCI interrupt routing policy")
122    int_base = Param.Unsigned("PCI interrupt base")
123    int_count = Param.Unsigned("Maximum number of interrupts used by this host")
124
125    # This python parameter can be used in configuration scripts to turn
126    # on/off the fdt dma-coherent flag when doing dtb autogeneration
127    _dma_coherent = True
128
129    def generateDeviceTree(self, state):
130        local_state = FdtState(
131            addr_cells=3, size_cells=2,
132            cpu_cells=1, interrupt_cells=1)
133
134        node = FdtNode("pci")
135
136        if int(self.conf_device_bits) == 8:
137            node.appendCompatible("pci-host-cam-generic")
138        elif int(self.conf_device_bits) == 12:
139            node.appendCompatible("pci-host-ecam-generic")
140        else:
141            m5.fatal("No compatibility string for the set conf_device_width")
142
143        node.append(FdtPropertyStrings("device_type", ["pci"]))
144
145        # Cell sizes of child nodes/peripherals
146        node.append(local_state.addrCellsProperty())
147        node.append(local_state.sizeCellsProperty())
148        node.append(local_state.interruptCellsProperty())
149        # PCI address for CPU
150        node.append(FdtPropertyWords("reg",
151            state.addrCells(self.conf_base) +
152            state.sizeCells(self.conf_size) ))
153
154        # Ranges mapping
155        # For now some of this is hard coded, because the PCI module does not
156        # have a proper full understanding of the memory map, but adapting the
157        # PCI module is beyond the scope of what I'm trying to do here.
158        # Values are taken from the VExpress_GEM5_V1 platform.
159        ranges = []
160        # Pio address range
161        ranges += self.pciFdtAddr(space=1, addr=0)
162        ranges += state.addrCells(self.pci_pio_base)
163        ranges += local_state.sizeCells(0x10000)  # Fixed size
164
165        # AXI memory address range
166        ranges += self.pciFdtAddr(space=2, addr=0)
167        ranges += state.addrCells(0x40000000) # Fixed offset
168        ranges += local_state.sizeCells(0x40000000) # Fixed size
169        node.append(FdtPropertyWords("ranges", ranges))
170
171        if str(self.int_policy) == 'ARM_PCI_INT_DEV':
172            gic = self._parent.unproxy(self).gic
173            int_phandle = state.phandle(gic)
174            # Interrupt mapping
175            interrupts = []
176
177            # child interrupt specifier
178            child_interrupt = local_state.interruptCells(0x0)
179
180            # parent unit address
181            parent_addr = gic._state.addrCells(0x0)
182
183            for i in range(int(self.int_count)):
184                parent_interrupt = gic.interruptCells(0,
185                    int(self.int_base) - 32 + i, 1)
186
187                interrupts += self.pciFdtAddr(device=i, addr=0) + \
188                    child_interrupt + [int_phandle] + parent_addr + \
189                    parent_interrupt
190
191            node.append(FdtPropertyWords("interrupt-map", interrupts))
192
193            int_count = int(self.int_count)
194            if int_count & (int_count - 1):
195                fatal("PCI interrupt count should be power of 2")
196
197            intmask = self.pciFdtAddr(device=int_count - 1, addr=0) + [0x0]
198            node.append(FdtPropertyWords("interrupt-map-mask", intmask))
199        else:
200            m5.fatal("Unsupported PCI interrupt policy " +
201                     "for Device Tree generation")
202
203        if self._dma_coherent:
204            node.append(FdtProperty("dma-coherent"))
205
206        yield node
207
208class RealViewCtrl(BasicPioDevice):
209    type = 'RealViewCtrl'
210    cxx_header = "dev/arm/rv_ctrl.hh"
211    proc_id0 = Param.UInt32(0x0C000000, "Processor ID, SYS_PROCID")
212    proc_id1 = Param.UInt32(0x0C000222, "Processor ID, SYS_PROCID1")
213    idreg = Param.UInt32(0x00000000, "ID Register, SYS_ID")
214
215    def generateDeviceTree(self, state):
216        node = FdtNode("sysreg@%x" % long(self.pio_addr))
217        node.appendCompatible("arm,vexpress-sysreg")
218        node.append(FdtPropertyWords("reg",
219            state.addrCells(self.pio_addr) +
220            state.sizeCells(0x1000) ))
221        node.append(FdtProperty("gpio-controller"))
222        node.append(FdtPropertyWords("#gpio-cells", [2]))
223        node.appendPhandle(self)
224
225        yield node
226
227class RealViewOsc(ClockDomain):
228    type = 'RealViewOsc'
229    cxx_header = "dev/arm/rv_ctrl.hh"
230
231    parent = Param.RealViewCtrl(Parent.any, "RealView controller")
232
233    # TODO: We currently don't have the notion of a clock source,
234    # which means we have to associate oscillators with a voltage
235    # source.
236    voltage_domain = Param.VoltageDomain(Parent.voltage_domain,
237                                         "Voltage domain")
238
239    # See ARM DUI 0447J (ARM Motherboard Express uATX -- V2M-P1) and
240    # the individual core/logic tile reference manuals for details
241    # about the site/position/dcc/device allocation.
242    site = Param.UInt8("Board Site")
243    position = Param.UInt8("Position in device stack")
244    dcc = Param.UInt8("Daughterboard Configuration Controller")
245    device = Param.UInt8("Device ID")
246
247    freq = Param.Clock("Default frequency")
248
249    def generateDeviceTree(self, state):
250        phandle = state.phandle(self)
251        node = FdtNode("osc@" + format(long(phandle), 'x'))
252        node.appendCompatible("arm,vexpress-osc")
253        node.append(FdtPropertyWords("arm,vexpress-sysreg,func",
254                                     [0x1, int(self.device)]))
255        node.append(FdtPropertyWords("#clock-cells", [0]))
256        freq = int(1.0/self.freq.value) # Values are stored as a clock period
257        node.append(FdtPropertyWords("freq-range", [freq, freq]))
258        node.append(FdtPropertyStrings("clock-output-names",
259                                       ["oscclk" + str(phandle)]))
260        node.appendPhandle(self)
261        yield node
262
263class RealViewTemperatureSensor(SimObject):
264    type = 'RealViewTemperatureSensor'
265    cxx_header = "dev/arm/rv_ctrl.hh"
266
267    parent = Param.RealViewCtrl(Parent.any, "RealView controller")
268
269    system = Param.System(Parent.any, "system")
270
271    # See ARM DUI 0447J (ARM Motherboard Express uATX -- V2M-P1) and
272    # the individual core/logic tile reference manuals for details
273    # about the site/position/dcc/device allocation.
274    site = Param.UInt8("Board Site")
275    position = Param.UInt8("Position in device stack")
276    dcc = Param.UInt8("Daughterboard Configuration Controller")
277    device = Param.UInt8("Device ID")
278
279class VExpressMCC(SubSystem):
280    """ARM V2M-P1 Motherboard Configuration Controller
281
282This subsystem describes a subset of the devices that sit behind the
283motherboard configuration controller on the the ARM Motherboard
284Express (V2M-P1) motherboard. See ARM DUI 0447J for details.
285    """
286
287    class Osc(RealViewOsc):
288        site, position, dcc = (0, 0, 0)
289
290    class Temperature(RealViewTemperatureSensor):
291        site, position, dcc = (0, 0, 0)
292
293    osc_mcc = Osc(device=0, freq="50MHz")
294    osc_clcd = Osc(device=1, freq="23.75MHz")
295    osc_peripheral = Osc(device=2, freq="24MHz")
296    osc_system_bus = Osc(device=4, freq="24MHz")
297
298    # See Table 4.19 in ARM DUI 0447J (Motherboard Express uATX TRM).
299    temp_crtl = Temperature(device=0)
300
301    def generateDeviceTree(self, state):
302        node = FdtNode("mcc")
303        node.appendCompatible("arm,vexpress,config-bus")
304        node.append(FdtPropertyWords("arm,vexpress,site", [0]))
305
306        for obj in self._children.values():
307            if issubclass(type(obj), SimObject):
308                node.append(obj.generateDeviceTree(state))
309
310        io_phandle = state.phandle(self.osc_mcc.parent.unproxy(self))
311        node.append(FdtPropertyWords("arm,vexpress,config-bridge", io_phandle))
312
313        yield node
314
315class CoreTile2A15DCC(SubSystem):
316    """ARM CoreTile Express A15x2 Daughterboard Configuration Controller
317
318This subsystem describes a subset of the devices that sit behind the
319daughterboard configuration controller on a CoreTile Express A15x2. See
320ARM DUI 0604E for details.
321    """
322
323    class Osc(RealViewOsc):
324        site, position, dcc = (1, 0, 0)
325
326    # See Table 2.8 in ARM DUI 0604E (CoreTile Express A15x2 TRM)
327    osc_cpu = Osc(device=0, freq="60MHz")
328    osc_hsbm = Osc(device=4, freq="40MHz")
329    osc_pxl = Osc(device=5, freq="23.75MHz")
330    osc_smb = Osc(device=6, freq="50MHz")
331    osc_sys = Osc(device=7, freq="60MHz")
332    osc_ddr = Osc(device=8, freq="40MHz")
333
334    def generateDeviceTree(self, state):
335        node = FdtNode("dcc")
336        node.appendCompatible("arm,vexpress,config-bus")
337
338        for obj in self._children.values():
339            if isinstance(obj, SimObject):
340                node.append(obj.generateDeviceTree(state))
341
342        io_phandle = state.phandle(self.osc_cpu.parent.unproxy(self))
343        node.append(FdtPropertyWords("arm,vexpress,config-bridge", io_phandle))
344
345        yield node
346
347class AmbaFake(AmbaPioDevice):
348    type = 'AmbaFake'
349    cxx_header = "dev/arm/amba_fake.hh"
350    ignore_access = Param.Bool(False, "Ignore reads/writes to this device, (e.g. IsaFake + AMBA)")
351    amba_id = 0;
352
353class Pl011(Uart):
354    type = 'Pl011'
355    cxx_header = "dev/arm/pl011.hh"
356    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
357    int_num = Param.UInt32("Interrupt number that connects to GIC")
358    end_on_eot = Param.Bool(False, "End the simulation when a EOT is received on the UART")
359    int_delay = Param.Latency("100ns", "Time between action and interrupt generation by UART")
360
361    def generateDeviceTree(self, state):
362        node = self.generateBasicPioDeviceNode(state, 'uart', self.pio_addr,
363                                               0x1000, [int(self.int_num)])
364        node.appendCompatible(["arm,pl011", "arm,primecell"])
365
366        # Hardcoded reference to the realview platform clocks, because the
367        # clk_domain can only store one clock (i.e. it is not a VectorParam)
368        realview = self._parent.unproxy(self)
369        node.append(FdtPropertyWords("clocks",
370            [state.phandle(realview.mcc.osc_peripheral),
371            state.phandle(realview.dcc.osc_smb)]))
372        node.append(FdtPropertyStrings("clock-names", ["uartclk", "apb_pclk"]))
373        yield node
374
375class Sp804(AmbaPioDevice):
376    type = 'Sp804'
377    cxx_header = "dev/arm/timer_sp804.hh"
378    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
379    int_num0 = Param.UInt32("Interrupt number that connects to GIC")
380    clock0 = Param.Clock('1MHz', "Clock speed of the input")
381    int_num1 = Param.UInt32("Interrupt number that connects to GIC")
382    clock1 = Param.Clock('1MHz', "Clock speed of the input")
383    amba_id = 0x00141804
384
385class A9GlobalTimer(BasicPioDevice):
386    type = 'A9GlobalTimer'
387    cxx_header = "dev/arm/timer_a9global.hh"
388    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
389    int_num = Param.UInt32("Interrrupt number that connects to GIC")
390
391class CpuLocalTimer(BasicPioDevice):
392    type = 'CpuLocalTimer'
393    cxx_header = "dev/arm/timer_cpulocal.hh"
394    int_timer = Param.ArmPPI("Interrrupt used per-cpu to GIC")
395    int_watchdog = Param.ArmPPI("Interrupt for per-cpu watchdog to GIC")
396
397class GenericTimer(ClockedObject):
398    type = 'GenericTimer'
399    cxx_header = "dev/arm/generic_timer.hh"
400    system = Param.ArmSystem(Parent.any, "system")
401    int_phys_s = Param.ArmPPI("Physical (S) timer interrupt")
402    int_phys_ns = Param.ArmPPI("Physical (NS) timer interrupt")
403    int_virt = Param.ArmPPI("Virtual timer interrupt")
404    int_hyp = Param.ArmPPI("Hypervisor timer interrupt")
405
406    def generateDeviceTree(self, state):
407        node = FdtNode("timer")
408
409        node.appendCompatible(["arm,cortex-a15-timer",
410                               "arm,armv7-timer",
411                               "arm,armv8-timer"])
412        node.append(FdtPropertyWords("interrupts", [
413            1, int(self.int_phys_s.num) - 16, 0xf08,
414            1, int(self.int_phys_ns.num) - 16, 0xf08,
415            1, int(self.int_virt.num) - 16, 0xf08,
416            1, int(self.int_hyp.num) - 16, 0xf08,
417        ]))
418        clock = state.phandle(self.clk_domain.unproxy(self))
419        node.append(FdtPropertyWords("clocks", clock))
420
421        yield node
422
423class GenericTimerMem(PioDevice):
424    type = 'GenericTimerMem'
425    cxx_header = "dev/arm/generic_timer.hh"
426
427    base = Param.Addr(0, "Base address")
428
429    int_phys = Param.ArmSPI("Physical Interrupt")
430    int_virt = Param.ArmSPI("Virtual Interrupt")
431
432class PL031(AmbaIntDevice):
433    type = 'PL031'
434    cxx_header = "dev/arm/rtc_pl031.hh"
435    time = Param.Time('01/01/2009', "System time to use ('Now' for actual time)")
436    amba_id = 0x00341031
437
438    def generateDeviceTree(self, state):
439        node = self.generateBasicPioDeviceNode(state, 'rtc', self.pio_addr,
440                                               0x1000, [int(self.int_num)])
441
442        node.appendCompatible(["arm,pl031", "arm,primecell"])
443        clock = state.phandle(self.clk_domain.unproxy(self))
444        node.append(FdtPropertyWords("clocks", clock))
445
446        yield node
447
448class Pl050(AmbaIntDevice):
449    type = 'Pl050'
450    cxx_header = "dev/arm/kmi.hh"
451    amba_id = 0x00141050
452
453    ps2 = Param.PS2Device("PS/2 device")
454
455    def generateDeviceTree(self, state):
456        node = self.generateBasicPioDeviceNode(state, 'kmi', self.pio_addr,
457                                               0x1000, [int(self.int_num)])
458
459        node.appendCompatible(["arm,pl050", "arm,primecell"])
460        clock = state.phandle(self.clk_domain.unproxy(self))
461        node.append(FdtPropertyWords("clocks", clock))
462
463        yield node
464
465class Pl111(AmbaDmaDevice):
466    type = 'Pl111'
467    cxx_header = "dev/arm/pl111.hh"
468    pixel_clock = Param.Clock('24MHz', "Pixel clock")
469    vnc   = Param.VncInput(Parent.any, "Vnc server for remote frame buffer display")
470    amba_id = 0x00141111
471    enable_capture = Param.Bool(True, "capture frame to system.framebuffer.bmp")
472
473class HDLcd(AmbaDmaDevice):
474    type = 'HDLcd'
475    cxx_header = "dev/arm/hdlcd.hh"
476    vnc = Param.VncInput(Parent.any, "Vnc server for remote frame buffer "
477                                     "display")
478    amba_id = 0x00141000
479    workaround_swap_rb = Param.Bool(False, "Workaround incorrect color "
480                                    "selector order in some kernels")
481    workaround_dma_line_count = Param.Bool(True, "Workaround incorrect "
482                                           "DMA line count (off by 1)")
483    enable_capture = Param.Bool(True, "capture frame to "
484                                      "system.framebuffer.{extension}")
485    frame_format = Param.ImageFormat("Auto",
486                                     "image format of the captured frame")
487
488    pixel_buffer_size = Param.MemorySize32("2kB", "Size of address range")
489
490    pxl_clk = Param.ClockDomain("Pixel clock source")
491    pixel_chunk = Param.Unsigned(32, "Number of pixels to handle in one batch")
492    virt_refresh_rate = Param.Frequency("20Hz", "Frame refresh rate "
493                                        "in KVM mode")
494
495    encoder = Param.Display(Display1080p(), "Display encoder")
496
497    def endpointPhandle(self):
498        return "hdlcd_endpoint"
499
500    def generateDeviceTree(self, state):
501        endpoint_node = FdtNode("endpoint")
502        endpoint_node.appendPhandle(self.endpointPhandle())
503
504        for encoder_node in self.encoder.generateDeviceTree(state):
505            encoder_endpoint = self.encoder.endpointNode()
506
507            # Endpoint subnode
508            endpoint_node.append(FdtPropertyWords("remote-endpoint",
509                [ state.phandle(self.encoder.endpointPhandle()) ]))
510            encoder_endpoint.append(FdtPropertyWords("remote-endpoint",
511                [ state.phandle(self.endpointPhandle()) ]))
512
513            yield encoder_node
514
515        port_node = FdtNode("port")
516        port_node.append(endpoint_node)
517
518        # Interrupt number is hardcoded; it is not a property of this class
519        node = self.generateBasicPioDeviceNode(state, 'hdlcd',
520                                               self.pio_addr, 0x1000, [63])
521
522        node.appendCompatible(["arm,hdlcd"])
523        node.append(FdtPropertyWords("clocks", state.phandle(self.pxl_clk)))
524        node.append(FdtPropertyStrings("clock-names", ["pxlclk"]))
525
526        # This driver is disabled by default since the required DT nodes
527        # haven't been standardized yet. To use it,  override this status to
528        # "ok" and add the display configuration nodes required by the driver.
529        # See the driver for more information.
530        node.append(FdtPropertyStrings("status", ["disabled"]))
531
532        self.addIommuProperty(state, node)
533
534        node.append(port_node)
535
536        yield node
537
538class RealView(Platform):
539    type = 'RealView'
540    cxx_header = "dev/arm/realview.hh"
541    system = Param.System(Parent.any, "system")
542    _mem_regions = [ AddrRange(0, size='256MB') ]
543
544    def _on_chip_devices(self):
545        return []
546
547    def _off_chip_devices(self):
548        return []
549
550    _off_chip_ranges = []
551
552    def _attach_device(self, device, bus, dma_ports=None):
553        if hasattr(device, "pio"):
554            device.pio = bus.master
555        if hasattr(device, "dma"):
556            if dma_ports is None:
557                device.dma = bus.slave
558            else:
559                dma_ports.append(device.dma)
560
561    def _attach_io(self, devices, *args, **kwargs):
562        for d in devices:
563            self._attach_device(d, *args, **kwargs)
564
565    def _attach_clk(self, devices, clkdomain):
566        for d in devices:
567            if hasattr(d, "clk_domain"):
568                d.clk_domain = clkdomain
569
570    def attachPciDevices(self):
571        pass
572
573    def enableMSIX(self):
574        pass
575
576    def onChipIOClkDomain(self, clkdomain):
577        self._attach_clk(self._on_chip_devices(), clkdomain)
578
579    def offChipIOClkDomain(self, clkdomain):
580        self._attach_clk(self._off_chip_devices(), clkdomain)
581
582    def attachOnChipIO(self, bus, bridge=None, *args, **kwargs):
583        self._attach_io(self._on_chip_devices(), bus, *args, **kwargs)
584        if bridge:
585            bridge.ranges = self._off_chip_ranges
586
587    def attachIO(self, *args, **kwargs):
588        self._attach_io(self._off_chip_devices(), *args, **kwargs)
589
590    def setupBootLoader(self, mem_bus, cur_sys, loc):
591        cur_sys.bootmem = SimpleMemory(
592            range = AddrRange('2GB', size = '64MB'),
593            conf_table_reported = False)
594        if mem_bus is not None:
595            cur_sys.bootmem.port = mem_bus.master
596        cur_sys.boot_loader = loc('boot.arm')
597        cur_sys.atags_addr = 0x100
598        cur_sys.load_offset = 0
599
600    def generateDeviceTree(self, state):
601        node = FdtNode("/") # Things in this module need to end up in the root
602        node.append(FdtPropertyWords("interrupt-parent",
603                                     state.phandle(self.gic)))
604
605        for subnode in self.recurseDeviceTree(state):
606            node.append(subnode)
607
608        yield node
609
610    def annotateCpuDeviceNode(self, cpu, state):
611        cpu.append(FdtPropertyStrings("enable-method", "spin-table"))
612        cpu.append(FdtPropertyWords("cpu-release-addr", \
613                                    state.addrCells(0x8000fff8)))
614
615# Reference for memory map and interrupt number
616# RealView Platform Baseboard Explore for Cortex-A9 User Guide(ARM DUI 0440A)
617# Chapter 4: Programmer's Reference
618class RealViewPBX(RealView):
619    uart = Pl011(pio_addr=0x10009000, int_num=44)
620    realview_io = RealViewCtrl(pio_addr=0x10000000)
621    mcc = VExpressMCC()
622    dcc = CoreTile2A15DCC()
623    gic = Gic400(cpu_addr=0x1f000100, dist_addr=0x1f001000, cpu_size=0x100)
624    pci_host = GenericPciHost(
625        conf_base=0x30000000, conf_size='256MB', conf_device_bits=16,
626        pci_pio_base=0)
627    timer0 = Sp804(int_num0=36, int_num1=36, pio_addr=0x10011000)
628    timer1 = Sp804(int_num0=37, int_num1=37, pio_addr=0x10012000)
629    global_timer = A9GlobalTimer(int_num=27, pio_addr=0x1f000200)
630    local_cpu_timer = CpuLocalTimer(int_timer=ArmPPI(num=29),
631                                    int_watchdog=ArmPPI(num=30),
632                                    pio_addr=0x1f000600)
633    clcd = Pl111(pio_addr=0x10020000, int_num=55)
634    kmi0   = Pl050(pio_addr=0x10006000, int_num=52, ps2=PS2Keyboard())
635    kmi1   = Pl050(pio_addr=0x10007000, int_num=53, ps2=PS2TouchKit())
636    a9scu  = A9SCU(pio_addr=0x1f000000)
637    cf_ctrl = IdeController(disks=[], pci_func=0, pci_dev=7, pci_bus=2,
638                            io_shift = 1, ctrl_offset = 2, Command = 0x1,
639                            BAR0 = 0x18000000, BAR0Size = '16B',
640                            BAR1 = 0x18000100, BAR1Size = '1B',
641                            BAR0LegacyIO = True, BAR1LegacyIO = True)
642
643
644    l2x0_fake     = IsaFake(pio_addr=0x1f002000, pio_size=0xfff)
645    flash_fake    = IsaFake(pio_addr=0x40000000, pio_size=0x20000000,
646                            fake_mem=True)
647    dmac_fake     = AmbaFake(pio_addr=0x10030000)
648    uart1_fake    = AmbaFake(pio_addr=0x1000a000)
649    uart2_fake    = AmbaFake(pio_addr=0x1000b000)
650    uart3_fake    = AmbaFake(pio_addr=0x1000c000)
651    smc_fake      = AmbaFake(pio_addr=0x100e1000)
652    sp810_fake    = AmbaFake(pio_addr=0x10001000, ignore_access=True)
653    watchdog_fake = AmbaFake(pio_addr=0x10010000)
654    gpio0_fake    = AmbaFake(pio_addr=0x10013000)
655    gpio1_fake    = AmbaFake(pio_addr=0x10014000)
656    gpio2_fake    = AmbaFake(pio_addr=0x10015000)
657    ssp_fake      = AmbaFake(pio_addr=0x1000d000)
658    sci_fake      = AmbaFake(pio_addr=0x1000e000)
659    aaci_fake     = AmbaFake(pio_addr=0x10004000)
660    mmc_fake      = AmbaFake(pio_addr=0x10005000)
661    rtc           = PL031(pio_addr=0x10017000, int_num=42)
662    energy_ctrl   = EnergyCtrl(pio_addr=0x1000f000)
663
664
665    # Attach I/O devices that are on chip and also set the appropriate
666    # ranges for the bridge
667    def attachOnChipIO(self, bus, bridge):
668       self.gic.pio = bus.master
669       self.l2x0_fake.pio = bus.master
670       self.a9scu.pio = bus.master
671       self.global_timer.pio = bus.master
672       self.local_cpu_timer.pio = bus.master
673       # Bridge ranges based on excluding what is part of on-chip I/O
674       # (gic, l2x0, a9scu, local_cpu_timer)
675       bridge.ranges = [AddrRange(self.realview_io.pio_addr,
676                                  self.a9scu.pio_addr - 1),
677                        AddrRange(self.flash_fake.pio_addr,
678                                  self.flash_fake.pio_addr + \
679                                  self.flash_fake.pio_size - 1)]
680
681    # Set the clock domain for IO objects that are considered
682    # to be "close" to the cores.
683    def onChipIOClkDomain(self, clkdomain):
684        self.gic.clk_domain             = clkdomain
685        self.l2x0_fake.clk_domain       = clkdomain
686        self.a9scu.clkdomain            = clkdomain
687        self.local_cpu_timer.clk_domain = clkdomain
688
689    # Attach I/O devices to specified bus object.  Can't do this
690    # earlier, since the bus object itself is typically defined at the
691    # System level.
692    def attachIO(self, bus):
693       self.uart.pio          = bus.master
694       self.realview_io.pio   = bus.master
695       self.pci_host.pio      = bus.master
696       self.timer0.pio        = bus.master
697       self.timer1.pio        = bus.master
698       self.clcd.pio          = bus.master
699       self.clcd.dma          = bus.slave
700       self.kmi0.pio          = bus.master
701       self.kmi1.pio          = bus.master
702       self.cf_ctrl.pio       = bus.master
703       self.cf_ctrl.dma       = bus.slave
704       self.dmac_fake.pio     = bus.master
705       self.uart1_fake.pio    = bus.master
706       self.uart2_fake.pio    = bus.master
707       self.uart3_fake.pio    = bus.master
708       self.smc_fake.pio      = bus.master
709       self.sp810_fake.pio    = bus.master
710       self.watchdog_fake.pio = bus.master
711       self.gpio0_fake.pio    = bus.master
712       self.gpio1_fake.pio    = bus.master
713       self.gpio2_fake.pio    = bus.master
714       self.ssp_fake.pio      = bus.master
715       self.sci_fake.pio      = bus.master
716       self.aaci_fake.pio     = bus.master
717       self.mmc_fake.pio      = bus.master
718       self.rtc.pio           = bus.master
719       self.flash_fake.pio    = bus.master
720       self.energy_ctrl.pio   = bus.master
721
722    # Set the clock domain for IO objects that are considered
723    # to be "far" away from the cores.
724    def offChipIOClkDomain(self, clkdomain):
725        self.uart.clk_domain          = clkdomain
726        self.realview_io.clk_domain   = clkdomain
727        self.timer0.clk_domain        = clkdomain
728        self.timer1.clk_domain        = clkdomain
729        self.clcd.clk_domain          = clkdomain
730        self.kmi0.clk_domain          = clkdomain
731        self.kmi1.clk_domain          = clkdomain
732        self.cf_ctrl.clk_domain       = clkdomain
733        self.dmac_fake.clk_domain     = clkdomain
734        self.uart1_fake.clk_domain    = clkdomain
735        self.uart2_fake.clk_domain    = clkdomain
736        self.uart3_fake.clk_domain    = clkdomain
737        self.smc_fake.clk_domain      = clkdomain
738        self.sp810_fake.clk_domain    = clkdomain
739        self.watchdog_fake.clk_domain = clkdomain
740        self.gpio0_fake.clk_domain    = clkdomain
741        self.gpio1_fake.clk_domain    = clkdomain
742        self.gpio2_fake.clk_domain    = clkdomain
743        self.ssp_fake.clk_domain      = clkdomain
744        self.sci_fake.clk_domain      = clkdomain
745        self.aaci_fake.clk_domain     = clkdomain
746        self.mmc_fake.clk_domain      = clkdomain
747        self.rtc.clk_domain           = clkdomain
748        self.flash_fake.clk_domain    = clkdomain
749        self.energy_ctrl.clk_domain   = clkdomain
750
751class VExpress_EMM(RealView):
752    _mem_regions = [ AddrRange('2GB', size='2GB') ]
753
754    # Ranges based on excluding what is part of on-chip I/O (gic,
755    # a9scu)
756    _off_chip_ranges = [AddrRange(0x2F000000, size='16MB'),
757                        AddrRange(0x30000000, size='256MB'),
758                        AddrRange(0x40000000, size='512MB'),
759                        AddrRange(0x18000000, size='64MB'),
760                        AddrRange(0x1C000000, size='64MB')]
761
762    # Platform control device (off-chip)
763    realview_io = RealViewCtrl(proc_id0=0x14000000, proc_id1=0x14000000,
764                               idreg=0x02250000, pio_addr=0x1C010000)
765
766    mcc = VExpressMCC()
767    dcc = CoreTile2A15DCC()
768
769    ### On-chip devices ###
770    gic = Gic400(dist_addr=0x2C001000, cpu_addr=0x2C002000)
771    vgic   = VGic(vcpu_addr=0x2c006000, hv_addr=0x2c004000, maint_int=25)
772
773    local_cpu_timer = CpuLocalTimer(int_timer=ArmPPI(num=29),
774                                    int_watchdog=ArmPPI(num=30),
775                                    pio_addr=0x2C080000)
776
777    hdlcd  = HDLcd(pxl_clk=dcc.osc_pxl,
778                   pio_addr=0x2b000000, int_num=117,
779                   workaround_swap_rb=True)
780
781    def _on_chip_devices(self):
782        devices = [
783            self.gic, self.vgic,
784            self.local_cpu_timer
785        ]
786        if hasattr(self, "gicv2m"):
787            devices.append(self.gicv2m)
788        devices.append(self.hdlcd)
789        return devices
790
791    ### Off-chip devices ###
792    uart = Pl011(pio_addr=0x1c090000, int_num=37)
793    pci_host = GenericPciHost(
794        conf_base=0x30000000, conf_size='256MB', conf_device_bits=16,
795        pci_pio_base=0)
796
797    generic_timer = GenericTimer(int_phys_s=ArmPPI(num=29),
798                                 int_phys_ns=ArmPPI(num=30),
799                                 int_virt=ArmPPI(num=27),
800                                 int_hyp=ArmPPI(num=26))
801
802    timer0 = Sp804(int_num0=34, int_num1=34, pio_addr=0x1C110000, clock0='1MHz', clock1='1MHz')
803    timer1 = Sp804(int_num0=35, int_num1=35, pio_addr=0x1C120000, clock0='1MHz', clock1='1MHz')
804    clcd   = Pl111(pio_addr=0x1c1f0000, int_num=46)
805    kmi0   = Pl050(pio_addr=0x1c060000, int_num=44, ps2=PS2Keyboard())
806    kmi1   = Pl050(pio_addr=0x1c070000, int_num=45, ps2=PS2TouchKit())
807    cf_ctrl = IdeController(disks=[], pci_func=0, pci_dev=0, pci_bus=2,
808                            io_shift = 2, ctrl_offset = 2, Command = 0x1,
809                            BAR0 = 0x1C1A0000, BAR0Size = '256B',
810                            BAR1 = 0x1C1A0100, BAR1Size = '4096B',
811                            BAR0LegacyIO = True, BAR1LegacyIO = True)
812
813    vram           = SimpleMemory(range = AddrRange(0x18000000, size='32MB'),
814                                  conf_table_reported = False)
815    rtc            = PL031(pio_addr=0x1C170000, int_num=36)
816
817    l2x0_fake      = IsaFake(pio_addr=0x2C100000, pio_size=0xfff)
818    uart1_fake     = AmbaFake(pio_addr=0x1C0A0000)
819    uart2_fake     = AmbaFake(pio_addr=0x1C0B0000)
820    uart3_fake     = AmbaFake(pio_addr=0x1C0C0000)
821    sp810_fake     = AmbaFake(pio_addr=0x1C020000, ignore_access=True)
822    watchdog_fake  = AmbaFake(pio_addr=0x1C0F0000)
823    aaci_fake      = AmbaFake(pio_addr=0x1C040000)
824    lan_fake       = IsaFake(pio_addr=0x1A000000, pio_size=0xffff)
825    usb_fake       = IsaFake(pio_addr=0x1B000000, pio_size=0x1ffff)
826    mmc_fake       = AmbaFake(pio_addr=0x1c050000)
827    energy_ctrl    = EnergyCtrl(pio_addr=0x1c080000)
828
829    def _off_chip_devices(self):
830        devices = [
831            self.uart,
832            self.realview_io,
833            self.pci_host,
834            self.timer0,
835            self.timer1,
836            self.clcd,
837            self.kmi0,
838            self.kmi1,
839            self.cf_ctrl,
840            self.rtc,
841            self.vram,
842            self.l2x0_fake,
843            self.uart1_fake,
844            self.uart2_fake,
845            self.uart3_fake,
846            self.sp810_fake,
847            self.watchdog_fake,
848            self.aaci_fake,
849            self.lan_fake,
850            self.usb_fake,
851            self.mmc_fake,
852            self.energy_ctrl,
853        ]
854        # Try to attach the I/O if it exists
855        if hasattr(self, "ide"):
856            devices.append(self.ide)
857        if hasattr(self, "ethernet"):
858            devices.append(self.ethernet)
859        return devices
860
861    # Attach any PCI devices that are supported
862    def attachPciDevices(self):
863        self.ethernet = IGbE_e1000(pci_bus=0, pci_dev=0, pci_func=0,
864                                   InterruptLine=1, InterruptPin=1)
865        self.ide = IdeController(disks = [], pci_bus=0, pci_dev=1, pci_func=0,
866                                 InterruptLine=2, InterruptPin=2)
867
868    def enableMSIX(self):
869        self.gic = Gic400(dist_addr=0x2C001000, cpu_addr=0x2C002000,
870                          it_lines=512)
871        self.gicv2m = Gicv2m()
872        self.gicv2m.frames = [Gicv2mFrame(spi_base=256, spi_len=64, addr=0x2C1C0000)]
873
874    def setupBootLoader(self, mem_bus, cur_sys, loc):
875        cur_sys.bootmem = SimpleMemory(range = AddrRange('64MB'),
876                                       conf_table_reported = False)
877        if mem_bus is not None:
878            cur_sys.bootmem.port = mem_bus.master
879        if not cur_sys.boot_loader:
880            cur_sys.boot_loader = loc('boot_emm.arm')
881        cur_sys.atags_addr = 0x8000000
882        cur_sys.load_offset = 0x80000000
883
884class VExpress_EMM64(VExpress_EMM):
885    # Three memory regions are specified totalling 512GB
886    _mem_regions = [ AddrRange('2GB', size='2GB'),
887                     AddrRange('34GB', size='30GB'),
888                     AddrRange('512GB', size='480GB') ]
889    pci_host = GenericPciHost(
890        conf_base=0x30000000, conf_size='256MB', conf_device_bits=12,
891        pci_pio_base=0x2f000000)
892
893    def setupBootLoader(self, mem_bus, cur_sys, loc):
894        cur_sys.bootmem = SimpleMemory(range=AddrRange(0, size='64MB'),
895                                       conf_table_reported=False)
896        if mem_bus is not None:
897            cur_sys.bootmem.port = mem_bus.master
898        if not cur_sys.boot_loader:
899            cur_sys.boot_loader = loc('boot_emm.arm64')
900        cur_sys.atags_addr = 0x8000000
901        cur_sys.load_offset = 0x80000000
902
903class VExpress_GEM5_Base(RealView):
904    """
905The VExpress gem5 memory map is loosely based on a modified
906Versatile Express RS1 memory map.
907
908The gem5 platform has been designed to implement a subset of the
909original Versatile Express RS1 memory map. Off-chip peripherals should,
910when possible, adhere to the Versatile Express memory map. Non-PCI
911off-chip devices that are gem5-specific should live in the CS5 memory
912space to avoid conflicts with existing devices that we might want to
913model in the future. Such devices should normally have interrupts in
914the gem5-specific SPI range.
915
916On-chip peripherals are loosely modeled after the ARM CoreTile Express
917A15x2 A7x3 memory and interrupt map. In particular, the GIC and
918Generic Timer have the same interrupt lines and base addresses. Other
919on-chip devices are gem5 specific.
920
921Unlike the original Versatile Express RS2 extended platform, gem5 implements a
922large contigious DRAM space, without aliases or holes, starting at the
9232GiB boundary. This means that PCI memory is limited to 1GiB.
924
925Memory map:
926   0x00000000-0x03ffffff: Boot memory (CS0)
927   0x04000000-0x07ffffff: Reserved
928   0x08000000-0x0bffffff: Reserved (CS0 alias)
929   0x0c000000-0x0fffffff: Reserved (Off-chip, CS4)
930   0x10000000-0x13ffffff: gem5-specific peripherals (Off-chip, CS5)
931       0x10000000-0x1000ffff: gem5 energy controller
932       0x10010000-0x1001ffff: gem5 pseudo-ops
933
934   0x14000000-0x17ffffff: Reserved (Off-chip, PSRAM, CS1)
935   0x18000000-0x1bffffff: Reserved (Off-chip, Peripherals, CS2)
936   0x1c000000-0x1fffffff: Peripheral block 1 (Off-chip, CS3):
937       0x1c010000-0x1c01ffff: realview_io (VE system control regs.)
938       0x1c060000-0x1c06ffff: KMI0 (keyboard)
939       0x1c070000-0x1c07ffff: KMI1 (mouse)
940       0x1c090000-0x1c09ffff: UART0
941       0x1c0a0000-0x1c0affff: UART1 (reserved)
942       0x1c0b0000-0x1c0bffff: UART2 (reserved)
943       0x1c0c0000-0x1c0cffff: UART3 (reserved)
944       0x1c130000-0x1c13ffff: VirtIO (gem5/FM extension)
945       0x1c140000-0x1c14ffff: VirtIO (gem5/FM extension)
946       0x1c170000-0x1c17ffff: RTC
947
948   0x20000000-0x3fffffff: On-chip peripherals:
949       0x2b000000-0x2b00ffff: HDLCD
950
951       0x2c001000-0x2c001fff: GIC (distributor)
952       0x2c002000-0x2c003fff: GIC (CPU interface)
953       0x2c004000-0x2c005fff: vGIC (HV)
954       0x2c006000-0x2c007fff: vGIC (VCPU)
955       0x2c1c0000-0x2c1cffff: GICv2m MSI frame 0
956
957       0x2d000000-0x2d00ffff: GPU (reserved)
958
959       0x2f000000-0x2fffffff: PCI IO space
960       0x30000000-0x3fffffff: PCI config space
961
962   0x40000000-0x7fffffff: Ext. AXI: Used as PCI memory
963
964   0x80000000-X: DRAM
965
966Interrupts:
967      0- 15: Software generated interrupts (SGIs)
968     16- 31: On-chip private peripherals (PPIs)
969        25   : vgic
970        26   : generic_timer (hyp)
971        27   : generic_timer (virt)
972        28   : Reserved (Legacy FIQ)
973        29   : generic_timer (phys, sec)
974        30   : generic_timer (phys, non-sec)
975        31   : Reserved (Legacy IRQ)
976    32- 95: Mother board peripherals (SPIs)
977        32   : Reserved (SP805)
978        33   : Reserved (IOFPGA SW int)
979        34-35: Reserved (SP804)
980        36   : RTC
981        37-40: uart0-uart3
982        41-42: Reserved (PL180)
983        43   : Reserved (AACI)
984        44-45: kmi0-kmi1
985        46   : Reserved (CLCD)
986        47   : Reserved (Ethernet)
987        48   : Reserved (USB)
988    95-255: On-chip interrupt sources (we use these for
989            gem5-specific devices, SPIs)
990         74    : VirtIO (gem5/FM extension)
991         75    : VirtIO (gem5/FM extension)
992         95    : HDLCD
993         96- 98: GPU (reserved)
994        100-103: PCI
995   256-319: MSI frame 0 (gem5-specific, SPIs)
996   320-511: Unused
997
998    """
999
1000    # Everything above 2GiB is memory
1001    _mem_regions = [ AddrRange('2GB', size='510GB') ]
1002
1003    _off_chip_ranges = [
1004        # CS1-CS5
1005        AddrRange(0x0c000000, 0x1fffffff),
1006        # External AXI interface (PCI)
1007        AddrRange(0x2f000000, 0x7fffffff),
1008    ]
1009
1010    # Platform control device (off-chip)
1011    realview_io = RealViewCtrl(proc_id0=0x14000000, proc_id1=0x14000000,
1012                               idreg=0x02250000, pio_addr=0x1c010000)
1013    mcc = VExpressMCC()
1014    dcc = CoreTile2A15DCC()
1015
1016    ### On-chip devices ###
1017    generic_timer = GenericTimer(int_phys_s=ArmPPI(num=29),
1018                                 int_phys_ns=ArmPPI(num=30),
1019                                 int_virt=ArmPPI(num=27),
1020                                 int_hyp=ArmPPI(num=26))
1021
1022    def _on_chip_devices(self):
1023        return [
1024            self.generic_timer,
1025        ]
1026
1027    ### Off-chip devices ###
1028    clock24MHz = SrcClockDomain(clock="24MHz",
1029        voltage_domain=VoltageDomain(voltage="3.3V"))
1030
1031    uart = [
1032        Pl011(pio_addr=0x1c090000, int_num=37),
1033    ]
1034
1035    kmi0 = Pl050(pio_addr=0x1c060000, int_num=44, ps2=PS2Keyboard())
1036    kmi1 = Pl050(pio_addr=0x1c070000, int_num=45, ps2=PS2TouchKit())
1037
1038    rtc = PL031(pio_addr=0x1c170000, int_num=36)
1039
1040    ### gem5-specific off-chip devices ###
1041    pci_host = GenericArmPciHost(
1042        conf_base=0x30000000, conf_size='256MB', conf_device_bits=12,
1043        pci_pio_base=0x2f000000,
1044        int_policy="ARM_PCI_INT_DEV", int_base=100, int_count=4)
1045
1046    energy_ctrl = EnergyCtrl(pio_addr=0x10000000)
1047
1048    vio = [
1049        MmioVirtIO(pio_addr=0x1c130000, pio_size=0x1000,
1050                   interrupt=ArmSPI(num=74)),
1051        MmioVirtIO(pio_addr=0x1c140000, pio_size=0x1000,
1052                   interrupt=ArmSPI(num=75)),
1053    ]
1054
1055    def _off_chip_devices(self):
1056        return [
1057            self.realview_io,
1058            self.uart[0],
1059            self.kmi0,
1060            self.kmi1,
1061            self.rtc,
1062            self.pci_host,
1063            self.energy_ctrl,
1064            self.clock24MHz,
1065            self.vio[0],
1066            self.vio[1],
1067        ]
1068
1069    def attachPciDevice(self, device, *args, **kwargs):
1070        device.host = self.pci_host
1071        self._attach_device(device, *args, **kwargs)
1072
1073    def setupBootLoader(self, mem_bus, cur_sys, loc):
1074        cur_sys.bootmem = SimpleMemory(range=AddrRange(0, size='64MB'),
1075                                       conf_table_reported=False)
1076        if mem_bus is not None:
1077            cur_sys.bootmem.port = mem_bus.master
1078        if not cur_sys.boot_loader:
1079            cur_sys.boot_loader = [ loc('boot_emm.arm64'), loc('boot_emm.arm') ]
1080        cur_sys.atags_addr = 0x8000000
1081        cur_sys.load_offset = 0x80000000
1082
1083        #  Setup m5ops. It's technically not a part of the boot
1084        #  loader, but this is the only place we can configure the
1085        #  system.
1086        cur_sys.m5ops_base = 0x10010000
1087
1088    def generateDeviceTree(self, state):
1089        # Generate using standard RealView function
1090        dt = list(super(VExpress_GEM5_Base, self).generateDeviceTree(state))
1091        if len(dt) > 1:
1092            raise Exception("System returned too many DT nodes")
1093        node = dt[0]
1094
1095        node.appendCompatible(["arm,vexpress"])
1096        node.append(FdtPropertyStrings("model", ["V2P-CA15"]))
1097        node.append(FdtPropertyWords("arm,hbi", [0x0]))
1098        node.append(FdtPropertyWords("arm,vexpress,site", [0xf]))
1099
1100        yield node
1101
1102class VExpress_GEM5_V1_Base(VExpress_GEM5_Base):
1103    gic = kvm_gicv2_class(dist_addr=0x2c001000, cpu_addr=0x2c002000,
1104                          it_lines=512)
1105    vgic = VGic(vcpu_addr=0x2c006000, hv_addr=0x2c004000, maint_int=25)
1106    gicv2m = Gicv2m()
1107    gicv2m.frames = [
1108        Gicv2mFrame(spi_base=256, spi_len=64, addr=0x2c1c0000),
1109    ]
1110
1111    def _on_chip_devices(self):
1112        return super(VExpress_GEM5_V1_Base,self)._on_chip_devices() + [
1113                self.gic, self.vgic, self.gicv2m,
1114            ]
1115
1116class VExpress_GEM5_V1(VExpress_GEM5_V1_Base):
1117    hdlcd  = HDLcd(pxl_clk=VExpress_GEM5_V1_Base.dcc.osc_pxl,
1118                   pio_addr=0x2b000000, int_num=95)
1119
1120    def _on_chip_devices(self):
1121        return super(VExpress_GEM5_V1,self)._on_chip_devices() + [
1122                self.hdlcd,
1123            ]
1124
1125class VExpress_GEM5_V2_Base(VExpress_GEM5_Base):
1126    gic = Gicv3(dist_addr=0x2c000000, redist_addr=0x2c010000,
1127                maint_int=ArmPPI(num=25),
1128                its=Gicv3Its(pio_addr=0x2e010000))
1129
1130    # Limiting to 128 since it will otherwise overlap with PCI space
1131    gic.cpu_max = 128
1132
1133    def _on_chip_devices(self):
1134        return super(VExpress_GEM5_V2_Base,self)._on_chip_devices() + [
1135                self.gic, self.gic.its
1136            ]
1137
1138    def setupBootLoader(self, mem_bus, cur_sys, loc):
1139        cur_sys.boot_loader = [ loc('boot_emm_v2.arm64') ]
1140        super(VExpress_GEM5_V2_Base,self).setupBootLoader(mem_bus,
1141                cur_sys, loc)
1142
1143class VExpress_GEM5_V2(VExpress_GEM5_V2_Base):
1144    hdlcd  = HDLcd(pxl_clk=VExpress_GEM5_V2_Base.dcc.osc_pxl,
1145                   pio_addr=0x2b000000, int_num=95)
1146
1147    def _on_chip_devices(self):
1148        return super(VExpress_GEM5_V2,self)._on_chip_devices() + [
1149                self.hdlcd,
1150            ]
1151