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