1 # Copyright (c) 2009-2018 ARM Limited
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.
13 # Copyright (c) 2006-2007 The Regents of The University of Michigan
14 # All rights reserved.
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.
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.
44 from m5
.defines
import buildEnv
45 from m5
.params
import *
46 from m5
.proxy
import *
47 from m5
.util
.fdthelper
import *
48 from m5
.objects
.ClockDomain
import ClockDomain
49 from m5
.objects
.VoltageDomain
import VoltageDomain
50 from m5
.objects
.Device
import \
51 BasicPioDevice
, PioDevice
, IsaFake
, BadAddr
, DmaDevice
52 from m5
.objects
.PciHost
import *
53 from m5
.objects
.Ethernet
import NSGigE
, IGbE_igb
, IGbE_e1000
54 from m5
.objects
.Ide
import *
55 from m5
.objects
.Platform
import Platform
56 from m5
.objects
.Terminal
import Terminal
57 from m5
.objects
.Uart
import Uart
58 from m5
.objects
.SimpleMemory
import SimpleMemory
59 from m5
.objects
.Gic
import *
60 from m5
.objects
.EnergyCtrl
import EnergyCtrl
61 from m5
.objects
.ClockedObject
import ClockedObject
62 from m5
.objects
.ClockDomain
import SrcClockDomain
63 from m5
.objects
.SubSystem
import SubSystem
64 from m5
.objects
.Graphics
import ImageFormat
65 from m5
.objects
.ClockedObject
import ClockedObject
66 from m5
.objects
.PS2
import *
67 from m5
.objects
.VirtIOMMIO
import MmioVirtIO
69 # Platforms with KVM support should generally use in-kernel GIC
70 # emulation. Use a GIC model that automatically switches between
71 # gem5's GIC model and KVM's GIC model if KVM is available.
73 from m5
.objects
.KvmGic
import MuxingKvmGic
74 kvm_gicv2_class
= MuxingKvmGic
76 # KVM support wasn't compiled into gem5. Fallback to a
78 kvm_gicv2_class
= Gic400
81 class AmbaPioDevice(BasicPioDevice
):
82 type = 'AmbaPioDevice'
84 cxx_header
= "dev/arm/amba_device.hh"
85 amba_id
= Param
.UInt32("ID of AMBA device for kernel detection")
87 class AmbaIntDevice(AmbaPioDevice
):
88 type = 'AmbaIntDevice'
90 cxx_header
= "dev/arm/amba_device.hh"
91 gic
= Param
.BaseGic(Parent
.any
, "Gic to use for interrupting")
92 int_num
= Param
.UInt32("Interrupt number that connects to GIC")
93 int_delay
= Param
.Latency("100ns",
94 "Time between action and interrupt generation by device")
96 class AmbaDmaDevice(DmaDevice
):
97 type = 'AmbaDmaDevice'
99 cxx_header
= "dev/arm/amba_device.hh"
100 pio_addr
= Param
.Addr("Address for AMBA slave interface")
101 pio_latency
= Param
.Latency("10ns", "Time between action and write/read result by AMBA DMA Device")
102 gic
= Param
.BaseGic(Parent
.any
, "Gic to use for interrupting")
103 int_num
= Param
.UInt32("Interrupt number that connects to GIC")
104 amba_id
= Param
.UInt32("ID of AMBA device for kernel detection")
106 class A9SCU(BasicPioDevice
):
108 cxx_header
= "dev/arm/a9scu.hh"
110 class ArmPciIntRouting(Enum
): vals
= [
111 'ARM_PCI_INT_STATIC',
116 class GenericArmPciHost(GenericPciHost
):
117 type = 'GenericArmPciHost'
118 cxx_header
= "dev/arm/pci_host.hh"
120 int_policy
= Param
.ArmPciIntRouting("PCI interrupt routing policy")
121 int_base
= Param
.Unsigned("PCI interrupt base")
122 int_count
= Param
.Unsigned("Maximum number of interrupts used by this host")
124 # This python parameter can be used in configuration scripts to turn
125 # on/off the fdt dma-coherent flag when doing dtb autogeneration
128 def generateDeviceTree(self
, state
):
129 local_state
= FdtState(addr_cells
=3, size_cells
=2, cpu_cells
=1)
132 node
= FdtNode("pci")
134 if int(self
.conf_device_bits
) == 8:
135 node
.appendCompatible("pci-host-cam-generic")
136 elif int(self
.conf_device_bits
) == 12:
137 node
.appendCompatible("pci-host-ecam-generic")
139 m5
.fatal("No compatibility string for the set conf_device_width")
141 node
.append(FdtPropertyStrings("device_type", ["pci"]))
143 # Cell sizes of child nodes/peripherals
144 node
.append(local_state
.addrCellsProperty())
145 node
.append(local_state
.sizeCellsProperty())
146 node
.append(FdtPropertyWords("#interrupt-cells", intterrupt_cells
))
147 # PCI address for CPU
148 node
.append(FdtPropertyWords("reg",
149 state
.addrCells(self
.conf_base
) +
150 state
.sizeCells(self
.conf_size
) ))
153 # For now some of this is hard coded, because the PCI module does not
154 # have a proper full understanding of the memory map, but adapting the
155 # PCI module is beyond the scope of what I'm trying to do here.
156 # Values are taken from the VExpress_GEM5_V1 platform.
159 ranges
+= self
.pciFdtAddr(space
=1, addr
=0)
160 ranges
+= state
.addrCells(self
.pci_pio_base
)
161 ranges
+= local_state
.sizeCells(0x10000) # Fixed size
163 # AXI memory address range
164 ranges
+= self
.pciFdtAddr(space
=2, addr
=0)
165 ranges
+= state
.addrCells(0x40000000) # Fixed offset
166 ranges
+= local_state
.sizeCells(0x40000000) # Fixed size
167 node
.append(FdtPropertyWords("ranges", ranges
))
169 if str(self
.int_policy
) == 'ARM_PCI_INT_DEV':
170 int_phandle
= state
.phandle(self
._parent
.unproxy(self
).gic
)
173 for i
in range(int(self
.int_count
)):
174 interrupts
+= self
.pciFdtAddr(device
=i
, addr
=0) + \
175 [0x0, int_phandle
, 0, int(self
.int_base
) - 32 + i
, 1]
177 node
.append(FdtPropertyWords("interrupt-map", interrupts
))
179 int_count
= int(self
.int_count
)
180 if int_count
& (int_count
- 1):
181 fatal("PCI interrupt count should be power of 2")
183 intmask
= self
.pciFdtAddr(device
=int_count
- 1, addr
=0) + [0x0]
184 node
.append(FdtPropertyWords("interrupt-map-mask", intmask
))
186 m5
.fatal("Unsupported PCI interrupt policy " +
187 "for Device Tree generation")
189 if self
._dma
_coherent
:
190 node
.append(FdtProperty("dma-coherent"))
194 class RealViewCtrl(BasicPioDevice
):
195 type = 'RealViewCtrl'
196 cxx_header
= "dev/arm/rv_ctrl.hh"
197 proc_id0
= Param
.UInt32(0x0C000000, "Processor ID, SYS_PROCID")
198 proc_id1
= Param
.UInt32(0x0C000222, "Processor ID, SYS_PROCID1")
199 idreg
= Param
.UInt32(0x00000000, "ID Register, SYS_ID")
201 def generateDeviceTree(self
, state
):
202 node
= FdtNode("sysreg@%x" % long(self
.pio_addr
))
203 node
.appendCompatible("arm,vexpress-sysreg")
204 node
.append(FdtPropertyWords("reg",
205 state
.addrCells(self
.pio_addr
) +
206 state
.sizeCells(0x1000) ))
207 node
.append(FdtProperty("gpio-controller"))
208 node
.append(FdtPropertyWords("#gpio-cells", [2]))
209 node
.appendPhandle(self
)
213 class RealViewOsc(ClockDomain
):
215 cxx_header
= "dev/arm/rv_ctrl.hh"
217 parent
= Param
.RealViewCtrl(Parent
.any
, "RealView controller")
219 # TODO: We currently don't have the notion of a clock source,
220 # which means we have to associate oscillators with a voltage
222 voltage_domain
= Param
.VoltageDomain(Parent
.voltage_domain
,
225 # See ARM DUI 0447J (ARM Motherboard Express uATX -- V2M-P1) and
226 # the individual core/logic tile reference manuals for details
227 # about the site/position/dcc/device allocation.
228 site
= Param
.UInt8("Board Site")
229 position
= Param
.UInt8("Position in device stack")
230 dcc
= Param
.UInt8("Daughterboard Configuration Controller")
231 device
= Param
.UInt8("Device ID")
233 freq
= Param
.Clock("Default frequency")
235 def generateDeviceTree(self
, state
):
236 phandle
= state
.phandle(self
)
237 node
= FdtNode("osc@" + format(long(phandle
), 'x'))
238 node
.appendCompatible("arm,vexpress-osc")
239 node
.append(FdtPropertyWords("arm,vexpress-sysreg,func",
240 [0x1, int(self
.device
)]))
241 node
.append(FdtPropertyWords("#clock-cells", [0]))
242 freq
= int(1.0/self
.freq
.value
) # Values are stored as a clock period
243 node
.append(FdtPropertyWords("freq-range", [freq
, freq
]))
244 node
.append(FdtPropertyStrings("clock-output-names",
245 ["oscclk" + str(phandle
)]))
246 node
.appendPhandle(self
)
249 class RealViewTemperatureSensor(SimObject
):
250 type = 'RealViewTemperatureSensor'
251 cxx_header
= "dev/arm/rv_ctrl.hh"
253 parent
= Param
.RealViewCtrl(Parent
.any
, "RealView controller")
255 system
= Param
.System(Parent
.any
, "system")
257 # See ARM DUI 0447J (ARM Motherboard Express uATX -- V2M-P1) and
258 # the individual core/logic tile reference manuals for details
259 # about the site/position/dcc/device allocation.
260 site
= Param
.UInt8("Board Site")
261 position
= Param
.UInt8("Position in device stack")
262 dcc
= Param
.UInt8("Daughterboard Configuration Controller")
263 device
= Param
.UInt8("Device ID")
265 class VExpressMCC(SubSystem
):
266 """ARM V2M-P1 Motherboard Configuration Controller
268 This subsystem describes a subset of the devices that sit behind the
269 motherboard configuration controller on the the ARM Motherboard
270 Express (V2M-P1) motherboard. See ARM DUI 0447J for details.
273 class Osc(RealViewOsc
):
274 site
, position
, dcc
= (0, 0, 0)
276 class Temperature(RealViewTemperatureSensor
):
277 site
, position
, dcc
= (0, 0, 0)
279 osc_mcc
= Osc(device
=0, freq
="50MHz")
280 osc_clcd
= Osc(device
=1, freq
="23.75MHz")
281 osc_peripheral
= Osc(device
=2, freq
="24MHz")
282 osc_system_bus
= Osc(device
=4, freq
="24MHz")
284 # See Table 4.19 in ARM DUI 0447J (Motherboard Express uATX TRM).
285 temp_crtl
= Temperature(device
=0)
287 def generateDeviceTree(self
, state
):
288 node
= FdtNode("mcc")
289 node
.appendCompatible("arm,vexpress,config-bus")
290 node
.append(FdtPropertyWords("arm,vexpress,site", [0]))
292 for obj
in self
._children
.values():
293 if issubclass(type(obj
), SimObject
):
294 node
.append(obj
.generateDeviceTree(state
))
296 io_phandle
= state
.phandle(self
.osc_mcc
.parent
.unproxy(self
))
297 node
.append(FdtPropertyWords("arm,vexpress,config-bridge", io_phandle
))
301 class CoreTile2A15DCC(SubSystem
):
302 """ARM CoreTile Express A15x2 Daughterboard Configuration Controller
304 This subsystem describes a subset of the devices that sit behind the
305 daughterboard configuration controller on a CoreTile Express A15x2. See
306 ARM DUI 0604E for details.
309 class Osc(RealViewOsc
):
310 site
, position
, dcc
= (1, 0, 0)
312 # See Table 2.8 in ARM DUI 0604E (CoreTile Express A15x2 TRM)
313 osc_cpu
= Osc(device
=0, freq
="60MHz")
314 osc_hsbm
= Osc(device
=4, freq
="40MHz")
315 osc_pxl
= Osc(device
=5, freq
="23.75MHz")
316 osc_smb
= Osc(device
=6, freq
="50MHz")
317 osc_sys
= Osc(device
=7, freq
="60MHz")
318 osc_ddr
= Osc(device
=8, freq
="40MHz")
320 def generateDeviceTree(self
, state
):
321 node
= FdtNode("dcc")
322 node
.appendCompatible("arm,vexpress,config-bus")
324 for obj
in self
._children
.values():
325 if isinstance(obj
, SimObject
):
326 node
.append(obj
.generateDeviceTree(state
))
328 io_phandle
= state
.phandle(self
.osc_cpu
.parent
.unproxy(self
))
329 node
.append(FdtPropertyWords("arm,vexpress,config-bridge", io_phandle
))
333 class AmbaFake(AmbaPioDevice
):
335 cxx_header
= "dev/arm/amba_fake.hh"
336 ignore_access
= Param
.Bool(False, "Ignore reads/writes to this device, (e.g. IsaFake + AMBA)")
341 cxx_header
= "dev/arm/pl011.hh"
342 gic
= Param
.BaseGic(Parent
.any
, "Gic to use for interrupting")
343 int_num
= Param
.UInt32("Interrupt number that connects to GIC")
344 end_on_eot
= Param
.Bool(False, "End the simulation when a EOT is received on the UART")
345 int_delay
= Param
.Latency("100ns", "Time between action and interrupt generation by UART")
347 def generateDeviceTree(self
, state
):
348 node
= self
.generateBasicPioDeviceNode(state
, 'uart', self
.pio_addr
,
349 0x1000, [int(self
.int_num
)])
350 node
.appendCompatible(["arm,pl011", "arm,primecell"])
352 # Hardcoded reference to the realview platform clocks, because the
353 # clk_domain can only store one clock (i.e. it is not a VectorParam)
354 realview
= self
._parent
.unproxy(self
)
355 node
.append(FdtPropertyWords("clocks",
356 [state
.phandle(realview
.mcc
.osc_peripheral
),
357 state
.phandle(realview
.dcc
.osc_smb
)]))
358 node
.append(FdtPropertyStrings("clock-names", ["uartclk", "apb_pclk"]))
361 class Sp804(AmbaPioDevice
):
363 cxx_header
= "dev/arm/timer_sp804.hh"
364 gic
= Param
.BaseGic(Parent
.any
, "Gic to use for interrupting")
365 int_num0
= Param
.UInt32("Interrupt number that connects to GIC")
366 clock0
= Param
.Clock('1MHz', "Clock speed of the input")
367 int_num1
= Param
.UInt32("Interrupt number that connects to GIC")
368 clock1
= Param
.Clock('1MHz', "Clock speed of the input")
371 class A9GlobalTimer(BasicPioDevice
):
372 type = 'A9GlobalTimer'
373 cxx_header
= "dev/arm/timer_a9global.hh"
374 gic
= Param
.BaseGic(Parent
.any
, "Gic to use for interrupting")
375 int_num
= Param
.UInt32("Interrrupt number that connects to GIC")
377 class CpuLocalTimer(BasicPioDevice
):
378 type = 'CpuLocalTimer'
379 cxx_header
= "dev/arm/timer_cpulocal.hh"
380 int_timer
= Param
.ArmPPI("Interrrupt used per-cpu to GIC")
381 int_watchdog
= Param
.ArmPPI("Interrupt for per-cpu watchdog to GIC")
383 class GenericTimer(ClockedObject
):
384 type = 'GenericTimer'
385 cxx_header
= "dev/arm/generic_timer.hh"
386 system
= Param
.ArmSystem(Parent
.any
, "system")
387 int_phys_s
= Param
.ArmPPI("Physical (S) timer interrupt")
388 int_phys_ns
= Param
.ArmPPI("Physical (NS) timer interrupt")
389 int_virt
= Param
.ArmPPI("Virtual timer interrupt")
390 int_hyp
= Param
.ArmPPI("Hypervisor timer interrupt")
392 def generateDeviceTree(self
, state
):
393 node
= FdtNode("timer")
395 node
.appendCompatible(["arm,cortex-a15-timer",
398 node
.append(FdtPropertyWords("interrupts", [
399 1, int(self
.int_phys_s
.num
) - 16, 0xf08,
400 1, int(self
.int_phys_ns
.num
) - 16, 0xf08,
401 1, int(self
.int_virt
.num
) - 16, 0xf08,
402 1, int(self
.int_hyp
.num
) - 16, 0xf08,
404 clock
= state
.phandle(self
.clk_domain
.unproxy(self
))
405 node
.append(FdtPropertyWords("clocks", clock
))
409 class GenericTimerMem(PioDevice
):
410 type = 'GenericTimerMem'
411 cxx_header
= "dev/arm/generic_timer.hh"
413 base
= Param
.Addr(0, "Base address")
415 int_phys
= Param
.ArmSPI("Physical Interrupt")
416 int_virt
= Param
.ArmSPI("Virtual Interrupt")
418 class PL031(AmbaIntDevice
):
420 cxx_header
= "dev/arm/rtc_pl031.hh"
421 time
= Param
.Time('01/01/2009', "System time to use ('Now' for actual time)")
424 def generateDeviceTree(self
, state
):
425 node
= self
.generateBasicPioDeviceNode(state
, 'rtc', self
.pio_addr
,
426 0x1000, [int(self
.int_num
)])
428 node
.appendCompatible(["arm,pl031", "arm,primecell"])
429 clock
= state
.phandle(self
.clk_domain
.unproxy(self
))
430 node
.append(FdtPropertyWords("clocks", clock
))
434 class Pl050(AmbaIntDevice
):
436 cxx_header
= "dev/arm/kmi.hh"
439 ps2
= Param
.PS2Device("PS/2 device")
441 def generateDeviceTree(self
, state
):
442 node
= self
.generateBasicPioDeviceNode(state
, 'kmi', self
.pio_addr
,
443 0x1000, [int(self
.int_num
)])
445 node
.appendCompatible(["arm,pl050", "arm,primecell"])
446 clock
= state
.phandle(self
.clk_domain
.unproxy(self
))
447 node
.append(FdtPropertyWords("clocks", clock
))
451 class Pl111(AmbaDmaDevice
):
453 cxx_header
= "dev/arm/pl111.hh"
454 pixel_clock
= Param
.Clock('24MHz', "Pixel clock")
455 vnc
= Param
.VncInput(Parent
.any
, "Vnc server for remote frame buffer display")
457 enable_capture
= Param
.Bool(True, "capture frame to system.framebuffer.bmp")
459 class HDLcd(AmbaDmaDevice
):
461 cxx_header
= "dev/arm/hdlcd.hh"
462 vnc
= Param
.VncInput(Parent
.any
, "Vnc server for remote frame buffer "
465 workaround_swap_rb
= Param
.Bool(False, "Workaround incorrect color "
466 "selector order in some kernels")
467 workaround_dma_line_count
= Param
.Bool(True, "Workaround incorrect "
468 "DMA line count (off by 1)")
469 enable_capture
= Param
.Bool(True, "capture frame to "
470 "system.framebuffer.{extension}")
471 frame_format
= Param
.ImageFormat("Auto",
472 "image format of the captured frame")
474 pixel_buffer_size
= Param
.MemorySize32("2kB", "Size of address range")
476 pxl_clk
= Param
.ClockDomain("Pixel clock source")
477 pixel_chunk
= Param
.Unsigned(32, "Number of pixels to handle in one batch")
478 virt_refresh_rate
= Param
.Frequency("20Hz", "Frame refresh rate "
481 def generateDeviceTree(self
, state
):
482 # Interrupt number is hardcoded; it is not a property of this class
483 node
= self
.generateBasicPioDeviceNode(state
, 'hdlcd',
484 self
.pio_addr
, 0x1000, [63])
486 node
.appendCompatible(["arm,hdlcd"])
487 node
.append(FdtPropertyWords("clocks", state
.phandle(self
.pxl_clk
)))
488 node
.append(FdtPropertyStrings("clock-names", ["pxlclk"]))
490 # This driver is disabled by default since the required DT nodes
491 # haven't been standardized yet. To use it, override this status to
492 # "ok" and add the display configuration nodes required by the driver.
493 # See the driver for more information.
494 node
.append(FdtPropertyStrings("status", ["disabled"]))
498 class RealView(Platform
):
500 cxx_header
= "dev/arm/realview.hh"
501 system
= Param
.System(Parent
.any
, "system")
502 _mem_regions
= [ AddrRange(0, size
='256MB') ]
504 def _on_chip_devices(self
):
507 def _off_chip_devices(self
):
510 _off_chip_ranges
= []
512 def _attach_device(self
, device
, bus
, dma_ports
=None):
513 if hasattr(device
, "pio"):
514 device
.pio
= bus
.master
515 if hasattr(device
, "dma"):
516 if dma_ports
is None:
517 device
.dma
= bus
.slave
519 dma_ports
.append(device
.dma
)
521 def _attach_io(self
, devices
, *args
, **kwargs
):
523 self
._attach
_device
(d
, *args
, **kwargs
)
525 def _attach_clk(self
, devices
, clkdomain
):
527 if hasattr(d
, "clk_domain"):
528 d
.clk_domain
= clkdomain
530 def attachPciDevices(self
):
533 def enableMSIX(self
):
536 def onChipIOClkDomain(self
, clkdomain
):
537 self
._attach
_clk
(self
._on
_chip
_devices
(), clkdomain
)
539 def offChipIOClkDomain(self
, clkdomain
):
540 self
._attach
_clk
(self
._off
_chip
_devices
(), clkdomain
)
542 def attachOnChipIO(self
, bus
, bridge
=None, *args
, **kwargs
):
543 self
._attach
_io
(self
._on
_chip
_devices
(), bus
, *args
, **kwargs
)
545 bridge
.ranges
= self
._off
_chip
_ranges
547 def attachIO(self
, *args
, **kwargs
):
548 self
._attach
_io
(self
._off
_chip
_devices
(), *args
, **kwargs
)
550 def setupBootLoader(self
, mem_bus
, cur_sys
, loc
):
551 cur_sys
.bootmem
= SimpleMemory(
552 range = AddrRange('2GB', size
= '64MB'),
553 conf_table_reported
= False)
554 if mem_bus
is not None:
555 cur_sys
.bootmem
.port
= mem_bus
.master
556 cur_sys
.boot_loader
= loc('boot.arm')
557 cur_sys
.atags_addr
= 0x100
558 cur_sys
.load_offset
= 0
560 def generateDeviceTree(self
, state
):
561 node
= FdtNode("/") # Things in this module need to end up in the root
562 node
.append(FdtPropertyWords("interrupt-parent",
563 state
.phandle(self
.gic
)))
565 for subnode
in self
.recurseDeviceTree(state
):
570 def annotateCpuDeviceNode(self
, cpu
, state
):
571 cpu
.append(FdtPropertyStrings("enable-method", "spin-table"))
572 cpu
.append(FdtPropertyWords("cpu-release-addr", \
573 state
.addrCells(0x8000fff8)))
575 # Reference for memory map and interrupt number
576 # RealView Platform Baseboard Explore for Cortex-A9 User Guide(ARM DUI 0440A)
577 # Chapter 4: Programmer's Reference
578 class RealViewPBX(RealView
):
579 uart
= Pl011(pio_addr
=0x10009000, int_num
=44)
580 realview_io
= RealViewCtrl(pio_addr
=0x10000000)
582 dcc
= CoreTile2A15DCC()
583 gic
= Gic400(cpu_addr
=0x1f000100, dist_addr
=0x1f001000, cpu_size
=0x100)
584 pci_host
= GenericPciHost(
585 conf_base
=0x30000000, conf_size
='256MB', conf_device_bits
=16,
587 timer0
= Sp804(int_num0
=36, int_num1
=36, pio_addr
=0x10011000)
588 timer1
= Sp804(int_num0
=37, int_num1
=37, pio_addr
=0x10012000)
589 global_timer
= A9GlobalTimer(int_num
=27, pio_addr
=0x1f000200)
590 local_cpu_timer
= CpuLocalTimer(int_timer
=ArmPPI(num
=29),
591 int_watchdog
=ArmPPI(num
=30),
593 clcd
= Pl111(pio_addr
=0x10020000, int_num
=55)
594 kmi0
= Pl050(pio_addr
=0x10006000, int_num
=52, ps2
=PS2Keyboard())
595 kmi1
= Pl050(pio_addr
=0x10007000, int_num
=53, ps2
=PS2TouchKit())
596 a9scu
= A9SCU(pio_addr
=0x1f000000)
597 cf_ctrl
= IdeController(disks
=[], pci_func
=0, pci_dev
=7, pci_bus
=2,
598 io_shift
= 1, ctrl_offset
= 2, Command
= 0x1,
599 BAR0
= 0x18000000, BAR0Size
= '16B',
600 BAR1
= 0x18000100, BAR1Size
= '1B',
601 BAR0LegacyIO
= True, BAR1LegacyIO
= True)
604 l2x0_fake
= IsaFake(pio_addr
=0x1f002000, pio_size
=0xfff)
605 flash_fake
= IsaFake(pio_addr
=0x40000000, pio_size
=0x20000000,
607 dmac_fake
= AmbaFake(pio_addr
=0x10030000)
608 uart1_fake
= AmbaFake(pio_addr
=0x1000a000)
609 uart2_fake
= AmbaFake(pio_addr
=0x1000b000)
610 uart3_fake
= AmbaFake(pio_addr
=0x1000c000)
611 smc_fake
= AmbaFake(pio_addr
=0x100e1000)
612 sp810_fake
= AmbaFake(pio_addr
=0x10001000, ignore_access
=True)
613 watchdog_fake
= AmbaFake(pio_addr
=0x10010000)
614 gpio0_fake
= AmbaFake(pio_addr
=0x10013000)
615 gpio1_fake
= AmbaFake(pio_addr
=0x10014000)
616 gpio2_fake
= AmbaFake(pio_addr
=0x10015000)
617 ssp_fake
= AmbaFake(pio_addr
=0x1000d000)
618 sci_fake
= AmbaFake(pio_addr
=0x1000e000)
619 aaci_fake
= AmbaFake(pio_addr
=0x10004000)
620 mmc_fake
= AmbaFake(pio_addr
=0x10005000)
621 rtc
= PL031(pio_addr
=0x10017000, int_num
=42)
622 energy_ctrl
= EnergyCtrl(pio_addr
=0x1000f000)
625 # Attach I/O devices that are on chip and also set the appropriate
626 # ranges for the bridge
627 def attachOnChipIO(self
, bus
, bridge
):
628 self
.gic
.pio
= bus
.master
629 self
.l2x0_fake
.pio
= bus
.master
630 self
.a9scu
.pio
= bus
.master
631 self
.global_timer
.pio
= bus
.master
632 self
.local_cpu_timer
.pio
= bus
.master
633 # Bridge ranges based on excluding what is part of on-chip I/O
634 # (gic, l2x0, a9scu, local_cpu_timer)
635 bridge
.ranges
= [AddrRange(self
.realview_io
.pio_addr
,
636 self
.a9scu
.pio_addr
- 1),
637 AddrRange(self
.flash_fake
.pio_addr
,
638 self
.flash_fake
.pio_addr
+ \
639 self
.flash_fake
.pio_size
- 1)]
641 # Set the clock domain for IO objects that are considered
642 # to be "close" to the cores.
643 def onChipIOClkDomain(self
, clkdomain
):
644 self
.gic
.clk_domain
= clkdomain
645 self
.l2x0_fake
.clk_domain
= clkdomain
646 self
.a9scu
.clkdomain
= clkdomain
647 self
.local_cpu_timer
.clk_domain
= clkdomain
649 # Attach I/O devices to specified bus object. Can't do this
650 # earlier, since the bus object itself is typically defined at the
652 def attachIO(self
, bus
):
653 self
.uart
.pio
= bus
.master
654 self
.realview_io
.pio
= bus
.master
655 self
.pci_host
.pio
= bus
.master
656 self
.timer0
.pio
= bus
.master
657 self
.timer1
.pio
= bus
.master
658 self
.clcd
.pio
= bus
.master
659 self
.clcd
.dma
= bus
.slave
660 self
.kmi0
.pio
= bus
.master
661 self
.kmi1
.pio
= bus
.master
662 self
.cf_ctrl
.pio
= bus
.master
663 self
.cf_ctrl
.dma
= bus
.slave
664 self
.dmac_fake
.pio
= bus
.master
665 self
.uart1_fake
.pio
= bus
.master
666 self
.uart2_fake
.pio
= bus
.master
667 self
.uart3_fake
.pio
= bus
.master
668 self
.smc_fake
.pio
= bus
.master
669 self
.sp810_fake
.pio
= bus
.master
670 self
.watchdog_fake
.pio
= bus
.master
671 self
.gpio0_fake
.pio
= bus
.master
672 self
.gpio1_fake
.pio
= bus
.master
673 self
.gpio2_fake
.pio
= bus
.master
674 self
.ssp_fake
.pio
= bus
.master
675 self
.sci_fake
.pio
= bus
.master
676 self
.aaci_fake
.pio
= bus
.master
677 self
.mmc_fake
.pio
= bus
.master
678 self
.rtc
.pio
= bus
.master
679 self
.flash_fake
.pio
= bus
.master
680 self
.energy_ctrl
.pio
= bus
.master
682 # Set the clock domain for IO objects that are considered
683 # to be "far" away from the cores.
684 def offChipIOClkDomain(self
, clkdomain
):
685 self
.uart
.clk_domain
= clkdomain
686 self
.realview_io
.clk_domain
= clkdomain
687 self
.timer0
.clk_domain
= clkdomain
688 self
.timer1
.clk_domain
= clkdomain
689 self
.clcd
.clk_domain
= clkdomain
690 self
.kmi0
.clk_domain
= clkdomain
691 self
.kmi1
.clk_domain
= clkdomain
692 self
.cf_ctrl
.clk_domain
= clkdomain
693 self
.dmac_fake
.clk_domain
= clkdomain
694 self
.uart1_fake
.clk_domain
= clkdomain
695 self
.uart2_fake
.clk_domain
= clkdomain
696 self
.uart3_fake
.clk_domain
= clkdomain
697 self
.smc_fake
.clk_domain
= clkdomain
698 self
.sp810_fake
.clk_domain
= clkdomain
699 self
.watchdog_fake
.clk_domain
= clkdomain
700 self
.gpio0_fake
.clk_domain
= clkdomain
701 self
.gpio1_fake
.clk_domain
= clkdomain
702 self
.gpio2_fake
.clk_domain
= clkdomain
703 self
.ssp_fake
.clk_domain
= clkdomain
704 self
.sci_fake
.clk_domain
= clkdomain
705 self
.aaci_fake
.clk_domain
= clkdomain
706 self
.mmc_fake
.clk_domain
= clkdomain
707 self
.rtc
.clk_domain
= clkdomain
708 self
.flash_fake
.clk_domain
= clkdomain
709 self
.energy_ctrl
.clk_domain
= clkdomain
711 class VExpress_EMM(RealView
):
712 _mem_regions
= [ AddrRange('2GB', size
='2GB') ]
714 # Ranges based on excluding what is part of on-chip I/O (gic,
716 _off_chip_ranges
= [AddrRange(0x2F000000, size
='16MB'),
717 AddrRange(0x30000000, size
='256MB'),
718 AddrRange(0x40000000, size
='512MB'),
719 AddrRange(0x18000000, size
='64MB'),
720 AddrRange(0x1C000000, size
='64MB')]
722 # Platform control device (off-chip)
723 realview_io
= RealViewCtrl(proc_id0
=0x14000000, proc_id1
=0x14000000,
724 idreg
=0x02250000, pio_addr
=0x1C010000)
727 dcc
= CoreTile2A15DCC()
729 ### On-chip devices ###
730 gic
= Gic400(dist_addr
=0x2C001000, cpu_addr
=0x2C002000)
731 vgic
= VGic(vcpu_addr
=0x2c006000, hv_addr
=0x2c004000, maint_int
=25)
733 local_cpu_timer
= CpuLocalTimer(int_timer
=ArmPPI(num
=29),
734 int_watchdog
=ArmPPI(num
=30),
737 hdlcd
= HDLcd(pxl_clk
=dcc
.osc_pxl
,
738 pio_addr
=0x2b000000, int_num
=117,
739 workaround_swap_rb
=True)
741 def _on_chip_devices(self
):
746 if hasattr(self
, "gicv2m"):
747 devices
.append(self
.gicv2m
)
748 devices
.append(self
.hdlcd
)
751 ### Off-chip devices ###
752 uart
= Pl011(pio_addr
=0x1c090000, int_num
=37)
753 pci_host
= GenericPciHost(
754 conf_base
=0x30000000, conf_size
='256MB', conf_device_bits
=16,
757 generic_timer
= GenericTimer(int_phys_s
=ArmPPI(num
=29),
758 int_phys_ns
=ArmPPI(num
=30),
759 int_virt
=ArmPPI(num
=27),
760 int_hyp
=ArmPPI(num
=26))
762 timer0
= Sp804(int_num0
=34, int_num1
=34, pio_addr
=0x1C110000, clock0
='1MHz', clock1
='1MHz')
763 timer1
= Sp804(int_num0
=35, int_num1
=35, pio_addr
=0x1C120000, clock0
='1MHz', clock1
='1MHz')
764 clcd
= Pl111(pio_addr
=0x1c1f0000, int_num
=46)
765 kmi0
= Pl050(pio_addr
=0x1c060000, int_num
=44, ps2
=PS2Keyboard())
766 kmi1
= Pl050(pio_addr
=0x1c070000, int_num
=45, ps2
=PS2TouchKit())
767 cf_ctrl
= IdeController(disks
=[], pci_func
=0, pci_dev
=0, pci_bus
=2,
768 io_shift
= 2, ctrl_offset
= 2, Command
= 0x1,
769 BAR0
= 0x1C1A0000, BAR0Size
= '256B',
770 BAR1
= 0x1C1A0100, BAR1Size
= '4096B',
771 BAR0LegacyIO
= True, BAR1LegacyIO
= True)
773 vram
= SimpleMemory(range = AddrRange(0x18000000, size
='32MB'),
774 conf_table_reported
= False)
775 rtc
= PL031(pio_addr
=0x1C170000, int_num
=36)
777 l2x0_fake
= IsaFake(pio_addr
=0x2C100000, pio_size
=0xfff)
778 uart1_fake
= AmbaFake(pio_addr
=0x1C0A0000)
779 uart2_fake
= AmbaFake(pio_addr
=0x1C0B0000)
780 uart3_fake
= AmbaFake(pio_addr
=0x1C0C0000)
781 sp810_fake
= AmbaFake(pio_addr
=0x1C020000, ignore_access
=True)
782 watchdog_fake
= AmbaFake(pio_addr
=0x1C0F0000)
783 aaci_fake
= AmbaFake(pio_addr
=0x1C040000)
784 lan_fake
= IsaFake(pio_addr
=0x1A000000, pio_size
=0xffff)
785 usb_fake
= IsaFake(pio_addr
=0x1B000000, pio_size
=0x1ffff)
786 mmc_fake
= AmbaFake(pio_addr
=0x1c050000)
787 energy_ctrl
= EnergyCtrl(pio_addr
=0x1c080000)
789 def _off_chip_devices(self
):
814 # Try to attach the I/O if it exists
815 if hasattr(self
, "ide"):
816 devices
.append(self
.ide
)
817 if hasattr(self
, "ethernet"):
818 devices
.append(self
.ethernet
)
821 # Attach any PCI devices that are supported
822 def attachPciDevices(self
):
823 self
.ethernet
= IGbE_e1000(pci_bus
=0, pci_dev
=0, pci_func
=0,
824 InterruptLine
=1, InterruptPin
=1)
825 self
.ide
= IdeController(disks
= [], pci_bus
=0, pci_dev
=1, pci_func
=0,
826 InterruptLine
=2, InterruptPin
=2)
828 def enableMSIX(self
):
829 self
.gic
= Gic400(dist_addr
=0x2C001000, cpu_addr
=0x2C002000,
831 self
.gicv2m
= Gicv2m()
832 self
.gicv2m
.frames
= [Gicv2mFrame(spi_base
=256, spi_len
=64, addr
=0x2C1C0000)]
834 def setupBootLoader(self
, mem_bus
, cur_sys
, loc
):
835 cur_sys
.bootmem
= SimpleMemory(range = AddrRange('64MB'),
836 conf_table_reported
= False)
837 if mem_bus
is not None:
838 cur_sys
.bootmem
.port
= mem_bus
.master
839 if not cur_sys
.boot_loader
:
840 cur_sys
.boot_loader
= loc('boot_emm.arm')
841 cur_sys
.atags_addr
= 0x8000000
842 cur_sys
.load_offset
= 0x80000000
844 class VExpress_EMM64(VExpress_EMM
):
845 # Three memory regions are specified totalling 512GB
846 _mem_regions
= [ AddrRange('2GB', size
='2GB'),
847 AddrRange('34GB', size
='30GB'),
848 AddrRange('512GB', size
='480GB') ]
849 pci_host
= GenericPciHost(
850 conf_base
=0x30000000, conf_size
='256MB', conf_device_bits
=12,
851 pci_pio_base
=0x2f000000)
853 def setupBootLoader(self
, mem_bus
, cur_sys
, loc
):
854 cur_sys
.bootmem
= SimpleMemory(range=AddrRange(0, size
='64MB'),
855 conf_table_reported
=False)
856 if mem_bus
is not None:
857 cur_sys
.bootmem
.port
= mem_bus
.master
858 if not cur_sys
.boot_loader
:
859 cur_sys
.boot_loader
= loc('boot_emm.arm64')
860 cur_sys
.atags_addr
= 0x8000000
861 cur_sys
.load_offset
= 0x80000000
863 class VExpress_GEM5_Base(RealView
):
865 The VExpress gem5 memory map is loosely based on a modified
866 Versatile Express RS1 memory map.
868 The gem5 platform has been designed to implement a subset of the
869 original Versatile Express RS1 memory map. Off-chip peripherals should,
870 when possible, adhere to the Versatile Express memory map. Non-PCI
871 off-chip devices that are gem5-specific should live in the CS5 memory
872 space to avoid conflicts with existing devices that we might want to
873 model in the future. Such devices should normally have interrupts in
874 the gem5-specific SPI range.
876 On-chip peripherals are loosely modeled after the ARM CoreTile Express
877 A15x2 A7x3 memory and interrupt map. In particular, the GIC and
878 Generic Timer have the same interrupt lines and base addresses. Other
879 on-chip devices are gem5 specific.
881 Unlike the original Versatile Express RS2 extended platform, gem5 implements a
882 large contigious DRAM space, without aliases or holes, starting at the
883 2GiB boundary. This means that PCI memory is limited to 1GiB.
886 0x00000000-0x03ffffff: Boot memory (CS0)
887 0x04000000-0x07ffffff: Reserved
888 0x08000000-0x0bffffff: Reserved (CS0 alias)
889 0x0c000000-0x0fffffff: Reserved (Off-chip, CS4)
890 0x10000000-0x13ffffff: gem5-specific peripherals (Off-chip, CS5)
891 0x10000000-0x1000ffff: gem5 energy controller
892 0x10010000-0x1001ffff: gem5 pseudo-ops
894 0x14000000-0x17ffffff: Reserved (Off-chip, PSRAM, CS1)
895 0x18000000-0x1bffffff: Reserved (Off-chip, Peripherals, CS2)
896 0x1c000000-0x1fffffff: Peripheral block 1 (Off-chip, CS3):
897 0x1c010000-0x1c01ffff: realview_io (VE system control regs.)
898 0x1c060000-0x1c06ffff: KMI0 (keyboard)
899 0x1c070000-0x1c07ffff: KMI1 (mouse)
900 0x1c090000-0x1c09ffff: UART0
901 0x1c0a0000-0x1c0affff: UART1 (reserved)
902 0x1c0b0000-0x1c0bffff: UART2 (reserved)
903 0x1c0c0000-0x1c0cffff: UART3 (reserved)
904 0x1c130000-0x1c13ffff: VirtIO (gem5/FM extension)
905 0x1c140000-0x1c14ffff: VirtIO (gem5/FM extension)
906 0x1c170000-0x1c17ffff: RTC
908 0x20000000-0x3fffffff: On-chip peripherals:
909 0x2b000000-0x2b00ffff: HDLCD
911 0x2c001000-0x2c001fff: GIC (distributor)
912 0x2c002000-0x2c003fff: GIC (CPU interface)
913 0x2c004000-0x2c005fff: vGIC (HV)
914 0x2c006000-0x2c007fff: vGIC (VCPU)
915 0x2c1c0000-0x2c1cffff: GICv2m MSI frame 0
917 0x2d000000-0x2d00ffff: GPU (reserved)
919 0x2f000000-0x2fffffff: PCI IO space
920 0x30000000-0x3fffffff: PCI config space
922 0x40000000-0x7fffffff: Ext. AXI: Used as PCI memory
927 0- 15: Software generated interrupts (SGIs)
928 16- 31: On-chip private peripherals (PPIs)
930 26 : generic_timer (hyp)
931 27 : generic_timer (virt)
932 28 : Reserved (Legacy FIQ)
933 29 : generic_timer (phys, sec)
934 30 : generic_timer (phys, non-sec)
935 31 : Reserved (Legacy IRQ)
936 32- 95: Mother board peripherals (SPIs)
937 32 : Reserved (SP805)
938 33 : Reserved (IOFPGA SW int)
939 34-35: Reserved (SP804)
942 41-42: Reserved (PL180)
946 47 : Reserved (Ethernet)
948 95-255: On-chip interrupt sources (we use these for
949 gem5-specific devices, SPIs)
950 74 : VirtIO (gem5/FM extension)
951 75 : VirtIO (gem5/FM extension)
953 96- 98: GPU (reserved)
955 256-319: MSI frame 0 (gem5-specific, SPIs)
960 # Everything above 2GiB is memory
961 _mem_regions
= [ AddrRange('2GB', size
='510GB') ]
965 AddrRange(0x0c000000, 0x1fffffff),
966 # External AXI interface (PCI)
967 AddrRange(0x2f000000, 0x7fffffff),
970 # Platform control device (off-chip)
971 realview_io
= RealViewCtrl(proc_id0
=0x14000000, proc_id1
=0x14000000,
972 idreg
=0x02250000, pio_addr
=0x1c010000)
974 dcc
= CoreTile2A15DCC()
976 ### On-chip devices ###
977 generic_timer
= GenericTimer(int_phys_s
=ArmPPI(num
=29),
978 int_phys_ns
=ArmPPI(num
=30),
979 int_virt
=ArmPPI(num
=27),
980 int_hyp
=ArmPPI(num
=26))
982 def _on_chip_devices(self
):
987 ### Off-chip devices ###
988 clock24MHz
= SrcClockDomain(clock
="24MHz",
989 voltage_domain
=VoltageDomain(voltage
="3.3V"))
992 Pl011(pio_addr
=0x1c090000, int_num
=37),
995 kmi0
= Pl050(pio_addr
=0x1c060000, int_num
=44, ps2
=PS2Keyboard())
996 kmi1
= Pl050(pio_addr
=0x1c070000, int_num
=45, ps2
=PS2TouchKit())
998 rtc
= PL031(pio_addr
=0x1c170000, int_num
=36)
1000 ### gem5-specific off-chip devices ###
1001 pci_host
= GenericArmPciHost(
1002 conf_base
=0x30000000, conf_size
='256MB', conf_device_bits
=12,
1003 pci_pio_base
=0x2f000000,
1004 int_policy
="ARM_PCI_INT_DEV", int_base
=100, int_count
=4)
1006 energy_ctrl
= EnergyCtrl(pio_addr
=0x10000000)
1009 MmioVirtIO(pio_addr
=0x1c130000, pio_size
=0x1000,
1010 interrupt
=ArmSPI(num
=74)),
1011 MmioVirtIO(pio_addr
=0x1c140000, pio_size
=0x1000,
1012 interrupt
=ArmSPI(num
=75)),
1015 def _off_chip_devices(self
):
1029 def attachPciDevice(self
, device
, *args
, **kwargs
):
1030 device
.host
= self
.pci_host
1031 self
._attach
_device
(device
, *args
, **kwargs
)
1033 def setupBootLoader(self
, mem_bus
, cur_sys
, loc
):
1034 cur_sys
.bootmem
= SimpleMemory(range=AddrRange(0, size
='64MB'),
1035 conf_table_reported
=False)
1036 if mem_bus
is not None:
1037 cur_sys
.bootmem
.port
= mem_bus
.master
1038 if not cur_sys
.boot_loader
:
1039 cur_sys
.boot_loader
= [ loc('boot_emm.arm64'), loc('boot_emm.arm') ]
1040 cur_sys
.atags_addr
= 0x8000000
1041 cur_sys
.load_offset
= 0x80000000
1043 # Setup m5ops. It's technically not a part of the boot
1044 # loader, but this is the only place we can configure the
1046 cur_sys
.m5ops_base
= 0x10010000
1048 def generateDeviceTree(self
, state
):
1049 # Generate using standard RealView function
1050 dt
= list(super(VExpress_GEM5_Base
, self
).generateDeviceTree(state
))
1052 raise Exception("System returned too many DT nodes")
1055 node
.appendCompatible(["arm,vexpress"])
1056 node
.append(FdtPropertyStrings("model", ["V2P-CA15"]))
1057 node
.append(FdtPropertyWords("arm,hbi", [0x0]))
1058 node
.append(FdtPropertyWords("arm,vexpress,site", [0xf]))
1062 class VExpress_GEM5_V1_Base(VExpress_GEM5_Base
):
1063 gic
= kvm_gicv2_class(dist_addr
=0x2c001000, cpu_addr
=0x2c002000,
1065 vgic
= VGic(vcpu_addr
=0x2c006000, hv_addr
=0x2c004000, maint_int
=25)
1068 Gicv2mFrame(spi_base
=256, spi_len
=64, addr
=0x2c1c0000),
1071 def _on_chip_devices(self
):
1072 return super(VExpress_GEM5_V1_Base
,self
)._on
_chip
_devices
() + [
1073 self
.gic
, self
.vgic
, self
.gicv2m
,
1076 class VExpress_GEM5_V1(VExpress_GEM5_V1_Base
):
1077 hdlcd
= HDLcd(pxl_clk
=VExpress_GEM5_V1_Base
.dcc
.osc_pxl
,
1078 pio_addr
=0x2b000000, int_num
=95)
1080 def _on_chip_devices(self
):
1081 return super(VExpress_GEM5_V1
,self
)._on
_chip
_devices
() + [
1085 class VExpress_GEM5_V2_Base(VExpress_GEM5_Base
):
1086 gic
= Gicv3(dist_addr
=0x2c000000, redist_addr
=0x2c010000,
1087 maint_int
=ArmPPI(num
=25))
1089 # Limiting to 128 since it will otherwise overlap with PCI space
1092 def _on_chip_devices(self
):
1093 return super(VExpress_GEM5_V2_Base
,self
)._on
_chip
_devices
() + [
1097 def setupBootLoader(self
, mem_bus
, cur_sys
, loc
):
1098 cur_sys
.boot_loader
= [ loc('boot_emm_v2.arm64') ]
1099 super(VExpress_GEM5_V2_Base
,self
).setupBootLoader(mem_bus
,
1102 class VExpress_GEM5_V2(VExpress_GEM5_V2_Base
):
1103 hdlcd
= HDLcd(pxl_clk
=VExpress_GEM5_V2_Base
.dcc
.osc_pxl
,
1104 pio_addr
=0x2b000000, int_num
=95)
1106 def _on_chip_devices(self
):
1107 return super(VExpress_GEM5_V2
,self
)._on
_chip
_devices
() + [