RealView.py revision 12069:6554872926ec
1# Copyright (c) 2009-2017 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
43from m5.params import *
44from m5.proxy import *
45from ClockDomain import ClockDomain
46from VoltageDomain import VoltageDomain
47from Device import BasicPioDevice, PioDevice, IsaFake, BadAddr, DmaDevice
48from PciHost import *
49from Ethernet import NSGigE, IGbE_igb, IGbE_e1000
50from Ide import *
51from Platform import Platform
52from Terminal import Terminal
53from Uart import Uart
54from SimpleMemory import SimpleMemory
55from Gic import *
56from EnergyCtrl import EnergyCtrl
57from ClockDomain import SrcClockDomain
58from SubSystem import SubSystem
59
60# Platforms with KVM support should generally use in-kernel GIC
61# emulation. Use a GIC model that automatically switches between
62# gem5's GIC model and KVM's GIC model if KVM is available.
63try:
64    from KvmGic import MuxingKvmGic
65    kvm_gicv2_class = MuxingKvmGic
66except ImportError:
67    # KVM support wasn't compiled into gem5. Fallback to a
68    # software-only GIC.
69    kvm_gicv2_class = Pl390
70    pass
71
72class AmbaPioDevice(BasicPioDevice):
73    type = 'AmbaPioDevice'
74    abstract = True
75    cxx_header = "dev/arm/amba_device.hh"
76    amba_id = Param.UInt32("ID of AMBA device for kernel detection")
77
78class AmbaIntDevice(AmbaPioDevice):
79    type = 'AmbaIntDevice'
80    abstract = True
81    cxx_header = "dev/arm/amba_device.hh"
82    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
83    int_num = Param.UInt32("Interrupt number that connects to GIC")
84    int_delay = Param.Latency("100ns",
85            "Time between action and interrupt generation by device")
86
87class AmbaDmaDevice(DmaDevice):
88    type = 'AmbaDmaDevice'
89    abstract = True
90    cxx_header = "dev/arm/amba_device.hh"
91    pio_addr = Param.Addr("Address for AMBA slave interface")
92    pio_latency = Param.Latency("10ns", "Time between action and write/read result by AMBA DMA Device")
93    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
94    int_num = Param.UInt32("Interrupt number that connects to GIC")
95    amba_id = Param.UInt32("ID of AMBA device for kernel detection")
96
97class A9SCU(BasicPioDevice):
98    type = 'A9SCU'
99    cxx_header = "dev/arm/a9scu.hh"
100
101class ArmPciIntRouting(Enum): vals = [
102    'ARM_PCI_INT_STATIC',
103    'ARM_PCI_INT_DEV',
104    'ARM_PCI_INT_PIN',
105    ]
106
107class GenericArmPciHost(GenericPciHost):
108    type = 'GenericArmPciHost'
109    cxx_header = "dev/arm/pci_host.hh"
110
111    int_policy = Param.ArmPciIntRouting("PCI interrupt routing policy")
112    int_base = Param.Unsigned("PCI interrupt base")
113    int_count = Param.Unsigned("Maximum number of interrupts used by this host")
114
115class RealViewCtrl(BasicPioDevice):
116    type = 'RealViewCtrl'
117    cxx_header = "dev/arm/rv_ctrl.hh"
118    proc_id0 = Param.UInt32(0x0C000000, "Processor ID, SYS_PROCID")
119    proc_id1 = Param.UInt32(0x0C000222, "Processor ID, SYS_PROCID1")
120    idreg = Param.UInt32(0x00000000, "ID Register, SYS_ID")
121
122class RealViewOsc(ClockDomain):
123    type = 'RealViewOsc'
124    cxx_header = "dev/arm/rv_ctrl.hh"
125
126    parent = Param.RealViewCtrl(Parent.any, "RealView controller")
127
128    # TODO: We currently don't have the notion of a clock source,
129    # which means we have to associate oscillators with a voltage
130    # source.
131    voltage_domain = Param.VoltageDomain(Parent.voltage_domain,
132                                         "Voltage domain")
133
134    # See ARM DUI 0447J (ARM Motherboard Express uATX -- V2M-P1) and
135    # the individual core/logic tile reference manuals for details
136    # about the site/position/dcc/device allocation.
137    site = Param.UInt8("Board Site")
138    position = Param.UInt8("Position in device stack")
139    dcc = Param.UInt8("Daughterboard Configuration Controller")
140    device = Param.UInt8("Device ID")
141
142    freq = Param.Clock("Default frequency")
143
144class RealViewTemperatureSensor(SimObject):
145    type = 'RealViewTemperatureSensor'
146    cxx_header = "dev/arm/rv_ctrl.hh"
147
148    parent = Param.RealViewCtrl(Parent.any, "RealView controller")
149
150    system = Param.System(Parent.any, "system")
151
152    # See ARM DUI 0447J (ARM Motherboard Express uATX -- V2M-P1) and
153    # the individual core/logic tile reference manuals for details
154    # about the site/position/dcc/device allocation.
155    site = Param.UInt8("Board Site")
156    position = Param.UInt8("Position in device stack")
157    dcc = Param.UInt8("Daughterboard Configuration Controller")
158    device = Param.UInt8("Device ID")
159
160class VExpressMCC(SubSystem):
161    """ARM V2M-P1 Motherboard Configuration Controller
162
163This subsystem describes a subset of the devices that sit behind the
164motherboard configuration controller on the the ARM Motherboard
165Express (V2M-P1) motherboard. See ARM DUI 0447J for details.
166    """
167
168    class Osc(RealViewOsc):
169        site, position, dcc = (0, 0, 0)
170
171    class Temperature(RealViewTemperatureSensor):
172        site, position, dcc = (0, 0, 0)
173
174    osc_mcc = Osc(device=0, freq="50MHz")
175    osc_clcd = Osc(device=1, freq="23.75MHz")
176    osc_peripheral = Osc(device=2, freq="24MHz")
177    osc_system_bus = Osc(device=4, freq="24MHz")
178
179    # See Table 4.19 in ARM DUI 0447J (Motherboard Express uATX TRM).
180    temp_crtl = Temperature(device=0)
181
182class CoreTile2A15DCC(SubSystem):
183    """ARM CoreTile Express A15x2 Daughterboard Configuration Controller
184
185This subsystem describes a subset of the devices that sit behind the
186daughterboard configuration controller on a CoreTile Express A15x2. See
187ARM DUI 0604E for details.
188    """
189
190    class Osc(RealViewOsc):
191        site, position, dcc = (1, 0, 0)
192
193    # See Table 2.8 in ARM DUI 0604E (CoreTile Express A15x2 TRM)
194    osc_cpu = Osc(device=0, freq="60MHz")
195    osc_hsbm = Osc(device=4, freq="40MHz")
196    osc_pxl = Osc(device=5, freq="23.75MHz")
197    osc_smb = Osc(device=6, freq="50MHz")
198    osc_sys = Osc(device=7, freq="60MHz")
199    osc_ddr = Osc(device=8, freq="40MHz")
200
201class VGic(PioDevice):
202    type = 'VGic'
203    cxx_header = "dev/arm/vgic.hh"
204    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
205    platform = Param.Platform(Parent.any, "Platform this device is part of.")
206    vcpu_addr = Param.Addr(0, "Address for vcpu interfaces")
207    hv_addr = Param.Addr(0, "Address for hv control")
208    pio_delay = Param.Latency('10ns', "Delay for PIO r/w")
209   # The number of list registers is not currently configurable at runtime.
210    ppint = Param.UInt32("HV maintenance interrupt number")
211
212class AmbaFake(AmbaPioDevice):
213    type = 'AmbaFake'
214    cxx_header = "dev/arm/amba_fake.hh"
215    ignore_access = Param.Bool(False, "Ignore reads/writes to this device, (e.g. IsaFake + AMBA)")
216    amba_id = 0;
217
218class Pl011(Uart):
219    type = 'Pl011'
220    cxx_header = "dev/arm/pl011.hh"
221    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
222    int_num = Param.UInt32("Interrupt number that connects to GIC")
223    end_on_eot = Param.Bool(False, "End the simulation when a EOT is received on the UART")
224    int_delay = Param.Latency("100ns", "Time between action and interrupt generation by UART")
225
226class Sp804(AmbaPioDevice):
227    type = 'Sp804'
228    cxx_header = "dev/arm/timer_sp804.hh"
229    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
230    int_num0 = Param.UInt32("Interrupt number that connects to GIC")
231    clock0 = Param.Clock('1MHz', "Clock speed of the input")
232    int_num1 = Param.UInt32("Interrupt number that connects to GIC")
233    clock1 = Param.Clock('1MHz', "Clock speed of the input")
234    amba_id = 0x00141804
235
236class CpuLocalTimer(BasicPioDevice):
237    type = 'CpuLocalTimer'
238    cxx_header = "dev/arm/timer_cpulocal.hh"
239    gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
240    int_num_timer = Param.UInt32("Interrrupt number used per-cpu to GIC")
241    int_num_watchdog = Param.UInt32("Interrupt number for per-cpu watchdog to GIC")
242
243class GenericTimer(SimObject):
244    type = 'GenericTimer'
245    cxx_header = "dev/arm/generic_timer.hh"
246    system = Param.ArmSystem(Parent.any, "system")
247    gic = Param.BaseGic(Parent.any, "GIC to use for interrupting")
248    # @todo: for now only two timers per CPU is supported, which is the
249    # normal behaviour when security extensions are disabled.
250    int_phys = Param.UInt32("Physical timer interrupt number")
251    int_virt = Param.UInt32("Virtual timer interrupt number")
252
253class GenericTimerMem(PioDevice):
254    type = 'GenericTimerMem'
255    cxx_header = "dev/arm/generic_timer.hh"
256    gic = Param.BaseGic(Parent.any, "GIC to use for interrupting")
257
258    base = Param.Addr(0, "Base address")
259
260    int_phys = Param.UInt32("Interrupt number")
261    int_virt = Param.UInt32("Interrupt number")
262
263class PL031(AmbaIntDevice):
264    type = 'PL031'
265    cxx_header = "dev/arm/rtc_pl031.hh"
266    time = Param.Time('01/01/2009', "System time to use ('Now' for actual time)")
267    amba_id = 0x00341031
268
269class Pl050(AmbaIntDevice):
270    type = 'Pl050'
271    cxx_header = "dev/arm/kmi.hh"
272    vnc = Param.VncInput(Parent.any, "Vnc server for remote frame buffer display")
273    is_mouse = Param.Bool(False, "Is this interface a mouse, if not a keyboard")
274    int_delay = '1us'
275    amba_id = 0x00141050
276
277class Pl111(AmbaDmaDevice):
278    type = 'Pl111'
279    cxx_header = "dev/arm/pl111.hh"
280    pixel_clock = Param.Clock('24MHz', "Pixel clock")
281    vnc   = Param.VncInput(Parent.any, "Vnc server for remote frame buffer display")
282    amba_id = 0x00141111
283    enable_capture = Param.Bool(True, "capture frame to system.framebuffer.bmp")
284
285class HDLcd(AmbaDmaDevice):
286    type = 'HDLcd'
287    cxx_header = "dev/arm/hdlcd.hh"
288    vnc = Param.VncInput(Parent.any, "Vnc server for remote frame buffer "
289                                     "display")
290    amba_id = 0x00141000
291    workaround_swap_rb = Param.Bool(False, "Workaround incorrect color "
292                                    "selector order in some kernels")
293    workaround_dma_line_count = Param.Bool(True, "Workaround incorrect "
294                                           "DMA line count (off by 1)")
295    enable_capture = Param.Bool(True, "capture frame to system.framebuffer.bmp")
296
297    pixel_buffer_size = Param.MemorySize32("2kB", "Size of address range")
298
299    pxl_clk = Param.ClockDomain("Pixel clock source")
300    pixel_chunk = Param.Unsigned(32, "Number of pixels to handle in one batch")
301    virt_refresh_rate = Param.Frequency("20Hz", "Frame refresh rate "
302                                        "in KVM mode")
303
304class RealView(Platform):
305    type = 'RealView'
306    cxx_header = "dev/arm/realview.hh"
307    system = Param.System(Parent.any, "system")
308    _mem_regions = [(Addr(0), Addr('256MB'))]
309
310    def _on_chip_devices(self):
311        return []
312
313    def _off_chip_devices(self):
314        return []
315
316    _off_chip_ranges = []
317
318    def _attach_device(self, device, bus, dma_ports=None):
319        if hasattr(device, "pio"):
320            device.pio = bus.master
321        if hasattr(device, "dma"):
322            if dma_ports is None:
323                device.dma = bus.slave
324            else:
325                dma_ports.append(device.dma)
326
327    def _attach_io(self, devices, *args, **kwargs):
328        for d in devices:
329            self._attach_device(d, *args, **kwargs)
330
331    def _attach_clk(self, devices, clkdomain):
332        for d in devices:
333            if hasattr(d, "clk_domain"):
334                d.clk_domain = clkdomain
335
336    def attachPciDevices(self):
337        pass
338
339    def enableMSIX(self):
340        pass
341
342    def onChipIOClkDomain(self, clkdomain):
343        self._attach_clk(self._on_chip_devices(), clkdomain)
344
345    def offChipIOClkDomain(self, clkdomain):
346        self._attach_clk(self._off_chip_devices(), clkdomain)
347
348    def attachOnChipIO(self, bus, bridge=None, *args, **kwargs):
349        self._attach_io(self._on_chip_devices(), bus, *args, **kwargs)
350        if bridge:
351            bridge.ranges = self._off_chip_ranges
352
353    def attachIO(self, *args, **kwargs):
354        self._attach_io(self._off_chip_devices(), *args, **kwargs)
355
356    def setupBootLoader(self, mem_bus, cur_sys, loc):
357        self.nvmem = SimpleMemory(range = AddrRange('2GB', size = '64MB'),
358                                  conf_table_reported = False)
359        self.nvmem.port = mem_bus.master
360        cur_sys.boot_loader = loc('boot.arm')
361        cur_sys.atags_addr = 0x100
362        cur_sys.load_addr_mask = 0xfffffff
363        cur_sys.load_offset = 0
364
365
366# Reference for memory map and interrupt number
367# RealView Platform Baseboard Explore for Cortex-A9 User Guide(ARM DUI 0440A)
368# Chapter 4: Programmer's Reference
369class RealViewPBX(RealView):
370    uart = Pl011(pio_addr=0x10009000, int_num=44)
371    realview_io = RealViewCtrl(pio_addr=0x10000000)
372    mcc = VExpressMCC()
373    dcc = CoreTile2A15DCC()
374    gic = Pl390()
375    pci_host = GenericPciHost(
376        conf_base=0x30000000, conf_size='256MB', conf_device_bits=16,
377        pci_pio_base=0)
378    timer0 = Sp804(int_num0=36, int_num1=36, pio_addr=0x10011000)
379    timer1 = Sp804(int_num0=37, int_num1=37, pio_addr=0x10012000)
380    local_cpu_timer = CpuLocalTimer(int_num_timer=29, int_num_watchdog=30, pio_addr=0x1f000600)
381    clcd = Pl111(pio_addr=0x10020000, int_num=55)
382    kmi0   = Pl050(pio_addr=0x10006000, int_num=52)
383    kmi1   = Pl050(pio_addr=0x10007000, int_num=53, is_mouse=True)
384    a9scu  = A9SCU(pio_addr=0x1f000000)
385    cf_ctrl = IdeController(disks=[], pci_func=0, pci_dev=7, pci_bus=2,
386                            io_shift = 1, ctrl_offset = 2, Command = 0x1,
387                            BAR0 = 0x18000000, BAR0Size = '16B',
388                            BAR1 = 0x18000100, BAR1Size = '1B',
389                            BAR0LegacyIO = True, BAR1LegacyIO = True)
390
391
392    l2x0_fake     = IsaFake(pio_addr=0x1f002000, pio_size=0xfff)
393    flash_fake    = IsaFake(pio_addr=0x40000000, pio_size=0x20000000,
394                            fake_mem=True)
395    dmac_fake     = AmbaFake(pio_addr=0x10030000)
396    uart1_fake    = AmbaFake(pio_addr=0x1000a000)
397    uart2_fake    = AmbaFake(pio_addr=0x1000b000)
398    uart3_fake    = AmbaFake(pio_addr=0x1000c000)
399    smc_fake      = AmbaFake(pio_addr=0x100e1000)
400    sp810_fake    = AmbaFake(pio_addr=0x10001000, ignore_access=True)
401    watchdog_fake = AmbaFake(pio_addr=0x10010000)
402    gpio0_fake    = AmbaFake(pio_addr=0x10013000)
403    gpio1_fake    = AmbaFake(pio_addr=0x10014000)
404    gpio2_fake    = AmbaFake(pio_addr=0x10015000)
405    ssp_fake      = AmbaFake(pio_addr=0x1000d000)
406    sci_fake      = AmbaFake(pio_addr=0x1000e000)
407    aaci_fake     = AmbaFake(pio_addr=0x10004000)
408    mmc_fake      = AmbaFake(pio_addr=0x10005000)
409    rtc           = PL031(pio_addr=0x10017000, int_num=42)
410    energy_ctrl   = EnergyCtrl(pio_addr=0x1000f000)
411
412
413    # Attach I/O devices that are on chip and also set the appropriate
414    # ranges for the bridge
415    def attachOnChipIO(self, bus, bridge):
416       self.gic.pio = bus.master
417       self.l2x0_fake.pio = bus.master
418       self.a9scu.pio = bus.master
419       self.local_cpu_timer.pio = bus.master
420       # Bridge ranges based on excluding what is part of on-chip I/O
421       # (gic, l2x0, a9scu, local_cpu_timer)
422       bridge.ranges = [AddrRange(self.realview_io.pio_addr,
423                                  self.a9scu.pio_addr - 1),
424                        AddrRange(self.flash_fake.pio_addr,
425                                  self.flash_fake.pio_addr + \
426                                  self.flash_fake.pio_size - 1)]
427
428    # Set the clock domain for IO objects that are considered
429    # to be "close" to the cores.
430    def onChipIOClkDomain(self, clkdomain):
431        self.gic.clk_domain             = clkdomain
432        self.l2x0_fake.clk_domain       = clkdomain
433        self.a9scu.clkdomain            = clkdomain
434        self.local_cpu_timer.clk_domain = clkdomain
435
436    # Attach I/O devices to specified bus object.  Can't do this
437    # earlier, since the bus object itself is typically defined at the
438    # System level.
439    def attachIO(self, bus):
440       self.uart.pio          = bus.master
441       self.realview_io.pio   = bus.master
442       self.pci_host.pio      = bus.master
443       self.timer0.pio        = bus.master
444       self.timer1.pio        = bus.master
445       self.clcd.pio          = bus.master
446       self.clcd.dma          = bus.slave
447       self.kmi0.pio          = bus.master
448       self.kmi1.pio          = bus.master
449       self.cf_ctrl.pio       = bus.master
450       self.cf_ctrl.dma       = bus.slave
451       self.dmac_fake.pio     = bus.master
452       self.uart1_fake.pio    = bus.master
453       self.uart2_fake.pio    = bus.master
454       self.uart3_fake.pio    = bus.master
455       self.smc_fake.pio      = bus.master
456       self.sp810_fake.pio    = bus.master
457       self.watchdog_fake.pio = bus.master
458       self.gpio0_fake.pio    = bus.master
459       self.gpio1_fake.pio    = bus.master
460       self.gpio2_fake.pio    = bus.master
461       self.ssp_fake.pio      = bus.master
462       self.sci_fake.pio      = bus.master
463       self.aaci_fake.pio     = bus.master
464       self.mmc_fake.pio      = bus.master
465       self.rtc.pio           = bus.master
466       self.flash_fake.pio    = bus.master
467       self.energy_ctrl.pio   = bus.master
468
469    # Set the clock domain for IO objects that are considered
470    # to be "far" away from the cores.
471    def offChipIOClkDomain(self, clkdomain):
472        self.uart.clk_domain          = clkdomain
473        self.realview_io.clk_domain   = clkdomain
474        self.timer0.clk_domain        = clkdomain
475        self.timer1.clk_domain        = clkdomain
476        self.clcd.clk_domain          = clkdomain
477        self.kmi0.clk_domain          = clkdomain
478        self.kmi1.clk_domain          = clkdomain
479        self.cf_ctrl.clk_domain       = clkdomain
480        self.dmac_fake.clk_domain     = clkdomain
481        self.uart1_fake.clk_domain    = clkdomain
482        self.uart2_fake.clk_domain    = clkdomain
483        self.uart3_fake.clk_domain    = clkdomain
484        self.smc_fake.clk_domain      = clkdomain
485        self.sp810_fake.clk_domain    = clkdomain
486        self.watchdog_fake.clk_domain = clkdomain
487        self.gpio0_fake.clk_domain    = clkdomain
488        self.gpio1_fake.clk_domain    = clkdomain
489        self.gpio2_fake.clk_domain    = clkdomain
490        self.ssp_fake.clk_domain      = clkdomain
491        self.sci_fake.clk_domain      = clkdomain
492        self.aaci_fake.clk_domain     = clkdomain
493        self.mmc_fake.clk_domain      = clkdomain
494        self.rtc.clk_domain           = clkdomain
495        self.flash_fake.clk_domain    = clkdomain
496        self.energy_ctrl.clk_domain   = clkdomain
497
498# Reference for memory map and interrupt number
499# RealView Emulation Baseboard User Guide (ARM DUI 0143B)
500# Chapter 4: Programmer's Reference
501class RealViewEB(RealView):
502    uart = Pl011(pio_addr=0x10009000, int_num=44)
503    realview_io = RealViewCtrl(pio_addr=0x10000000, idreg=0x01400500)
504    mcc = VExpressMCC()
505    dcc = CoreTile2A15DCC()
506    gic = Pl390(dist_addr=0x10041000, cpu_addr=0x10040000)
507    timer0 = Sp804(int_num0=36, int_num1=36, pio_addr=0x10011000)
508    timer1 = Sp804(int_num0=37, int_num1=37, pio_addr=0x10012000)
509    clcd   = Pl111(pio_addr=0x10020000, int_num=23)
510    kmi0   = Pl050(pio_addr=0x10006000, int_num=20)
511    kmi1   = Pl050(pio_addr=0x10007000, int_num=21, is_mouse=True)
512
513    l2x0_fake     = IsaFake(pio_addr=0x1f002000, pio_size=0xfff, warn_access="1")
514    flash_fake    = IsaFake(pio_addr=0x40000000, pio_size=0x20000000-1,
515                            fake_mem=True)
516    dmac_fake     = AmbaFake(pio_addr=0x10030000)
517    uart1_fake    = AmbaFake(pio_addr=0x1000a000)
518    uart2_fake    = AmbaFake(pio_addr=0x1000b000)
519    uart3_fake    = AmbaFake(pio_addr=0x1000c000)
520    smcreg_fake   = IsaFake(pio_addr=0x10080000, pio_size=0x10000-1)
521    smc_fake      = AmbaFake(pio_addr=0x100e1000)
522    sp810_fake    = AmbaFake(pio_addr=0x10001000, ignore_access=True)
523    watchdog_fake = AmbaFake(pio_addr=0x10010000)
524    gpio0_fake    = AmbaFake(pio_addr=0x10013000)
525    gpio1_fake    = AmbaFake(pio_addr=0x10014000)
526    gpio2_fake    = AmbaFake(pio_addr=0x10015000)
527    ssp_fake      = AmbaFake(pio_addr=0x1000d000)
528    sci_fake      = AmbaFake(pio_addr=0x1000e000)
529    aaci_fake     = AmbaFake(pio_addr=0x10004000)
530    mmc_fake      = AmbaFake(pio_addr=0x10005000)
531    rtc_fake      = AmbaFake(pio_addr=0x10017000, amba_id=0x41031)
532    energy_ctrl   = EnergyCtrl(pio_addr=0x1000f000)
533
534    # Attach I/O devices that are on chip and also set the appropriate
535    # ranges for the bridge
536    def attachOnChipIO(self, bus, bridge):
537       self.gic.pio = bus.master
538       self.l2x0_fake.pio = bus.master
539       # Bridge ranges based on excluding what is part of on-chip I/O
540       # (gic, l2x0)
541       bridge.ranges = [AddrRange(self.realview_io.pio_addr,
542                                  self.gic.cpu_addr - 1),
543                        AddrRange(self.flash_fake.pio_addr, Addr.max)]
544
545    # Set the clock domain for IO objects that are considered
546    # to be "close" to the cores.
547    def onChipIOClkDomain(self, clkdomain):
548        self.gic.clk_domain             = clkdomain
549        self.l2x0_fake.clk_domain       = clkdomain
550
551    # Attach I/O devices to specified bus object.  Can't do this
552    # earlier, since the bus object itself is typically defined at the
553    # System level.
554    def attachIO(self, bus):
555       self.uart.pio          = bus.master
556       self.realview_io.pio   = bus.master
557       self.pci_host.pio      = bus.master
558       self.timer0.pio        = bus.master
559       self.timer1.pio        = bus.master
560       self.clcd.pio          = bus.master
561       self.clcd.dma          = bus.slave
562       self.kmi0.pio          = bus.master
563       self.kmi1.pio          = bus.master
564       self.dmac_fake.pio     = bus.master
565       self.uart1_fake.pio    = bus.master
566       self.uart2_fake.pio    = bus.master
567       self.uart3_fake.pio    = bus.master
568       self.smc_fake.pio      = bus.master
569       self.sp810_fake.pio    = bus.master
570       self.watchdog_fake.pio = bus.master
571       self.gpio0_fake.pio    = bus.master
572       self.gpio1_fake.pio    = bus.master
573       self.gpio2_fake.pio    = bus.master
574       self.ssp_fake.pio      = bus.master
575       self.sci_fake.pio      = bus.master
576       self.aaci_fake.pio     = bus.master
577       self.mmc_fake.pio      = bus.master
578       self.rtc_fake.pio      = bus.master
579       self.flash_fake.pio    = bus.master
580       self.smcreg_fake.pio   = bus.master
581       self.energy_ctrl.pio   = bus.master
582
583    # Set the clock domain for IO objects that are considered
584    # to be "far" away from the cores.
585    def offChipIOClkDomain(self, clkdomain):
586        self.uart.clk_domain          = clkdomain
587        self.realview_io.clk_domain   = clkdomain
588        self.timer0.clk_domain        = clkdomain
589        self.timer1.clk_domain        = clkdomain
590        self.clcd.clk_domain          = clkdomain
591        self.kmi0.clk_domain          = clkdomain
592        self.kmi1.clk_domain          = clkdomain
593        self.dmac_fake.clk_domain     = clkdomain
594        self.uart1_fake.clk_domain    = clkdomain
595        self.uart2_fake.clk_domain    = clkdomain
596        self.uart3_fake.clk_domain    = clkdomain
597        self.smc_fake.clk_domain      = clkdomain
598        self.sp810_fake.clk_domain    = clkdomain
599        self.watchdog_fake.clk_domain = clkdomain
600        self.gpio0_fake.clk_domain    = clkdomain
601        self.gpio1_fake.clk_domain    = clkdomain
602        self.gpio2_fake.clk_domain    = clkdomain
603        self.ssp_fake.clk_domain      = clkdomain
604        self.sci_fake.clk_domain      = clkdomain
605        self.aaci_fake.clk_domain     = clkdomain
606        self.mmc_fake.clk_domain      = clkdomain
607        self.rtc.clk_domain           = clkdomain
608        self.flash_fake.clk_domain    = clkdomain
609        self.smcreg_fake.clk_domain   = clkdomain
610        self.energy_ctrl.clk_domain   = clkdomain
611
612class VExpress_EMM(RealView):
613    _mem_regions = [(Addr('2GB'), Addr('2GB'))]
614
615    # Ranges based on excluding what is part of on-chip I/O (gic,
616    # a9scu)
617    _off_chip_ranges = [AddrRange(0x2F000000, size='16MB'),
618                        AddrRange(0x30000000, size='256MB'),
619                        AddrRange(0x40000000, size='512MB'),
620                        AddrRange(0x18000000, size='64MB'),
621                        AddrRange(0x1C000000, size='64MB')]
622
623    # Platform control device (off-chip)
624    realview_io = RealViewCtrl(proc_id0=0x14000000, proc_id1=0x14000000,
625                               idreg=0x02250000, pio_addr=0x1C010000)
626
627    mcc = VExpressMCC()
628    dcc = CoreTile2A15DCC()
629
630    ### On-chip devices ###
631    gic = Pl390(dist_addr=0x2C001000, cpu_addr=0x2C002000)
632    vgic   = VGic(vcpu_addr=0x2c006000, hv_addr=0x2c004000, ppint=25)
633
634    local_cpu_timer = CpuLocalTimer(int_num_timer=29, int_num_watchdog=30,
635                                    pio_addr=0x2C080000)
636
637    hdlcd  = HDLcd(pxl_clk=dcc.osc_pxl,
638                   pio_addr=0x2b000000, int_num=117,
639                   workaround_swap_rb=True)
640
641    def _on_chip_devices(self):
642        devices = [
643            self.gic, self.vgic,
644            self.local_cpu_timer
645        ]
646        if hasattr(self, "gicv2m"):
647            devices.append(self.gicv2m)
648        devices.append(self.hdlcd)
649        return devices
650
651    ### Off-chip devices ###
652    uart = Pl011(pio_addr=0x1c090000, int_num=37)
653    pci_host = GenericPciHost(
654        conf_base=0x30000000, conf_size='256MB', conf_device_bits=16,
655        pci_pio_base=0)
656
657    generic_timer = GenericTimer(int_phys=29, int_virt=27)
658    timer0 = Sp804(int_num0=34, int_num1=34, pio_addr=0x1C110000, clock0='1MHz', clock1='1MHz')
659    timer1 = Sp804(int_num0=35, int_num1=35, pio_addr=0x1C120000, clock0='1MHz', clock1='1MHz')
660    clcd   = Pl111(pio_addr=0x1c1f0000, int_num=46)
661    kmi0   = Pl050(pio_addr=0x1c060000, int_num=44)
662    kmi1   = Pl050(pio_addr=0x1c070000, int_num=45, is_mouse=True)
663    cf_ctrl = IdeController(disks=[], pci_func=0, pci_dev=0, pci_bus=2,
664                            io_shift = 2, ctrl_offset = 2, Command = 0x1,
665                            BAR0 = 0x1C1A0000, BAR0Size = '256B',
666                            BAR1 = 0x1C1A0100, BAR1Size = '4096B',
667                            BAR0LegacyIO = True, BAR1LegacyIO = True)
668
669    vram           = SimpleMemory(range = AddrRange(0x18000000, size='32MB'),
670                                  conf_table_reported = False)
671    rtc            = PL031(pio_addr=0x1C170000, int_num=36)
672
673    l2x0_fake      = IsaFake(pio_addr=0x2C100000, pio_size=0xfff)
674    uart1_fake     = AmbaFake(pio_addr=0x1C0A0000)
675    uart2_fake     = AmbaFake(pio_addr=0x1C0B0000)
676    uart3_fake     = AmbaFake(pio_addr=0x1C0C0000)
677    sp810_fake     = AmbaFake(pio_addr=0x1C020000, ignore_access=True)
678    watchdog_fake  = AmbaFake(pio_addr=0x1C0F0000)
679    aaci_fake      = AmbaFake(pio_addr=0x1C040000)
680    lan_fake       = IsaFake(pio_addr=0x1A000000, pio_size=0xffff)
681    usb_fake       = IsaFake(pio_addr=0x1B000000, pio_size=0x1ffff)
682    mmc_fake       = AmbaFake(pio_addr=0x1c050000)
683    energy_ctrl    = EnergyCtrl(pio_addr=0x1c080000)
684
685    def _off_chip_devices(self):
686        devices = [
687            self.uart,
688            self.realview_io,
689            self.pci_host,
690            self.timer0,
691            self.timer1,
692            self.clcd,
693            self.kmi0,
694            self.kmi1,
695            self.cf_ctrl,
696            self.rtc,
697            self.vram,
698            self.l2x0_fake,
699            self.uart1_fake,
700            self.uart2_fake,
701            self.uart3_fake,
702            self.sp810_fake,
703            self.watchdog_fake,
704            self.aaci_fake,
705            self.lan_fake,
706            self.usb_fake,
707            self.mmc_fake,
708            self.energy_ctrl,
709        ]
710        # Try to attach the I/O if it exists
711        if hasattr(self, "ide"):
712            devices.append(self.ide)
713        if hasattr(self, "ethernet"):
714            devices.append(self.ethernet)
715        return devices
716
717    # Attach any PCI devices that are supported
718    def attachPciDevices(self):
719        self.ethernet = IGbE_e1000(pci_bus=0, pci_dev=0, pci_func=0,
720                                   InterruptLine=1, InterruptPin=1)
721        self.ide = IdeController(disks = [], pci_bus=0, pci_dev=1, pci_func=0,
722                                 InterruptLine=2, InterruptPin=2)
723
724    def enableMSIX(self):
725        self.gic = Pl390(dist_addr=0x2C001000, cpu_addr=0x2C002000, it_lines=512)
726        self.gicv2m = Gicv2m()
727        self.gicv2m.frames = [Gicv2mFrame(spi_base=256, spi_len=64, addr=0x2C1C0000)]
728
729    def setupBootLoader(self, mem_bus, cur_sys, loc):
730        self.nvmem = SimpleMemory(range = AddrRange('64MB'),
731                                  conf_table_reported = False)
732        self.nvmem.port = mem_bus.master
733        cur_sys.boot_loader = loc('boot_emm.arm')
734        cur_sys.atags_addr = 0x8000000
735        cur_sys.load_addr_mask = 0xfffffff
736        cur_sys.load_offset = 0x80000000
737
738class VExpress_EMM64(VExpress_EMM):
739    # Three memory regions are specified totalling 512GB
740    _mem_regions = [(Addr('2GB'), Addr('2GB')), (Addr('34GB'), Addr('30GB')),
741                    (Addr('512GB'), Addr('480GB'))]
742    pci_host = GenericPciHost(
743        conf_base=0x30000000, conf_size='256MB', conf_device_bits=12,
744        pci_pio_base=0x2f000000)
745
746    def setupBootLoader(self, mem_bus, cur_sys, loc):
747        self.nvmem = SimpleMemory(range=AddrRange(0, size='64MB'),
748                                  conf_table_reported=False)
749        self.nvmem.port = mem_bus.master
750        cur_sys.boot_loader = loc('boot_emm.arm64')
751        cur_sys.atags_addr = 0x8000000
752        cur_sys.load_addr_mask = 0xfffffff
753        cur_sys.load_offset = 0x80000000
754
755
756class VExpress_GEM5_V1(RealView):
757    """
758The VExpress gem5 memory map is loosely based on a modified
759Versatile Express RS1 memory map.
760
761The gem5 platform has been designed to implement a subset of the
762original Versatile Express RS1 memory map. Off-chip peripherals should,
763when possible, adhere to the Versatile Express memory map. Non-PCI
764off-chip devices that are gem5-specific should live in the CS5 memory
765space to avoid conflicts with existing devices that we might want to
766model in the future. Such devices should normally have interrupts in
767the gem5-specific SPI range.
768
769On-chip peripherals are loosely modeled after the ARM CoreTile Express
770A15x2 A7x3 memory and interrupt map. In particular, the GIC and
771Generic Timer have the same interrupt lines and base addresses. Other
772on-chip devices are gem5 specific.
773
774Unlike the original Versatile Express RS2 extended platform, gem5 implements a
775large contigious DRAM space, without aliases or holes, starting at the
7762GiB boundary. This means that PCI memory is limited to 1GiB.
777
778Memory map:
779   0x00000000-0x03ffffff: Boot memory (CS0)
780   0x04000000-0x07ffffff: Reserved
781   0x08000000-0x0bffffff: Reserved (CS0 alias)
782   0x0c000000-0x0fffffff: Reserved (Off-chip, CS4)
783   0x10000000-0x13ffffff: gem5-specific peripherals (Off-chip, CS5)
784       0x10000000-0x1000ffff: gem5 energy controller
785       0x10010000-0x1001ffff: gem5 pseudo-ops
786
787   0x14000000-0x17ffffff: Reserved (Off-chip, PSRAM, CS1)
788   0x18000000-0x1bffffff: Reserved (Off-chip, Peripherals, CS2)
789   0x1c000000-0x1fffffff: Peripheral block 1 (Off-chip, CS3):
790       0x1c010000-0x1c01ffff: realview_io (VE system control regs.)
791       0x1c060000-0x1c06ffff: KMI0 (keyboard)
792       0x1c070000-0x1c07ffff: KMI1 (mouse)
793       0x1c090000-0x1c09ffff: UART0
794       0x1c0a0000-0x1c0affff: UART1 (reserved)
795       0x1c0b0000-0x1c0bffff: UART2 (reserved)
796       0x1c0c0000-0x1c0cffff: UART3 (reserved)
797       0x1c170000-0x1c17ffff: RTC
798
799   0x20000000-0x3fffffff: On-chip peripherals:
800       0x2b000000-0x2b00ffff: HDLCD
801
802       0x2c001000-0x2c001fff: GIC (distributor)
803       0x2c002000-0x2c0020ff: GIC (CPU interface)
804       0x2c004000-0x2c005fff: vGIC (HV)
805       0x2c006000-0x2c007fff: vGIC (VCPU)
806       0x2c1c0000-0x2c1cffff: GICv2m MSI frame 0
807
808       0x2d000000-0x2d00ffff: GPU (reserved)
809
810       0x2f000000-0x2fffffff: PCI IO space
811       0x30000000-0x3fffffff: PCI config space
812
813   0x40000000-0x7fffffff: Ext. AXI: Used as PCI memory
814
815   0x80000000-X: DRAM
816
817Interrupts:
818      0- 15: Software generated interrupts (SGIs)
819     16- 31: On-chip private peripherals (PPIs)
820        25   : vgic
821        26   : generic_timer (hyp)
822        27   : generic_timer (virt)
823        28   : Reserved (Legacy FIQ)
824        29   : generic_timer (phys, sec)
825        30   : generic_timer (phys, non-sec)
826        31   : Reserved (Legacy IRQ)
827    32- 95: Mother board peripherals (SPIs)
828        32   : Reserved (SP805)
829        33   : Reserved (IOFPGA SW int)
830        34-35: Reserved (SP804)
831        36   : RTC
832        37-40: uart0-uart3
833        41-42: Reserved (PL180)
834        43   : Reserved (AACI)
835        44-45: kmi0-kmi1
836        46   : Reserved (CLCD)
837        47   : Reserved (Ethernet)
838        48   : Reserved (USB)
839    95-255: On-chip interrupt sources (we use these for
840            gem5-specific devices, SPIs)
841         95    : HDLCD
842         96- 98: GPU (reserved)
843        100-103: PCI
844   256-319: MSI frame 0 (gem5-specific, SPIs)
845   320-511: Unused
846
847    """
848
849    # Everything above 2GiB is memory
850    _mem_regions = [(Addr('2GB'), Addr('510GB'))]
851
852    _off_chip_ranges = [
853        # CS1-CS5
854        AddrRange(0x0c000000, 0x1fffffff),
855        # External AXI interface (PCI)
856        AddrRange(0x2f000000, 0x7fffffff),
857    ]
858
859    # Platform control device (off-chip)
860    realview_io = RealViewCtrl(proc_id0=0x14000000, proc_id1=0x14000000,
861                               idreg=0x02250000, pio_addr=0x1c010000)
862    mcc = VExpressMCC()
863    dcc = CoreTile2A15DCC()
864
865    ### On-chip devices ###
866    gic = kvm_gicv2_class(dist_addr=0x2c001000, cpu_addr=0x2c002000,
867                          it_lines=512)
868    vgic = VGic(vcpu_addr=0x2c006000, hv_addr=0x2c004000, ppint=25)
869    gicv2m = Gicv2m()
870    gicv2m.frames = [
871        Gicv2mFrame(spi_base=256, spi_len=64, addr=0x2c1c0000),
872    ]
873
874    generic_timer = GenericTimer(int_phys=29, int_virt=27)
875
876    hdlcd  = HDLcd(pxl_clk=dcc.osc_pxl,
877                   pio_addr=0x2b000000, int_num=95)
878
879    def _on_chip_devices(self):
880        return [
881            self.gic, self.vgic, self.gicv2m,
882            self.hdlcd,
883            self.generic_timer,
884        ]
885
886    ### Off-chip devices ###
887    uart0 = Pl011(pio_addr=0x1c090000, int_num=37)
888
889    kmi0 = Pl050(pio_addr=0x1c060000, int_num=44)
890    kmi1 = Pl050(pio_addr=0x1c070000, int_num=45, is_mouse=True)
891
892    rtc = PL031(pio_addr=0x1c170000, int_num=36)
893
894    ### gem5-specific off-chip devices ###
895    pci_host = GenericArmPciHost(
896        conf_base=0x30000000, conf_size='256MB', conf_device_bits=12,
897        pci_pio_base=0x2f000000,
898        int_policy="ARM_PCI_INT_DEV", int_base=100, int_count=4)
899
900    energy_ctrl = EnergyCtrl(pio_addr=0x10000000)
901
902
903    def _off_chip_devices(self):
904        return [
905            self.realview_io,
906            self.uart0,
907            self.kmi0, self.kmi1,
908            self.rtc,
909            self.pci_host,
910            self.energy_ctrl,
911        ]
912
913    def attachPciDevice(self, device, *args, **kwargs):
914        device.host = self.pci_host
915        self._attach_device(device, *args, **kwargs)
916
917    def setupBootLoader(self, mem_bus, cur_sys, loc):
918        self.nvmem = SimpleMemory(range=AddrRange(0, size='64MB'),
919                                  conf_table_reported=False)
920        self.nvmem.port = mem_bus.master
921        cur_sys.boot_loader = [ loc('boot_emm.arm64'), loc('boot_emm.arm') ]
922        cur_sys.atags_addr = 0x8000000
923        # the old load_add_mask 0xfffffff works for 32-bit kernel
924        # but not the 64-bit one. The new value 0x7ffffff works for both
925        cur_sys.load_addr_mask = 0x7ffffff
926        cur_sys.load_offset = 0x80000000
927
928        #  Setup m5ops. It's technically not a part of the boot
929        #  loader, but this is the only place we can configure the
930        #  system.
931        cur_sys.m5ops_base = 0x10010000
932