RealView.py (13805:f6d331fa1303) RealView.py (13814:90cdf66cca54)
1# Copyright (c) 2009-2018 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# Glenn Bergmans
43
44from m5.defines import buildEnv
45from m5.params import *
46from m5.proxy import *
47from m5.util.fdthelper import *
48from m5.objects.ClockDomain import ClockDomain
49from m5.objects.VoltageDomain import VoltageDomain
50from m5.objects.Device import \
51 BasicPioDevice, PioDevice, IsaFake, BadAddr, DmaDevice
52from m5.objects.PciHost import *
53from m5.objects.Ethernet import NSGigE, IGbE_igb, IGbE_e1000
54from m5.objects.Ide import *
55from m5.objects.Platform import Platform
56from m5.objects.Terminal import Terminal
57from m5.objects.Uart import Uart
58from m5.objects.SimpleMemory import SimpleMemory
59from m5.objects.Gic import *
60from m5.objects.EnergyCtrl import EnergyCtrl
61from m5.objects.ClockedObject import ClockedObject
62from m5.objects.ClockDomain import SrcClockDomain
63from m5.objects.SubSystem import SubSystem
64from m5.objects.Graphics import ImageFormat
65from m5.objects.ClockedObject import ClockedObject
66from m5.objects.PS2 import *
67from m5.objects.VirtIOMMIO import MmioVirtIO
68
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.
72try:
73 from m5.objects.KvmGic import MuxingKvmGic
74 kvm_gicv2_class = MuxingKvmGic
75except ImportError:
76 # KVM support wasn't compiled into gem5. Fallback to a
77 # software-only GIC.
78 kvm_gicv2_class = Gic400
79 pass
80
81class AmbaPioDevice(BasicPioDevice):
82 type = 'AmbaPioDevice'
83 abstract = True
84 cxx_header = "dev/arm/amba_device.hh"
85 amba_id = Param.UInt32("ID of AMBA device for kernel detection")
86
87class AmbaIntDevice(AmbaPioDevice):
88 type = 'AmbaIntDevice'
89 abstract = True
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")
95
96class AmbaDmaDevice(DmaDevice):
97 type = 'AmbaDmaDevice'
98 abstract = True
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")
105
106class A9SCU(BasicPioDevice):
107 type = 'A9SCU'
108 cxx_header = "dev/arm/a9scu.hh"
109
110class ArmPciIntRouting(Enum): vals = [
111 'ARM_PCI_INT_STATIC',
112 'ARM_PCI_INT_DEV',
113 'ARM_PCI_INT_PIN',
114 ]
115
116class GenericArmPciHost(GenericPciHost):
117 type = 'GenericArmPciHost'
118 cxx_header = "dev/arm/pci_host.hh"
119
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")
123
124 # This python parameter can be used in configuration scripts to turn
125 # on/off the fdt dma-coherent flag when doing dtb autogeneration
126 _dma_coherent = True
127
128 def generateDeviceTree(self, state):
129 local_state = FdtState(addr_cells=3, size_cells=2, cpu_cells=1)
130 intterrupt_cells = 1
131
132 node = FdtNode("pci")
133
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")
138 else:
139 m5.fatal("No compatibility string for the set conf_device_width")
140
141 node.append(FdtPropertyStrings("device_type", ["pci"]))
142
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) ))
151
152 # Ranges mapping
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.
157 ranges = []
158 # Pio address range
159 ranges += self.pciFdtAddr(space=1, addr=0)
160 ranges += state.addrCells(self.pci_pio_base)
161 ranges += local_state.sizeCells(0x10000) # Fixed size
162
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))
168
169 if str(self.int_policy) == 'ARM_PCI_INT_DEV':
170 int_phandle = state.phandle(self._parent.unproxy(self).gic)
171 # Interrupt mapping
172 interrupts = []
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]
176
177 node.append(FdtPropertyWords("interrupt-map", interrupts))
178
179 int_count = int(self.int_count)
180 if int_count & (int_count - 1):
181 fatal("PCI interrupt count should be power of 2")
182
183 intmask = self.pciFdtAddr(device=int_count - 1, addr=0) + [0x0]
184 node.append(FdtPropertyWords("interrupt-map-mask", intmask))
185 else:
186 m5.fatal("Unsupported PCI interrupt policy " +
187 "for Device Tree generation")
188
189 if self._dma_coherent:
190 node.append(FdtProperty("dma-coherent"))
191
192 yield node
193
194class 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")
200
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)
210
211 yield node
212
213class RealViewOsc(ClockDomain):
214 type = 'RealViewOsc'
215 cxx_header = "dev/arm/rv_ctrl.hh"
216
217 parent = Param.RealViewCtrl(Parent.any, "RealView controller")
218
219 # TODO: We currently don't have the notion of a clock source,
220 # which means we have to associate oscillators with a voltage
221 # source.
222 voltage_domain = Param.VoltageDomain(Parent.voltage_domain,
223 "Voltage domain")
224
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")
232
233 freq = Param.Clock("Default frequency")
234
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)
247 yield node
248
249class RealViewTemperatureSensor(SimObject):
250 type = 'RealViewTemperatureSensor'
251 cxx_header = "dev/arm/rv_ctrl.hh"
252
253 parent = Param.RealViewCtrl(Parent.any, "RealView controller")
254
255 system = Param.System(Parent.any, "system")
256
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")
264
265class VExpressMCC(SubSystem):
266 """ARM V2M-P1 Motherboard Configuration Controller
267
268This subsystem describes a subset of the devices that sit behind the
269motherboard configuration controller on the the ARM Motherboard
270Express (V2M-P1) motherboard. See ARM DUI 0447J for details.
271 """
272
273 class Osc(RealViewOsc):
274 site, position, dcc = (0, 0, 0)
275
276 class Temperature(RealViewTemperatureSensor):
277 site, position, dcc = (0, 0, 0)
278
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")
283
284 # See Table 4.19 in ARM DUI 0447J (Motherboard Express uATX TRM).
285 temp_crtl = Temperature(device=0)
286
287 def generateDeviceTree(self, state):
288 node = FdtNode("mcc")
289 node.appendCompatible("arm,vexpress,config-bus")
290 node.append(FdtPropertyWords("arm,vexpress,site", [0]))
291
292 for obj in self._children.values():
293 if issubclass(type(obj), SimObject):
294 node.append(obj.generateDeviceTree(state))
295
296 io_phandle = state.phandle(self.osc_mcc.parent.unproxy(self))
297 node.append(FdtPropertyWords("arm,vexpress,config-bridge", io_phandle))
298
299 yield node
300
301class CoreTile2A15DCC(SubSystem):
302 """ARM CoreTile Express A15x2 Daughterboard Configuration Controller
303
304This subsystem describes a subset of the devices that sit behind the
305daughterboard configuration controller on a CoreTile Express A15x2. See
306ARM DUI 0604E for details.
307 """
308
309 class Osc(RealViewOsc):
310 site, position, dcc = (1, 0, 0)
311
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")
319
320 def generateDeviceTree(self, state):
321 node = FdtNode("dcc")
322 node.appendCompatible("arm,vexpress,config-bus")
323
324 for obj in self._children.values():
325 if isinstance(obj, SimObject):
326 node.append(obj.generateDeviceTree(state))
327
328 io_phandle = state.phandle(self.osc_cpu.parent.unproxy(self))
329 node.append(FdtPropertyWords("arm,vexpress,config-bridge", io_phandle))
330
331 yield node
332
333class AmbaFake(AmbaPioDevice):
334 type = 'AmbaFake'
335 cxx_header = "dev/arm/amba_fake.hh"
336 ignore_access = Param.Bool(False, "Ignore reads/writes to this device, (e.g. IsaFake + AMBA)")
337 amba_id = 0;
338
339class Pl011(Uart):
340 type = 'Pl011'
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")
346
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"])
351
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"]))
359 yield node
360
361class Sp804(AmbaPioDevice):
362 type = 'Sp804'
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")
369 amba_id = 0x00141804
370
371class 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")
376
377class 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")
382
383class 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")
391
392 def generateDeviceTree(self, state):
393 node = FdtNode("timer")
394
395 node.appendCompatible(["arm,cortex-a15-timer",
396 "arm,armv7-timer",
397 "arm,armv8-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,
403 ]))
404 clock = state.phandle(self.clk_domain.unproxy(self))
405 node.append(FdtPropertyWords("clocks", clock))
406
407 yield node
408
409class GenericTimerMem(PioDevice):
410 type = 'GenericTimerMem'
411 cxx_header = "dev/arm/generic_timer.hh"
412
413 base = Param.Addr(0, "Base address")
414
415 int_phys = Param.ArmSPI("Physical Interrupt")
416 int_virt = Param.ArmSPI("Virtual Interrupt")
417
418class PL031(AmbaIntDevice):
419 type = 'PL031'
420 cxx_header = "dev/arm/rtc_pl031.hh"
421 time = Param.Time('01/01/2009', "System time to use ('Now' for actual time)")
422 amba_id = 0x00341031
423
424 def generateDeviceTree(self, state):
425 node = self.generateBasicPioDeviceNode(state, 'rtc', self.pio_addr,
426 0x1000, [int(self.int_num)])
427
428 node.appendCompatible(["arm,pl031", "arm,primecell"])
429 clock = state.phandle(self.clk_domain.unproxy(self))
430 node.append(FdtPropertyWords("clocks", clock))
431
432 yield node
433
434class Pl050(AmbaIntDevice):
435 type = 'Pl050'
436 cxx_header = "dev/arm/kmi.hh"
437 amba_id = 0x00141050
438
439 ps2 = Param.PS2Device("PS/2 device")
440
441 def generateDeviceTree(self, state):
442 node = self.generateBasicPioDeviceNode(state, 'kmi', self.pio_addr,
443 0x1000, [int(self.int_num)])
444
445 node.appendCompatible(["arm,pl050", "arm,primecell"])
446 clock = state.phandle(self.clk_domain.unproxy(self))
447 node.append(FdtPropertyWords("clocks", clock))
448
449 yield node
450
451class Pl111(AmbaDmaDevice):
452 type = 'Pl111'
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")
456 amba_id = 0x00141111
457 enable_capture = Param.Bool(True, "capture frame to system.framebuffer.bmp")
458
459class HDLcd(AmbaDmaDevice):
460 type = 'HDLcd'
461 cxx_header = "dev/arm/hdlcd.hh"
462 vnc = Param.VncInput(Parent.any, "Vnc server for remote frame buffer "
463 "display")
464 amba_id = 0x00141000
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")
473
474 pixel_buffer_size = Param.MemorySize32("2kB", "Size of address range")
475
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 "
479 "in KVM mode")
480
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])
485
486 node.appendCompatible(["arm,hdlcd"])
487 node.append(FdtPropertyWords("clocks", state.phandle(self.pxl_clk)))
488 node.append(FdtPropertyStrings("clock-names", ["pxlclk"]))
489
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"]))
495
496 yield node
497
498class RealView(Platform):
499 type = 'RealView'
500 cxx_header = "dev/arm/realview.hh"
501 system = Param.System(Parent.any, "system")
502 _mem_regions = [ AddrRange(0, size='256MB') ]
503
504 def _on_chip_devices(self):
505 return []
506
507 def _off_chip_devices(self):
508 return []
509
510 _off_chip_ranges = []
511
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
518 else:
519 dma_ports.append(device.dma)
520
521 def _attach_io(self, devices, *args, **kwargs):
522 for d in devices:
523 self._attach_device(d, *args, **kwargs)
524
525 def _attach_clk(self, devices, clkdomain):
526 for d in devices:
527 if hasattr(d, "clk_domain"):
528 d.clk_domain = clkdomain
529
530 def attachPciDevices(self):
531 pass
532
533 def enableMSIX(self):
534 pass
535
536 def onChipIOClkDomain(self, clkdomain):
537 self._attach_clk(self._on_chip_devices(), clkdomain)
538
539 def offChipIOClkDomain(self, clkdomain):
540 self._attach_clk(self._off_chip_devices(), clkdomain)
541
542 def attachOnChipIO(self, bus, bridge=None, *args, **kwargs):
543 self._attach_io(self._on_chip_devices(), bus, *args, **kwargs)
544 if bridge:
545 bridge.ranges = self._off_chip_ranges
546
547 def attachIO(self, *args, **kwargs):
548 self._attach_io(self._off_chip_devices(), *args, **kwargs)
549
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
559
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)))
564
565 for subnode in self.recurseDeviceTree(state):
566 node.append(subnode)
567
568 yield node
569
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)))
574
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
578class RealViewPBX(RealView):
579 uart = Pl011(pio_addr=0x10009000, int_num=44)
580 realview_io = RealViewCtrl(pio_addr=0x10000000)
581 mcc = VExpressMCC()
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,
586 pci_pio_base=0)
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),
592 pio_addr=0x1f000600)
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)
602
603
604 l2x0_fake = IsaFake(pio_addr=0x1f002000, pio_size=0xfff)
605 flash_fake = IsaFake(pio_addr=0x40000000, pio_size=0x20000000,
606 fake_mem=True)
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)
623
624
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)]
640
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
648
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
651 # System level.
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
681
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
710
711class VExpress_EMM(RealView):
712 _mem_regions = [ AddrRange('2GB', size='2GB') ]
713
714 # Ranges based on excluding what is part of on-chip I/O (gic,
715 # a9scu)
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')]
721
722 # Platform control device (off-chip)
723 realview_io = RealViewCtrl(proc_id0=0x14000000, proc_id1=0x14000000,
724 idreg=0x02250000, pio_addr=0x1C010000)
725
726 mcc = VExpressMCC()
727 dcc = CoreTile2A15DCC()
728
729 ### On-chip devices ###
730 gic = Gic400(dist_addr=0x2C001000, cpu_addr=0x2C002000)
1# Copyright (c) 2009-2018 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# Glenn Bergmans
43
44from m5.defines import buildEnv
45from m5.params import *
46from m5.proxy import *
47from m5.util.fdthelper import *
48from m5.objects.ClockDomain import ClockDomain
49from m5.objects.VoltageDomain import VoltageDomain
50from m5.objects.Device import \
51 BasicPioDevice, PioDevice, IsaFake, BadAddr, DmaDevice
52from m5.objects.PciHost import *
53from m5.objects.Ethernet import NSGigE, IGbE_igb, IGbE_e1000
54from m5.objects.Ide import *
55from m5.objects.Platform import Platform
56from m5.objects.Terminal import Terminal
57from m5.objects.Uart import Uart
58from m5.objects.SimpleMemory import SimpleMemory
59from m5.objects.Gic import *
60from m5.objects.EnergyCtrl import EnergyCtrl
61from m5.objects.ClockedObject import ClockedObject
62from m5.objects.ClockDomain import SrcClockDomain
63from m5.objects.SubSystem import SubSystem
64from m5.objects.Graphics import ImageFormat
65from m5.objects.ClockedObject import ClockedObject
66from m5.objects.PS2 import *
67from m5.objects.VirtIOMMIO import MmioVirtIO
68
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.
72try:
73 from m5.objects.KvmGic import MuxingKvmGic
74 kvm_gicv2_class = MuxingKvmGic
75except ImportError:
76 # KVM support wasn't compiled into gem5. Fallback to a
77 # software-only GIC.
78 kvm_gicv2_class = Gic400
79 pass
80
81class AmbaPioDevice(BasicPioDevice):
82 type = 'AmbaPioDevice'
83 abstract = True
84 cxx_header = "dev/arm/amba_device.hh"
85 amba_id = Param.UInt32("ID of AMBA device for kernel detection")
86
87class AmbaIntDevice(AmbaPioDevice):
88 type = 'AmbaIntDevice'
89 abstract = True
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")
95
96class AmbaDmaDevice(DmaDevice):
97 type = 'AmbaDmaDevice'
98 abstract = True
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")
105
106class A9SCU(BasicPioDevice):
107 type = 'A9SCU'
108 cxx_header = "dev/arm/a9scu.hh"
109
110class ArmPciIntRouting(Enum): vals = [
111 'ARM_PCI_INT_STATIC',
112 'ARM_PCI_INT_DEV',
113 'ARM_PCI_INT_PIN',
114 ]
115
116class GenericArmPciHost(GenericPciHost):
117 type = 'GenericArmPciHost'
118 cxx_header = "dev/arm/pci_host.hh"
119
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")
123
124 # This python parameter can be used in configuration scripts to turn
125 # on/off the fdt dma-coherent flag when doing dtb autogeneration
126 _dma_coherent = True
127
128 def generateDeviceTree(self, state):
129 local_state = FdtState(addr_cells=3, size_cells=2, cpu_cells=1)
130 intterrupt_cells = 1
131
132 node = FdtNode("pci")
133
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")
138 else:
139 m5.fatal("No compatibility string for the set conf_device_width")
140
141 node.append(FdtPropertyStrings("device_type", ["pci"]))
142
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) ))
151
152 # Ranges mapping
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.
157 ranges = []
158 # Pio address range
159 ranges += self.pciFdtAddr(space=1, addr=0)
160 ranges += state.addrCells(self.pci_pio_base)
161 ranges += local_state.sizeCells(0x10000) # Fixed size
162
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))
168
169 if str(self.int_policy) == 'ARM_PCI_INT_DEV':
170 int_phandle = state.phandle(self._parent.unproxy(self).gic)
171 # Interrupt mapping
172 interrupts = []
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]
176
177 node.append(FdtPropertyWords("interrupt-map", interrupts))
178
179 int_count = int(self.int_count)
180 if int_count & (int_count - 1):
181 fatal("PCI interrupt count should be power of 2")
182
183 intmask = self.pciFdtAddr(device=int_count - 1, addr=0) + [0x0]
184 node.append(FdtPropertyWords("interrupt-map-mask", intmask))
185 else:
186 m5.fatal("Unsupported PCI interrupt policy " +
187 "for Device Tree generation")
188
189 if self._dma_coherent:
190 node.append(FdtProperty("dma-coherent"))
191
192 yield node
193
194class 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")
200
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)
210
211 yield node
212
213class RealViewOsc(ClockDomain):
214 type = 'RealViewOsc'
215 cxx_header = "dev/arm/rv_ctrl.hh"
216
217 parent = Param.RealViewCtrl(Parent.any, "RealView controller")
218
219 # TODO: We currently don't have the notion of a clock source,
220 # which means we have to associate oscillators with a voltage
221 # source.
222 voltage_domain = Param.VoltageDomain(Parent.voltage_domain,
223 "Voltage domain")
224
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")
232
233 freq = Param.Clock("Default frequency")
234
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)
247 yield node
248
249class RealViewTemperatureSensor(SimObject):
250 type = 'RealViewTemperatureSensor'
251 cxx_header = "dev/arm/rv_ctrl.hh"
252
253 parent = Param.RealViewCtrl(Parent.any, "RealView controller")
254
255 system = Param.System(Parent.any, "system")
256
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")
264
265class VExpressMCC(SubSystem):
266 """ARM V2M-P1 Motherboard Configuration Controller
267
268This subsystem describes a subset of the devices that sit behind the
269motherboard configuration controller on the the ARM Motherboard
270Express (V2M-P1) motherboard. See ARM DUI 0447J for details.
271 """
272
273 class Osc(RealViewOsc):
274 site, position, dcc = (0, 0, 0)
275
276 class Temperature(RealViewTemperatureSensor):
277 site, position, dcc = (0, 0, 0)
278
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")
283
284 # See Table 4.19 in ARM DUI 0447J (Motherboard Express uATX TRM).
285 temp_crtl = Temperature(device=0)
286
287 def generateDeviceTree(self, state):
288 node = FdtNode("mcc")
289 node.appendCompatible("arm,vexpress,config-bus")
290 node.append(FdtPropertyWords("arm,vexpress,site", [0]))
291
292 for obj in self._children.values():
293 if issubclass(type(obj), SimObject):
294 node.append(obj.generateDeviceTree(state))
295
296 io_phandle = state.phandle(self.osc_mcc.parent.unproxy(self))
297 node.append(FdtPropertyWords("arm,vexpress,config-bridge", io_phandle))
298
299 yield node
300
301class CoreTile2A15DCC(SubSystem):
302 """ARM CoreTile Express A15x2 Daughterboard Configuration Controller
303
304This subsystem describes a subset of the devices that sit behind the
305daughterboard configuration controller on a CoreTile Express A15x2. See
306ARM DUI 0604E for details.
307 """
308
309 class Osc(RealViewOsc):
310 site, position, dcc = (1, 0, 0)
311
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")
319
320 def generateDeviceTree(self, state):
321 node = FdtNode("dcc")
322 node.appendCompatible("arm,vexpress,config-bus")
323
324 for obj in self._children.values():
325 if isinstance(obj, SimObject):
326 node.append(obj.generateDeviceTree(state))
327
328 io_phandle = state.phandle(self.osc_cpu.parent.unproxy(self))
329 node.append(FdtPropertyWords("arm,vexpress,config-bridge", io_phandle))
330
331 yield node
332
333class AmbaFake(AmbaPioDevice):
334 type = 'AmbaFake'
335 cxx_header = "dev/arm/amba_fake.hh"
336 ignore_access = Param.Bool(False, "Ignore reads/writes to this device, (e.g. IsaFake + AMBA)")
337 amba_id = 0;
338
339class Pl011(Uart):
340 type = 'Pl011'
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")
346
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"])
351
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"]))
359 yield node
360
361class Sp804(AmbaPioDevice):
362 type = 'Sp804'
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")
369 amba_id = 0x00141804
370
371class 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")
376
377class 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")
382
383class 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")
391
392 def generateDeviceTree(self, state):
393 node = FdtNode("timer")
394
395 node.appendCompatible(["arm,cortex-a15-timer",
396 "arm,armv7-timer",
397 "arm,armv8-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,
403 ]))
404 clock = state.phandle(self.clk_domain.unproxy(self))
405 node.append(FdtPropertyWords("clocks", clock))
406
407 yield node
408
409class GenericTimerMem(PioDevice):
410 type = 'GenericTimerMem'
411 cxx_header = "dev/arm/generic_timer.hh"
412
413 base = Param.Addr(0, "Base address")
414
415 int_phys = Param.ArmSPI("Physical Interrupt")
416 int_virt = Param.ArmSPI("Virtual Interrupt")
417
418class PL031(AmbaIntDevice):
419 type = 'PL031'
420 cxx_header = "dev/arm/rtc_pl031.hh"
421 time = Param.Time('01/01/2009', "System time to use ('Now' for actual time)")
422 amba_id = 0x00341031
423
424 def generateDeviceTree(self, state):
425 node = self.generateBasicPioDeviceNode(state, 'rtc', self.pio_addr,
426 0x1000, [int(self.int_num)])
427
428 node.appendCompatible(["arm,pl031", "arm,primecell"])
429 clock = state.phandle(self.clk_domain.unproxy(self))
430 node.append(FdtPropertyWords("clocks", clock))
431
432 yield node
433
434class Pl050(AmbaIntDevice):
435 type = 'Pl050'
436 cxx_header = "dev/arm/kmi.hh"
437 amba_id = 0x00141050
438
439 ps2 = Param.PS2Device("PS/2 device")
440
441 def generateDeviceTree(self, state):
442 node = self.generateBasicPioDeviceNode(state, 'kmi', self.pio_addr,
443 0x1000, [int(self.int_num)])
444
445 node.appendCompatible(["arm,pl050", "arm,primecell"])
446 clock = state.phandle(self.clk_domain.unproxy(self))
447 node.append(FdtPropertyWords("clocks", clock))
448
449 yield node
450
451class Pl111(AmbaDmaDevice):
452 type = 'Pl111'
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")
456 amba_id = 0x00141111
457 enable_capture = Param.Bool(True, "capture frame to system.framebuffer.bmp")
458
459class HDLcd(AmbaDmaDevice):
460 type = 'HDLcd'
461 cxx_header = "dev/arm/hdlcd.hh"
462 vnc = Param.VncInput(Parent.any, "Vnc server for remote frame buffer "
463 "display")
464 amba_id = 0x00141000
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")
473
474 pixel_buffer_size = Param.MemorySize32("2kB", "Size of address range")
475
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 "
479 "in KVM mode")
480
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])
485
486 node.appendCompatible(["arm,hdlcd"])
487 node.append(FdtPropertyWords("clocks", state.phandle(self.pxl_clk)))
488 node.append(FdtPropertyStrings("clock-names", ["pxlclk"]))
489
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"]))
495
496 yield node
497
498class RealView(Platform):
499 type = 'RealView'
500 cxx_header = "dev/arm/realview.hh"
501 system = Param.System(Parent.any, "system")
502 _mem_regions = [ AddrRange(0, size='256MB') ]
503
504 def _on_chip_devices(self):
505 return []
506
507 def _off_chip_devices(self):
508 return []
509
510 _off_chip_ranges = []
511
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
518 else:
519 dma_ports.append(device.dma)
520
521 def _attach_io(self, devices, *args, **kwargs):
522 for d in devices:
523 self._attach_device(d, *args, **kwargs)
524
525 def _attach_clk(self, devices, clkdomain):
526 for d in devices:
527 if hasattr(d, "clk_domain"):
528 d.clk_domain = clkdomain
529
530 def attachPciDevices(self):
531 pass
532
533 def enableMSIX(self):
534 pass
535
536 def onChipIOClkDomain(self, clkdomain):
537 self._attach_clk(self._on_chip_devices(), clkdomain)
538
539 def offChipIOClkDomain(self, clkdomain):
540 self._attach_clk(self._off_chip_devices(), clkdomain)
541
542 def attachOnChipIO(self, bus, bridge=None, *args, **kwargs):
543 self._attach_io(self._on_chip_devices(), bus, *args, **kwargs)
544 if bridge:
545 bridge.ranges = self._off_chip_ranges
546
547 def attachIO(self, *args, **kwargs):
548 self._attach_io(self._off_chip_devices(), *args, **kwargs)
549
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
559
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)))
564
565 for subnode in self.recurseDeviceTree(state):
566 node.append(subnode)
567
568 yield node
569
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)))
574
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
578class RealViewPBX(RealView):
579 uart = Pl011(pio_addr=0x10009000, int_num=44)
580 realview_io = RealViewCtrl(pio_addr=0x10000000)
581 mcc = VExpressMCC()
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,
586 pci_pio_base=0)
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),
592 pio_addr=0x1f000600)
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)
602
603
604 l2x0_fake = IsaFake(pio_addr=0x1f002000, pio_size=0xfff)
605 flash_fake = IsaFake(pio_addr=0x40000000, pio_size=0x20000000,
606 fake_mem=True)
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)
623
624
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)]
640
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
648
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
651 # System level.
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
681
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
710
711class VExpress_EMM(RealView):
712 _mem_regions = [ AddrRange('2GB', size='2GB') ]
713
714 # Ranges based on excluding what is part of on-chip I/O (gic,
715 # a9scu)
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')]
721
722 # Platform control device (off-chip)
723 realview_io = RealViewCtrl(proc_id0=0x14000000, proc_id1=0x14000000,
724 idreg=0x02250000, pio_addr=0x1C010000)
725
726 mcc = VExpressMCC()
727 dcc = CoreTile2A15DCC()
728
729 ### On-chip devices ###
730 gic = Gic400(dist_addr=0x2C001000, cpu_addr=0x2C002000)
731 vgic = VGic(vcpu_addr=0x2c006000, hv_addr=0x2c004000, ppint=25)
731 vgic = VGic(vcpu_addr=0x2c006000, hv_addr=0x2c004000, maint_int=25)
732
733 local_cpu_timer = CpuLocalTimer(int_timer=ArmPPI(num=29),
734 int_watchdog=ArmPPI(num=30),
735 pio_addr=0x2C080000)
736
737 hdlcd = HDLcd(pxl_clk=dcc.osc_pxl,
738 pio_addr=0x2b000000, int_num=117,
739 workaround_swap_rb=True)
740
741 def _on_chip_devices(self):
742 devices = [
743 self.gic, self.vgic,
744 self.local_cpu_timer
745 ]
746 if hasattr(self, "gicv2m"):
747 devices.append(self.gicv2m)
748 devices.append(self.hdlcd)
749 return devices
750
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,
755 pci_pio_base=0)
756
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))
761
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)
772
773 vram = SimpleMemory(range = AddrRange(0x18000000, size='32MB'),
774 conf_table_reported = False)
775 rtc = PL031(pio_addr=0x1C170000, int_num=36)
776
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)
788
789 def _off_chip_devices(self):
790 devices = [
791 self.uart,
792 self.realview_io,
793 self.pci_host,
794 self.timer0,
795 self.timer1,
796 self.clcd,
797 self.kmi0,
798 self.kmi1,
799 self.cf_ctrl,
800 self.rtc,
801 self.vram,
802 self.l2x0_fake,
803 self.uart1_fake,
804 self.uart2_fake,
805 self.uart3_fake,
806 self.sp810_fake,
807 self.watchdog_fake,
808 self.aaci_fake,
809 self.lan_fake,
810 self.usb_fake,
811 self.mmc_fake,
812 self.energy_ctrl,
813 ]
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)
819 return devices
820
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)
827
828 def enableMSIX(self):
829 self.gic = Gic400(dist_addr=0x2C001000, cpu_addr=0x2C002000,
830 it_lines=512)
831 self.gicv2m = Gicv2m()
832 self.gicv2m.frames = [Gicv2mFrame(spi_base=256, spi_len=64, addr=0x2C1C0000)]
833
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
843
844class 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)
852
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
862
863class VExpress_GEM5_Base(RealView):
864 """
865The VExpress gem5 memory map is loosely based on a modified
866Versatile Express RS1 memory map.
867
868The gem5 platform has been designed to implement a subset of the
869original Versatile Express RS1 memory map. Off-chip peripherals should,
870when possible, adhere to the Versatile Express memory map. Non-PCI
871off-chip devices that are gem5-specific should live in the CS5 memory
872space to avoid conflicts with existing devices that we might want to
873model in the future. Such devices should normally have interrupts in
874the gem5-specific SPI range.
875
876On-chip peripherals are loosely modeled after the ARM CoreTile Express
877A15x2 A7x3 memory and interrupt map. In particular, the GIC and
878Generic Timer have the same interrupt lines and base addresses. Other
879on-chip devices are gem5 specific.
880
881Unlike the original Versatile Express RS2 extended platform, gem5 implements a
882large contigious DRAM space, without aliases or holes, starting at the
8832GiB boundary. This means that PCI memory is limited to 1GiB.
884
885Memory map:
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
893
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
907
908 0x20000000-0x3fffffff: On-chip peripherals:
909 0x2b000000-0x2b00ffff: HDLCD
910
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
916
917 0x2d000000-0x2d00ffff: GPU (reserved)
918
919 0x2f000000-0x2fffffff: PCI IO space
920 0x30000000-0x3fffffff: PCI config space
921
922 0x40000000-0x7fffffff: Ext. AXI: Used as PCI memory
923
924 0x80000000-X: DRAM
925
926Interrupts:
927 0- 15: Software generated interrupts (SGIs)
928 16- 31: On-chip private peripherals (PPIs)
929 25 : vgic
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)
940 36 : RTC
941 37-40: uart0-uart3
942 41-42: Reserved (PL180)
943 43 : Reserved (AACI)
944 44-45: kmi0-kmi1
945 46 : Reserved (CLCD)
946 47 : Reserved (Ethernet)
947 48 : Reserved (USB)
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)
952 95 : HDLCD
953 96- 98: GPU (reserved)
954 100-103: PCI
955 256-319: MSI frame 0 (gem5-specific, SPIs)
956 320-511: Unused
957
958 """
959
960 # Everything above 2GiB is memory
961 _mem_regions = [ AddrRange('2GB', size='510GB') ]
962
963 _off_chip_ranges = [
964 # CS1-CS5
965 AddrRange(0x0c000000, 0x1fffffff),
966 # External AXI interface (PCI)
967 AddrRange(0x2f000000, 0x7fffffff),
968 ]
969
970 # Platform control device (off-chip)
971 realview_io = RealViewCtrl(proc_id0=0x14000000, proc_id1=0x14000000,
972 idreg=0x02250000, pio_addr=0x1c010000)
973 mcc = VExpressMCC()
974 dcc = CoreTile2A15DCC()
975
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))
981
982 def _on_chip_devices(self):
983 return [
984 self.generic_timer,
985 ]
986
987 ### Off-chip devices ###
988 clock24MHz = SrcClockDomain(clock="24MHz",
989 voltage_domain=VoltageDomain(voltage="3.3V"))
990
991 uart = [
992 Pl011(pio_addr=0x1c090000, int_num=37),
993 ]
994
995 kmi0 = Pl050(pio_addr=0x1c060000, int_num=44, ps2=PS2Keyboard())
996 kmi1 = Pl050(pio_addr=0x1c070000, int_num=45, ps2=PS2TouchKit())
997
998 rtc = PL031(pio_addr=0x1c170000, int_num=36)
999
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)
1005
1006 energy_ctrl = EnergyCtrl(pio_addr=0x10000000)
1007
1008 vio = [
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)),
1013 ]
1014
1015 def _off_chip_devices(self):
1016 return [
1017 self.realview_io,
1018 self.uart[0],
1019 self.kmi0,
1020 self.kmi1,
1021 self.rtc,
1022 self.pci_host,
1023 self.energy_ctrl,
1024 self.clock24MHz,
1025 self.vio[0],
1026 self.vio[1],
1027 ]
1028
1029 def attachPciDevice(self, device, *args, **kwargs):
1030 device.host = self.pci_host
1031 self._attach_device(device, *args, **kwargs)
1032
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
1042
1043 # Setup m5ops. It's technically not a part of the boot
1044 # loader, but this is the only place we can configure the
1045 # system.
1046 cur_sys.m5ops_base = 0x10010000
1047
1048 def generateDeviceTree(self, state):
1049 # Generate using standard RealView function
1050 dt = list(super(VExpress_GEM5_Base, self).generateDeviceTree(state))
1051 if len(dt) > 1:
1052 raise Exception("System returned too many DT nodes")
1053 node = dt[0]
1054
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]))
1059
1060 yield node
1061
1062class VExpress_GEM5_V1_Base(VExpress_GEM5_Base):
1063 gic = kvm_gicv2_class(dist_addr=0x2c001000, cpu_addr=0x2c002000,
1064 it_lines=512)
732
733 local_cpu_timer = CpuLocalTimer(int_timer=ArmPPI(num=29),
734 int_watchdog=ArmPPI(num=30),
735 pio_addr=0x2C080000)
736
737 hdlcd = HDLcd(pxl_clk=dcc.osc_pxl,
738 pio_addr=0x2b000000, int_num=117,
739 workaround_swap_rb=True)
740
741 def _on_chip_devices(self):
742 devices = [
743 self.gic, self.vgic,
744 self.local_cpu_timer
745 ]
746 if hasattr(self, "gicv2m"):
747 devices.append(self.gicv2m)
748 devices.append(self.hdlcd)
749 return devices
750
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,
755 pci_pio_base=0)
756
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))
761
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)
772
773 vram = SimpleMemory(range = AddrRange(0x18000000, size='32MB'),
774 conf_table_reported = False)
775 rtc = PL031(pio_addr=0x1C170000, int_num=36)
776
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)
788
789 def _off_chip_devices(self):
790 devices = [
791 self.uart,
792 self.realview_io,
793 self.pci_host,
794 self.timer0,
795 self.timer1,
796 self.clcd,
797 self.kmi0,
798 self.kmi1,
799 self.cf_ctrl,
800 self.rtc,
801 self.vram,
802 self.l2x0_fake,
803 self.uart1_fake,
804 self.uart2_fake,
805 self.uart3_fake,
806 self.sp810_fake,
807 self.watchdog_fake,
808 self.aaci_fake,
809 self.lan_fake,
810 self.usb_fake,
811 self.mmc_fake,
812 self.energy_ctrl,
813 ]
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)
819 return devices
820
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)
827
828 def enableMSIX(self):
829 self.gic = Gic400(dist_addr=0x2C001000, cpu_addr=0x2C002000,
830 it_lines=512)
831 self.gicv2m = Gicv2m()
832 self.gicv2m.frames = [Gicv2mFrame(spi_base=256, spi_len=64, addr=0x2C1C0000)]
833
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
843
844class 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)
852
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
862
863class VExpress_GEM5_Base(RealView):
864 """
865The VExpress gem5 memory map is loosely based on a modified
866Versatile Express RS1 memory map.
867
868The gem5 platform has been designed to implement a subset of the
869original Versatile Express RS1 memory map. Off-chip peripherals should,
870when possible, adhere to the Versatile Express memory map. Non-PCI
871off-chip devices that are gem5-specific should live in the CS5 memory
872space to avoid conflicts with existing devices that we might want to
873model in the future. Such devices should normally have interrupts in
874the gem5-specific SPI range.
875
876On-chip peripherals are loosely modeled after the ARM CoreTile Express
877A15x2 A7x3 memory and interrupt map. In particular, the GIC and
878Generic Timer have the same interrupt lines and base addresses. Other
879on-chip devices are gem5 specific.
880
881Unlike the original Versatile Express RS2 extended platform, gem5 implements a
882large contigious DRAM space, without aliases or holes, starting at the
8832GiB boundary. This means that PCI memory is limited to 1GiB.
884
885Memory map:
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
893
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
907
908 0x20000000-0x3fffffff: On-chip peripherals:
909 0x2b000000-0x2b00ffff: HDLCD
910
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
916
917 0x2d000000-0x2d00ffff: GPU (reserved)
918
919 0x2f000000-0x2fffffff: PCI IO space
920 0x30000000-0x3fffffff: PCI config space
921
922 0x40000000-0x7fffffff: Ext. AXI: Used as PCI memory
923
924 0x80000000-X: DRAM
925
926Interrupts:
927 0- 15: Software generated interrupts (SGIs)
928 16- 31: On-chip private peripherals (PPIs)
929 25 : vgic
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)
940 36 : RTC
941 37-40: uart0-uart3
942 41-42: Reserved (PL180)
943 43 : Reserved (AACI)
944 44-45: kmi0-kmi1
945 46 : Reserved (CLCD)
946 47 : Reserved (Ethernet)
947 48 : Reserved (USB)
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)
952 95 : HDLCD
953 96- 98: GPU (reserved)
954 100-103: PCI
955 256-319: MSI frame 0 (gem5-specific, SPIs)
956 320-511: Unused
957
958 """
959
960 # Everything above 2GiB is memory
961 _mem_regions = [ AddrRange('2GB', size='510GB') ]
962
963 _off_chip_ranges = [
964 # CS1-CS5
965 AddrRange(0x0c000000, 0x1fffffff),
966 # External AXI interface (PCI)
967 AddrRange(0x2f000000, 0x7fffffff),
968 ]
969
970 # Platform control device (off-chip)
971 realview_io = RealViewCtrl(proc_id0=0x14000000, proc_id1=0x14000000,
972 idreg=0x02250000, pio_addr=0x1c010000)
973 mcc = VExpressMCC()
974 dcc = CoreTile2A15DCC()
975
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))
981
982 def _on_chip_devices(self):
983 return [
984 self.generic_timer,
985 ]
986
987 ### Off-chip devices ###
988 clock24MHz = SrcClockDomain(clock="24MHz",
989 voltage_domain=VoltageDomain(voltage="3.3V"))
990
991 uart = [
992 Pl011(pio_addr=0x1c090000, int_num=37),
993 ]
994
995 kmi0 = Pl050(pio_addr=0x1c060000, int_num=44, ps2=PS2Keyboard())
996 kmi1 = Pl050(pio_addr=0x1c070000, int_num=45, ps2=PS2TouchKit())
997
998 rtc = PL031(pio_addr=0x1c170000, int_num=36)
999
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)
1005
1006 energy_ctrl = EnergyCtrl(pio_addr=0x10000000)
1007
1008 vio = [
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)),
1013 ]
1014
1015 def _off_chip_devices(self):
1016 return [
1017 self.realview_io,
1018 self.uart[0],
1019 self.kmi0,
1020 self.kmi1,
1021 self.rtc,
1022 self.pci_host,
1023 self.energy_ctrl,
1024 self.clock24MHz,
1025 self.vio[0],
1026 self.vio[1],
1027 ]
1028
1029 def attachPciDevice(self, device, *args, **kwargs):
1030 device.host = self.pci_host
1031 self._attach_device(device, *args, **kwargs)
1032
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
1042
1043 # Setup m5ops. It's technically not a part of the boot
1044 # loader, but this is the only place we can configure the
1045 # system.
1046 cur_sys.m5ops_base = 0x10010000
1047
1048 def generateDeviceTree(self, state):
1049 # Generate using standard RealView function
1050 dt = list(super(VExpress_GEM5_Base, self).generateDeviceTree(state))
1051 if len(dt) > 1:
1052 raise Exception("System returned too many DT nodes")
1053 node = dt[0]
1054
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]))
1059
1060 yield node
1061
1062class VExpress_GEM5_V1_Base(VExpress_GEM5_Base):
1063 gic = kvm_gicv2_class(dist_addr=0x2c001000, cpu_addr=0x2c002000,
1064 it_lines=512)
1065 vgic = VGic(vcpu_addr=0x2c006000, hv_addr=0x2c004000, ppint=25)
1065 vgic = VGic(vcpu_addr=0x2c006000, hv_addr=0x2c004000, maint_int=25)
1066 gicv2m = Gicv2m()
1067 gicv2m.frames = [
1068 Gicv2mFrame(spi_base=256, spi_len=64, addr=0x2c1c0000),
1069 ]
1070
1071 def _on_chip_devices(self):
1072 return super(VExpress_GEM5_V1_Base,self)._on_chip_devices() + [
1073 self.gic, self.vgic, self.gicv2m,
1074 ]
1075
1076class 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)
1079
1080 def _on_chip_devices(self):
1081 return super(VExpress_GEM5_V1,self)._on_chip_devices() + [
1082 self.hdlcd,
1083 ]
1084
1085class VExpress_GEM5_V2_Base(VExpress_GEM5_Base):
1086 gic = Gicv3()
1087
1088 def _on_chip_devices(self):
1089 return super(VExpress_GEM5_V2_Base,self)._on_chip_devices() + [
1090 self.gic,
1091 ]
1092
1093 def setupBootLoader(self, mem_bus, cur_sys, loc):
1094 cur_sys.boot_loader = [ loc('boot_emm_v2.arm64') ]
1095 super(VExpress_GEM5_V2_Base,self).setupBootLoader(mem_bus,
1096 cur_sys, loc)
1097
1098class VExpress_GEM5_V2(VExpress_GEM5_V2_Base):
1099 hdlcd = HDLcd(pxl_clk=VExpress_GEM5_V2_Base.dcc.osc_pxl,
1100 pio_addr=0x2b000000, int_num=95)
1101
1102 def _on_chip_devices(self):
1103 return super(VExpress_GEM5_V2,self)._on_chip_devices() + [
1104 self.hdlcd,
1105 ]
1066 gicv2m = Gicv2m()
1067 gicv2m.frames = [
1068 Gicv2mFrame(spi_base=256, spi_len=64, addr=0x2c1c0000),
1069 ]
1070
1071 def _on_chip_devices(self):
1072 return super(VExpress_GEM5_V1_Base,self)._on_chip_devices() + [
1073 self.gic, self.vgic, self.gicv2m,
1074 ]
1075
1076class 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)
1079
1080 def _on_chip_devices(self):
1081 return super(VExpress_GEM5_V1,self)._on_chip_devices() + [
1082 self.hdlcd,
1083 ]
1084
1085class VExpress_GEM5_V2_Base(VExpress_GEM5_Base):
1086 gic = Gicv3()
1087
1088 def _on_chip_devices(self):
1089 return super(VExpress_GEM5_V2_Base,self)._on_chip_devices() + [
1090 self.gic,
1091 ]
1092
1093 def setupBootLoader(self, mem_bus, cur_sys, loc):
1094 cur_sys.boot_loader = [ loc('boot_emm_v2.arm64') ]
1095 super(VExpress_GEM5_V2_Base,self).setupBootLoader(mem_bus,
1096 cur_sys, loc)
1097
1098class VExpress_GEM5_V2(VExpress_GEM5_V2_Base):
1099 hdlcd = HDLcd(pxl_clk=VExpress_GEM5_V2_Base.dcc.osc_pxl,
1100 pio_addr=0x2b000000, int_num=95)
1101
1102 def _on_chip_devices(self):
1103 return super(VExpress_GEM5_V2,self)._on_chip_devices() + [
1104 self.hdlcd,
1105 ]