1 # Copyright (c) 2009-2012 ARM Limited
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.
13 # Copyright (c) 2006-2007 The Regents of The University of Michigan
14 # All rights reserved.
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.
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.
43 from m5
.params
import *
44 from m5
.proxy
import *
45 from Device
import BasicPioDevice
, PioDevice
, IsaFake
, BadAddr
, DmaDevice
46 from Pci
import PciConfigAll
47 from Ethernet
import NSGigE
, IGbE_e1000
, IGbE_igb
49 from Platform
import Platform
50 from Terminal
import Terminal
52 from SimpleMemory
import SimpleMemory
55 class AmbaDevice(BasicPioDevice
):
58 cxx_header
= "dev/arm/amba_device.hh"
59 amba_id
= Param
.UInt32("ID of AMBA device for kernel detection")
61 class AmbaIntDevice(AmbaDevice
):
62 type = 'AmbaIntDevice'
64 cxx_header
= "dev/arm/amba_device.hh"
65 gic
= Param
.BaseGic(Parent
.any
, "Gic to use for interrupting")
66 int_num
= Param
.UInt32("Interrupt number that connects to GIC")
67 int_delay
= Param
.Latency("100ns",
68 "Time between action and interrupt generation by device")
70 class AmbaDmaDevice(DmaDevice
):
71 type = 'AmbaDmaDevice'
73 cxx_header
= "dev/arm/amba_device.hh"
74 pio_addr
= Param
.Addr("Address for AMBA slave interface")
75 pio_latency
= Param
.Latency("10ns", "Time between action and write/read result by AMBA DMA Device")
76 gic
= Param
.BaseGic(Parent
.any
, "Gic to use for interrupting")
77 int_num
= Param
.UInt32("Interrupt number that connects to GIC")
78 amba_id
= Param
.UInt32("ID of AMBA device for kernel detection")
80 class A9SCU(BasicPioDevice
):
82 cxx_header
= "dev/arm/a9scu.hh"
84 class RealViewCtrl(BasicPioDevice
):
86 cxx_header
= "dev/arm/rv_ctrl.hh"
87 proc_id0
= Param
.UInt32(0x0C000000, "Processor ID, SYS_PROCID")
88 proc_id1
= Param
.UInt32(0x0C000222, "Processor ID, SYS_PROCID1")
89 idreg
= Param
.UInt32(0x00000000, "ID Register, SYS_ID")
91 class AmbaFake(AmbaDevice
):
93 cxx_header
= "dev/arm/amba_fake.hh"
94 ignore_access
= Param
.Bool(False, "Ignore reads/writes to this device, (e.g. IsaFake + AMBA)")
99 cxx_header
= "dev/arm/pl011.hh"
100 gic
= Param
.BaseGic(Parent
.any
, "Gic to use for interrupting")
101 int_num
= Param
.UInt32("Interrupt number that connects to GIC")
102 end_on_eot
= Param
.Bool(False, "End the simulation when a EOT is received on the UART")
103 int_delay
= Param
.Latency("100ns", "Time between action and interrupt generation by UART")
105 class Sp804(AmbaDevice
):
107 cxx_header
= "dev/arm/timer_sp804.hh"
108 gic
= Param
.BaseGic(Parent
.any
, "Gic to use for interrupting")
109 int_num0
= Param
.UInt32("Interrupt number that connects to GIC")
110 clock0
= Param
.Clock('1MHz', "Clock speed of the input")
111 int_num1
= Param
.UInt32("Interrupt number that connects to GIC")
112 clock1
= Param
.Clock('1MHz', "Clock speed of the input")
115 class CpuLocalTimer(BasicPioDevice
):
116 type = 'CpuLocalTimer'
117 cxx_header
= "dev/arm/timer_cpulocal.hh"
118 gic
= Param
.BaseGic(Parent
.any
, "Gic to use for interrupting")
119 int_num_timer
= Param
.UInt32("Interrrupt number used per-cpu to GIC")
120 int_num_watchdog
= Param
.UInt32("Interrupt number for per-cpu watchdog to GIC")
121 # Override the default clock
124 class PL031(AmbaIntDevice
):
126 cxx_header
= "dev/arm/rtc_pl031.hh"
127 time
= Param
.Time('01/01/2009', "System time to use ('Now' for actual time)")
130 class Pl050(AmbaIntDevice
):
132 cxx_header
= "dev/arm/kmi.hh"
133 vnc
= Param
.VncInput(Parent
.any
, "Vnc server for remote frame buffer display")
134 is_mouse
= Param
.Bool(False, "Is this interface a mouse, if not a keyboard")
138 class Pl111(AmbaDmaDevice
):
140 cxx_header
= "dev/arm/pl111.hh"
141 pixel_clock
= Param
.Clock('24MHz', "Pixel clock")
142 vnc
= Param
.VncInput(Parent
.any
, "Vnc server for remote frame buffer display")
145 class RealView(Platform
):
147 cxx_header
= "dev/arm/realview.hh"
148 system
= Param
.System(Parent
.any
, "system")
149 pci_cfg_base
= Param
.Addr(0, "Base address of PCI Configuraiton Space")
150 mem_start_addr
= Param
.Addr(0, "Start address of main memory")
151 max_mem_size
= Param
.Addr('256MB', "Maximum amount of RAM supported by platform")
153 def setupBootLoader(self
, mem_bus
, cur_sys
, loc
):
154 self
.nvmem
= SimpleMemory(range = AddrRange(Addr('2GB'),
157 self
.nvmem
.port
= mem_bus
.master
158 cur_sys
.boot_loader
= loc('boot.arm')
161 # Reference for memory map and interrupt number
162 # RealView Platform Baseboard Explore for Cortex-A9 User Guide(ARM DUI 0440A)
163 # Chapter 4: Programmer's Reference
164 class RealViewPBX(RealView
):
165 uart
= Pl011(pio_addr
=0x10009000, int_num
=44)
166 realview_io
= RealViewCtrl(pio_addr
=0x10000000)
168 timer0
= Sp804(int_num0
=36, int_num1
=36, pio_addr
=0x10011000)
169 timer1
= Sp804(int_num0
=37, int_num1
=37, pio_addr
=0x10012000)
170 local_cpu_timer
= CpuLocalTimer(int_num_timer
=29, int_num_watchdog
=30, pio_addr
=0x1f000600)
171 clcd
= Pl111(pio_addr
=0x10020000, int_num
=55)
172 kmi0
= Pl050(pio_addr
=0x10006000, int_num
=52)
173 kmi1
= Pl050(pio_addr
=0x10007000, int_num
=53, is_mouse
=True)
174 a9scu
= A9SCU(pio_addr
=0x1f000000)
175 cf_ctrl
= IdeController(disks
=[], pci_func
=0, pci_dev
=7, pci_bus
=2,
176 io_shift
= 1, ctrl_offset
= 2, Command
= 0x1,
177 BAR0
= 0x18000000, BAR0Size
= '16B',
178 BAR1
= 0x18000100, BAR1Size
= '1B',
179 BAR0LegacyIO
= True, BAR1LegacyIO
= True)
182 l2x0_fake
= IsaFake(pio_addr
=0x1f002000, pio_size
=0xfff)
183 flash_fake
= IsaFake(pio_addr
=0x40000000, pio_size
=0x20000000,
185 dmac_fake
= AmbaFake(pio_addr
=0x10030000)
186 uart1_fake
= AmbaFake(pio_addr
=0x1000a000)
187 uart2_fake
= AmbaFake(pio_addr
=0x1000b000)
188 uart3_fake
= AmbaFake(pio_addr
=0x1000c000)
189 smc_fake
= AmbaFake(pio_addr
=0x100e1000)
190 sp810_fake
= AmbaFake(pio_addr
=0x10001000, ignore_access
=True)
191 watchdog_fake
= AmbaFake(pio_addr
=0x10010000)
192 gpio0_fake
= AmbaFake(pio_addr
=0x10013000)
193 gpio1_fake
= AmbaFake(pio_addr
=0x10014000)
194 gpio2_fake
= AmbaFake(pio_addr
=0x10015000)
195 ssp_fake
= AmbaFake(pio_addr
=0x1000d000)
196 sci_fake
= AmbaFake(pio_addr
=0x1000e000)
197 aaci_fake
= AmbaFake(pio_addr
=0x10004000)
198 mmc_fake
= AmbaFake(pio_addr
=0x10005000)
199 rtc
= PL031(pio_addr
=0x10017000, int_num
=42)
202 # Attach I/O devices that are on chip and also set the appropriate
203 # ranges for the bridge
204 def attachOnChipIO(self
, bus
, bridge
):
205 self
.gic
.pio
= bus
.master
206 self
.l2x0_fake
.pio
= bus
.master
207 self
.a9scu
.pio
= bus
.master
208 self
.local_cpu_timer
.pio
= bus
.master
209 # Bridge ranges based on excluding what is part of on-chip I/O
210 # (gic, l2x0, a9scu, local_cpu_timer)
211 bridge
.ranges
= [AddrRange(self
.realview_io
.pio_addr
,
212 self
.a9scu
.pio_addr
- 1),
213 AddrRange(self
.flash_fake
.pio_addr
,
214 self
.flash_fake
.pio_addr
+ \
215 self
.flash_fake
.pio_size
- 1)]
217 # Attach I/O devices to specified bus object. Can't do this
218 # earlier, since the bus object itself is typically defined at the
220 def attachIO(self
, bus
):
221 self
.uart
.pio
= bus
.master
222 self
.realview_io
.pio
= bus
.master
223 self
.timer0
.pio
= bus
.master
224 self
.timer1
.pio
= bus
.master
225 self
.clcd
.pio
= bus
.master
226 self
.clcd
.dma
= bus
.slave
227 self
.kmi0
.pio
= bus
.master
228 self
.kmi1
.pio
= bus
.master
229 self
.cf_ctrl
.pio
= bus
.master
230 self
.cf_ctrl
.config
= bus
.master
231 self
.cf_ctrl
.dma
= bus
.slave
232 self
.dmac_fake
.pio
= bus
.master
233 self
.uart1_fake
.pio
= bus
.master
234 self
.uart2_fake
.pio
= bus
.master
235 self
.uart3_fake
.pio
= bus
.master
236 self
.smc_fake
.pio
= bus
.master
237 self
.sp810_fake
.pio
= bus
.master
238 self
.watchdog_fake
.pio
= bus
.master
239 self
.gpio0_fake
.pio
= bus
.master
240 self
.gpio1_fake
.pio
= bus
.master
241 self
.gpio2_fake
.pio
= bus
.master
242 self
.ssp_fake
.pio
= bus
.master
243 self
.sci_fake
.pio
= bus
.master
244 self
.aaci_fake
.pio
= bus
.master
245 self
.mmc_fake
.pio
= bus
.master
246 self
.rtc
.pio
= bus
.master
247 self
.flash_fake
.pio
= bus
.master
249 # Reference for memory map and interrupt number
250 # RealView Emulation Baseboard User Guide (ARM DUI 0143B)
251 # Chapter 4: Programmer's Reference
252 class RealViewEB(RealView
):
253 uart
= Pl011(pio_addr
=0x10009000, int_num
=44)
254 realview_io
= RealViewCtrl(pio_addr
=0x10000000)
255 gic
= Pl390(dist_addr
=0x10041000, cpu_addr
=0x10040000)
256 timer0
= Sp804(int_num0
=36, int_num1
=36, pio_addr
=0x10011000)
257 timer1
= Sp804(int_num0
=37, int_num1
=37, pio_addr
=0x10012000)
258 clcd
= Pl111(pio_addr
=0x10020000, int_num
=23)
259 kmi0
= Pl050(pio_addr
=0x10006000, int_num
=20)
260 kmi1
= Pl050(pio_addr
=0x10007000, int_num
=21, is_mouse
=True)
262 l2x0_fake
= IsaFake(pio_addr
=0x1f002000, pio_size
=0xfff, warn_access
="1")
263 flash_fake
= IsaFake(pio_addr
=0x40000000, pio_size
=0x20000000-1,
265 dmac_fake
= AmbaFake(pio_addr
=0x10030000)
266 uart1_fake
= AmbaFake(pio_addr
=0x1000a000)
267 uart2_fake
= AmbaFake(pio_addr
=0x1000b000)
268 uart3_fake
= AmbaFake(pio_addr
=0x1000c000)
269 smcreg_fake
= IsaFake(pio_addr
=0x10080000, pio_size
=0x10000-1)
270 smc_fake
= AmbaFake(pio_addr
=0x100e1000)
271 sp810_fake
= AmbaFake(pio_addr
=0x10001000, ignore_access
=True)
272 watchdog_fake
= AmbaFake(pio_addr
=0x10010000)
273 gpio0_fake
= AmbaFake(pio_addr
=0x10013000)
274 gpio1_fake
= AmbaFake(pio_addr
=0x10014000)
275 gpio2_fake
= AmbaFake(pio_addr
=0x10015000)
276 ssp_fake
= AmbaFake(pio_addr
=0x1000d000)
277 sci_fake
= AmbaFake(pio_addr
=0x1000e000)
278 aaci_fake
= AmbaFake(pio_addr
=0x10004000)
279 mmc_fake
= AmbaFake(pio_addr
=0x10005000)
280 rtc_fake
= AmbaFake(pio_addr
=0x10017000, amba_id
=0x41031)
284 # Attach I/O devices that are on chip and also set the appropriate
285 # ranges for the bridge
286 def attachOnChipIO(self
, bus
, bridge
):
287 self
.gic
.pio
= bus
.master
288 self
.l2x0_fake
.pio
= bus
.master
289 # Bridge ranges based on excluding what is part of on-chip I/O
291 bridge
.ranges
= [AddrRange(self
.realview_io
.pio_addr
,
292 self
.gic
.cpu_addr
- 1),
293 AddrRange(self
.flash_fake
.pio_addr
, Addr
.max)]
295 # Attach I/O devices to specified bus object. Can't do this
296 # earlier, since the bus object itself is typically defined at the
298 def attachIO(self
, bus
):
299 self
.uart
.pio
= bus
.master
300 self
.realview_io
.pio
= bus
.master
301 self
.timer0
.pio
= bus
.master
302 self
.timer1
.pio
= bus
.master
303 self
.clcd
.pio
= bus
.master
304 self
.clcd
.dma
= bus
.slave
305 self
.kmi0
.pio
= bus
.master
306 self
.kmi1
.pio
= bus
.master
307 self
.dmac_fake
.pio
= bus
.master
308 self
.uart1_fake
.pio
= bus
.master
309 self
.uart2_fake
.pio
= bus
.master
310 self
.uart3_fake
.pio
= bus
.master
311 self
.smc_fake
.pio
= bus
.master
312 self
.sp810_fake
.pio
= bus
.master
313 self
.watchdog_fake
.pio
= bus
.master
314 self
.gpio0_fake
.pio
= bus
.master
315 self
.gpio1_fake
.pio
= bus
.master
316 self
.gpio2_fake
.pio
= bus
.master
317 self
.ssp_fake
.pio
= bus
.master
318 self
.sci_fake
.pio
= bus
.master
319 self
.aaci_fake
.pio
= bus
.master
320 self
.mmc_fake
.pio
= bus
.master
321 self
.rtc_fake
.pio
= bus
.master
322 self
.flash_fake
.pio
= bus
.master
323 self
.smcreg_fake
.pio
= bus
.master
325 class VExpress_EMM(RealView
):
326 mem_start_addr
= '2GB'
328 pci_cfg_base
= 0x30000000
329 uart
= Pl011(pio_addr
=0x1c090000, int_num
=37)
330 realview_io
= RealViewCtrl(proc_id0
=0x14000000, proc_id1
=0x14000000, pio_addr
=0x1C010000)
331 gic
= Pl390(dist_addr
=0x2C001000, cpu_addr
=0x2C002000)
332 local_cpu_timer
= CpuLocalTimer(int_num_timer
=29, int_num_watchdog
=30, pio_addr
=0x2C080000)
333 timer0
= Sp804(int_num0
=34, int_num1
=34, pio_addr
=0x1C110000, clock0
='1MHz', clock1
='1MHz')
334 timer1
= Sp804(int_num0
=35, int_num1
=35, pio_addr
=0x1C120000, clock0
='1MHz', clock1
='1MHz')
335 clcd
= Pl111(pio_addr
=0x1c1f0000, int_num
=46)
336 kmi0
= Pl050(pio_addr
=0x1c060000, int_num
=44)
337 kmi1
= Pl050(pio_addr
=0x1c070000, int_num
=45, is_mouse
=True)
338 cf_ctrl
= IdeController(disks
=[], pci_func
=0, pci_dev
=0, pci_bus
=2,
339 io_shift
= 2, ctrl_offset
= 2, Command
= 0x1,
340 BAR0
= 0x1C1A0000, BAR0Size
= '256B',
341 BAR1
= 0x1C1A0100, BAR1Size
= '4096B',
342 BAR0LegacyIO
= True, BAR1LegacyIO
= True)
344 pciconfig
= PciConfigAll(size
='256MB')
345 ethernet
= IGbE_e1000(pci_bus
=0, pci_dev
=0, pci_func
=0,
346 InterruptLine
=1, InterruptPin
=1)
348 ide
= IdeController(disks
= [], pci_bus
=0, pci_dev
=1, pci_func
=0,
349 InterruptLine
=2, InterruptPin
=2)
352 vram
= SimpleMemory(range = AddrRange(0x18000000, size
='32MB'),
354 rtc
= PL031(pio_addr
=0x1C170000, int_num
=36)
356 l2x0_fake
= IsaFake(pio_addr
=0x2C100000, pio_size
=0xfff)
357 uart1_fake
= AmbaFake(pio_addr
=0x1C0A0000)
358 uart2_fake
= AmbaFake(pio_addr
=0x1C0B0000)
359 uart3_fake
= AmbaFake(pio_addr
=0x1C0C0000)
360 sp810_fake
= AmbaFake(pio_addr
=0x1C020000, ignore_access
=True)
361 watchdog_fake
= AmbaFake(pio_addr
=0x1C0F0000)
362 aaci_fake
= AmbaFake(pio_addr
=0x1C040000)
363 lan_fake
= IsaFake(pio_addr
=0x1A000000, pio_size
=0xffff)
364 usb_fake
= IsaFake(pio_addr
=0x1B000000, pio_size
=0x1ffff)
365 mmc_fake
= AmbaFake(pio_addr
=0x1c050000)
367 def setupBootLoader(self
, mem_bus
, cur_sys
, loc
):
368 self
.nvmem
= SimpleMemory(range = AddrRange(0, size
= '64MB'),
370 self
.nvmem
.port
= mem_bus
.master
371 cur_sys
.boot_loader
= loc('boot_emm.arm')
372 cur_sys
.atags_addr
= 0x80000100
374 # Attach I/O devices that are on chip and also set the appropriate
375 # ranges for the bridge
376 def attachOnChipIO(self
, bus
, bridge
):
377 self
.gic
.pio
= bus
.master
378 self
.local_cpu_timer
.pio
= bus
.master
379 # Bridge ranges based on excluding what is part of on-chip I/O
381 bridge
.ranges
= [AddrRange(0x2F000000, size
='16MB'),
382 AddrRange(0x30000000, size
='256MB'),
383 AddrRange(0x40000000, size
='512MB'),
384 AddrRange(0x18000000, size
='64MB'),
385 AddrRange(0x1C000000, size
='64MB')]
387 # Attach I/O devices to specified bus object. Can't do this
388 # earlier, since the bus object itself is typically defined at the
390 def attachIO(self
, bus
):
391 self
.uart
.pio
= bus
.master
392 self
.realview_io
.pio
= bus
.master
393 self
.timer0
.pio
= bus
.master
394 self
.timer1
.pio
= bus
.master
395 self
.clcd
.pio
= bus
.master
396 self
.clcd
.dma
= bus
.slave
397 self
.kmi0
.pio
= bus
.master
398 self
.kmi1
.pio
= bus
.master
399 self
.cf_ctrl
.pio
= bus
.master
400 self
.cf_ctrl
.dma
= bus
.slave
401 self
.cf_ctrl
.config
= bus
.master
402 self
.rtc
.pio
= bus
.master
403 bus
.use_default_range
= True
404 self
.vram
.port
= bus
.master
405 self
.ide
.pio
= bus
.master
406 self
.ide
.config
= bus
.master
407 self
.ide
.dma
= bus
.slave
408 self
.ethernet
.pio
= bus
.master
409 self
.ethernet
.config
= bus
.master
410 self
.ethernet
.dma
= bus
.slave
411 self
.pciconfig
.pio
= bus
.default
413 self
.l2x0_fake
.pio
= bus
.master
414 self
.uart1_fake
.pio
= bus
.master
415 self
.uart2_fake
.pio
= bus
.master
416 self
.uart3_fake
.pio
= bus
.master
417 self
.sp810_fake
.pio
= bus
.master
418 self
.watchdog_fake
.pio
= bus
.master
419 self
.aaci_fake
.pio
= bus
.master
420 self
.lan_fake
.pio
= bus
.master
421 self
.usb_fake
.pio
= bus
.master
422 self
.mmc_fake
.pio
= bus
.master