RealView.py revision 11595
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                                  conf_table_reported=False)
764        self.nvmem.port = mem_bus.master
765        cur_sys.boot_loader = loc('boot_emm.arm64')
766        cur_sys.atags_addr = 0x8000000
767        cur_sys.load_addr_mask = 0xfffffff
768        cur_sys.load_offset = 0x80000000
769
770
771class VExpress_GEM5_V1(RealView):
772    """
773The VExpress gem5 memory map is loosely based on a modified
774Versatile Express RS1 memory map.
775
776The gem5 platform has been designed to implement a subset of the
777original Versatile Express RS1 memory map. Off-chip peripherals should,
778when possible, adhere to the Versatile Express memory map. Non-PCI
779off-chip devices that are gem5-specific should live in the CS5 memory
780space to avoid conflicts with existing devices that we might want to
781model in the future. Such devices should normally have interrupts in
782the gem5-specific SPI range.
783
784On-chip peripherals are loosely modeled after the ARM CoreTile Express
785A15x2 A7x3 memory and interrupt map. In particular, the GIC and
786Generic Timer have the same interrupt lines and base addresses. Other
787on-chip devices are gem5 specific.
788
789Unlike the original Versatile Express RS2 extended platform, gem5 implements a
790large contigious DRAM space, without aliases or holes, starting at the
7912GiB boundary. This means that PCI memory is limited to 1GiB.
792
793Memory map:
794   0x00000000-0x03ffffff: Boot memory (CS0)
795   0x04000000-0x07ffffff: Reserved
796   0x08000000-0x0bffffff: Reserved (CS0 alias)
797   0x0c000000-0x0fffffff: Reserved (Off-chip, CS4)
798   0x10000000-0x13ffffff: gem5-specific peripherals (Off-chip, CS5)
799       0x10000000-0x1000ffff: gem5 energy controller
800
801   0x14000000-0x17ffffff: Reserved (Off-chip, PSRAM, CS1)
802   0x18000000-0x1bffffff: Reserved (Off-chip, Peripherals, CS2)
803   0x1c000000-0x1fffffff: Peripheral block 1 (Off-chip, CS3):
804       0x1c010000-0x1c01ffff: realview_io (VE system control regs.)
805       0x1c060000-0x1c06ffff: KMI0 (keyboard)
806       0x1c070000-0x1c07ffff: KMI1 (mouse)
807       0x1c090000-0x1c09ffff: UART0
808       0x1c0a0000-0x1c0affff: UART1 (reserved)
809       0x1c0b0000-0x1c0bffff: UART2 (reserved)
810       0x1c0c0000-0x1c0cffff: UART3 (reserved)
811       0x1c170000-0x1c17ffff: RTC
812
813   0x20000000-0x3fffffff: On-chip peripherals:
814       0x2b000000-0x2b00ffff: HDLCD
815
816       0x2c001000-0x2c001fff: GIC (distributor)
817       0x2c002000-0x2c0020ff: GIC (CPU interface)
818       0x2c004000-0x2c005fff: vGIC (HV)
819       0x2c006000-0x2c007fff: vGIC (VCPU)
820       0x2c1c0000-0x2c1cffff: GICv2m MSI frame 0
821
822       0x2d000000-0x2d00ffff: GPU (reserved)
823
824       0x2f000000-0x2fffffff: PCI IO space
825       0x30000000-0x3fffffff: PCI config space
826
827   0x40000000-0x7fffffff: Ext. AXI: Used as PCI memory
828
829   0x80000000-X: DRAM
830
831Interrupts:
832      0- 15: Software generated interrupts (SGIs)
833     16- 31: On-chip private peripherals (PPIs)
834        25   : vgic
835        26   : generic_timer (hyp)
836        27   : generic_timer (virt)
837        28   : Reserved (Legacy FIQ)
838        29   : generic_timer (phys, sec)
839        30   : generic_timer (phys, non-sec)
840        31   : Reserved (Legacy IRQ)
841    32- 95: Mother board peripherals (SPIs)
842        32   : Reserved (SP805)
843        33   : Reserved (IOFPGA SW int)
844        34-35: Reserved (SP804)
845        36   : RTC
846        37-40: uart0-uart3
847        41-42: Reserved (PL180)
848        43   : Reserved (AACI)
849        44-45: kmi0-kmi1
850        46   : Reserved (CLCD)
851        47   : Reserved (Ethernet)
852        48   : Reserved (USB)
853    95-255: On-chip interrupt sources (we use these for
854            gem5-specific devices, SPIs)
855         95    : HDLCD
856         96- 98: GPU (reserved)
857        100-103: PCI
858   256-319: MSI frame 0 (gem5-specific, SPIs)
859   320-511: Unused
860
861    """
862
863    # Everything above 2GiB is memory
864    _mem_regions = [(Addr('2GB'), Addr('510GB'))]
865
866    _off_chip_ranges = [
867        # CS1-CS5
868        AddrRange(0x0c000000, 0x1fffffff),
869        # External AXI interface (PCI)
870        AddrRange(0x2f000000, 0x7fffffff),
871    ]
872
873    # Platform control device (off-chip)
874    realview_io = RealViewCtrl(proc_id0=0x14000000, proc_id1=0x14000000,
875                               idreg=0x02250000, pio_addr=0x1c010000)
876    mcc = VExpressMCC()
877    dcc = CoreTile2A15DCC()
878
879    ### On-chip devices ###
880    gic = Pl390(dist_addr=0x2c001000, cpu_addr=0x2c002000, it_lines=512)
881    vgic = VGic(vcpu_addr=0x2c006000, hv_addr=0x2c004000, ppint=25)
882    gicv2m = Gicv2m()
883    gicv2m.frames = [
884        Gicv2mFrame(spi_base=256, spi_len=64, addr=0x2c1c0000),
885    ]
886
887    generic_timer = GenericTimer(int_phys=29, int_virt=27)
888
889    hdlcd  = HDLcd(pxl_clk=dcc.osc_pxl,
890                   pio_addr=0x2b000000, int_num=95)
891
892    def _on_chip_devices(self):
893        return [
894            self.gic, self.vgic, self.gicv2m,
895            self.hdlcd,
896            self.generic_timer,
897        ]
898
899    ### Off-chip devices ###
900    uart0 = Pl011(pio_addr=0x1c090000, int_num=37)
901
902    kmi0 = Pl050(pio_addr=0x1c060000, int_num=44)
903    kmi1 = Pl050(pio_addr=0x1c070000, int_num=45, is_mouse=True)
904
905    rtc = PL031(pio_addr=0x1c170000, int_num=36)
906
907    ### gem5-specific off-chip devices ###
908    pci_host = GenericArmPciHost(
909        conf_base=0x30000000, conf_size='256MB', conf_device_bits=12,
910        pci_pio_base=0x2f000000,
911        int_policy="ARM_PCI_INT_DEV", int_base=100, int_count=4)
912
913    energy_ctrl = EnergyCtrl(pio_addr=0x10000000)
914
915
916    def _off_chip_devices(self):
917        return [
918            self.realview_io,
919            self.uart0,
920            self.kmi0, self.kmi1,
921            self.rtc,
922            self.pci_host,
923            self.energy_ctrl,
924        ]
925
926    def attachPciDevice(self, device, bus):
927        device.host = self.pci_host
928        device.pio = bus.master
929        device.dma = bus.slave
930
931    def setupBootLoader(self, mem_bus, cur_sys, loc):
932        self.nvmem = SimpleMemory(range=AddrRange(0, size='64MB'),
933                                  conf_table_reported=False)
934        self.nvmem.port = mem_bus.master
935        cur_sys.boot_loader = [ loc('boot_emm.arm64'), loc('boot_emm.arm') ]
936        cur_sys.atags_addr = 0x8000000
937        cur_sys.load_addr_mask = 0xfffffff
938        cur_sys.load_offset = 0x80000000
939