RealView.py revision 13826
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, 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) 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(maint_int=ArmPPI(num=25)) 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 ] 1106