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