RealView.py revision 11421
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.System(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_io(self, devices, bus):
305        for d in devices:
306            if hasattr(d, "pio"):
307                d.pio = bus.master
308            if hasattr(d, "dma"):
309                d.dma = bus.slave
310
311    def _attach_clk(self, devices, clkdomain):
312        for d in devices:
313            if hasattr(d, "clk_domain"):
314                d.clk_domain = clkdomain
315
316    def attachPciDevices(self):
317        pass
318
319    def enableMSIX(self):
320        pass
321
322    def onChipIOClkDomain(self, clkdomain):
323        self._attach_clk(self._on_chip_devices(), clkdomain)
324
325    def offChipIOClkDomain(self, clkdomain):
326        self._attach_clk(self._off_chip_devices(), clkdomain)
327
328    def attachOnChipIO(self, bus, bridge=None):
329        self._attach_io(self._on_chip_devices(), bus)
330        if bridge:
331            bridge.ranges = self._off_chip_ranges
332
333    def attachIO(self, bus):
334        self._attach_io(self._off_chip_devices(), bus)
335
336
337    def setupBootLoader(self, mem_bus, cur_sys, loc):
338        self.nvmem = SimpleMemory(range = AddrRange('2GB', size = '64MB'),
339                                  conf_table_reported = False)
340        self.nvmem.port = mem_bus.master
341        cur_sys.boot_loader = loc('boot.arm')
342        cur_sys.atags_addr = 0x100
343        cur_sys.load_addr_mask = 0xfffffff
344        cur_sys.load_offset = 0
345
346
347# Reference for memory map and interrupt number
348# RealView Platform Baseboard Explore for Cortex-A9 User Guide(ARM DUI 0440A)
349# Chapter 4: Programmer's Reference
350class RealViewPBX(RealView):
351    uart = Pl011(pio_addr=0x10009000, int_num=44)
352    realview_io = RealViewCtrl(pio_addr=0x10000000)
353    mcc = VExpressMCC()
354    dcc = CoreTile2A15DCC()
355    gic = Pl390()
356    pci_host = GenericPciHost(
357        conf_base=0x30000000, conf_size='256MB', conf_device_bits=16,
358        pci_pio_base=0)
359    timer0 = Sp804(int_num0=36, int_num1=36, pio_addr=0x10011000)
360    timer1 = Sp804(int_num0=37, int_num1=37, pio_addr=0x10012000)
361    local_cpu_timer = CpuLocalTimer(int_num_timer=29, int_num_watchdog=30, pio_addr=0x1f000600)
362    clcd = Pl111(pio_addr=0x10020000, int_num=55)
363    kmi0   = Pl050(pio_addr=0x10006000, int_num=52)
364    kmi1   = Pl050(pio_addr=0x10007000, int_num=53, is_mouse=True)
365    a9scu  = A9SCU(pio_addr=0x1f000000)
366    cf_ctrl = IdeController(disks=[], pci_func=0, pci_dev=7, pci_bus=2,
367                            io_shift = 1, ctrl_offset = 2, Command = 0x1,
368                            BAR0 = 0x18000000, BAR0Size = '16B',
369                            BAR1 = 0x18000100, BAR1Size = '1B',
370                            BAR0LegacyIO = True, BAR1LegacyIO = True)
371
372
373    l2x0_fake     = IsaFake(pio_addr=0x1f002000, pio_size=0xfff)
374    flash_fake    = IsaFake(pio_addr=0x40000000, pio_size=0x20000000,
375                            fake_mem=True)
376    dmac_fake     = AmbaFake(pio_addr=0x10030000)
377    uart1_fake    = AmbaFake(pio_addr=0x1000a000)
378    uart2_fake    = AmbaFake(pio_addr=0x1000b000)
379    uart3_fake    = AmbaFake(pio_addr=0x1000c000)
380    smc_fake      = AmbaFake(pio_addr=0x100e1000)
381    sp810_fake    = AmbaFake(pio_addr=0x10001000, ignore_access=True)
382    watchdog_fake = AmbaFake(pio_addr=0x10010000)
383    gpio0_fake    = AmbaFake(pio_addr=0x10013000)
384    gpio1_fake    = AmbaFake(pio_addr=0x10014000)
385    gpio2_fake    = AmbaFake(pio_addr=0x10015000)
386    ssp_fake      = AmbaFake(pio_addr=0x1000d000)
387    sci_fake      = AmbaFake(pio_addr=0x1000e000)
388    aaci_fake     = AmbaFake(pio_addr=0x10004000)
389    mmc_fake      = AmbaFake(pio_addr=0x10005000)
390    rtc           = PL031(pio_addr=0x10017000, int_num=42)
391    energy_ctrl   = EnergyCtrl(pio_addr=0x1000f000)
392
393
394    # Attach I/O devices that are on chip and also set the appropriate
395    # ranges for the bridge
396    def attachOnChipIO(self, bus, bridge):
397       self.gic.pio = bus.master
398       self.l2x0_fake.pio = bus.master
399       self.a9scu.pio = bus.master
400       self.local_cpu_timer.pio = bus.master
401       # Bridge ranges based on excluding what is part of on-chip I/O
402       # (gic, l2x0, a9scu, local_cpu_timer)
403       bridge.ranges = [AddrRange(self.realview_io.pio_addr,
404                                  self.a9scu.pio_addr - 1),
405                        AddrRange(self.flash_fake.pio_addr,
406                                  self.flash_fake.pio_addr + \
407                                  self.flash_fake.pio_size - 1)]
408
409    # Set the clock domain for IO objects that are considered
410    # to be "close" to the cores.
411    def onChipIOClkDomain(self, clkdomain):
412        self.gic.clk_domain             = clkdomain
413        self.l2x0_fake.clk_domain       = clkdomain
414        self.a9scu.clkdomain            = clkdomain
415        self.local_cpu_timer.clk_domain = clkdomain
416
417    # Attach I/O devices to specified bus object.  Can't do this
418    # earlier, since the bus object itself is typically defined at the
419    # System level.
420    def attachIO(self, bus):
421       self.uart.pio          = bus.master
422       self.realview_io.pio   = bus.master
423       self.pci_host.pio      = bus.master
424       self.timer0.pio        = bus.master
425       self.timer1.pio        = bus.master
426       self.clcd.pio          = bus.master
427       self.clcd.dma          = bus.slave
428       self.kmi0.pio          = bus.master
429       self.kmi1.pio          = bus.master
430       self.cf_ctrl.pio       = bus.master
431       self.cf_ctrl.dma       = bus.slave
432       self.dmac_fake.pio     = bus.master
433       self.uart1_fake.pio    = bus.master
434       self.uart2_fake.pio    = bus.master
435       self.uart3_fake.pio    = bus.master
436       self.smc_fake.pio      = bus.master
437       self.sp810_fake.pio    = bus.master
438       self.watchdog_fake.pio = bus.master
439       self.gpio0_fake.pio    = bus.master
440       self.gpio1_fake.pio    = bus.master
441       self.gpio2_fake.pio    = bus.master
442       self.ssp_fake.pio      = bus.master
443       self.sci_fake.pio      = bus.master
444       self.aaci_fake.pio     = bus.master
445       self.mmc_fake.pio      = bus.master
446       self.rtc.pio           = bus.master
447       self.flash_fake.pio    = bus.master
448       self.energy_ctrl.pio   = bus.master
449
450    # Set the clock domain for IO objects that are considered
451    # to be "far" away from the cores.
452    def offChipIOClkDomain(self, clkdomain):
453        self.uart.clk_domain          = clkdomain
454        self.realview_io.clk_domain   = clkdomain
455        self.timer0.clk_domain        = clkdomain
456        self.timer1.clk_domain        = clkdomain
457        self.clcd.clk_domain          = clkdomain
458        self.kmi0.clk_domain          = clkdomain
459        self.kmi1.clk_domain          = clkdomain
460        self.cf_ctrl.clk_domain       = clkdomain
461        self.dmac_fake.clk_domain     = clkdomain
462        self.uart1_fake.clk_domain    = clkdomain
463        self.uart2_fake.clk_domain    = clkdomain
464        self.uart3_fake.clk_domain    = clkdomain
465        self.smc_fake.clk_domain      = clkdomain
466        self.sp810_fake.clk_domain    = clkdomain
467        self.watchdog_fake.clk_domain = clkdomain
468        self.gpio0_fake.clk_domain    = clkdomain
469        self.gpio1_fake.clk_domain    = clkdomain
470        self.gpio2_fake.clk_domain    = clkdomain
471        self.ssp_fake.clk_domain      = clkdomain
472        self.sci_fake.clk_domain      = clkdomain
473        self.aaci_fake.clk_domain     = clkdomain
474        self.mmc_fake.clk_domain      = clkdomain
475        self.rtc.clk_domain           = clkdomain
476        self.flash_fake.clk_domain    = clkdomain
477        self.energy_ctrl.clk_domain   = clkdomain
478
479# Reference for memory map and interrupt number
480# RealView Emulation Baseboard User Guide (ARM DUI 0143B)
481# Chapter 4: Programmer's Reference
482class RealViewEB(RealView):
483    uart = Pl011(pio_addr=0x10009000, int_num=44)
484    realview_io = RealViewCtrl(pio_addr=0x10000000, idreg=0x01400500)
485    mcc = VExpressMCC()
486    dcc = CoreTile2A15DCC()
487    gic = Pl390(dist_addr=0x10041000, cpu_addr=0x10040000)
488    timer0 = Sp804(int_num0=36, int_num1=36, pio_addr=0x10011000)
489    timer1 = Sp804(int_num0=37, int_num1=37, pio_addr=0x10012000)
490    clcd   = Pl111(pio_addr=0x10020000, int_num=23)
491    kmi0   = Pl050(pio_addr=0x10006000, int_num=20)
492    kmi1   = Pl050(pio_addr=0x10007000, int_num=21, is_mouse=True)
493
494    l2x0_fake     = IsaFake(pio_addr=0x1f002000, pio_size=0xfff, warn_access="1")
495    flash_fake    = IsaFake(pio_addr=0x40000000, pio_size=0x20000000-1,
496                            fake_mem=True)
497    dmac_fake     = AmbaFake(pio_addr=0x10030000)
498    uart1_fake    = AmbaFake(pio_addr=0x1000a000)
499    uart2_fake    = AmbaFake(pio_addr=0x1000b000)
500    uart3_fake    = AmbaFake(pio_addr=0x1000c000)
501    smcreg_fake   = IsaFake(pio_addr=0x10080000, pio_size=0x10000-1)
502    smc_fake      = AmbaFake(pio_addr=0x100e1000)
503    sp810_fake    = AmbaFake(pio_addr=0x10001000, ignore_access=True)
504    watchdog_fake = AmbaFake(pio_addr=0x10010000)
505    gpio0_fake    = AmbaFake(pio_addr=0x10013000)
506    gpio1_fake    = AmbaFake(pio_addr=0x10014000)
507    gpio2_fake    = AmbaFake(pio_addr=0x10015000)
508    ssp_fake      = AmbaFake(pio_addr=0x1000d000)
509    sci_fake      = AmbaFake(pio_addr=0x1000e000)
510    aaci_fake     = AmbaFake(pio_addr=0x10004000)
511    mmc_fake      = AmbaFake(pio_addr=0x10005000)
512    rtc_fake      = AmbaFake(pio_addr=0x10017000, amba_id=0x41031)
513    energy_ctrl   = EnergyCtrl(pio_addr=0x1000f000)
514
515    # Attach I/O devices that are on chip and also set the appropriate
516    # ranges for the bridge
517    def attachOnChipIO(self, bus, bridge):
518       self.gic.pio = bus.master
519       self.l2x0_fake.pio = bus.master
520       # Bridge ranges based on excluding what is part of on-chip I/O
521       # (gic, l2x0)
522       bridge.ranges = [AddrRange(self.realview_io.pio_addr,
523                                  self.gic.cpu_addr - 1),
524                        AddrRange(self.flash_fake.pio_addr, Addr.max)]
525
526    # Set the clock domain for IO objects that are considered
527    # to be "close" to the cores.
528    def onChipIOClkDomain(self, clkdomain):
529        self.gic.clk_domain             = clkdomain
530        self.l2x0_fake.clk_domain       = clkdomain
531
532    # Attach I/O devices to specified bus object.  Can't do this
533    # earlier, since the bus object itself is typically defined at the
534    # System level.
535    def attachIO(self, bus):
536       self.uart.pio          = bus.master
537       self.realview_io.pio   = bus.master
538       self.pci_host.pio      = bus.master
539       self.timer0.pio        = bus.master
540       self.timer1.pio        = bus.master
541       self.clcd.pio          = bus.master
542       self.clcd.dma          = bus.slave
543       self.kmi0.pio          = bus.master
544       self.kmi1.pio          = bus.master
545       self.dmac_fake.pio     = bus.master
546       self.uart1_fake.pio    = bus.master
547       self.uart2_fake.pio    = bus.master
548       self.uart3_fake.pio    = bus.master
549       self.smc_fake.pio      = bus.master
550       self.sp810_fake.pio    = bus.master
551       self.watchdog_fake.pio = bus.master
552       self.gpio0_fake.pio    = bus.master
553       self.gpio1_fake.pio    = bus.master
554       self.gpio2_fake.pio    = bus.master
555       self.ssp_fake.pio      = bus.master
556       self.sci_fake.pio      = bus.master
557       self.aaci_fake.pio     = bus.master
558       self.mmc_fake.pio      = bus.master
559       self.rtc_fake.pio      = bus.master
560       self.flash_fake.pio    = bus.master
561       self.smcreg_fake.pio   = bus.master
562       self.energy_ctrl.pio   = bus.master
563
564    # Set the clock domain for IO objects that are considered
565    # to be "far" away from the cores.
566    def offChipIOClkDomain(self, clkdomain):
567        self.uart.clk_domain          = clkdomain
568        self.realview_io.clk_domain   = clkdomain
569        self.timer0.clk_domain        = clkdomain
570        self.timer1.clk_domain        = clkdomain
571        self.clcd.clk_domain          = clkdomain
572        self.kmi0.clk_domain          = clkdomain
573        self.kmi1.clk_domain          = clkdomain
574        self.dmac_fake.clk_domain     = clkdomain
575        self.uart1_fake.clk_domain    = clkdomain
576        self.uart2_fake.clk_domain    = clkdomain
577        self.uart3_fake.clk_domain    = clkdomain
578        self.smc_fake.clk_domain      = clkdomain
579        self.sp810_fake.clk_domain    = clkdomain
580        self.watchdog_fake.clk_domain = clkdomain
581        self.gpio0_fake.clk_domain    = clkdomain
582        self.gpio1_fake.clk_domain    = clkdomain
583        self.gpio2_fake.clk_domain    = clkdomain
584        self.ssp_fake.clk_domain      = clkdomain
585        self.sci_fake.clk_domain      = clkdomain
586        self.aaci_fake.clk_domain     = clkdomain
587        self.mmc_fake.clk_domain      = clkdomain
588        self.rtc.clk_domain           = clkdomain
589        self.flash_fake.clk_domain    = clkdomain
590        self.smcreg_fake.clk_domain   = clkdomain
591        self.energy_ctrl.clk_domain   = clkdomain
592
593class VExpress_EMM(RealView):
594    _mem_regions = [(Addr('2GB'), Addr('2GB'))]
595    uart = Pl011(pio_addr=0x1c090000, int_num=37)
596    realview_io = RealViewCtrl(
597        proc_id0=0x14000000, proc_id1=0x14000000,
598        idreg=0x02250000, pio_addr=0x1C010000)
599    mcc = VExpressMCC()
600    dcc = CoreTile2A15DCC()
601    gic = Pl390(dist_addr=0x2C001000, cpu_addr=0x2C002000)
602    pci_host = GenericPciHost(
603        conf_base=0x30000000, conf_size='256MB', conf_device_bits=16,
604        pci_pio_base=0)
605    local_cpu_timer = CpuLocalTimer(int_num_timer=29, int_num_watchdog=30, pio_addr=0x2C080000)
606    generic_timer = GenericTimer(int_phys=29, int_virt=27)
607    timer0 = Sp804(int_num0=34, int_num1=34, pio_addr=0x1C110000, clock0='1MHz', clock1='1MHz')
608    timer1 = Sp804(int_num0=35, int_num1=35, pio_addr=0x1C120000, clock0='1MHz', clock1='1MHz')
609    clcd   = Pl111(pio_addr=0x1c1f0000, int_num=46)
610    hdlcd  = HDLcd(pxl_clk=dcc.osc_pxl,
611                   pio_addr=0x2b000000, int_num=117,
612                   workaround_swap_rb=True)
613    kmi0   = Pl050(pio_addr=0x1c060000, int_num=44)
614    kmi1   = Pl050(pio_addr=0x1c070000, int_num=45, is_mouse=True)
615    vgic   = VGic(vcpu_addr=0x2c006000, hv_addr=0x2c004000, ppint=25)
616    cf_ctrl = IdeController(disks=[], pci_func=0, pci_dev=0, pci_bus=2,
617                            io_shift = 2, ctrl_offset = 2, Command = 0x1,
618                            BAR0 = 0x1C1A0000, BAR0Size = '256B',
619                            BAR1 = 0x1C1A0100, BAR1Size = '4096B',
620                            BAR0LegacyIO = True, BAR1LegacyIO = True)
621
622    vram           = SimpleMemory(range = AddrRange(0x18000000, size='32MB'),
623                                  conf_table_reported = False)
624    rtc            = PL031(pio_addr=0x1C170000, int_num=36)
625
626    l2x0_fake      = IsaFake(pio_addr=0x2C100000, pio_size=0xfff)
627    uart1_fake     = AmbaFake(pio_addr=0x1C0A0000)
628    uart2_fake     = AmbaFake(pio_addr=0x1C0B0000)
629    uart3_fake     = AmbaFake(pio_addr=0x1C0C0000)
630    sp810_fake     = AmbaFake(pio_addr=0x1C020000, ignore_access=True)
631    watchdog_fake  = AmbaFake(pio_addr=0x1C0F0000)
632    aaci_fake      = AmbaFake(pio_addr=0x1C040000)
633    lan_fake       = IsaFake(pio_addr=0x1A000000, pio_size=0xffff)
634    usb_fake       = IsaFake(pio_addr=0x1B000000, pio_size=0x1ffff)
635    mmc_fake       = AmbaFake(pio_addr=0x1c050000)
636    energy_ctrl    = EnergyCtrl(pio_addr=0x1c080000)
637
638    # Attach any PCI devices that are supported
639    def attachPciDevices(self):
640        self.ethernet = IGbE_e1000(pci_bus=0, pci_dev=0, pci_func=0,
641                                   InterruptLine=1, InterruptPin=1)
642        self.ide = IdeController(disks = [], pci_bus=0, pci_dev=1, pci_func=0,
643                                 InterruptLine=2, InterruptPin=2)
644
645    def enableMSIX(self):
646        self.gic = Pl390(dist_addr=0x2C001000, cpu_addr=0x2C002000, it_lines=512)
647        self.gicv2m = Gicv2m()
648        self.gicv2m.frames = [Gicv2mFrame(spi_base=256, spi_len=64, addr=0x2C1C0000)]
649
650    def setupBootLoader(self, mem_bus, cur_sys, loc):
651        self.nvmem = SimpleMemory(range = AddrRange('64MB'),
652                                  conf_table_reported = False)
653        self.nvmem.port = mem_bus.master
654        cur_sys.boot_loader = loc('boot_emm.arm')
655        cur_sys.atags_addr = 0x8000000
656        cur_sys.load_addr_mask = 0xfffffff
657        cur_sys.load_offset = 0x80000000
658
659    # Attach I/O devices that are on chip and also set the appropriate
660    # ranges for the bridge
661    def attachOnChipIO(self, bus, bridge=None):
662        self.gic.pio             = bus.master
663        self.vgic.pio            = bus.master
664        self.local_cpu_timer.pio = bus.master
665        if hasattr(self, "gicv2m"):
666            self.gicv2m.pio      = bus.master
667        self.hdlcd.dma           = bus.slave
668        if bridge:
669            # Bridge ranges based on excluding what is part of on-chip I/O
670            # (gic, a9scu)
671            bridge.ranges = [AddrRange(0x2F000000, size='16MB'),
672                             AddrRange(0x2B000000, size='4MB'),
673                             AddrRange(0x30000000, size='256MB'),
674                             AddrRange(0x40000000, size='512MB'),
675                             AddrRange(0x18000000, size='64MB'),
676                             AddrRange(0x1C000000, size='64MB')]
677
678
679    # Set the clock domain for IO objects that are considered
680    # to be "close" to the cores.
681    def onChipIOClkDomain(self, clkdomain):
682        self.gic.clk_domain             = clkdomain
683        if hasattr(self, "gicv2m"):
684            self.gicv2m.clk_domain      = clkdomain
685        self.hdlcd.clk_domain           = clkdomain
686        self.vgic.clk_domain            = clkdomain
687
688    # Attach I/O devices to specified bus object.  Done here
689    # as the specified bus to connect to may not always be fixed.
690    def attachIO(self, bus):
691       self.uart.pio            = bus.master
692       self.realview_io.pio     = bus.master
693       self.pci_host.pio        = bus.master
694       self.timer0.pio          = bus.master
695       self.timer1.pio          = bus.master
696       self.clcd.pio            = bus.master
697       self.clcd.dma            = bus.slave
698       self.hdlcd.pio           = bus.master
699       self.kmi0.pio            = bus.master
700       self.kmi1.pio            = bus.master
701       self.cf_ctrl.pio         = bus.master
702       self.cf_ctrl.dma         = bus.slave
703       self.rtc.pio             = bus.master
704       self.vram.port           = bus.master
705
706       self.l2x0_fake.pio       = bus.master
707       self.uart1_fake.pio      = bus.master
708       self.uart2_fake.pio      = bus.master
709       self.uart3_fake.pio      = bus.master
710       self.sp810_fake.pio      = bus.master
711       self.watchdog_fake.pio   = bus.master
712       self.aaci_fake.pio       = bus.master
713       self.lan_fake.pio        = bus.master
714       self.usb_fake.pio        = bus.master
715       self.mmc_fake.pio        = bus.master
716       self.energy_ctrl.pio     = bus.master
717
718       # Try to attach the I/O if it exists
719       try:
720           self.ide.pio         = bus.master
721           self.ide.dma         = bus.slave
722           self.ethernet.pio    = bus.master
723           self.ethernet.dma    = bus.slave
724       except:
725           pass
726
727    # Set the clock domain for IO objects that are considered
728    # to be "far" away from the cores.
729    def offChipIOClkDomain(self, clkdomain):
730        self.uart.clk_domain          = clkdomain
731        self.realview_io.clk_domain   = clkdomain
732        self.timer0.clk_domain        = clkdomain
733        self.timer1.clk_domain        = clkdomain
734        self.clcd.clk_domain          = clkdomain
735        self.kmi0.clk_domain          = clkdomain
736        self.kmi1.clk_domain          = clkdomain
737        self.cf_ctrl.clk_domain       = clkdomain
738        self.rtc.clk_domain           = clkdomain
739        self.vram.clk_domain          = clkdomain
740
741        self.l2x0_fake.clk_domain     = clkdomain
742        self.uart1_fake.clk_domain    = clkdomain
743        self.uart2_fake.clk_domain    = clkdomain
744        self.uart3_fake.clk_domain    = clkdomain
745        self.sp810_fake.clk_domain    = clkdomain
746        self.watchdog_fake.clk_domain = clkdomain
747        self.aaci_fake.clk_domain     = clkdomain
748        self.lan_fake.clk_domain      = clkdomain
749        self.usb_fake.clk_domain      = clkdomain
750        self.mmc_fake.clk_domain      = clkdomain
751        self.energy_ctrl.clk_domain   = clkdomain
752
753class VExpress_EMM64(VExpress_EMM):
754    # Three memory regions are specified totalling 512GB
755    _mem_regions = [(Addr('2GB'), Addr('2GB')), (Addr('34GB'), Addr('30GB')),
756                    (Addr('512GB'), Addr('480GB'))]
757    pci_host = GenericPciHost(
758        conf_base=0x30000000, conf_size='256MB', conf_device_bits=12,
759        pci_pio_base=0x2f000000)
760
761    def setupBootLoader(self, mem_bus, cur_sys, loc):
762        self.nvmem = SimpleMemory(range = AddrRange(0, size = '64MB'))
763        self.nvmem.port = mem_bus.master
764        cur_sys.boot_loader = loc('boot_emm.arm64')
765        cur_sys.atags_addr = 0x8000000
766        cur_sys.load_addr_mask = 0xfffffff
767        cur_sys.load_offset = 0x80000000
768
769
770class VExpress_GEM5_V1(RealView):
771    """
772The VExpress gem5 memory map is loosely based on a modified
773Versatile Express RS1 memory map.
774
775The gem5 platform has been designed to implement a subset of the
776original Versatile Express RS1 memory map. Off-chip peripherals should,
777when possible, adhere to the Versatile Express memory map. Non-PCI
778off-chip devices that are gem5-specific should live in the CS5 memory
779space to avoid conflicts with existing devices that we might want to
780model in the future. Such devices should normally have interrupts in
781the gem5-specific SPI range.
782
783On-chip peripherals are loosely modeled after the ARM CoreTile Express
784A15x2 A7x3 memory and interrupt map. In particular, the GIC and
785Generic Timer have the same interrupt lines and base addresses. Other
786on-chip devices are gem5 specific.
787
788Unlike the original Versatile Express RS2 extended platform, gem5 implements a
789large contigious DRAM space, without aliases or holes, starting at the
7902GiB boundary. This means that PCI memory is limited to 1GiB.
791
792Memory map:
793   0x00000000-0x03ffffff: Boot memory (CS0)
794   0x04000000-0x07ffffff: Reserved
795   0x08000000-0x0bffffff: Reserved (CS0 alias)
796   0x0c000000-0x0fffffff: Reserved (Off-chip, CS4)
797   0x10000000-0x13ffffff: gem5-specific peripherals (Off-chip, CS5)
798       0x10000000-0x1000ffff: gem5 energy controller
799
800   0x14000000-0x17ffffff: Reserved (Off-chip, PSRAM, CS1)
801   0x18000000-0x1bffffff: Reserved (Off-chip, Peripherals, CS2)
802   0x1c000000-0x1fffffff: Peripheral block 1 (Off-chip, CS3):
803       0x1c010000-0x1c01ffff: realview_io (VE system control regs.)
804       0x1c060000-0x1c06ffff: KMI0 (keyboard)
805       0x1c070000-0x1c07ffff: KMI1 (mouse)
806       0x1c090000-0x1c09ffff: UART0
807       0x1c0a0000-0x1c0affff: UART1 (reserved)
808       0x1c0b0000-0x1c0bffff: UART2 (reserved)
809       0x1c0c0000-0x1c0cffff: UART3 (reserved)
810       0x1c170000-0x1c17ffff: RTC
811
812   0x20000000-0x3fffffff: On-chip peripherals:
813       0x2b000000-0x2b00ffff: HDLCD
814
815       0x2c001000-0x2c001fff: GIC (distributor)
816       0x2c002000-0x2c0020ff: GIC (CPU interface)
817       0x2c004000-0x2c005fff: vGIC (HV)
818       0x2c006000-0x2c007fff: vGIC (VCPU)
819       0x2c1c0000-0x2c1cffff: GICv2m MSI frame 0
820
821       0x2d000000-0x2d00ffff: GPU (reserved)
822
823       0x2f000000-0x2fffffff: PCI IO space
824       0x30000000-0x3fffffff: PCI config space
825
826   0x40000000-0x7fffffff: Ext. AXI: Used as PCI memory
827
828   0x80000000-X: DRAM
829
830Interrupts:
831      0- 15: Software generated interrupts (SGIs)
832     16- 31: On-chip private peripherals (PPIs)
833        25   : vgic
834        26   : generic_timer (hyp)
835        27   : generic_timer (virt)
836        28   : Reserved (Legacy FIQ)
837        29   : generic_timer (phys, sec)
838        30   : generic_timer (phys, non-sec)
839        31   : Reserved (Legacy IRQ)
840    32- 95: Mother board peripherals (SPIs)
841        32   : Reserved (SP805)
842        33   : Reserved (IOFPGA SW int)
843        34-35: Reserved (SP804)
844        36   : RTC
845        37-40: uart0-uart3
846        41-42: Reserved (PL180)
847        43   : Reserved (AACI)
848        44-45: kmi0-kmi1
849        46   : Reserved (CLCD)
850        47   : Reserved (Ethernet)
851        48   : Reserved (USB)
852    95-255: On-chip interrupt sources (we use these for
853            gem5-specific devices, SPIs)
854         95    : HDLCD
855         96- 98: GPU (reserved)
856        100-103: PCI
857   256-319: MSI frame 0 (gem5-specific, SPIs)
858   320-511: Unused
859
860    """
861
862    # Everything above 2GiB is memory
863    _mem_regions = [(Addr('2GB'), Addr('510GB'))]
864
865    _off_chip_ranges = [
866        # CS1-CS5
867        AddrRange(0x0c000000, 0x1fffffff),
868        # External AXI interface (PCI)
869        AddrRange(0x2f000000, 0x7fffffff),
870    ]
871
872    # Platform control device (off-chip)
873    realview_io = RealViewCtrl(proc_id0=0x14000000, proc_id1=0x14000000,
874                               idreg=0x02250000, pio_addr=0x1c010000)
875    mcc = VExpressMCC()
876    dcc = CoreTile2A15DCC()
877
878    ### On-chip devices ###
879    gic = Pl390(dist_addr=0x2c001000, cpu_addr=0x2c002000, it_lines=512)
880    vgic = VGic(vcpu_addr=0x2c006000, hv_addr=0x2c004000, ppint=25)
881    gicv2m = Gicv2m()
882    gicv2m.frames = [
883        Gicv2mFrame(spi_base=256, spi_len=64, addr=0x2c1c0000),
884    ]
885
886    generic_timer = GenericTimer(int_phys=29, int_virt=27)
887
888    hdlcd  = HDLcd(pxl_clk=dcc.osc_pxl,
889                   pio_addr=0x2b000000, int_num=95)
890
891    def _on_chip_devices(self):
892        return [
893            self.gic, self.vgic, self.gicv2m,
894            self.hdlcd,
895            self.generic_timer,
896        ]
897
898    ### Off-chip devices ###
899    uart0 = Pl011(pio_addr=0x1c090000, int_num=37)
900
901    kmi0 = Pl050(pio_addr=0x1c060000, int_num=44)
902    kmi1 = Pl050(pio_addr=0x1c070000, int_num=45, is_mouse=True)
903
904    rtc = PL031(pio_addr=0x1c170000, int_num=36)
905
906    ### gem5-specific off-chip devices ###
907    pci_host = GenericArmPciHost(
908        conf_base=0x30000000, conf_size='256MB', conf_device_bits=12,
909        pci_pio_base=0x2f000000,
910        int_policy="ARM_PCI_INT_DEV", int_base=100, int_count=4)
911
912    energy_ctrl = EnergyCtrl(pio_addr=0x10000000)
913
914
915    def _off_chip_devices(self):
916        return [
917            self.realview_io,
918            self.uart0,
919            self.kmi0, self.kmi1,
920            self.rtc,
921            self.pci_host,
922            self.energy_ctrl,
923        ]
924
925    def attachPciDevice(self, device, bus):
926        device.host = self.pci_host
927        device.pio = bus.master
928        device.dma = bus.slave
929
930    def setupBootLoader(self, mem_bus, cur_sys, loc):
931        self.nvmem = SimpleMemory(range=AddrRange(0, size='64MB'))
932        self.nvmem.port = mem_bus.master
933        cur_sys.boot_loader = [ loc('boot_emm.arm64'), loc('boot_emm.arm') ]
934        cur_sys.atags_addr = 0x8000000
935        cur_sys.load_addr_mask = 0xfffffff
936        cur_sys.load_offset = 0x80000000
937