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