1# Copyright (c) 2009-2017 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 --- 25 unchanged lines hidden (view full) --- 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 ClockDomain import ClockDomain 49from VoltageDomain import VoltageDomain 50from Device import BasicPioDevice, PioDevice, IsaFake, BadAddr, DmaDevice 51from PciHost import * 52from Ethernet import NSGigE, IGbE_igb, IGbE_e1000 53from Ide import * 54from Platform import Platform 55from Terminal import Terminal 56from Uart import Uart 57from SimpleMemory import SimpleMemory 58from Gic import * 59from EnergyCtrl import EnergyCtrl 60from ClockedObject import ClockedObject 61from ClockDomain import SrcClockDomain 62from SubSystem import SubSystem 63from Graphics import ImageFormat |
64from ClockedObject import ClockedObject |
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. 69try: 70 from KvmGic import MuxingKvmGic 71 kvm_gicv2_class = MuxingKvmGic 72except ImportError: --- 47 unchanged lines hidden (view full) --- 120 121class RealViewCtrl(BasicPioDevice): 122 type = 'RealViewCtrl' 123 cxx_header = "dev/arm/rv_ctrl.hh" 124 proc_id0 = Param.UInt32(0x0C000000, "Processor ID, SYS_PROCID") 125 proc_id1 = Param.UInt32(0x0C000222, "Processor ID, SYS_PROCID1") 126 idreg = Param.UInt32(0x00000000, "ID Register, SYS_ID") 127 |
128 def generateDeviceTree(self, state): 129 node = FdtNode("sysreg@%x" % long(self.pio_addr)) 130 node.appendCompatible("arm,vexpress-sysreg") 131 node.append(FdtPropertyWords("reg", 132 state.addrCells(self.pio_addr) + 133 state.sizeCells(0x1000) )) 134 node.append(FdtProperty("gpio-controller")) 135 node.append(FdtPropertyWords("#gpio-cells", [2])) 136 node.appendPhandle(self) 137 138 yield node 139 |
140class RealViewOsc(ClockDomain): 141 type = 'RealViewOsc' 142 cxx_header = "dev/arm/rv_ctrl.hh" 143 144 parent = Param.RealViewCtrl(Parent.any, "RealView controller") 145 146 # TODO: We currently don't have the notion of a clock source, 147 # which means we have to associate oscillators with a voltage --- 6 unchanged lines hidden (view full) --- 154 # about the site/position/dcc/device allocation. 155 site = Param.UInt8("Board Site") 156 position = Param.UInt8("Position in device stack") 157 dcc = Param.UInt8("Daughterboard Configuration Controller") 158 device = Param.UInt8("Device ID") 159 160 freq = Param.Clock("Default frequency") 161 |
162 def generateDeviceTree(self, state): 163 phandle = state.phandle(self) 164 node = FdtNode("osc@" + format(long(phandle), 'x')) 165 node.appendCompatible("arm,vexpress-osc") 166 node.append(FdtPropertyWords("arm,vexpress-sysreg,func", 167 [0x1, int(self.device)])) 168 node.append(FdtPropertyWords("#clock-cells", [0])) 169 freq = int(1.0/self.freq.value) # Values are stored as a clock period 170 node.append(FdtPropertyWords("freq-range", [freq, freq])) 171 node.append(FdtPropertyStrings("clock-output-names", 172 ["oscclk" + str(phandle)])) 173 node.appendPhandle(self) 174 yield node 175 |
176class RealViewTemperatureSensor(SimObject): 177 type = 'RealViewTemperatureSensor' 178 cxx_header = "dev/arm/rv_ctrl.hh" 179 180 parent = Param.RealViewCtrl(Parent.any, "RealView controller") 181 182 system = Param.System(Parent.any, "system") 183 --- 22 unchanged lines hidden (view full) --- 206 osc_mcc = Osc(device=0, freq="50MHz") 207 osc_clcd = Osc(device=1, freq="23.75MHz") 208 osc_peripheral = Osc(device=2, freq="24MHz") 209 osc_system_bus = Osc(device=4, freq="24MHz") 210 211 # See Table 4.19 in ARM DUI 0447J (Motherboard Express uATX TRM). 212 temp_crtl = Temperature(device=0) 213 |
214 def generateDeviceTree(self, state): 215 node = FdtNode("mcc") 216 node.appendCompatible("arm,vexpress,config-bus") 217 node.append(FdtPropertyWords("arm,vexpress,site", [0])) 218 219 for obj in self._children.values(): 220 if issubclass(type(obj), SimObject): 221 node.append(obj.generateDeviceTree(state)) 222 223 io_phandle = state.phandle(self.osc_mcc.parent.unproxy(self)) 224 node.append(FdtPropertyWords("arm,vexpress,config-bridge", io_phandle)) 225 226 yield node 227 |
228class CoreTile2A15DCC(SubSystem): 229 """ARM CoreTile Express A15x2 Daughterboard Configuration Controller 230 231This subsystem describes a subset of the devices that sit behind the 232daughterboard configuration controller on a CoreTile Express A15x2. See 233ARM DUI 0604E for details. 234 """ 235 236 class Osc(RealViewOsc): 237 site, position, dcc = (1, 0, 0) 238 239 # See Table 2.8 in ARM DUI 0604E (CoreTile Express A15x2 TRM) 240 osc_cpu = Osc(device=0, freq="60MHz") 241 osc_hsbm = Osc(device=4, freq="40MHz") 242 osc_pxl = Osc(device=5, freq="23.75MHz") 243 osc_smb = Osc(device=6, freq="50MHz") 244 osc_sys = Osc(device=7, freq="60MHz") 245 osc_ddr = Osc(device=8, freq="40MHz") 246 |
247 def generateDeviceTree(self, state): 248 node = FdtNode("dcc") 249 node.appendCompatible("arm,vexpress,config-bus") 250 251 for obj in self._children.values(): 252 if isinstance(obj, SimObject): 253 node.append(obj.generateDeviceTree(state)) 254 255 io_phandle = state.phandle(self.osc_cpu.parent.unproxy(self)) 256 node.append(FdtPropertyWords("arm,vexpress,config-bridge", io_phandle)) 257 258 yield node 259 |
260class VGic(PioDevice): 261 type = 'VGic' 262 cxx_header = "dev/arm/vgic.hh" 263 gic = Param.BaseGic(Parent.any, "Gic to use for interrupting") 264 platform = Param.Platform(Parent.any, "Platform this device is part of.") 265 vcpu_addr = Param.Addr(0, "Address for vcpu interfaces") 266 hv_addr = Param.Addr(0, "Address for hv control") 267 pio_delay = Param.Latency('10ns', "Delay for PIO r/w") 268 # The number of list registers is not currently configurable at runtime. 269 ppint = Param.UInt32("HV maintenance interrupt number") 270 |
271 def generateDeviceTree(self, state): 272 gic = self.gic.unproxy(self) 273 274 node = FdtNode("interrupt-controller") 275 node.appendCompatible(["gem5,gic", "arm,cortex-a15-gic", 276 "arm,cortex-a9-gic"]) 277 node.append(FdtPropertyWords("#interrupt-cells", [3])) 278 node.append(FdtPropertyWords("#address-cells", [0])) 279 node.append(FdtProperty("interrupt-controller")) 280 281 regs = ( 282 state.addrCells(gic.dist_addr) + 283 state.sizeCells(0x1000) + 284 state.addrCells(gic.cpu_addr) + 285 state.sizeCells(0x1000) + 286 state.addrCells(self.hv_addr) + 287 state.sizeCells(0x2000) + 288 state.addrCells(self.vcpu_addr) + 289 state.sizeCells(0x2000) ) 290 291 node.append(FdtPropertyWords("reg", regs)) 292 node.append(FdtPropertyWords("interrupts", 293 [1, int(self.ppint)-16, 0xf04])) 294 295 node.appendPhandle(gic) 296 297 yield node 298 |
299class AmbaFake(AmbaPioDevice): 300 type = 'AmbaFake' 301 cxx_header = "dev/arm/amba_fake.hh" 302 ignore_access = Param.Bool(False, "Ignore reads/writes to this device, (e.g. IsaFake + AMBA)") 303 amba_id = 0; 304 305class Pl011(Uart): 306 type = 'Pl011' 307 cxx_header = "dev/arm/pl011.hh" 308 gic = Param.BaseGic(Parent.any, "Gic to use for interrupting") 309 int_num = Param.UInt32("Interrupt number that connects to GIC") 310 end_on_eot = Param.Bool(False, "End the simulation when a EOT is received on the UART") 311 int_delay = Param.Latency("100ns", "Time between action and interrupt generation by UART") 312 |
313 def generateDeviceTree(self, state): 314 node = self.generateBasicPioDeviceNode(state, 'uart', self.pio_addr, 315 0x1000, [int(self.int_num)]) 316 node.appendCompatible(["arm,pl011", "arm,primecell"]) 317 318 # Hardcoded reference to the realview platform clocks, because the 319 # clk_domain can only store one clock (i.e. it is not a VectorParam) 320 realview = self._parent.unproxy(self) 321 node.append(FdtPropertyWords("clocks", 322 [state.phandle(realview.mcc.osc_peripheral), 323 state.phandle(realview.dcc.osc_smb)])) 324 node.append(FdtPropertyStrings("clock-names", ["uartclk", "apb_pclk"])) 325 yield node 326 |
327class Sp804(AmbaPioDevice): 328 type = 'Sp804' 329 cxx_header = "dev/arm/timer_sp804.hh" 330 gic = Param.BaseGic(Parent.any, "Gic to use for interrupting") 331 int_num0 = Param.UInt32("Interrupt number that connects to GIC") 332 clock0 = Param.Clock('1MHz', "Clock speed of the input") 333 int_num1 = Param.UInt32("Interrupt number that connects to GIC") 334 clock1 = Param.Clock('1MHz', "Clock speed of the input") --- 17 unchanged lines hidden (view full) --- 352 cxx_header = "dev/arm/generic_timer.hh" 353 system = Param.ArmSystem(Parent.any, "system") 354 gic = Param.BaseGic(Parent.any, "GIC to use for interrupting") 355 # @todo: for now only two timers per CPU is supported, which is the 356 # normal behaviour when security extensions are disabled. 357 int_phys = Param.UInt32("Physical timer interrupt number") 358 int_virt = Param.UInt32("Virtual timer interrupt number") 359 |
360 def generateDeviceTree(self, state): 361 node = FdtNode("timer") 362 363 node.appendCompatible(["arm,cortex-a15-timer", 364 "arm,armv7-timer", 365 "arm,armv8-timer"]) 366 node.append(FdtPropertyWords("interrupts", 367 [1, int(self.int_phys) - 16, 0xf08, 368 1, int(self.int_virt) - 16, 0xf08])) 369 clock = state.phandle(self.clk_domain.unproxy(self)) 370 node.append(FdtPropertyWords("clocks", clock)) 371 372 yield node 373 |
374class GenericTimerMem(PioDevice): 375 type = 'GenericTimerMem' 376 cxx_header = "dev/arm/generic_timer.hh" 377 gic = Param.BaseGic(Parent.any, "GIC to use for interrupting") 378 379 base = Param.Addr(0, "Base address") 380 381 int_phys = Param.UInt32("Interrupt number") 382 int_virt = Param.UInt32("Interrupt number") 383 384class PL031(AmbaIntDevice): 385 type = 'PL031' 386 cxx_header = "dev/arm/rtc_pl031.hh" 387 time = Param.Time('01/01/2009', "System time to use ('Now' for actual time)") 388 amba_id = 0x00341031 389 |
390 def generateDeviceTree(self, state): 391 node = self.generateBasicPioDeviceNode(state, 'rtc', self.pio_addr, 392 0x1000, [int(self.int_num)]) 393 394 node.appendCompatible(["arm,pl031", "arm,primecell"]) 395 clock = state.phandle(self.clk_domain.unproxy(self)) 396 node.append(FdtPropertyWords("clocks", clock)) 397 398 yield node 399 |
400class Pl050(AmbaIntDevice): 401 type = 'Pl050' 402 cxx_header = "dev/arm/kmi.hh" 403 vnc = Param.VncInput(Parent.any, "Vnc server for remote frame buffer display") 404 is_mouse = Param.Bool(False, "Is this interface a mouse, if not a keyboard") 405 int_delay = '1us' 406 amba_id = 0x00141050 407 |
408 def generateDeviceTree(self, state): 409 node = self.generateBasicPioDeviceNode(state, 'kmi', self.pio_addr, 410 0x1000, [int(self.int_num)]) 411 412 node.appendCompatible(["arm,pl050", "arm,primecell"]) 413 clock = state.phandle(self.clk_domain.unproxy(self)) 414 node.append(FdtPropertyWords("clocks", clock)) 415 416 yield node 417 |
418class Pl111(AmbaDmaDevice): 419 type = 'Pl111' 420 cxx_header = "dev/arm/pl111.hh" 421 pixel_clock = Param.Clock('24MHz', "Pixel clock") 422 vnc = Param.VncInput(Parent.any, "Vnc server for remote frame buffer display") 423 amba_id = 0x00141111 424 enable_capture = Param.Bool(True, "capture frame to system.framebuffer.bmp") 425 --- 14 unchanged lines hidden (view full) --- 440 441 pixel_buffer_size = Param.MemorySize32("2kB", "Size of address range") 442 443 pxl_clk = Param.ClockDomain("Pixel clock source") 444 pixel_chunk = Param.Unsigned(32, "Number of pixels to handle in one batch") 445 virt_refresh_rate = Param.Frequency("20Hz", "Frame refresh rate " 446 "in KVM mode") 447 |
448 def generateDeviceTree(self, state): 449 # Interrupt number is hardcoded; it is not a property of this class 450 node = self.generateBasicPioDeviceNode(state, 'hdlcd', 451 self.pio_addr, 0x1000, [63]) 452 453 node.appendCompatible(["arm,hdlcd"]) 454 node.append(FdtPropertyWords("clocks", state.phandle(self.pxl_clk))) 455 node.append(FdtPropertyStrings("clock-names", ["pxlclk"])) 456 457 # This driver is disabled by default since the required DT nodes 458 # haven't been standardized yet. To use it, override this status to 459 # "ok" and add the display configuration nodes required by the driver. 460 # See the driver for more information. 461 node.append(FdtPropertyStrings("status", ["disabled"])) 462 463 yield node 464 |
465class RealView(Platform): 466 type = 'RealView' 467 cxx_header = "dev/arm/realview.hh" 468 system = Param.System(Parent.any, "system") 469 _mem_regions = [(Addr(0), Addr('256MB'))] 470 471 def _on_chip_devices(self): 472 return [] --- 44 unchanged lines hidden (view full) --- 517 def setupBootLoader(self, mem_bus, cur_sys, loc): 518 self.nvmem = SimpleMemory(range = AddrRange('2GB', size = '64MB'), 519 conf_table_reported = False) 520 self.nvmem.port = mem_bus.master 521 cur_sys.boot_loader = loc('boot.arm') 522 cur_sys.atags_addr = 0x100 523 cur_sys.load_offset = 0 524 |
525 def generateDeviceTree(self, state): 526 node = FdtNode("/") # Things in this module need to end up in the root 527 node.append(FdtPropertyWords("interrupt-parent", 528 state.phandle(self.gic))) |
529 |
530 for device in [getattr(self, c) for c in self._children]: 531 if issubclass(type(device), SimObject): 532 subnode = device.generateDeviceTree(state) 533 node.append(subnode) 534 535 yield node 536 537 def annotateCpuDeviceNode(self, cpu, state): 538 cpu.append(FdtPropertyStrings("enable-method", "spin-table")) 539 cpu.append(FdtPropertyWords("cpu-release-addr", \ 540 state.addrCells(0x8000fff8))) 541 |
542# Reference for memory map and interrupt number 543# RealView Platform Baseboard Explore for Cortex-A9 User Guide(ARM DUI 0440A) 544# Chapter 4: Programmer's Reference 545class RealViewPBX(RealView): 546 uart = Pl011(pio_addr=0x10009000, int_num=44) 547 realview_io = RealViewCtrl(pio_addr=0x10000000) 548 mcc = VExpressMCC() 549 dcc = CoreTile2A15DCC() --- 508 unchanged lines hidden (view full) --- 1058 def _on_chip_devices(self): 1059 return [ 1060 self.gic, self.vgic, self.gicv2m, 1061 self.hdlcd, 1062 self.generic_timer, 1063 ] 1064 1065 ### Off-chip devices ### |
1066 clock24MHz = SrcClockDomain(clock="24MHz", 1067 voltage_domain=VoltageDomain(voltage="3.3V")) 1068 |
1069 uart0 = Pl011(pio_addr=0x1c090000, int_num=37) 1070 1071 kmi0 = Pl050(pio_addr=0x1c060000, int_num=44) 1072 kmi1 = Pl050(pio_addr=0x1c070000, int_num=45, is_mouse=True) 1073 1074 rtc = PL031(pio_addr=0x1c170000, int_num=36) 1075 1076 ### gem5-specific off-chip devices ### --- 4 unchanged lines hidden (view full) --- 1081 1082 energy_ctrl = EnergyCtrl(pio_addr=0x10000000) 1083 1084 1085 def _off_chip_devices(self): 1086 return [ 1087 self.realview_io, 1088 self.uart0, |
1089 self.kmi0, 1090 self.kmi1, |
1091 self.rtc, 1092 self.pci_host, 1093 self.energy_ctrl, |
1094 self.clock24MHz, |
1095 ] 1096 1097 def attachPciDevice(self, device, *args, **kwargs): 1098 device.host = self.pci_host 1099 self._attach_device(device, *args, **kwargs) 1100 1101 def setupBootLoader(self, mem_bus, cur_sys, loc): 1102 self.nvmem = SimpleMemory(range=AddrRange(0, size='64MB'), 1103 conf_table_reported=False) 1104 self.nvmem.port = mem_bus.master 1105 if not cur_sys.boot_loader: 1106 cur_sys.boot_loader = [ loc('boot_emm.arm64'), loc('boot_emm.arm') ] 1107 cur_sys.atags_addr = 0x8000000 1108 cur_sys.load_offset = 0x80000000 1109 1110 # Setup m5ops. It's technically not a part of the boot 1111 # loader, but this is the only place we can configure the 1112 # system. 1113 cur_sys.m5ops_base = 0x10010000 |
1114 1115 def generateDeviceTree(self, state): 1116 # Generate using standard RealView function 1117 dt = list(super(VExpress_GEM5_V1, self).generateDeviceTree(state)) 1118 if len(dt) > 1: 1119 raise Exception("System returned too many DT nodes") 1120 node = dt[0] 1121 1122 node.appendCompatible(["arm,vexpress"]) 1123 node.append(FdtPropertyStrings("model", ["V2P-CA15"])) 1124 node.append(FdtPropertyWords("arm,hbi", [0x0])) 1125 node.append(FdtPropertyWords("arm,vexpress,site", [0xf])) 1126 1127 yield node |