2225d87655a701e5f9737e60190cef25c127e9e5
[gem5.git] / src / dev / arm / RealView.py
1 # Copyright (c) 2009-2020 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 from m5.defines import buildEnv
40 from m5.params import *
41 from m5.proxy import *
42 from m5.util.fdthelper import *
43 from m5.objects.ClockDomain import ClockDomain, SrcClockDomain
44 from m5.objects.VoltageDomain import VoltageDomain
45 from m5.objects.Device import \
46 BasicPioDevice, PioDevice, IsaFake, BadAddr, DmaDevice
47 from m5.objects.PciHost import *
48 from m5.objects.Ethernet import NSGigE, IGbE_igb, IGbE_e1000
49 from m5.objects.Ide import *
50 from m5.objects.Platform import Platform
51 from m5.objects.Terminal import Terminal
52 from m5.objects.Uart import Uart
53 from m5.objects.SimpleMemory import SimpleMemory
54 from m5.objects.Gic import *
55 from m5.objects.EnergyCtrl import EnergyCtrl
56 from m5.objects.ClockedObject import ClockedObject
57 from m5.objects.SubSystem import SubSystem
58 from m5.objects.Graphics import ImageFormat
59 from m5.objects.ClockedObject import ClockedObject
60 from m5.objects.PS2 import *
61 from m5.objects.VirtIOMMIO import MmioVirtIO
62 from m5.objects.Display import Display, Display1080p
63 from m5.objects.SMMUv3 import SMMUv3
64
65 # Platforms with KVM support should generally use in-kernel GIC
66 # emulation. Use a GIC model that automatically switches between
67 # gem5's GIC model and KVM's GIC model if KVM is available.
68 try:
69 from m5.objects.KvmGic import MuxingKvmGic
70 kvm_gicv2_class = MuxingKvmGic
71 except ImportError:
72 # KVM support wasn't compiled into gem5. Fallback to a
73 # software-only GIC.
74 kvm_gicv2_class = Gic400
75 pass
76
77 class AmbaPioDevice(BasicPioDevice):
78 type = 'AmbaPioDevice'
79 abstract = True
80 cxx_header = "dev/arm/amba_device.hh"
81 amba_id = Param.UInt32("ID of AMBA device for kernel detection")
82
83 class AmbaIntDevice(AmbaPioDevice):
84 type = 'AmbaIntDevice'
85 abstract = True
86 cxx_header = "dev/arm/amba_device.hh"
87 gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
88 int_num = Param.UInt32("Interrupt number that connects to GIC")
89 int_delay = Param.Latency("100ns",
90 "Time between action and interrupt generation by device")
91
92 class AmbaDmaDevice(DmaDevice):
93 type = 'AmbaDmaDevice'
94 abstract = True
95 cxx_header = "dev/arm/amba_device.hh"
96 pio_addr = Param.Addr("Address for AMBA slave interface")
97 pio_latency = Param.Latency("10ns", "Time between action and write/read result by AMBA DMA Device")
98 gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
99 int_num = Param.UInt32("Interrupt number that connects to GIC")
100 amba_id = Param.UInt32("ID of AMBA device for kernel detection")
101
102 class A9SCU(BasicPioDevice):
103 type = 'A9SCU'
104 cxx_header = "dev/arm/a9scu.hh"
105
106 class ArmPciIntRouting(Enum): vals = [
107 'ARM_PCI_INT_STATIC',
108 'ARM_PCI_INT_DEV',
109 'ARM_PCI_INT_PIN',
110 ]
111
112 class GenericArmPciHost(GenericPciHost):
113 type = 'GenericArmPciHost'
114 cxx_header = "dev/arm/pci_host.hh"
115
116 int_policy = Param.ArmPciIntRouting("PCI interrupt routing policy")
117 int_base = Param.Unsigned("PCI interrupt base")
118 int_count = Param.Unsigned("Maximum number of interrupts used by this host")
119
120 # This python parameter can be used in configuration scripts to turn
121 # on/off the fdt dma-coherent flag when doing dtb autogeneration
122 _dma_coherent = True
123
124 def generateDeviceTree(self, state):
125 local_state = FdtState(
126 addr_cells=3, size_cells=2,
127 cpu_cells=1, interrupt_cells=1)
128
129 node = FdtNode("pci")
130
131 if int(self.conf_device_bits) == 8:
132 node.appendCompatible("pci-host-cam-generic")
133 elif int(self.conf_device_bits) == 12:
134 node.appendCompatible("pci-host-ecam-generic")
135 else:
136 m5.fatal("No compatibility string for the set conf_device_width")
137
138 node.append(FdtPropertyStrings("device_type", ["pci"]))
139
140 # Cell sizes of child nodes/peripherals
141 node.append(local_state.addrCellsProperty())
142 node.append(local_state.sizeCellsProperty())
143 node.append(local_state.interruptCellsProperty())
144 # PCI address for CPU
145 node.append(FdtPropertyWords("reg",
146 state.addrCells(self.conf_base) +
147 state.sizeCells(self.conf_size) ))
148
149 # Ranges mapping
150 # For now some of this is hard coded, because the PCI module does not
151 # have a proper full understanding of the memory map, but adapting the
152 # PCI module is beyond the scope of what I'm trying to do here.
153 # Values are taken from the VExpress_GEM5_V1 platform.
154 ranges = []
155 # Pio address range
156 ranges += self.pciFdtAddr(space=1, addr=0)
157 ranges += state.addrCells(self.pci_pio_base)
158 ranges += local_state.sizeCells(0x10000) # Fixed size
159
160 # AXI memory address range
161 ranges += self.pciFdtAddr(space=2, addr=0)
162 ranges += state.addrCells(0x40000000) # Fixed offset
163 ranges += local_state.sizeCells(0x40000000) # Fixed size
164 node.append(FdtPropertyWords("ranges", ranges))
165
166 if str(self.int_policy) == 'ARM_PCI_INT_DEV':
167 gic = self._parent.unproxy(self).gic
168 int_phandle = state.phandle(gic)
169 # Interrupt mapping
170 interrupts = []
171
172 # child interrupt specifier
173 child_interrupt = local_state.interruptCells(0x0)
174
175 # parent unit address
176 parent_addr = gic._state.addrCells(0x0)
177
178 for i in range(int(self.int_count)):
179 parent_interrupt = gic.interruptCells(0,
180 int(self.int_base) - 32 + i, 1)
181
182 interrupts += self.pciFdtAddr(device=i, addr=0) + \
183 child_interrupt + [int_phandle] + parent_addr + \
184 parent_interrupt
185
186 node.append(FdtPropertyWords("interrupt-map", interrupts))
187
188 int_count = int(self.int_count)
189 if int_count & (int_count - 1):
190 fatal("PCI interrupt count should be power of 2")
191
192 intmask = self.pciFdtAddr(device=int_count - 1, addr=0) + [0x0]
193 node.append(FdtPropertyWords("interrupt-map-mask", intmask))
194 else:
195 m5.fatal("Unsupported PCI interrupt policy " +
196 "for Device Tree generation")
197
198 if self._dma_coherent:
199 node.append(FdtProperty("dma-coherent"))
200
201 yield node
202
203 class RealViewCtrl(BasicPioDevice):
204 type = 'RealViewCtrl'
205 cxx_header = "dev/arm/rv_ctrl.hh"
206 proc_id0 = Param.UInt32(0x0C000000, "Processor ID, SYS_PROCID")
207 proc_id1 = Param.UInt32(0x0C000222, "Processor ID, SYS_PROCID1")
208 idreg = Param.UInt32(0x00000000, "ID Register, SYS_ID")
209
210 def generateDeviceTree(self, state):
211 node = FdtNode("sysreg@%x" % long(self.pio_addr))
212 node.appendCompatible("arm,vexpress-sysreg")
213 node.append(FdtPropertyWords("reg",
214 state.addrCells(self.pio_addr) +
215 state.sizeCells(0x1000) ))
216 node.append(FdtProperty("gpio-controller"))
217 node.append(FdtPropertyWords("#gpio-cells", [2]))
218 node.appendPhandle(self)
219
220 yield node
221
222 class RealViewOsc(ClockDomain):
223 type = 'RealViewOsc'
224 cxx_header = "dev/arm/rv_ctrl.hh"
225
226 parent = Param.RealViewCtrl(Parent.any, "RealView controller")
227
228 # TODO: We currently don't have the notion of a clock source,
229 # which means we have to associate oscillators with a voltage
230 # source.
231 voltage_domain = Param.VoltageDomain(Parent.voltage_domain,
232 "Voltage domain")
233
234 # See ARM DUI 0447J (ARM Motherboard Express uATX -- V2M-P1) and
235 # the individual core/logic tile reference manuals for details
236 # about the site/position/dcc/device allocation.
237 site = Param.UInt8("Board Site")
238 position = Param.UInt8("Position in device stack")
239 dcc = Param.UInt8("Daughterboard Configuration Controller")
240 device = Param.UInt8("Device ID")
241
242 freq = Param.Clock("Default frequency")
243
244 def generateDeviceTree(self, state):
245 phandle = state.phandle(self)
246 node = FdtNode("osc@" + format(long(phandle), 'x'))
247 node.appendCompatible("arm,vexpress-osc")
248 node.append(FdtPropertyWords("arm,vexpress-sysreg,func",
249 [0x1, int(self.device)]))
250 node.append(FdtPropertyWords("#clock-cells", [0]))
251 freq = int(1.0/self.freq.value) # Values are stored as a clock period
252 node.append(FdtPropertyWords("freq-range", [freq, freq]))
253 node.append(FdtPropertyStrings("clock-output-names",
254 ["oscclk" + str(phandle)]))
255 node.appendPhandle(self)
256 yield node
257
258 class RealViewTemperatureSensor(SimObject):
259 type = 'RealViewTemperatureSensor'
260 cxx_header = "dev/arm/rv_ctrl.hh"
261
262 parent = Param.RealViewCtrl(Parent.any, "RealView controller")
263
264 system = Param.System(Parent.any, "system")
265
266 # See ARM DUI 0447J (ARM Motherboard Express uATX -- V2M-P1) and
267 # the individual core/logic tile reference manuals for details
268 # about the site/position/dcc/device allocation.
269 site = Param.UInt8("Board Site")
270 position = Param.UInt8("Position in device stack")
271 dcc = Param.UInt8("Daughterboard Configuration Controller")
272 device = Param.UInt8("Device ID")
273
274 class VExpressMCC(SubSystem):
275 """ARM V2M-P1 Motherboard Configuration Controller
276
277 This subsystem describes a subset of the devices that sit behind the
278 motherboard configuration controller on the the ARM Motherboard
279 Express (V2M-P1) motherboard. See ARM DUI 0447J for details.
280 """
281
282 class Osc(RealViewOsc):
283 site, position, dcc = (0, 0, 0)
284
285 class Temperature(RealViewTemperatureSensor):
286 site, position, dcc = (0, 0, 0)
287
288 osc_mcc = Osc(device=0, freq="50MHz")
289 osc_clcd = Osc(device=1, freq="23.75MHz")
290 osc_peripheral = Osc(device=2, freq="24MHz")
291 osc_system_bus = Osc(device=4, freq="24MHz")
292
293 # See Table 4.19 in ARM DUI 0447J (Motherboard Express uATX TRM).
294 temp_crtl = Temperature(device=0)
295
296 def generateDeviceTree(self, state):
297 node = FdtNode("mcc")
298 node.appendCompatible("arm,vexpress,config-bus")
299 node.append(FdtPropertyWords("arm,vexpress,site", [0]))
300
301 for obj in self._children.values():
302 if issubclass(type(obj), SimObject):
303 node.append(obj.generateDeviceTree(state))
304
305 io_phandle = state.phandle(self.osc_mcc.parent.unproxy(self))
306 node.append(FdtPropertyWords("arm,vexpress,config-bridge", io_phandle))
307
308 yield node
309
310 class CoreTile2A15DCC(SubSystem):
311 """ARM CoreTile Express A15x2 Daughterboard Configuration Controller
312
313 This subsystem describes a subset of the devices that sit behind the
314 daughterboard configuration controller on a CoreTile Express A15x2. See
315 ARM DUI 0604E for details.
316 """
317
318 class Osc(RealViewOsc):
319 site, position, dcc = (1, 0, 0)
320
321 # See Table 2.8 in ARM DUI 0604E (CoreTile Express A15x2 TRM)
322 osc_cpu = Osc(device=0, freq="60MHz")
323 osc_hsbm = Osc(device=4, freq="40MHz")
324 osc_pxl = Osc(device=5, freq="23.75MHz")
325 osc_smb = Osc(device=6, freq="50MHz")
326 osc_sys = Osc(device=7, freq="60MHz")
327 osc_ddr = Osc(device=8, freq="40MHz")
328
329 def generateDeviceTree(self, state):
330 node = FdtNode("dcc")
331 node.appendCompatible("arm,vexpress,config-bus")
332
333 for obj in self._children.values():
334 if isinstance(obj, SimObject):
335 node.append(obj.generateDeviceTree(state))
336
337 io_phandle = state.phandle(self.osc_cpu.parent.unproxy(self))
338 node.append(FdtPropertyWords("arm,vexpress,config-bridge", io_phandle))
339
340 yield node
341
342 class AmbaFake(AmbaPioDevice):
343 type = 'AmbaFake'
344 cxx_header = "dev/arm/amba_fake.hh"
345 ignore_access = Param.Bool(False, "Ignore reads/writes to this device, (e.g. IsaFake + AMBA)")
346 amba_id = 0;
347
348 # Simple fixed-rate clock source. Intended to be instantiated in Platform
349 # instances for definition of clock bindings on DTB auto-generation
350 class FixedClock(SrcClockDomain):
351 # Keep track of the number of FixedClock instances in the system
352 # to provide unique names
353 _index = 0
354
355 def generateDeviceTree(self, state):
356 if len(self.clock) > 1:
357 fatal('FixedClock configured with multiple frequencies')
358 node = FdtNode('clock{}'.format(FixedClock._index))
359 node.appendCompatible('fixed-clock')
360 node.append(FdtPropertyWords('#clock-cells', 0))
361 node.append(FdtPropertyWords('clock-frequency',
362 self.clock[0].frequency))
363 node.appendPhandle(self)
364 FixedClock._index += 1
365
366 yield node
367
368 class Pl011(Uart):
369 type = 'Pl011'
370 cxx_header = "dev/arm/pl011.hh"
371 gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
372 int_num = Param.UInt32("Interrupt number that connects to GIC")
373 end_on_eot = Param.Bool(False, "End the simulation when a EOT is received on the UART")
374 int_delay = Param.Latency("100ns", "Time between action and interrupt generation by UART")
375
376 def generateDeviceTree(self, state):
377 node = self.generateBasicPioDeviceNode(state, 'uart', self.pio_addr,
378 0x1000, [int(self.int_num)])
379 node.appendCompatible(["arm,pl011", "arm,primecell"])
380
381 # Hardcoded reference to the realview platform clocks, because the
382 # clk_domain can only store one clock (i.e. it is not a VectorParam)
383 realview = self._parent.unproxy(self)
384 node.append(FdtPropertyWords("clocks",
385 [state.phandle(realview.mcc.osc_peripheral),
386 state.phandle(realview.dcc.osc_smb)]))
387 node.append(FdtPropertyStrings("clock-names", ["uartclk", "apb_pclk"]))
388 yield node
389
390 class Sp804(AmbaPioDevice):
391 type = 'Sp804'
392 cxx_header = "dev/arm/timer_sp804.hh"
393 gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
394 int_num0 = Param.UInt32("Interrupt number that connects to GIC")
395 clock0 = Param.Clock('1MHz', "Clock speed of the input")
396 int_num1 = Param.UInt32("Interrupt number that connects to GIC")
397 clock1 = Param.Clock('1MHz', "Clock speed of the input")
398 amba_id = 0x00141804
399
400 class Sp805(AmbaIntDevice):
401 """
402 Arm Watchdog Module (SP805)
403 Reference:
404 Arm Watchdog Module (SP805) - Technical Reference Manual - rev. r1p0
405 Doc. ID: ARM DDI 0270B
406 """
407
408 type = 'Sp805'
409 cxx_header = 'dev/arm/watchdog_sp805.hh'
410
411 amba_id = 0x00141805
412
413 def generateDeviceTree(self, state):
414 node = self.generateBasicPioDeviceNode(state, 'watchdog',
415 self.pio_addr, 0x1000, [int(self.int_num)])
416 node.appendCompatible(['arm,sp805', 'arm,primecell'])
417 clocks = [state.phandle(self.clk_domain.unproxy(self))]
418 clock_names = ['wdogclk']
419 platform = self._parent.unproxy(self)
420 if self in platform._off_chip_devices():
421 clocks.append(state.phandle(platform.dcc.osc_smb))
422 clock_names.append('apb_pclk')
423 node.append(FdtPropertyWords('clocks', clocks))
424 node.append(FdtPropertyStrings('clock-names', clock_names))
425
426 yield node
427
428 class A9GlobalTimer(BasicPioDevice):
429 type = 'A9GlobalTimer'
430 cxx_header = "dev/arm/timer_a9global.hh"
431 gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
432 int_num = Param.UInt32("Interrrupt number that connects to GIC")
433
434 class CpuLocalTimer(BasicPioDevice):
435 type = 'CpuLocalTimer'
436 cxx_header = "dev/arm/timer_cpulocal.hh"
437 int_timer = Param.ArmPPI("Interrrupt used per-cpu to GIC")
438 int_watchdog = Param.ArmPPI("Interrupt for per-cpu watchdog to GIC")
439
440 class GenericTimer(ClockedObject):
441 type = 'GenericTimer'
442 cxx_header = "dev/arm/generic_timer.hh"
443 system = Param.ArmSystem(Parent.any, "system")
444 int_phys_s = Param.ArmPPI("Physical (S) timer interrupt")
445 int_phys_ns = Param.ArmPPI("Physical (NS) timer interrupt")
446 int_virt = Param.ArmPPI("Virtual timer interrupt")
447 int_hyp = Param.ArmPPI("Hypervisor timer interrupt")
448
449 freqs = VectorParam.UInt32([0x01800000], "Frequencies available for the "
450 "system counter (in Hz). First element is the base frequency, "
451 "following are alternative lower ones which must be exact divisors")
452
453 def generateDeviceTree(self, state):
454 node = FdtNode("timer")
455
456 node.appendCompatible(["arm,cortex-a15-timer",
457 "arm,armv7-timer",
458 "arm,armv8-timer"])
459 node.append(FdtPropertyWords("interrupts", [
460 1, int(self.int_phys_s.num) - 16, 0xf08,
461 1, int(self.int_phys_ns.num) - 16, 0xf08,
462 1, int(self.int_virt.num) - 16, 0xf08,
463 1, int(self.int_hyp.num) - 16, 0xf08,
464 ]))
465 clock = state.phandle(self.clk_domain.unproxy(self))
466 node.append(FdtPropertyWords("clocks", clock))
467
468 yield node
469
470 class GenericTimerMem(PioDevice):
471 type = 'GenericTimerMem'
472 cxx_header = "dev/arm/generic_timer.hh"
473
474 base = Param.Addr(0, "Base address")
475
476 int_phys = Param.ArmSPI("Physical Interrupt")
477 int_virt = Param.ArmSPI("Virtual Interrupt")
478
479 freqs = VectorParam.UInt32([0x01800000], "Frequencies available for the "
480 "system counter (in Hz). First element is the base frequency, "
481 "following are alternative lower ones which must be exact divisors")
482
483 class PL031(AmbaIntDevice):
484 type = 'PL031'
485 cxx_header = "dev/arm/rtc_pl031.hh"
486 time = Param.Time('01/01/2009', "System time to use ('Now' for actual time)")
487 amba_id = 0x00041031
488
489 def generateDeviceTree(self, state):
490 node = self.generateBasicPioDeviceNode(state, 'rtc', self.pio_addr,
491 0x1000, [int(self.int_num)])
492
493 node.appendCompatible(["arm,pl031", "arm,primecell"])
494 clock = state.phandle(self.clk_domain.unproxy(self))
495 node.append(FdtPropertyWords("clocks", clock))
496 node.append(FdtPropertyStrings("clock-names", ["apb_pclk"]))
497
498 yield node
499
500 class Pl050(AmbaIntDevice):
501 type = 'Pl050'
502 cxx_header = "dev/arm/kmi.hh"
503 amba_id = 0x00141050
504
505 ps2 = Param.PS2Device("PS/2 device")
506
507 def generateDeviceTree(self, state):
508 node = self.generateBasicPioDeviceNode(state, 'kmi', self.pio_addr,
509 0x1000, [int(self.int_num)])
510
511 node.appendCompatible(["arm,pl050", "arm,primecell"])
512 clock = state.phandle(self.clk_domain.unproxy(self))
513 node.append(FdtPropertyWords("clocks", clock))
514
515 yield node
516
517 class Pl111(AmbaDmaDevice):
518 type = 'Pl111'
519 cxx_header = "dev/arm/pl111.hh"
520 pixel_clock = Param.Clock('24MHz', "Pixel clock")
521 vnc = Param.VncInput(Parent.any, "Vnc server for remote frame buffer display")
522 amba_id = 0x00141111
523 enable_capture = Param.Bool(True, "capture frame to system.framebuffer.bmp")
524
525 class HDLcd(AmbaDmaDevice):
526 type = 'HDLcd'
527 cxx_header = "dev/arm/hdlcd.hh"
528 vnc = Param.VncInput(Parent.any, "Vnc server for remote frame buffer "
529 "display")
530 amba_id = 0x00141000
531 workaround_swap_rb = Param.Bool(False, "Workaround incorrect color "
532 "selector order in some kernels")
533 workaround_dma_line_count = Param.Bool(True, "Workaround incorrect "
534 "DMA line count (off by 1)")
535 enable_capture = Param.Bool(True, "capture frame to "
536 "system.framebuffer.{extension}")
537 frame_format = Param.ImageFormat("Auto",
538 "image format of the captured frame")
539
540 pixel_buffer_size = Param.MemorySize32("2kB", "Size of address range")
541
542 pxl_clk = Param.ClockDomain("Pixel clock source")
543 pixel_chunk = Param.Unsigned(32, "Number of pixels to handle in one batch")
544 virt_refresh_rate = Param.Frequency("20Hz", "Frame refresh rate "
545 "in KVM mode")
546 _status = "disabled"
547
548 encoder = Param.Display(Display1080p(), "Display encoder")
549
550 def endpointPhandle(self):
551 return "hdlcd_endpoint"
552
553 def generateDeviceTree(self, state):
554 endpoint_node = FdtNode("endpoint")
555 endpoint_node.appendPhandle(self.endpointPhandle())
556
557 for encoder_node in self.encoder.generateDeviceTree(state):
558 encoder_endpoint = self.encoder.endpointNode()
559
560 # Endpoint subnode
561 endpoint_node.append(FdtPropertyWords("remote-endpoint",
562 [ state.phandle(self.encoder.endpointPhandle()) ]))
563 encoder_endpoint.append(FdtPropertyWords("remote-endpoint",
564 [ state.phandle(self.endpointPhandle()) ]))
565
566 yield encoder_node
567
568 port_node = FdtNode("port")
569 port_node.append(endpoint_node)
570
571 # Interrupt number is hardcoded; it is not a property of this class
572 node = self.generateBasicPioDeviceNode(state, 'hdlcd',
573 self.pio_addr, 0x1000, [63])
574
575 node.appendCompatible(["arm,hdlcd"])
576 node.append(FdtPropertyWords("clocks", state.phandle(self.pxl_clk)))
577 node.append(FdtPropertyStrings("clock-names", ["pxlclk"]))
578
579 # This driver is disabled by default since the required DT nodes
580 # haven't been standardized yet. To use it, override this status to
581 # "ok" and add the display configuration nodes required by the driver.
582 # See the driver for more information.
583 node.append(FdtPropertyStrings("status", [ self._status ]))
584
585 self.addIommuProperty(state, node)
586
587 node.append(port_node)
588
589 yield node
590
591 class RealView(Platform):
592 type = 'RealView'
593 cxx_header = "dev/arm/realview.hh"
594 system = Param.System(Parent.any, "system")
595 _mem_regions = [ AddrRange(0, size='256MB') ]
596 _num_pci_dev = 0
597
598 def _on_chip_devices(self):
599 return []
600
601 def _off_chip_devices(self):
602 return []
603
604 def _on_chip_memory(self):
605 return []
606
607 def _off_chip_memory(self):
608 return []
609
610 _off_chip_ranges = []
611
612 def _attach_memory(self, mem, bus, mem_ports=None):
613 if hasattr(mem, "port"):
614 if mem_ports is None:
615 mem.port = bus.master
616 else:
617 mem_ports.append(mem.port)
618
619 def _attach_device(self, device, bus, dma_ports=None):
620 if hasattr(device, "pio"):
621 device.pio = bus.master
622 if hasattr(device, "dma"):
623 if dma_ports is None:
624 device.dma = bus.slave
625 else:
626 dma_ports.append(device.dma)
627
628 def _attach_io(self, devices, *args, **kwargs):
629 for d in devices:
630 self._attach_device(d, *args, **kwargs)
631
632 def _attach_mem(self, memories, *args, **kwargs):
633 for mem in memories:
634 self._attach_memory(mem, *args, **kwargs)
635
636 def _attach_clk(self, devices, clkdomain):
637 for d in devices:
638 if hasattr(d, "clk_domain"):
639 d.clk_domain = clkdomain
640
641 def attachPciDevices(self):
642 pass
643
644 def enableMSIX(self):
645 pass
646
647 def onChipIOClkDomain(self, clkdomain):
648 self._attach_clk(self._on_chip_devices(), clkdomain)
649
650 def offChipIOClkDomain(self, clkdomain):
651 self._attach_clk(self._off_chip_devices(), clkdomain)
652
653 def attachOnChipIO(self, bus, bridge=None, dma_ports=None, mem_ports=None):
654 self._attach_mem(self._on_chip_memory(), bus, mem_ports)
655 self._attach_io(self._on_chip_devices(), bus, dma_ports)
656 if bridge:
657 bridge.ranges = self._off_chip_ranges
658
659 def attachIO(self, *args, **kwargs):
660 self._attach_mem(self._off_chip_memory(), *args, **kwargs)
661 self._attach_io(self._off_chip_devices(), *args, **kwargs)
662
663 def setupBootLoader(self, cur_sys, boot_loader, atags_addr, load_offset):
664 cur_sys.boot_loader = boot_loader
665 cur_sys.atags_addr = atags_addr
666 cur_sys.load_offset = load_offset
667
668 def generateDeviceTree(self, state):
669 node = FdtNode("/") # Things in this module need to end up in the root
670 node.append(FdtPropertyWords("interrupt-parent",
671 state.phandle(self.gic)))
672
673 for subnode in self.recurseDeviceTree(state):
674 node.append(subnode)
675
676 yield node
677
678 def annotateCpuDeviceNode(self, cpu, state):
679 cpu.append(FdtPropertyStrings("enable-method", "spin-table"))
680 cpu.append(FdtPropertyWords("cpu-release-addr", \
681 state.addrCells(0x8000fff8)))
682
683 class VExpress_EMM(RealView):
684 _mem_regions = [ AddrRange('2GB', size='2GB') ]
685
686 # Ranges based on excluding what is part of on-chip I/O (gic,
687 # a9scu)
688 _off_chip_ranges = [AddrRange(0x2F000000, size='16MB'),
689 AddrRange(0x30000000, size='256MB'),
690 AddrRange(0x40000000, size='512MB'),
691 AddrRange(0x18000000, size='64MB'),
692 AddrRange(0x1C000000, size='64MB')]
693
694 # Platform control device (off-chip)
695 realview_io = RealViewCtrl(proc_id0=0x14000000, proc_id1=0x14000000,
696 idreg=0x02250000, pio_addr=0x1C010000)
697
698 mcc = VExpressMCC()
699 dcc = CoreTile2A15DCC()
700
701 ### On-chip devices ###
702 gic = Gic400(dist_addr=0x2C001000, cpu_addr=0x2C002000)
703 vgic = VGic(vcpu_addr=0x2c006000, hv_addr=0x2c004000, maint_int=25)
704
705 local_cpu_timer = CpuLocalTimer(int_timer=ArmPPI(num=29),
706 int_watchdog=ArmPPI(num=30),
707 pio_addr=0x2C080000)
708
709 hdlcd = HDLcd(pxl_clk=dcc.osc_pxl,
710 pio_addr=0x2b000000, int_num=117,
711 workaround_swap_rb=True)
712
713 def _on_chip_devices(self):
714 devices = [
715 self.gic, self.vgic,
716 self.local_cpu_timer
717 ]
718 if hasattr(self, "gicv2m"):
719 devices.append(self.gicv2m)
720 devices.append(self.hdlcd)
721 return devices
722
723 def _on_chip_memory(self):
724 memories = [
725 self.bootmem,
726 ]
727 return memories
728
729 ### Off-chip devices ###
730 uart = Pl011(pio_addr=0x1c090000, int_num=37)
731 pci_host = GenericPciHost(
732 conf_base=0x30000000, conf_size='256MB', conf_device_bits=16,
733 pci_pio_base=0)
734
735 generic_timer = GenericTimer(int_phys_s=ArmPPI(num=29),
736 int_phys_ns=ArmPPI(num=30),
737 int_virt=ArmPPI(num=27),
738 int_hyp=ArmPPI(num=26))
739
740 timer0 = Sp804(int_num0=34, int_num1=34, pio_addr=0x1C110000, clock0='1MHz', clock1='1MHz')
741 timer1 = Sp804(int_num0=35, int_num1=35, pio_addr=0x1C120000, clock0='1MHz', clock1='1MHz')
742 clcd = Pl111(pio_addr=0x1c1f0000, int_num=46)
743 kmi0 = Pl050(pio_addr=0x1c060000, int_num=44, ps2=PS2Keyboard())
744 kmi1 = Pl050(pio_addr=0x1c070000, int_num=45, ps2=PS2TouchKit())
745 cf_ctrl = IdeController(disks=[], pci_func=0, pci_dev=0, pci_bus=2,
746 io_shift = 2, ctrl_offset = 2, Command = 0x1,
747 BAR0 = 0x1C1A0000, BAR0Size = '256B',
748 BAR1 = 0x1C1A0100, BAR1Size = '4096B',
749 BAR0LegacyIO = True, BAR1LegacyIO = True)
750
751 bootmem = SimpleMemory(range = AddrRange('64MB'),
752 conf_table_reported = False)
753 vram = SimpleMemory(range = AddrRange(0x18000000, size='32MB'),
754 conf_table_reported = False)
755 rtc = PL031(pio_addr=0x1C170000, int_num=36)
756
757 l2x0_fake = IsaFake(pio_addr=0x2C100000, pio_size=0xfff)
758 uart1_fake = AmbaFake(pio_addr=0x1C0A0000)
759 uart2_fake = AmbaFake(pio_addr=0x1C0B0000)
760 uart3_fake = AmbaFake(pio_addr=0x1C0C0000)
761 sp810_fake = AmbaFake(pio_addr=0x1C020000, ignore_access=True)
762 watchdog_fake = AmbaFake(pio_addr=0x1C0F0000)
763 aaci_fake = AmbaFake(pio_addr=0x1C040000)
764 lan_fake = IsaFake(pio_addr=0x1A000000, pio_size=0xffff)
765 usb_fake = IsaFake(pio_addr=0x1B000000, pio_size=0x1ffff)
766 mmc_fake = AmbaFake(pio_addr=0x1c050000)
767 energy_ctrl = EnergyCtrl(pio_addr=0x1c080000)
768
769 def _off_chip_devices(self):
770 devices = [
771 self.uart,
772 self.realview_io,
773 self.pci_host,
774 self.timer0,
775 self.timer1,
776 self.clcd,
777 self.kmi0,
778 self.kmi1,
779 self.cf_ctrl,
780 self.rtc,
781 self.vram,
782 self.l2x0_fake,
783 self.uart1_fake,
784 self.uart2_fake,
785 self.uart3_fake,
786 self.sp810_fake,
787 self.watchdog_fake,
788 self.aaci_fake,
789 self.lan_fake,
790 self.usb_fake,
791 self.mmc_fake,
792 self.energy_ctrl,
793 ]
794 # Try to attach the I/O if it exists
795 if hasattr(self, "ide"):
796 devices.append(self.ide)
797 if hasattr(self, "ethernet"):
798 devices.append(self.ethernet)
799 return devices
800
801 # Attach any PCI devices that are supported
802 def attachPciDevices(self):
803 self.ethernet = IGbE_e1000(pci_bus=0, pci_dev=0, pci_func=0,
804 InterruptLine=1, InterruptPin=1)
805 self.ide = IdeController(disks = [], pci_bus=0, pci_dev=1, pci_func=0,
806 InterruptLine=2, InterruptPin=2)
807
808 def enableMSIX(self):
809 self.gic = Gic400(dist_addr=0x2C001000, cpu_addr=0x2C002000,
810 it_lines=512)
811 self.gicv2m = Gicv2m()
812 self.gicv2m.frames = [Gicv2mFrame(spi_base=256, spi_len=64, addr=0x2C1C0000)]
813
814 def setupBootLoader(self, cur_sys, loc, boot_loader=None):
815 if boot_loader is None:
816 boot_loader = loc('boot_emm.arm')
817 super(VExpress_EMM, self).setupBootLoader(
818 cur_sys, boot_loader, 0x8000000, 0x80000000)
819
820 class VExpress_EMM64(VExpress_EMM):
821 # Three memory regions are specified totalling 512GB
822 _mem_regions = [ AddrRange('2GB', size='2GB'),
823 AddrRange('34GB', size='30GB'),
824 AddrRange('512GB', size='480GB') ]
825 pci_host = GenericPciHost(
826 conf_base=0x30000000, conf_size='256MB', conf_device_bits=12,
827 pci_pio_base=0x2f000000)
828
829 def setupBootLoader(self, cur_sys, loc, boot_loader=None):
830 if boot_loader is None:
831 boot_loader = loc('boot_emm.arm64')
832 RealView.setupBootLoader(self, cur_sys, boot_loader,
833 0x8000000, 0x80000000)
834
835 class VExpress_GEM5_Base(RealView):
836 """
837 The VExpress gem5 memory map is loosely based on a modified
838 Versatile Express RS1 memory map.
839
840 The gem5 platform has been designed to implement a subset of the
841 original Versatile Express RS1 memory map. Off-chip peripherals should,
842 when possible, adhere to the Versatile Express memory map. Non-PCI
843 off-chip devices that are gem5-specific should live in the CS5 memory
844 space to avoid conflicts with existing devices that we might want to
845 model in the future. Such devices should normally have interrupts in
846 the gem5-specific SPI range.
847
848 On-chip peripherals are loosely modeled after the ARM CoreTile Express
849 A15x2 memory and interrupt map. In particular, the GIC and
850 Generic Timer have the same interrupt lines and base addresses. Other
851 on-chip devices are gem5 specific.
852
853 Unlike the original Versatile Express RS2 extended platform, gem5 implements a
854 large contigious DRAM space, without aliases or holes, starting at the
855 2GiB boundary. This means that PCI memory is limited to 1GiB.
856
857 References:
858
859 Technical Reference Manuals:
860 Arm Motherboard Express uATX (V2M-P1) - ARM DUI 0447J
861 Arm CoreTile Express A15x2 (V2P-CA15) - ARM DUI 0604E
862
863 Official Linux device tree specifications:
864 V2M-P1 - arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
865 V2P-CA15 - arch/arm/boot/dts/vexpress-v2p-ca15-tc1.dts
866
867 Memory map:
868 Arm CoreTile Express A15x2 (V2P-CA15) - ARM DUI 0604E
869 Daughterboard (global)
870 Section 3.2.1 - Table 3-1 - Daughterboard memory map
871 On-chip
872 Section 3.2.3 - Table 3-2 - Cortex-A15 MPCore on-chip peripheral
873 memory map
874
875 Interrupts:
876 Arm CoreTile Express A15x2 (V2P-CA15) - ARM DUI 0604E
877 Section 2.8.2 - Test chip interrupts
878
879 Memory map:
880 0x00000000-0x03ffffff: Boot memory (CS0)
881 0x04000000-0x07ffffff: Reserved
882 0x08000000-0x0bffffff: NOR FLASH0 (CS0 alias)
883 0x0c000000-0x0fffffff: Reserved (Off-chip, CS4)
884 0x10000000-0x13ffffff: gem5-specific peripherals (Off-chip, CS5)
885 0x10000000-0x1000ffff: gem5 energy controller
886 0x10010000-0x1001ffff: gem5 pseudo-ops
887
888 0x14000000-0x17ffffff: Reserved (Off-chip, PSRAM, CS1)
889 0x18000000-0x1bffffff: Reserved (Off-chip, Peripherals, CS2)
890 0x1c000000-0x1fffffff: Peripheral block 1 (Off-chip, CS3):
891 0x1c010000-0x1c01ffff: realview_io (VE system control regs.)
892 0x1c060000-0x1c06ffff: KMI0 (keyboard)
893 0x1c070000-0x1c07ffff: KMI1 (mouse)
894 0x1c090000-0x1c09ffff: UART0
895 0x1c0a0000-0x1c0affff: UART1 (reserved)
896 0x1c0b0000-0x1c0bffff: UART2 (reserved)
897 0x1c0c0000-0x1c0cffff: UART3 (reserved)
898 0x1c0f0000-0x1c0fffff: Watchdog (SP805)
899 0x1c130000-0x1c13ffff: VirtIO (gem5/FM extension)
900 0x1c140000-0x1c14ffff: VirtIO (gem5/FM extension)
901 0x1c170000-0x1c17ffff: RTC
902
903 0x20000000-0x3fffffff: On-chip peripherals:
904 0x2a490000-0x2a49ffff: Trusted Watchdog (SP805)
905 0x2b000000-0x2b00ffff: HDLCD
906
907 0x2b060000-0x2b060fff: System Watchdog (SP805)
908
909 0x2b400000-0x2b41ffff: SMMUv3
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
926 Interrupts:
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 : Watchdog (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 56 : Trusted Watchdog (SP805)
949 95-255: On-chip interrupt sources (we use these for
950 gem5-specific devices, SPIs)
951 74 : VirtIO (gem5/FM extension)
952 75 : VirtIO (gem5/FM extension)
953 95 : HDLCD
954 96- 98: GPU (reserved)
955 100-103: PCI
956 130 : System Watchdog (SP805)
957 256-319: MSI frame 0 (gem5-specific, SPIs)
958 320-511: Unused
959
960 """
961
962 # Everything above 2GiB is memory
963 _mem_regions = [ AddrRange('2GB', size='510GB') ]
964
965 _off_chip_ranges = [
966 # CS1-CS5
967 AddrRange(0x0c000000, 0x20000000),
968 # External AXI interface (PCI)
969 AddrRange(0x2f000000, 0x80000000),
970 ]
971
972 bootmem = SimpleMemory(range=AddrRange(0, size='64MB'),
973 conf_table_reported=False)
974
975 # NOR flash, flash0
976 flash0 = SimpleMemory(range=AddrRange(0x08000000, size='64MB'),
977 conf_table_reported=False)
978
979 # Trusted SRAM
980 trusted_sram = SimpleMemory(range=AddrRange(0x04000000, size='256kB'),
981 conf_table_reported=False)
982
983 # Platform control device (off-chip)
984 realview_io = RealViewCtrl(proc_id0=0x14000000, proc_id1=0x14000000,
985 idreg=0x02250000, pio_addr=0x1c010000)
986 mcc = VExpressMCC()
987 dcc = CoreTile2A15DCC()
988
989 ### On-chip devices ###
990
991 # Trusted Watchdog, SP805
992 trusted_watchdog = Sp805(pio_addr=0x2a490000, int_num=56)
993
994 generic_timer = GenericTimer(int_phys_s=ArmPPI(num=29),
995 int_phys_ns=ArmPPI(num=30),
996 int_virt=ArmPPI(num=27),
997 int_hyp=ArmPPI(num=26))
998
999 system_watchdog = Sp805(pio_addr=0x2b060000, int_num=130)
1000
1001 def _on_chip_devices(self):
1002 return [
1003 self.generic_timer,
1004 self.trusted_watchdog,
1005 self.system_watchdog
1006 ]
1007
1008 def _on_chip_memory(self):
1009 memories = [
1010 self.bootmem,
1011 self.trusted_sram,
1012 self.flash0,
1013 ]
1014 return memories
1015
1016 ### Off-chip devices ###
1017 io_voltage = VoltageDomain(voltage="3.3V")
1018 clock32KHz = SrcClockDomain(clock="32kHz")
1019 clock24MHz = SrcClockDomain(clock="24MHz")
1020
1021 uart = [
1022 Pl011(pio_addr=0x1c090000, int_num=37),
1023 ]
1024
1025 kmi0 = Pl050(pio_addr=0x1c060000, int_num=44, ps2=PS2Keyboard())
1026 kmi1 = Pl050(pio_addr=0x1c070000, int_num=45, ps2=PS2TouchKit())
1027
1028 watchdog = Sp805(pio_addr=0x1c0f0000, int_num=32)
1029
1030 rtc = PL031(pio_addr=0x1c170000, int_num=36)
1031
1032 ### gem5-specific off-chip devices ###
1033 pci_host = GenericArmPciHost(
1034 conf_base=0x30000000, conf_size='256MB', conf_device_bits=12,
1035 pci_pio_base=0x2f000000,
1036 int_policy="ARM_PCI_INT_DEV", int_base=100, int_count=4)
1037
1038 energy_ctrl = EnergyCtrl(pio_addr=0x10000000)
1039
1040 vio = [
1041 MmioVirtIO(pio_addr=0x1c130000, pio_size=0x1000,
1042 interrupt=ArmSPI(num=74)),
1043 MmioVirtIO(pio_addr=0x1c140000, pio_size=0x1000,
1044 interrupt=ArmSPI(num=75)),
1045 ]
1046
1047 def _off_chip_devices(self):
1048 return [
1049 self.realview_io,
1050 self.uart[0],
1051 self.kmi0,
1052 self.kmi1,
1053 self.watchdog,
1054 self.rtc,
1055 self.pci_host,
1056 self.energy_ctrl,
1057 self.clock32KHz,
1058 self.clock24MHz,
1059 self.vio[0],
1060 self.vio[1],
1061 ]
1062
1063 def __init__(self, **kwargs):
1064 super(VExpress_GEM5_Base, self).__init__(**kwargs)
1065 self.clock32KHz.voltage_domain = self.io_voltage
1066 self.clock24MHz.voltage_domain = self.io_voltage
1067 self.system_watchdog.clk_domain = self.dcc.osc_sys
1068 self.watchdog.clk_domain = self.clock32KHz
1069
1070 def attachPciDevice(self, device, *args, **kwargs):
1071 device.host = self.pci_host
1072 self._num_pci_dev += 1
1073 device.pci_bus = 0
1074 device.pci_dev = self._num_pci_dev
1075 device.pci_func = 0
1076 self._attach_device(device, *args, **kwargs)
1077
1078 def attachSmmu(self, devices, bus):
1079 """
1080 Instantiate a single SMMU and attach a group of client devices to it.
1081 The devices' dma port is wired to the SMMU and the SMMU's dma port
1082 (master) is attached to the bus. In order to make it work, the list
1083 of clients shouldn't contain any device part of the _off_chip_devices
1084 or _on_chip_devices.
1085 This method should be called only once.
1086
1087 Parameters:
1088 devices (list): List of devices which will be using the SMMU
1089 bus (Bus): The bus downstream of the SMMU. Its slave port will
1090 receive memory requests from the SMMU, and its master
1091 port will forward accesses to the memory mapped devices
1092 """
1093 if hasattr(self, 'smmu'):
1094 m5.fatal("A SMMU has already been instantiated\n")
1095
1096 self.smmu = SMMUv3(reg_map=AddrRange(0x2b400000, size=0x00020000))
1097
1098 dma_ports = []
1099 for dev in devices:
1100 self._attach_device(dev, bus, dma_ports)
1101 self.smmu.connect(dev, bus)
1102
1103 def setupBootLoader(self, cur_sys, boot_loader):
1104 super(VExpress_GEM5_Base, self).setupBootLoader(
1105 cur_sys, boot_loader, 0x8000000, 0x80000000)
1106
1107 # Setup m5ops. It's technically not a part of the boot
1108 # loader, but this is the only place we can configure the
1109 # system.
1110 cur_sys.m5ops_base = 0x10010000
1111
1112 def generateDeviceTree(self, state):
1113 # Generate using standard RealView function
1114 dt = list(super(VExpress_GEM5_Base, self).generateDeviceTree(state))
1115 if len(dt) > 1:
1116 raise Exception("System returned too many DT nodes")
1117 node = dt[0]
1118
1119 node.appendCompatible(["arm,vexpress"])
1120 node.append(FdtPropertyStrings("model", ["V2P-CA15"]))
1121 node.append(FdtPropertyWords("arm,hbi", [0x0]))
1122 node.append(FdtPropertyWords("arm,vexpress,site", [0xf]))
1123
1124 yield node
1125
1126 class VExpress_GEM5_V1_Base(VExpress_GEM5_Base):
1127 gic = kvm_gicv2_class(dist_addr=0x2c001000, cpu_addr=0x2c002000,
1128 it_lines=512)
1129 vgic = VGic(vcpu_addr=0x2c006000, hv_addr=0x2c004000, maint_int=25)
1130 gicv2m = Gicv2m()
1131 gicv2m.frames = [
1132 Gicv2mFrame(spi_base=256, spi_len=64, addr=0x2c1c0000),
1133 ]
1134
1135 def setupBootLoader(self, cur_sys, loc, boot_loader=None):
1136 if boot_loader is None:
1137 boot_loader = [ loc('boot.arm64'), loc('boot.arm') ]
1138 super(VExpress_GEM5_V1_Base, self).setupBootLoader(
1139 cur_sys, boot_loader)
1140
1141 def _on_chip_devices(self):
1142 return super(VExpress_GEM5_V1_Base,self)._on_chip_devices() + [
1143 self.gic, self.vgic, self.gicv2m,
1144 ]
1145
1146 class VExpress_GEM5_V1(VExpress_GEM5_V1_Base):
1147 hdlcd = HDLcd(pxl_clk=VExpress_GEM5_V1_Base.dcc.osc_pxl,
1148 pio_addr=0x2b000000, int_num=95)
1149
1150 def _on_chip_devices(self):
1151 return super(VExpress_GEM5_V1,self)._on_chip_devices() + [
1152 self.hdlcd,
1153 ]
1154
1155 class VExpress_GEM5_V2_Base(VExpress_GEM5_Base):
1156 gic = Gicv3(dist_addr=0x2c000000, redist_addr=0x2c010000,
1157 maint_int=ArmPPI(num=25),
1158 its=Gicv3Its(pio_addr=0x2e010000))
1159
1160 # Limiting to 128 since it will otherwise overlap with PCI space
1161 gic.cpu_max = 128
1162
1163 def _on_chip_devices(self):
1164 return super(VExpress_GEM5_V2_Base,self)._on_chip_devices() + [
1165 self.gic, self.gic.its
1166 ]
1167
1168 def setupBootLoader(self, cur_sys, loc, boot_loader=None):
1169 if boot_loader is None:
1170 boot_loader = [ loc('boot_v2.arm64') ]
1171 super(VExpress_GEM5_V2_Base, self).setupBootLoader(
1172 cur_sys, boot_loader)
1173
1174 class VExpress_GEM5_V2(VExpress_GEM5_V2_Base):
1175 hdlcd = HDLcd(pxl_clk=VExpress_GEM5_V2_Base.dcc.osc_pxl,
1176 pio_addr=0x2b000000, int_num=95)
1177
1178 def _on_chip_devices(self):
1179 return super(VExpress_GEM5_V2,self)._on_chip_devices() + [
1180 self.hdlcd,
1181 ]