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