FSConfig.py revision 13774:a1be2a0c55f2
1# Copyright (c) 2010-2012, 2015-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) 2010-2011 Advanced Micro Devices, Inc. 14# Copyright (c) 2006-2008 The Regents of The University of Michigan 15# All rights reserved. 16# 17# Redistribution and use in source and binary forms, with or without 18# modification, are permitted provided that the following conditions are 19# met: redistributions of source code must retain the above copyright 20# notice, this list of conditions and the following disclaimer; 21# redistributions in binary form must reproduce the above copyright 22# notice, this list of conditions and the following disclaimer in the 23# documentation and/or other materials provided with the distribution; 24# neither the name of the copyright holders nor the names of its 25# contributors may be used to endorse or promote products derived from 26# this software without specific prior written permission. 27# 28# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39# 40# Authors: Kevin Lim 41 42from __future__ import print_function 43from __future__ import absolute_import 44 45from m5.objects import * 46from m5.util import * 47from .Benchmarks import * 48from . import PlatformConfig 49 50# Populate to reflect supported os types per target ISA 51os_types = { 'alpha' : [ 'linux' ], 52 'mips' : [ 'linux' ], 53 'sparc' : [ 'linux' ], 54 'x86' : [ 'linux' ], 55 'arm' : [ 'linux', 56 'android-gingerbread', 57 'android-ics', 58 'android-jellybean', 59 'android-kitkat', 60 'android-nougat', ], 61 } 62 63class CowIdeDisk(IdeDisk): 64 image = CowDiskImage(child=RawDiskImage(read_only=True), 65 read_only=False) 66 67 def childImage(self, ci): 68 self.image.child.image_file = ci 69 70class MemBus(SystemXBar): 71 badaddr_responder = BadAddr() 72 default = Self.badaddr_responder.pio 73 74def fillInCmdline(mdesc, template, **kwargs): 75 kwargs.setdefault('disk', mdesc.disk()) 76 kwargs.setdefault('rootdev', mdesc.rootdev()) 77 kwargs.setdefault('mem', mdesc.mem()) 78 kwargs.setdefault('script', mdesc.script()) 79 return template % kwargs 80 81def makeLinuxAlphaSystem(mem_mode, mdesc=None, ruby=False, cmdline=None): 82 83 class BaseTsunami(Tsunami): 84 ethernet = NSGigE(pci_bus=0, pci_dev=1, pci_func=0) 85 ide = IdeController(disks=[Parent.disk0, Parent.disk2], 86 pci_func=0, pci_dev=0, pci_bus=0) 87 88 self = LinuxAlphaSystem() 89 if not mdesc: 90 # generic system 91 mdesc = SysConfig() 92 self.readfile = mdesc.script() 93 94 self.tsunami = BaseTsunami() 95 96 # Create the io bus to connect all device ports 97 self.iobus = IOXBar() 98 self.tsunami.attachIO(self.iobus) 99 100 self.tsunami.ide.pio = self.iobus.master 101 102 self.tsunami.ethernet.pio = self.iobus.master 103 104 if ruby: 105 # Store the dma devices for later connection to dma ruby ports. 106 # Append an underscore to dma_ports to avoid the SimObjectVector check. 107 self._dma_ports = [self.tsunami.ide.dma, self.tsunami.ethernet.dma] 108 else: 109 self.membus = MemBus() 110 111 # By default the bridge responds to all addresses above the I/O 112 # base address (including the PCI config space) 113 IO_address_space_base = 0x80000000000 114 self.bridge = Bridge(delay='50ns', 115 ranges = [AddrRange(IO_address_space_base, Addr.max)]) 116 self.bridge.master = self.iobus.slave 117 self.bridge.slave = self.membus.master 118 119 self.tsunami.ide.dma = self.iobus.slave 120 self.tsunami.ethernet.dma = self.iobus.slave 121 122 self.system_port = self.membus.slave 123 124 self.mem_ranges = [AddrRange(mdesc.mem())] 125 self.disk0 = CowIdeDisk(driveID='master') 126 self.disk2 = CowIdeDisk(driveID='master') 127 self.disk0.childImage(mdesc.disk()) 128 self.disk2.childImage(disk('linux-bigswap2.img')) 129 self.simple_disk = SimpleDisk(disk=RawDiskImage(image_file = mdesc.disk(), 130 read_only = True)) 131 self.intrctrl = IntrControl() 132 self.mem_mode = mem_mode 133 self.terminal = Terminal() 134 self.kernel = binary('vmlinux') 135 self.pal = binary('ts_osfpal') 136 self.console = binary('console') 137 if not cmdline: 138 cmdline = 'root=/dev/hda1 console=ttyS0' 139 self.boot_osflags = fillInCmdline(mdesc, cmdline) 140 141 return self 142 143def makeSparcSystem(mem_mode, mdesc=None, cmdline=None): 144 # Constants from iob.cc and uart8250.cc 145 iob_man_addr = 0x9800000000 146 uart_pio_size = 8 147 148 class CowMmDisk(MmDisk): 149 image = CowDiskImage(child=RawDiskImage(read_only=True), 150 read_only=False) 151 152 def childImage(self, ci): 153 self.image.child.image_file = ci 154 155 self = SparcSystem() 156 if not mdesc: 157 # generic system 158 mdesc = SysConfig() 159 self.readfile = mdesc.script() 160 self.iobus = IOXBar() 161 self.membus = MemBus() 162 self.bridge = Bridge(delay='50ns') 163 self.t1000 = T1000() 164 self.t1000.attachOnChipIO(self.membus) 165 self.t1000.attachIO(self.iobus) 166 self.mem_ranges = [AddrRange(Addr('1MB'), size = '64MB'), 167 AddrRange(Addr('2GB'), size ='256MB')] 168 self.bridge.master = self.iobus.slave 169 self.bridge.slave = self.membus.master 170 self.rom.port = self.membus.master 171 self.nvram.port = self.membus.master 172 self.hypervisor_desc.port = self.membus.master 173 self.partition_desc.port = self.membus.master 174 self.intrctrl = IntrControl() 175 self.disk0 = CowMmDisk() 176 self.disk0.childImage(mdesc.disk()) 177 self.disk0.pio = self.iobus.master 178 179 # The puart0 and hvuart are placed on the IO bus, so create ranges 180 # for them. The remaining IO range is rather fragmented, so poke 181 # holes for the iob and partition descriptors etc. 182 self.bridge.ranges = \ 183 [ 184 AddrRange(self.t1000.puart0.pio_addr, 185 self.t1000.puart0.pio_addr + uart_pio_size - 1), 186 AddrRange(self.disk0.pio_addr, 187 self.t1000.fake_jbi.pio_addr + 188 self.t1000.fake_jbi.pio_size - 1), 189 AddrRange(self.t1000.fake_clk.pio_addr, 190 iob_man_addr - 1), 191 AddrRange(self.t1000.fake_l2_1.pio_addr, 192 self.t1000.fake_ssi.pio_addr + 193 self.t1000.fake_ssi.pio_size - 1), 194 AddrRange(self.t1000.hvuart.pio_addr, 195 self.t1000.hvuart.pio_addr + uart_pio_size - 1) 196 ] 197 self.reset_bin = binary('reset_new.bin') 198 self.hypervisor_bin = binary('q_new.bin') 199 self.openboot_bin = binary('openboot_new.bin') 200 self.nvram_bin = binary('nvram1') 201 self.hypervisor_desc_bin = binary('1up-hv.bin') 202 self.partition_desc_bin = binary('1up-md.bin') 203 204 self.system_port = self.membus.slave 205 206 return self 207 208def makeArmSystem(mem_mode, machine_type, num_cpus=1, mdesc=None, 209 dtb_filename=None, bare_metal=False, cmdline=None, 210 external_memory="", ruby=False, security=False): 211 assert machine_type 212 213 pci_devices = [] 214 215 if bare_metal: 216 self = ArmSystem() 217 else: 218 self = LinuxArmSystem() 219 220 if not mdesc: 221 # generic system 222 mdesc = SysConfig() 223 224 self.readfile = mdesc.script() 225 self.iobus = IOXBar() 226 if not ruby: 227 self.bridge = Bridge(delay='50ns') 228 self.bridge.master = self.iobus.slave 229 self.membus = MemBus() 230 self.membus.badaddr_responder.warn_access = "warn" 231 self.bridge.slave = self.membus.master 232 233 self.mem_mode = mem_mode 234 235 platform_class = PlatformConfig.get(machine_type) 236 # Resolve the real platform name, the original machine_type 237 # variable might have been an alias. 238 machine_type = platform_class.__name__ 239 self.realview = platform_class() 240 241 if isinstance(self.realview, VExpress_EMM64): 242 if os.path.split(mdesc.disk())[-1] == 'linux-aarch32-ael.img': 243 print("Selected 64-bit ARM architecture, updating default " 244 "disk image...") 245 mdesc.diskname = 'linaro-minimal-aarch64.img' 246 247 248 # Attach any PCI devices this platform supports 249 self.realview.attachPciDevices() 250 251 self.cf0 = CowIdeDisk(driveID='master') 252 self.cf0.childImage(mdesc.disk()) 253 # Old platforms have a built-in IDE or CF controller. Default to 254 # the IDE controller if both exist. New platforms expect the 255 # storage controller to be added from the config script. 256 if hasattr(self.realview, "ide"): 257 self.realview.ide.disks = [self.cf0] 258 elif hasattr(self.realview, "cf_ctrl"): 259 self.realview.cf_ctrl.disks = [self.cf0] 260 else: 261 self.pci_ide = IdeController(disks=[self.cf0]) 262 pci_devices.append(self.pci_ide) 263 264 self.mem_ranges = [] 265 size_remain = long(Addr(mdesc.mem())) 266 for region in self.realview._mem_regions: 267 if size_remain > long(region.size()): 268 self.mem_ranges.append(region) 269 size_remain = size_remain - long(region.size()) 270 else: 271 self.mem_ranges.append(AddrRange(region.start, size=size_remain)) 272 size_remain = 0 273 break 274 warn("Memory size specified spans more than one region. Creating" \ 275 " another memory controller for that range.") 276 277 if size_remain > 0: 278 fatal("The currently selected ARM platforms doesn't support" \ 279 " the amount of DRAM you've selected. Please try" \ 280 " another platform") 281 282 self.have_security = security 283 284 if bare_metal: 285 # EOT character on UART will end the simulation 286 self.realview.uart[0].end_on_eot = True 287 else: 288 if dtb_filename: 289 self.dtb_filename = binary(dtb_filename) 290 291 self.machine_type = machine_type if machine_type in ArmMachineType.map \ 292 else "DTOnly" 293 294 # Ensure that writes to the UART actually go out early in the boot 295 if not cmdline: 296 cmdline = 'earlyprintk=pl011,0x1c090000 console=ttyAMA0 ' + \ 297 'lpj=19988480 norandmaps rw loglevel=8 ' + \ 298 'mem=%(mem)s root=%(rootdev)s' 299 300 # When using external memory, gem5 writes the boot loader to nvmem 301 # and then SST will read from it, but SST can only get to nvmem from 302 # iobus, as gem5's membus is only used for initialization and 303 # SST doesn't use it. Attaching nvmem to iobus solves this issue. 304 # During initialization, system_port -> membus -> iobus -> nvmem. 305 if external_memory: 306 self.realview.setupBootLoader(self.iobus, self, binary) 307 elif ruby: 308 self.realview.setupBootLoader(None, self, binary) 309 else: 310 self.realview.setupBootLoader(self.membus, self, binary) 311 312 if hasattr(self.realview.gic, 'cpu_addr'): 313 self.gic_cpu_addr = self.realview.gic.cpu_addr 314 315 self.flags_addr = self.realview.realview_io.pio_addr + 0x30 316 317 # This check is for users who have previously put 'android' in 318 # the disk image filename to tell the config scripts to 319 # prepare the kernel with android-specific boot options. That 320 # behavior has been replaced with a more explicit option per 321 # the error message below. The disk can have any name now and 322 # doesn't need to include 'android' substring. 323 if (os.path.split(mdesc.disk())[-1]).lower().count('android'): 324 if 'android' not in mdesc.os_type(): 325 fatal("It looks like you are trying to boot an Android " \ 326 "platform. To boot Android, you must specify " \ 327 "--os-type with an appropriate Android release on " \ 328 "the command line.") 329 330 # android-specific tweaks 331 if 'android' in mdesc.os_type(): 332 # generic tweaks 333 cmdline += " init=/init" 334 335 # release-specific tweaks 336 if 'kitkat' in mdesc.os_type(): 337 cmdline += " androidboot.hardware=gem5 qemu=1 qemu.gles=0 " + \ 338 "android.bootanim=0 " 339 elif 'nougat' in mdesc.os_type(): 340 cmdline += " androidboot.hardware=gem5 qemu=1 qemu.gles=0 " + \ 341 "android.bootanim=0 " + \ 342 "vmalloc=640MB " + \ 343 "android.early.fstab=/fstab.gem5 " + \ 344 "androidboot.selinux=permissive " + \ 345 "video=Virtual-1:1920x1080-16" 346 347 self.boot_osflags = fillInCmdline(mdesc, cmdline) 348 349 if external_memory: 350 # I/O traffic enters iobus 351 self.external_io = ExternalMaster(port_data="external_io", 352 port_type=external_memory) 353 self.external_io.port = self.iobus.slave 354 355 # Ensure iocache only receives traffic destined for (actual) memory. 356 self.iocache = ExternalSlave(port_data="iocache", 357 port_type=external_memory, 358 addr_ranges=self.mem_ranges) 359 self.iocache.port = self.iobus.master 360 361 # Let system_port get to nvmem and nothing else. 362 self.bridge.ranges = [self.realview.nvmem.range] 363 364 self.realview.attachOnChipIO(self.iobus) 365 # Attach off-chip devices 366 self.realview.attachIO(self.iobus) 367 elif ruby: 368 self._dma_ports = [ ] 369 self.realview.attachOnChipIO(self.iobus, dma_ports=self._dma_ports) 370 self.realview.attachIO(self.iobus, dma_ports=self._dma_ports) 371 else: 372 self.realview.attachOnChipIO(self.membus, self.bridge) 373 # Attach off-chip devices 374 self.realview.attachIO(self.iobus) 375 376 for dev_id, dev in enumerate(pci_devices): 377 dev.pci_bus, dev.pci_dev, dev.pci_func = (0, dev_id + 1, 0) 378 self.realview.attachPciDevice( 379 dev, self.iobus, 380 dma_ports=self._dma_ports if ruby else None) 381 382 self.intrctrl = IntrControl() 383 self.terminal = Terminal() 384 self.vncserver = VncServer() 385 386 if not ruby: 387 self.system_port = self.membus.slave 388 389 if ruby: 390 if buildEnv['PROTOCOL'] == 'MI_example' and num_cpus > 1: 391 fatal("The MI_example protocol cannot implement Load/Store " 392 "Exclusive operations. Multicore ARM systems configured " 393 "with the MI_example protocol will not work properly.") 394 warn("You are trying to use Ruby on ARM, which is not working " 395 "properly yet.") 396 397 return self 398 399 400def makeLinuxMipsSystem(mem_mode, mdesc=None, cmdline=None): 401 class BaseMalta(Malta): 402 ethernet = NSGigE(pci_bus=0, pci_dev=1, pci_func=0) 403 ide = IdeController(disks=[Parent.disk0, Parent.disk2], 404 pci_func=0, pci_dev=0, pci_bus=0) 405 406 self = LinuxMipsSystem() 407 if not mdesc: 408 # generic system 409 mdesc = SysConfig() 410 self.readfile = mdesc.script() 411 self.iobus = IOXBar() 412 self.membus = MemBus() 413 self.bridge = Bridge(delay='50ns') 414 self.mem_ranges = [AddrRange('1GB')] 415 self.bridge.master = self.iobus.slave 416 self.bridge.slave = self.membus.master 417 self.disk0 = CowIdeDisk(driveID='master') 418 self.disk2 = CowIdeDisk(driveID='master') 419 self.disk0.childImage(mdesc.disk()) 420 self.disk2.childImage(disk('linux-bigswap2.img')) 421 self.malta = BaseMalta() 422 self.malta.attachIO(self.iobus) 423 self.malta.ide.pio = self.iobus.master 424 self.malta.ide.dma = self.iobus.slave 425 self.malta.ethernet.pio = self.iobus.master 426 self.malta.ethernet.dma = self.iobus.slave 427 self.simple_disk = SimpleDisk(disk=RawDiskImage(image_file = mdesc.disk(), 428 read_only = True)) 429 self.intrctrl = IntrControl() 430 self.mem_mode = mem_mode 431 self.terminal = Terminal() 432 self.kernel = binary('mips/vmlinux') 433 self.console = binary('mips/console') 434 if not cmdline: 435 cmdline = 'root=/dev/hda1 console=ttyS0' 436 self.boot_osflags = fillInCmdline(mdesc, cmdline) 437 438 self.system_port = self.membus.slave 439 440 return self 441 442def x86IOAddress(port): 443 IO_address_space_base = 0x8000000000000000 444 return IO_address_space_base + port 445 446def connectX86ClassicSystem(x86_sys, numCPUs): 447 # Constants similar to x86_traits.hh 448 IO_address_space_base = 0x8000000000000000 449 pci_config_address_space_base = 0xc000000000000000 450 interrupts_address_space_base = 0xa000000000000000 451 APIC_range_size = 1 << 12; 452 453 x86_sys.membus = MemBus() 454 455 # North Bridge 456 x86_sys.iobus = IOXBar() 457 x86_sys.bridge = Bridge(delay='50ns') 458 x86_sys.bridge.master = x86_sys.iobus.slave 459 x86_sys.bridge.slave = x86_sys.membus.master 460 # Allow the bridge to pass through: 461 # 1) kernel configured PCI device memory map address: address range 462 # [0xC0000000, 0xFFFF0000). (The upper 64kB are reserved for m5ops.) 463 # 2) the bridge to pass through the IO APIC (two pages, already contained in 1), 464 # 3) everything in the IO address range up to the local APIC, and 465 # 4) then the entire PCI address space and beyond. 466 x86_sys.bridge.ranges = \ 467 [ 468 AddrRange(0xC0000000, 0xFFFF0000), 469 AddrRange(IO_address_space_base, 470 interrupts_address_space_base - 1), 471 AddrRange(pci_config_address_space_base, 472 Addr.max) 473 ] 474 475 # Create a bridge from the IO bus to the memory bus to allow access to 476 # the local APIC (two pages) 477 x86_sys.apicbridge = Bridge(delay='50ns') 478 x86_sys.apicbridge.slave = x86_sys.iobus.master 479 x86_sys.apicbridge.master = x86_sys.membus.slave 480 x86_sys.apicbridge.ranges = [AddrRange(interrupts_address_space_base, 481 interrupts_address_space_base + 482 numCPUs * APIC_range_size 483 - 1)] 484 485 # connect the io bus 486 x86_sys.pc.attachIO(x86_sys.iobus) 487 488 x86_sys.system_port = x86_sys.membus.slave 489 490def connectX86RubySystem(x86_sys): 491 # North Bridge 492 x86_sys.iobus = IOXBar() 493 494 # add the ide to the list of dma devices that later need to attach to 495 # dma controllers 496 x86_sys._dma_ports = [x86_sys.pc.south_bridge.ide.dma] 497 x86_sys.pc.attachIO(x86_sys.iobus, x86_sys._dma_ports) 498 499 500def makeX86System(mem_mode, numCPUs=1, mdesc=None, self=None, Ruby=False): 501 if self == None: 502 self = X86System() 503 504 if not mdesc: 505 # generic system 506 mdesc = SysConfig() 507 self.readfile = mdesc.script() 508 509 self.mem_mode = mem_mode 510 511 # Physical memory 512 # On the PC platform, the memory region 0xC0000000-0xFFFFFFFF is reserved 513 # for various devices. Hence, if the physical memory size is greater than 514 # 3GB, we need to split it into two parts. 515 excess_mem_size = \ 516 convert.toMemorySize(mdesc.mem()) - convert.toMemorySize('3GB') 517 if excess_mem_size <= 0: 518 self.mem_ranges = [AddrRange(mdesc.mem())] 519 else: 520 warn("Physical memory size specified is %s which is greater than " \ 521 "3GB. Twice the number of memory controllers would be " \ 522 "created." % (mdesc.mem())) 523 524 self.mem_ranges = [AddrRange('3GB'), 525 AddrRange(Addr('4GB'), size = excess_mem_size)] 526 527 # Platform 528 self.pc = Pc() 529 530 # Create and connect the busses required by each memory system 531 if Ruby: 532 connectX86RubySystem(self) 533 else: 534 connectX86ClassicSystem(self, numCPUs) 535 536 self.intrctrl = IntrControl() 537 538 # Disks 539 disk0 = CowIdeDisk(driveID='master') 540 disk2 = CowIdeDisk(driveID='master') 541 disk0.childImage(mdesc.disk()) 542 disk2.childImage(disk('linux-bigswap2.img')) 543 self.pc.south_bridge.ide.disks = [disk0, disk2] 544 545 # Add in a Bios information structure. 546 structures = [X86SMBiosBiosInformation()] 547 self.smbios_table.structures = structures 548 549 # Set up the Intel MP table 550 base_entries = [] 551 ext_entries = [] 552 for i in range(numCPUs): 553 bp = X86IntelMPProcessor( 554 local_apic_id = i, 555 local_apic_version = 0x14, 556 enable = True, 557 bootstrap = (i == 0)) 558 base_entries.append(bp) 559 io_apic = X86IntelMPIOAPIC( 560 id = numCPUs, 561 version = 0x11, 562 enable = True, 563 address = 0xfec00000) 564 self.pc.south_bridge.io_apic.apic_id = io_apic.id 565 base_entries.append(io_apic) 566 # In gem5 Pc::calcPciConfigAddr(), it required "assert(bus==0)", 567 # but linux kernel cannot config PCI device if it was not connected to PCI bus, 568 # so we fix PCI bus id to 0, and ISA bus id to 1. 569 pci_bus = X86IntelMPBus(bus_id = 0, bus_type='PCI ') 570 base_entries.append(pci_bus) 571 isa_bus = X86IntelMPBus(bus_id = 1, bus_type='ISA ') 572 base_entries.append(isa_bus) 573 connect_busses = X86IntelMPBusHierarchy(bus_id=1, 574 subtractive_decode=True, parent_bus=0) 575 ext_entries.append(connect_busses) 576 pci_dev4_inta = X86IntelMPIOIntAssignment( 577 interrupt_type = 'INT', 578 polarity = 'ConformPolarity', 579 trigger = 'ConformTrigger', 580 source_bus_id = 0, 581 source_bus_irq = 0 + (4 << 2), 582 dest_io_apic_id = io_apic.id, 583 dest_io_apic_intin = 16) 584 base_entries.append(pci_dev4_inta) 585 def assignISAInt(irq, apicPin): 586 assign_8259_to_apic = X86IntelMPIOIntAssignment( 587 interrupt_type = 'ExtInt', 588 polarity = 'ConformPolarity', 589 trigger = 'ConformTrigger', 590 source_bus_id = 1, 591 source_bus_irq = irq, 592 dest_io_apic_id = io_apic.id, 593 dest_io_apic_intin = 0) 594 base_entries.append(assign_8259_to_apic) 595 assign_to_apic = X86IntelMPIOIntAssignment( 596 interrupt_type = 'INT', 597 polarity = 'ConformPolarity', 598 trigger = 'ConformTrigger', 599 source_bus_id = 1, 600 source_bus_irq = irq, 601 dest_io_apic_id = io_apic.id, 602 dest_io_apic_intin = apicPin) 603 base_entries.append(assign_to_apic) 604 assignISAInt(0, 2) 605 assignISAInt(1, 1) 606 for i in range(3, 15): 607 assignISAInt(i, i) 608 self.intel_mp_table.base_entries = base_entries 609 self.intel_mp_table.ext_entries = ext_entries 610 611def makeLinuxX86System(mem_mode, numCPUs=1, mdesc=None, Ruby=False, 612 cmdline=None): 613 self = LinuxX86System() 614 615 # Build up the x86 system and then specialize it for Linux 616 makeX86System(mem_mode, numCPUs, mdesc, self, Ruby) 617 618 # We assume below that there's at least 1MB of memory. We'll require 2 619 # just to avoid corner cases. 620 phys_mem_size = sum(map(lambda r: r.size(), self.mem_ranges)) 621 assert(phys_mem_size >= 0x200000) 622 assert(len(self.mem_ranges) <= 2) 623 624 entries = \ 625 [ 626 # Mark the first megabyte of memory as reserved 627 X86E820Entry(addr = 0, size = '639kB', range_type = 1), 628 X86E820Entry(addr = 0x9fc00, size = '385kB', range_type = 2), 629 # Mark the rest of physical memory as available 630 X86E820Entry(addr = 0x100000, 631 size = '%dB' % (self.mem_ranges[0].size() - 0x100000), 632 range_type = 1), 633 ] 634 635 # Mark [mem_size, 3GB) as reserved if memory less than 3GB, which force 636 # IO devices to be mapped to [0xC0000000, 0xFFFF0000). Requests to this 637 # specific range can pass though bridge to iobus. 638 if len(self.mem_ranges) == 1: 639 entries.append(X86E820Entry(addr = self.mem_ranges[0].size(), 640 size='%dB' % (0xC0000000 - self.mem_ranges[0].size()), 641 range_type=2)) 642 643 # Reserve the last 16kB of the 32-bit address space for the m5op interface 644 entries.append(X86E820Entry(addr=0xFFFF0000, size='64kB', range_type=2)) 645 646 # In case the physical memory is greater than 3GB, we split it into two 647 # parts and add a separate e820 entry for the second part. This entry 648 # starts at 0x100000000, which is the first address after the space 649 # reserved for devices. 650 if len(self.mem_ranges) == 2: 651 entries.append(X86E820Entry(addr = 0x100000000, 652 size = '%dB' % (self.mem_ranges[1].size()), range_type = 1)) 653 654 self.e820_table.entries = entries 655 656 # Command line 657 if not cmdline: 658 cmdline = 'earlyprintk=ttyS0 console=ttyS0 lpj=7999923 root=/dev/hda1' 659 self.boot_osflags = fillInCmdline(mdesc, cmdline) 660 self.kernel = binary('x86_64-vmlinux-2.6.22.9') 661 return self 662 663 664def makeDualRoot(full_system, testSystem, driveSystem, dumpfile): 665 self = Root(full_system = full_system) 666 self.testsys = testSystem 667 self.drivesys = driveSystem 668 self.etherlink = EtherLink() 669 670 if hasattr(testSystem, 'realview'): 671 self.etherlink.int0 = Parent.testsys.realview.ethernet.interface 672 self.etherlink.int1 = Parent.drivesys.realview.ethernet.interface 673 elif hasattr(testSystem, 'tsunami'): 674 self.etherlink.int0 = Parent.testsys.tsunami.ethernet.interface 675 self.etherlink.int1 = Parent.drivesys.tsunami.ethernet.interface 676 else: 677 fatal("Don't know how to connect these system together") 678 679 if dumpfile: 680 self.etherdump = EtherDump(file=dumpfile) 681 self.etherlink.dump = Parent.etherdump 682 683 return self 684 685 686def makeDistRoot(testSystem, 687 rank, 688 size, 689 server_name, 690 server_port, 691 sync_repeat, 692 sync_start, 693 linkspeed, 694 linkdelay, 695 dumpfile): 696 self = Root(full_system = True) 697 self.testsys = testSystem 698 699 self.etherlink = DistEtherLink(speed = linkspeed, 700 delay = linkdelay, 701 dist_rank = rank, 702 dist_size = size, 703 server_name = server_name, 704 server_port = server_port, 705 sync_start = sync_start, 706 sync_repeat = sync_repeat) 707 708 if hasattr(testSystem, 'realview'): 709 self.etherlink.int0 = Parent.testsys.realview.ethernet.interface 710 elif hasattr(testSystem, 'tsunami'): 711 self.etherlink.int0 = Parent.testsys.tsunami.ethernet.interface 712 else: 713 fatal("Don't know how to connect DistEtherLink to this system") 714 715 if dumpfile: 716 self.etherdump = EtherDump(file=dumpfile) 717 self.etherlink.dump = Parent.etherdump 718 719 return self 720