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