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,
920 self.kmi0, self.kmi1,
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