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