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