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