FSConfig.py revision 10358
15359Sgblack@eecs.umich.edu# Copyright (c) 2010-2012 ARM Limited 25359Sgblack@eecs.umich.edu# All rights reserved. 35359Sgblack@eecs.umich.edu# 45359Sgblack@eecs.umich.edu# The license below extends only to copyright in the software and shall 55359Sgblack@eecs.umich.edu# not be construed as granting a license to any other intellectual 65359Sgblack@eecs.umich.edu# property including but not limited to intellectual property relating 75359Sgblack@eecs.umich.edu# to a hardware implementation of the functionality of the software 85359Sgblack@eecs.umich.edu# licensed hereunder. You may use the software subject to the license 95359Sgblack@eecs.umich.edu# terms below provided that you ensure that this notice is replicated 105359Sgblack@eecs.umich.edu# unmodified and in its entirety in all distributions of the software, 115359Sgblack@eecs.umich.edu# modified or unmodified, in source code or in binary form. 125359Sgblack@eecs.umich.edu# 135359Sgblack@eecs.umich.edu# Copyright (c) 2010-2011 Advanced Micro Devices, Inc. 145359Sgblack@eecs.umich.edu# Copyright (c) 2006-2008 The Regents of The University of Michigan 155359Sgblack@eecs.umich.edu# All rights reserved. 165359Sgblack@eecs.umich.edu# 175359Sgblack@eecs.umich.edu# Redistribution and use in source and binary forms, with or without 185359Sgblack@eecs.umich.edu# modification, are permitted provided that the following conditions are 195359Sgblack@eecs.umich.edu# met: redistributions of source code must retain the above copyright 205359Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer; 215359Sgblack@eecs.umich.edu# redistributions in binary form must reproduce the above copyright 225359Sgblack@eecs.umich.edu# notice, this list of conditions and the following disclaimer in the 235359Sgblack@eecs.umich.edu# documentation and/or other materials provided with the distribution; 245359Sgblack@eecs.umich.edu# neither the name of the copyright holders nor the names of its 255359Sgblack@eecs.umich.edu# contributors may be used to endorse or promote products derived from 265359Sgblack@eecs.umich.edu# this software without specific prior written permission. 275359Sgblack@eecs.umich.edu# 285359Sgblack@eecs.umich.edu# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 295359Sgblack@eecs.umich.edu# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 304561Sgblack@eecs.umich.edu# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 314561Sgblack@eecs.umich.edu# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 324561Sgblack@eecs.umich.edu# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 334561Sgblack@eecs.umich.edu# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 344561Sgblack@eecs.umich.edu# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 354561Sgblack@eecs.umich.edu# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 364561Sgblack@eecs.umich.edu# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 374561Sgblack@eecs.umich.edu# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 384561Sgblack@eecs.umich.edu# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 394561Sgblack@eecs.umich.edu# 404561Sgblack@eecs.umich.edu# Authors: Kevin Lim 414561Sgblack@eecs.umich.edu 424561Sgblack@eecs.umich.edufrom m5.objects import * 434561Sgblack@eecs.umich.edufrom Benchmarks import * 444561Sgblack@eecs.umich.edufrom m5.util import * 454561Sgblack@eecs.umich.edu 464561Sgblack@eecs.umich.educlass CowIdeDisk(IdeDisk): 474561Sgblack@eecs.umich.edu image = CowDiskImage(child=RawDiskImage(read_only=True), 484561Sgblack@eecs.umich.edu read_only=False) 494561Sgblack@eecs.umich.edu 504561Sgblack@eecs.umich.edu def childImage(self, ci): 514561Sgblack@eecs.umich.edu self.image.child.image_file = ci 524561Sgblack@eecs.umich.edu 534561Sgblack@eecs.umich.educlass MemBus(CoherentBus): 544561Sgblack@eecs.umich.edu badaddr_responder = BadAddr() 554561Sgblack@eecs.umich.edu default = Self.badaddr_responder.pio 564561Sgblack@eecs.umich.edu 574561Sgblack@eecs.umich.edu 584561Sgblack@eecs.umich.edudef makeLinuxAlphaSystem(mem_mode, mdesc = None, ruby = False): 594561Sgblack@eecs.umich.edu 604561Sgblack@eecs.umich.edu class BaseTsunami(Tsunami): 614561Sgblack@eecs.umich.edu ethernet = NSGigE(pci_bus=0, pci_dev=1, pci_func=0) 624561Sgblack@eecs.umich.edu ide = IdeController(disks=[Parent.disk0, Parent.disk2], 634561Sgblack@eecs.umich.edu pci_func=0, pci_dev=0, pci_bus=0) 644561Sgblack@eecs.umich.edu 654561Sgblack@eecs.umich.edu self = LinuxAlphaSystem() 664561Sgblack@eecs.umich.edu if not mdesc: 674561Sgblack@eecs.umich.edu # generic system 684561Sgblack@eecs.umich.edu mdesc = SysConfig() 694561Sgblack@eecs.umich.edu self.readfile = mdesc.script() 704561Sgblack@eecs.umich.edu 714561Sgblack@eecs.umich.edu self.tsunami = BaseTsunami() 724561Sgblack@eecs.umich.edu 734561Sgblack@eecs.umich.edu # Create the io bus to connect all device ports 744561Sgblack@eecs.umich.edu self.iobus = NoncoherentBus() 754561Sgblack@eecs.umich.edu self.tsunami.attachIO(self.iobus) 764561Sgblack@eecs.umich.edu 774561Sgblack@eecs.umich.edu self.tsunami.ide.pio = self.iobus.master 784561Sgblack@eecs.umich.edu self.tsunami.ide.config = self.iobus.master 794561Sgblack@eecs.umich.edu 804561Sgblack@eecs.umich.edu self.tsunami.ethernet.pio = self.iobus.master 814561Sgblack@eecs.umich.edu self.tsunami.ethernet.config = self.iobus.master 824561Sgblack@eecs.umich.edu 834561Sgblack@eecs.umich.edu if ruby: 844561Sgblack@eecs.umich.edu # Store the dma devices for later connection to dma ruby ports. 854561Sgblack@eecs.umich.edu # Append an underscore to dma_ports to avoid the SimObjectVector check. 864561Sgblack@eecs.umich.edu self._dma_ports = [self.tsunami.ide.dma, self.tsunami.ethernet.dma] 874561Sgblack@eecs.umich.edu else: 884561Sgblack@eecs.umich.edu self.membus = MemBus() 894561Sgblack@eecs.umich.edu 904601Sgblack@eecs.umich.edu # By default the bridge responds to all addresses above the I/O 914601Sgblack@eecs.umich.edu # base address (including the PCI config space) 924601Sgblack@eecs.umich.edu IO_address_space_base = 0x80000000000 934601Sgblack@eecs.umich.edu self.bridge = Bridge(delay='50ns', 944601Sgblack@eecs.umich.edu ranges = [AddrRange(IO_address_space_base, Addr.max)]) 954601Sgblack@eecs.umich.edu self.bridge.master = self.iobus.slave 964601Sgblack@eecs.umich.edu self.bridge.slave = self.membus.master 974601Sgblack@eecs.umich.edu 984601Sgblack@eecs.umich.edu self.tsunami.ide.dma = self.iobus.slave 994601Sgblack@eecs.umich.edu self.tsunami.ethernet.dma = self.iobus.slave 1004601Sgblack@eecs.umich.edu 1014601Sgblack@eecs.umich.edu self.system_port = self.membus.slave 1024601Sgblack@eecs.umich.edu 1034601Sgblack@eecs.umich.edu self.mem_ranges = [AddrRange(mdesc.mem())] 1044601Sgblack@eecs.umich.edu self.disk0 = CowIdeDisk(driveID='master') 1054601Sgblack@eecs.umich.edu self.disk2 = CowIdeDisk(driveID='master') 1064601Sgblack@eecs.umich.edu self.disk0.childImage(mdesc.disk()) 1074601Sgblack@eecs.umich.edu self.disk2.childImage(disk('linux-bigswap2.img')) 1084601Sgblack@eecs.umich.edu self.simple_disk = SimpleDisk(disk=RawDiskImage(image_file = mdesc.disk(), 1094601Sgblack@eecs.umich.edu read_only = True)) 1104601Sgblack@eecs.umich.edu self.intrctrl = IntrControl() 1114601Sgblack@eecs.umich.edu self.mem_mode = mem_mode 1124601Sgblack@eecs.umich.edu self.terminal = Terminal() 1134601Sgblack@eecs.umich.edu self.kernel = binary('vmlinux') 1144601Sgblack@eecs.umich.edu self.pal = binary('ts_osfpal') 1154601Sgblack@eecs.umich.edu self.console = binary('console') 1164601Sgblack@eecs.umich.edu self.boot_osflags = 'root=/dev/hda1 console=ttyS0' 1174601Sgblack@eecs.umich.edu 1184601Sgblack@eecs.umich.edu return self 1194601Sgblack@eecs.umich.edu 1204601Sgblack@eecs.umich.edudef makeSparcSystem(mem_mode, mdesc = None): 1214601Sgblack@eecs.umich.edu # Constants from iob.cc and uart8250.cc 1224601Sgblack@eecs.umich.edu iob_man_addr = 0x9800000000 1234601Sgblack@eecs.umich.edu uart_pio_size = 8 1244601Sgblack@eecs.umich.edu 1254601Sgblack@eecs.umich.edu class CowMmDisk(MmDisk): 1264601Sgblack@eecs.umich.edu image = CowDiskImage(child=RawDiskImage(read_only=True), 1274601Sgblack@eecs.umich.edu read_only=False) 1284601Sgblack@eecs.umich.edu 1294601Sgblack@eecs.umich.edu def childImage(self, ci): 1304601Sgblack@eecs.umich.edu self.image.child.image_file = ci 1314601Sgblack@eecs.umich.edu 1324601Sgblack@eecs.umich.edu self = SparcSystem() 1334601Sgblack@eecs.umich.edu if not mdesc: 1344601Sgblack@eecs.umich.edu # generic system 1354601Sgblack@eecs.umich.edu mdesc = SysConfig() 1364601Sgblack@eecs.umich.edu self.readfile = mdesc.script() 1374601Sgblack@eecs.umich.edu self.iobus = NoncoherentBus() 1384601Sgblack@eecs.umich.edu self.membus = MemBus() 1394601Sgblack@eecs.umich.edu self.bridge = Bridge(delay='50ns') 1404601Sgblack@eecs.umich.edu self.t1000 = T1000() 1414601Sgblack@eecs.umich.edu self.t1000.attachOnChipIO(self.membus) 1424587Sgblack@eecs.umich.edu self.t1000.attachIO(self.iobus) 1434587Sgblack@eecs.umich.edu self.mem_ranges = [AddrRange(Addr('1MB'), size = '64MB'), 1444587Sgblack@eecs.umich.edu AddrRange(Addr('2GB'), size ='256MB')] 1454587Sgblack@eecs.umich.edu self.bridge.master = self.iobus.slave 1464587Sgblack@eecs.umich.edu self.bridge.slave = self.membus.master 1474587Sgblack@eecs.umich.edu self.rom.port = self.membus.master 1484587Sgblack@eecs.umich.edu self.nvram.port = self.membus.master 1494587Sgblack@eecs.umich.edu self.hypervisor_desc.port = self.membus.master 1504587Sgblack@eecs.umich.edu self.partition_desc.port = self.membus.master 1514587Sgblack@eecs.umich.edu self.intrctrl = IntrControl() 1524587Sgblack@eecs.umich.edu self.disk0 = CowMmDisk() 1534587Sgblack@eecs.umich.edu self.disk0.childImage(disk('disk.s10hw2')) 1545232Sgblack@eecs.umich.edu self.disk0.pio = self.iobus.master 1554720Sgblack@eecs.umich.edu 1564587Sgblack@eecs.umich.edu # The puart0 and hvuart are placed on the IO bus, so create ranges 1574587Sgblack@eecs.umich.edu # for them. The remaining IO range is rather fragmented, so poke 1584587Sgblack@eecs.umich.edu # holes for the iob and partition descriptors etc. 1594587Sgblack@eecs.umich.edu self.bridge.ranges = \ 1604587Sgblack@eecs.umich.edu [ 1614587Sgblack@eecs.umich.edu AddrRange(self.t1000.puart0.pio_addr, 1624587Sgblack@eecs.umich.edu self.t1000.puart0.pio_addr + uart_pio_size - 1), 1634587Sgblack@eecs.umich.edu AddrRange(self.disk0.pio_addr, 1644587Sgblack@eecs.umich.edu self.t1000.fake_jbi.pio_addr + 1654587Sgblack@eecs.umich.edu self.t1000.fake_jbi.pio_size - 1), 1664587Sgblack@eecs.umich.edu AddrRange(self.t1000.fake_clk.pio_addr, 1674587Sgblack@eecs.umich.edu iob_man_addr - 1), 1684587Sgblack@eecs.umich.edu AddrRange(self.t1000.fake_l2_1.pio_addr, 1694587Sgblack@eecs.umich.edu self.t1000.fake_ssi.pio_addr + 1704587Sgblack@eecs.umich.edu self.t1000.fake_ssi.pio_size - 1), 1714587Sgblack@eecs.umich.edu AddrRange(self.t1000.hvuart.pio_addr, 1724587Sgblack@eecs.umich.edu self.t1000.hvuart.pio_addr + uart_pio_size - 1) 1734587Sgblack@eecs.umich.edu ] 1744587Sgblack@eecs.umich.edu self.reset_bin = binary('reset_new.bin') 1754587Sgblack@eecs.umich.edu self.hypervisor_bin = binary('q_new.bin') 1764587Sgblack@eecs.umich.edu self.openboot_bin = binary('openboot_new.bin') 1774587Sgblack@eecs.umich.edu self.nvram_bin = binary('nvram1') 1784587Sgblack@eecs.umich.edu self.hypervisor_desc_bin = binary('1up-hv.bin') 1794587Sgblack@eecs.umich.edu self.partition_desc_bin = binary('1up-md.bin') 1804587Sgblack@eecs.umich.edu 1815232Sgblack@eecs.umich.edu self.system_port = self.membus.slave 1824587Sgblack@eecs.umich.edu 1834587Sgblack@eecs.umich.edu return self 1844587Sgblack@eecs.umich.edu 1854587Sgblack@eecs.umich.edudef makeArmSystem(mem_mode, machine_type, mdesc = None, 1864587Sgblack@eecs.umich.edu dtb_filename = None, bare_metal=False): 1874587Sgblack@eecs.umich.edu assert machine_type 1884587Sgblack@eecs.umich.edu 1894587Sgblack@eecs.umich.edu if bare_metal: 1904587Sgblack@eecs.umich.edu self = ArmSystem() 1914587Sgblack@eecs.umich.edu else: 1924587Sgblack@eecs.umich.edu self = LinuxArmSystem() 1934587Sgblack@eecs.umich.edu 1944587Sgblack@eecs.umich.edu if not mdesc: 1954587Sgblack@eecs.umich.edu # generic system 1964587Sgblack@eecs.umich.edu mdesc = SysConfig() 1975727Sgblack@eecs.umich.edu 1985002Sgblack@eecs.umich.edu self.readfile = mdesc.script() 1994587Sgblack@eecs.umich.edu self.iobus = NoncoherentBus() 2004587Sgblack@eecs.umich.edu self.membus = MemBus() 2014587Sgblack@eecs.umich.edu self.membus.badaddr_responder.warn_access = "warn" 2024587Sgblack@eecs.umich.edu self.bridge = Bridge(delay='50ns') 2034587Sgblack@eecs.umich.edu self.bridge.master = self.iobus.slave 2044587Sgblack@eecs.umich.edu self.bridge.slave = self.membus.master 2054587Sgblack@eecs.umich.edu 2064587Sgblack@eecs.umich.edu self.mem_mode = mem_mode 2074587Sgblack@eecs.umich.edu 2084587Sgblack@eecs.umich.edu if machine_type == "RealView_PBX": 2094587Sgblack@eecs.umich.edu self.realview = RealViewPBX() 2104587Sgblack@eecs.umich.edu elif machine_type == "RealView_EB": 2114587Sgblack@eecs.umich.edu self.realview = RealViewEB() 2124587Sgblack@eecs.umich.edu elif machine_type == "VExpress_ELT": 2134587Sgblack@eecs.umich.edu self.realview = VExpress_ELT() 2144587Sgblack@eecs.umich.edu elif machine_type == "VExpress_EMM": 2154587Sgblack@eecs.umich.edu self.realview = VExpress_EMM() 2164587Sgblack@eecs.umich.edu elif machine_type == "VExpress_EMM64": 2174587Sgblack@eecs.umich.edu self.realview = VExpress_EMM64() 2184587Sgblack@eecs.umich.edu else: 2194587Sgblack@eecs.umich.edu print "Unknown Machine Type" 2204587Sgblack@eecs.umich.edu sys.exit(1) 2214587Sgblack@eecs.umich.edu 2224587Sgblack@eecs.umich.edu self.cf0 = CowIdeDisk(driveID='master') 2234587Sgblack@eecs.umich.edu self.cf0.childImage(mdesc.disk()) 2244587Sgblack@eecs.umich.edu 2254587Sgblack@eecs.umich.edu # Attach any PCI devices this platform supports 2264587Sgblack@eecs.umich.edu self.realview.attachPciDevices() 2274587Sgblack@eecs.umich.edu # default to an IDE controller rather than a CF one 2285232Sgblack@eecs.umich.edu try: 2294767Sgblack@eecs.umich.edu self.realview.ide.disks = [self.cf0] 2304720Sgblack@eecs.umich.edu except: 2314767Sgblack@eecs.umich.edu self.realview.cf_ctrl.disks = [self.cf0] 2324720Sgblack@eecs.umich.edu 2334587Sgblack@eecs.umich.edu if bare_metal: 2344587Sgblack@eecs.umich.edu # EOT character on UART will end the simulation 2354587Sgblack@eecs.umich.edu self.realview.uart.end_on_eot = True 2364587Sgblack@eecs.umich.edu self.mem_ranges = [AddrRange(self.realview.mem_start_addr, 2374587Sgblack@eecs.umich.edu size = mdesc.mem())] 2384587Sgblack@eecs.umich.edu else: 2394587Sgblack@eecs.umich.edu if machine_type == "VExpress_EMM64": 2404587Sgblack@eecs.umich.edu self.kernel = binary('vmlinux-3.16-aarch64-vexpress-emm64-pcie') 2414587Sgblack@eecs.umich.edu elif machine_type == "VExpress_EMM": 2424587Sgblack@eecs.umich.edu self.kernel = binary('vmlinux-3.3-arm-vexpress-emm-pcie') 2434587Sgblack@eecs.umich.edu else: 2444587Sgblack@eecs.umich.edu self.kernel = binary('vmlinux.arm.smp.fb.2.6.38.8') 2454587Sgblack@eecs.umich.edu 2464587Sgblack@eecs.umich.edu if dtb_filename: 2474587Sgblack@eecs.umich.edu self.dtb_filename = binary(dtb_filename) 2484587Sgblack@eecs.umich.edu self.machine_type = machine_type 2494587Sgblack@eecs.umich.edu # Ensure that writes to the UART actually go out early in the boot 2504587Sgblack@eecs.umich.edu boot_flags = 'earlyprintk=pl011,0x1c090000 console=ttyAMA0 ' + \ 2514587Sgblack@eecs.umich.edu 'lpj=19988480 norandmaps rw loglevel=8 ' + \ 2524587Sgblack@eecs.umich.edu 'mem=%s root=/dev/sda1' % mdesc.mem() 2534587Sgblack@eecs.umich.edu 2544587Sgblack@eecs.umich.edu self.mem_ranges = [] 2555232Sgblack@eecs.umich.edu size_remain = long(Addr(mdesc.mem())) 2564767Sgblack@eecs.umich.edu for region in self.realview._mem_regions: 2574720Sgblack@eecs.umich.edu if size_remain > long(region[1]): 2584767Sgblack@eecs.umich.edu self.mem_ranges.append(AddrRange(region[0], size=region[1])) 2594720Sgblack@eecs.umich.edu size_remain = size_remain - long(region[1]) 2604587Sgblack@eecs.umich.edu else: 2614587Sgblack@eecs.umich.edu self.mem_ranges.append(AddrRange(region[0], size=size_remain)) 2624587Sgblack@eecs.umich.edu size_remain = 0 2634587Sgblack@eecs.umich.edu break 2644587Sgblack@eecs.umich.edu warn("Memory size specified spans more than one region. Creating" \ 2654587Sgblack@eecs.umich.edu " another memory controller for that range.") 2664587Sgblack@eecs.umich.edu 2674587Sgblack@eecs.umich.edu if size_remain > 0: 2684587Sgblack@eecs.umich.edu fatal("The currently selected ARM platforms doesn't support" \ 2694587Sgblack@eecs.umich.edu " the amount of DRAM you've selected. Please try" \ 2704587Sgblack@eecs.umich.edu " another platform") 2714587Sgblack@eecs.umich.edu 2724587Sgblack@eecs.umich.edu 2734587Sgblack@eecs.umich.edu self.realview.setupBootLoader(self.membus, self, binary) 2744587Sgblack@eecs.umich.edu self.gic_cpu_addr = self.realview.gic.cpu_addr 2754587Sgblack@eecs.umich.edu self.flags_addr = self.realview.realview_io.pio_addr + 0x30 2764587Sgblack@eecs.umich.edu 2774587Sgblack@eecs.umich.edu if mdesc.disk().lower().count('android'): 2784587Sgblack@eecs.umich.edu boot_flags += " init=/init " 2794587Sgblack@eecs.umich.edu self.boot_osflags = boot_flags 2804587Sgblack@eecs.umich.edu self.realview.attachOnChipIO(self.membus, self.bridge) 2814587Sgblack@eecs.umich.edu self.realview.attachIO(self.iobus) 2824587Sgblack@eecs.umich.edu self.intrctrl = IntrControl() 2834587Sgblack@eecs.umich.edu self.terminal = Terminal() 2844587Sgblack@eecs.umich.edu self.vncserver = VncServer() 2854587Sgblack@eecs.umich.edu 2864587Sgblack@eecs.umich.edu self.system_port = self.membus.slave 2874587Sgblack@eecs.umich.edu 2884587Sgblack@eecs.umich.edu return self 2894561Sgblack@eecs.umich.edu 2904561Sgblack@eecs.umich.edu 2914561Sgblack@eecs.umich.edudef makeLinuxMipsSystem(mem_mode, mdesc = None): 2924561Sgblack@eecs.umich.edu class BaseMalta(Malta): 2934561Sgblack@eecs.umich.edu ethernet = NSGigE(pci_bus=0, pci_dev=1, pci_func=0) 2944561Sgblack@eecs.umich.edu ide = IdeController(disks=[Parent.disk0, Parent.disk2], 2954561Sgblack@eecs.umich.edu pci_func=0, pci_dev=0, pci_bus=0) 2964561Sgblack@eecs.umich.edu 2974561Sgblack@eecs.umich.edu self = LinuxMipsSystem() 2984561Sgblack@eecs.umich.edu if not mdesc: 2994561Sgblack@eecs.umich.edu # generic system 3004561Sgblack@eecs.umich.edu mdesc = SysConfig() 3014561Sgblack@eecs.umich.edu self.readfile = mdesc.script() 3024561Sgblack@eecs.umich.edu self.iobus = NoncoherentBus() 3034561Sgblack@eecs.umich.edu self.membus = MemBus() 3044561Sgblack@eecs.umich.edu self.bridge = Bridge(delay='50ns') 3054561Sgblack@eecs.umich.edu self.mem_ranges = [AddrRange('1GB')] 3064561Sgblack@eecs.umich.edu self.bridge.master = self.iobus.slave 3074561Sgblack@eecs.umich.edu self.bridge.slave = self.membus.master 3084587Sgblack@eecs.umich.edu self.disk0 = CowIdeDisk(driveID='master') 3094587Sgblack@eecs.umich.edu self.disk2 = CowIdeDisk(driveID='master') 3104587Sgblack@eecs.umich.edu self.disk0.childImage(mdesc.disk()) 3114587Sgblack@eecs.umich.edu self.disk2.childImage(disk('linux-bigswap2.img')) 3124561Sgblack@eecs.umich.edu self.malta = BaseMalta() 3134561Sgblack@eecs.umich.edu self.malta.attachIO(self.iobus) 3144561Sgblack@eecs.umich.edu self.malta.ide.pio = self.iobus.master 3154561Sgblack@eecs.umich.edu self.malta.ide.config = self.iobus.master 3164561Sgblack@eecs.umich.edu self.malta.ide.dma = self.iobus.slave 3174561Sgblack@eecs.umich.edu self.malta.ethernet.pio = self.iobus.master 3184561Sgblack@eecs.umich.edu self.malta.ethernet.config = self.iobus.master 3194561Sgblack@eecs.umich.edu self.malta.ethernet.dma = self.iobus.slave 3204561Sgblack@eecs.umich.edu self.simple_disk = SimpleDisk(disk=RawDiskImage(image_file = mdesc.disk(), 3214561Sgblack@eecs.umich.edu read_only = True)) 3224561Sgblack@eecs.umich.edu self.intrctrl = IntrControl() 3234561Sgblack@eecs.umich.edu self.mem_mode = mem_mode 3244561Sgblack@eecs.umich.edu self.terminal = Terminal() 3254561Sgblack@eecs.umich.edu self.kernel = binary('mips/vmlinux') 3264561Sgblack@eecs.umich.edu self.console = binary('mips/console') 3274561Sgblack@eecs.umich.edu self.boot_osflags = 'root=/dev/hda1 console=ttyS0' 3284561Sgblack@eecs.umich.edu 3294587Sgblack@eecs.umich.edu self.system_port = self.membus.slave 3304587Sgblack@eecs.umich.edu 3314587Sgblack@eecs.umich.edu return self 3324587Sgblack@eecs.umich.edu 3334561Sgblack@eecs.umich.edudef x86IOAddress(port): 3344561Sgblack@eecs.umich.edu IO_address_space_base = 0x8000000000000000 3354561Sgblack@eecs.umich.edu return IO_address_space_base + port 3364561Sgblack@eecs.umich.edu 3374561Sgblack@eecs.umich.edudef connectX86ClassicSystem(x86_sys, numCPUs): 3384561Sgblack@eecs.umich.edu # Constants similar to x86_traits.hh 3394561Sgblack@eecs.umich.edu IO_address_space_base = 0x8000000000000000 3404561Sgblack@eecs.umich.edu pci_config_address_space_base = 0xc000000000000000 3414587Sgblack@eecs.umich.edu interrupts_address_space_base = 0xa000000000000000 3424587Sgblack@eecs.umich.edu APIC_range_size = 1 << 12; 3434587Sgblack@eecs.umich.edu 3444561Sgblack@eecs.umich.edu x86_sys.membus = MemBus() 3454587Sgblack@eecs.umich.edu 3464587Sgblack@eecs.umich.edu # North Bridge 3474587Sgblack@eecs.umich.edu x86_sys.iobus = NoncoherentBus() 3484587Sgblack@eecs.umich.edu x86_sys.bridge = Bridge(delay='50ns') 3494561Sgblack@eecs.umich.edu x86_sys.bridge.master = x86_sys.iobus.slave 3504561Sgblack@eecs.umich.edu x86_sys.bridge.slave = x86_sys.membus.master 3514561Sgblack@eecs.umich.edu # Allow the bridge to pass through the IO APIC (two pages), 3524561Sgblack@eecs.umich.edu # everything in the IO address range up to the local APIC, and 3534561Sgblack@eecs.umich.edu # then the entire PCI address space and beyond 3544587Sgblack@eecs.umich.edu x86_sys.bridge.ranges = \ 3554587Sgblack@eecs.umich.edu [ 3565149Sgblack@eecs.umich.edu AddrRange(x86_sys.pc.south_bridge.io_apic.pio_addr, 3574587Sgblack@eecs.umich.edu x86_sys.pc.south_bridge.io_apic.pio_addr + 3584587Sgblack@eecs.umich.edu APIC_range_size - 1), 3594587Sgblack@eecs.umich.edu AddrRange(IO_address_space_base, 3604587Sgblack@eecs.umich.edu interrupts_address_space_base - 1), 3614712Sgblack@eecs.umich.edu AddrRange(pci_config_address_space_base, 3625149Sgblack@eecs.umich.edu Addr.max) 3634587Sgblack@eecs.umich.edu ] 3644587Sgblack@eecs.umich.edu 3655788Sgblack@eecs.umich.edu # Create a bridge from the IO bus to the memory bus to allow access to 3664587Sgblack@eecs.umich.edu # the local APIC (two pages) 3674587Sgblack@eecs.umich.edu x86_sys.apicbridge = Bridge(delay='50ns') 3684587Sgblack@eecs.umich.edu x86_sys.apicbridge.slave = x86_sys.iobus.master 3694587Sgblack@eecs.umich.edu x86_sys.apicbridge.master = x86_sys.membus.slave 3704587Sgblack@eecs.umich.edu x86_sys.apicbridge.ranges = [AddrRange(interrupts_address_space_base, 3714587Sgblack@eecs.umich.edu interrupts_address_space_base + 3724587Sgblack@eecs.umich.edu numCPUs * APIC_range_size 3734587Sgblack@eecs.umich.edu - 1)] 3744587Sgblack@eecs.umich.edu 3754587Sgblack@eecs.umich.edu # connect the io bus 3764587Sgblack@eecs.umich.edu x86_sys.pc.attachIO(x86_sys.iobus) 3774587Sgblack@eecs.umich.edu 3784587Sgblack@eecs.umich.edu x86_sys.system_port = x86_sys.membus.slave 3794587Sgblack@eecs.umich.edu 3804587Sgblack@eecs.umich.edudef connectX86RubySystem(x86_sys): 3814587Sgblack@eecs.umich.edu # North Bridge 3824587Sgblack@eecs.umich.edu x86_sys.iobus = NoncoherentBus() 3834587Sgblack@eecs.umich.edu 3844587Sgblack@eecs.umich.edu # add the ide to the list of dma devices that later need to attach to 3854587Sgblack@eecs.umich.edu # dma controllers 3864587Sgblack@eecs.umich.edu x86_sys._dma_ports = [x86_sys.pc.south_bridge.ide.dma] 3874863Sgblack@eecs.umich.edu x86_sys.pc.attachIO(x86_sys.iobus, x86_sys._dma_ports) 3884587Sgblack@eecs.umich.edu 3895118Sgblack@eecs.umich.edu 3904587Sgblack@eecs.umich.edudef makeX86System(mem_mode, numCPUs = 1, mdesc = None, self = None, 3914587Sgblack@eecs.umich.edu Ruby = False): 3924587Sgblack@eecs.umich.edu if self == None: 3934587Sgblack@eecs.umich.edu self = X86System() 3944587Sgblack@eecs.umich.edu 3954587Sgblack@eecs.umich.edu if not mdesc: 3964587Sgblack@eecs.umich.edu # generic system 3974587Sgblack@eecs.umich.edu mdesc = SysConfig() 3984679Sgblack@eecs.umich.edu self.readfile = mdesc.script() 3995118Sgblack@eecs.umich.edu 4005118Sgblack@eecs.umich.edu self.mem_mode = mem_mode 4015118Sgblack@eecs.umich.edu 4024587Sgblack@eecs.umich.edu # Physical memory 4034587Sgblack@eecs.umich.edu # On the PC platform, the memory region 0xC0000000-0xFFFFFFFF is reserved 4044587Sgblack@eecs.umich.edu # for various devices. Hence, if the physical memory size is greater than 4054587Sgblack@eecs.umich.edu # 3GB, we need to split it into two parts. 4064587Sgblack@eecs.umich.edu excess_mem_size = \ 4074587Sgblack@eecs.umich.edu convert.toMemorySize(mdesc.mem()) - convert.toMemorySize('3GB') 4084587Sgblack@eecs.umich.edu if excess_mem_size <= 0: 4095149Sgblack@eecs.umich.edu self.mem_ranges = [AddrRange(mdesc.mem())] 4105149Sgblack@eecs.umich.edu else: 4114712Sgblack@eecs.umich.edu warn("Physical memory size specified is %s which is greater than " \ 4125149Sgblack@eecs.umich.edu "3GB. Twice the number of memory controllers would be " \ 4134587Sgblack@eecs.umich.edu "created." % (mdesc.mem())) 4144587Sgblack@eecs.umich.edu 4154587Sgblack@eecs.umich.edu self.mem_ranges = [AddrRange('3GB'), 4164587Sgblack@eecs.umich.edu AddrRange(Addr('4GB'), size = excess_mem_size)] 4174587Sgblack@eecs.umich.edu 4184587Sgblack@eecs.umich.edu # Platform 4195118Sgblack@eecs.umich.edu self.pc = Pc() 4205027Sgblack@eecs.umich.edu 4214587Sgblack@eecs.umich.edu # Create and connect the busses required by each memory system 4225118Sgblack@eecs.umich.edu if Ruby: 4234587Sgblack@eecs.umich.edu connectX86RubySystem(self) 4244587Sgblack@eecs.umich.edu else: 4254587Sgblack@eecs.umich.edu connectX86ClassicSystem(self, numCPUs) 4264587Sgblack@eecs.umich.edu 4274587Sgblack@eecs.umich.edu self.intrctrl = IntrControl() 4284587Sgblack@eecs.umich.edu 4294587Sgblack@eecs.umich.edu # Disks 4304587Sgblack@eecs.umich.edu disk0 = CowIdeDisk(driveID='master') 4314679Sgblack@eecs.umich.edu disk2 = CowIdeDisk(driveID='master') 4325118Sgblack@eecs.umich.edu disk0.childImage(mdesc.disk()) 4335118Sgblack@eecs.umich.edu disk2.childImage(disk('linux-bigswap2.img')) 4345118Sgblack@eecs.umich.edu self.pc.south_bridge.ide.disks = [disk0, disk2] 4354587Sgblack@eecs.umich.edu 4364587Sgblack@eecs.umich.edu # Add in a Bios information structure. 4374587Sgblack@eecs.umich.edu structures = [X86SMBiosBiosInformation()] 4384587Sgblack@eecs.umich.edu self.smbios_table.structures = structures 4394587Sgblack@eecs.umich.edu 4404587Sgblack@eecs.umich.edu # Set up the Intel MP table 4414587Sgblack@eecs.umich.edu base_entries = [] 4425149Sgblack@eecs.umich.edu ext_entries = [] 4435149Sgblack@eecs.umich.edu for i in xrange(numCPUs): 4444712Sgblack@eecs.umich.edu bp = X86IntelMPProcessor( 4455149Sgblack@eecs.umich.edu local_apic_id = i, 4464587Sgblack@eecs.umich.edu local_apic_version = 0x14, 4474587Sgblack@eecs.umich.edu enable = True, 4484587Sgblack@eecs.umich.edu bootstrap = (i == 0)) 4494587Sgblack@eecs.umich.edu base_entries.append(bp) 4504587Sgblack@eecs.umich.edu io_apic = X86IntelMPIOAPIC( 4514706Sgblack@eecs.umich.edu id = numCPUs, 4525027Sgblack@eecs.umich.edu version = 0x11, 4535175Sgblack@eecs.umich.edu enable = True, 4545175Sgblack@eecs.umich.edu address = 0xfec00000) 4555175Sgblack@eecs.umich.edu self.pc.south_bridge.io_apic.apic_id = io_apic.id 4565175Sgblack@eecs.umich.edu base_entries.append(io_apic) 4575175Sgblack@eecs.umich.edu isa_bus = X86IntelMPBus(bus_id = 0, bus_type='ISA') 4584601Sgblack@eecs.umich.edu base_entries.append(isa_bus) 4594679Sgblack@eecs.umich.edu pci_bus = X86IntelMPBus(bus_id = 1, bus_type='PCI') 4605118Sgblack@eecs.umich.edu base_entries.append(pci_bus) 4615118Sgblack@eecs.umich.edu connect_busses = X86IntelMPBusHierarchy(bus_id=0, 4625118Sgblack@eecs.umich.edu subtractive_decode=True, parent_bus=1) 4634601Sgblack@eecs.umich.edu ext_entries.append(connect_busses) 4644601Sgblack@eecs.umich.edu pci_dev4_inta = X86IntelMPIOIntAssignment( 4654601Sgblack@eecs.umich.edu interrupt_type = 'INT', 4664601Sgblack@eecs.umich.edu polarity = 'ConformPolarity', 4674601Sgblack@eecs.umich.edu trigger = 'ConformTrigger', 4685149Sgblack@eecs.umich.edu source_bus_id = 1, 4695149Sgblack@eecs.umich.edu source_bus_irq = 0 + (4 << 2), 4704712Sgblack@eecs.umich.edu dest_io_apic_id = io_apic.id, 4715149Sgblack@eecs.umich.edu dest_io_apic_intin = 16) 4724601Sgblack@eecs.umich.edu base_entries.append(pci_dev4_inta) 4734601Sgblack@eecs.umich.edu def assignISAInt(irq, apicPin): 4744601Sgblack@eecs.umich.edu assign_8259_to_apic = X86IntelMPIOIntAssignment( 4754601Sgblack@eecs.umich.edu interrupt_type = 'ExtInt', 4765178Sgblack@eecs.umich.edu polarity = 'ConformPolarity', 4775178Sgblack@eecs.umich.edu trigger = 'ConformTrigger', 4785359Sgblack@eecs.umich.edu source_bus_id = 0, 4795359Sgblack@eecs.umich.edu source_bus_irq = irq, 4805359Sgblack@eecs.umich.edu dest_io_apic_id = io_apic.id, 4815359Sgblack@eecs.umich.edu dest_io_apic_intin = 0) 4825359Sgblack@eecs.umich.edu base_entries.append(assign_8259_to_apic) 4835359Sgblack@eecs.umich.edu assign_to_apic = X86IntelMPIOIntAssignment( 4845359Sgblack@eecs.umich.edu interrupt_type = 'INT', 4855359Sgblack@eecs.umich.edu polarity = 'ConformPolarity', 4865359Sgblack@eecs.umich.edu trigger = 'ConformTrigger', 4875359Sgblack@eecs.umich.edu source_bus_id = 0, 4885359Sgblack@eecs.umich.edu source_bus_irq = irq, 4895359Sgblack@eecs.umich.edu dest_io_apic_id = io_apic.id, 4905359Sgblack@eecs.umich.edu dest_io_apic_intin = apicPin) 4915359Sgblack@eecs.umich.edu base_entries.append(assign_to_apic) 4925359Sgblack@eecs.umich.edu assignISAInt(0, 2) 4935359Sgblack@eecs.umich.edu assignISAInt(1, 1) 4945359Sgblack@eecs.umich.edu for i in range(3, 15): 4955359Sgblack@eecs.umich.edu assignISAInt(i, i) 4965178Sgblack@eecs.umich.edu self.intel_mp_table.base_entries = base_entries 4975178Sgblack@eecs.umich.edu self.intel_mp_table.ext_entries = ext_entries 4985178Sgblack@eecs.umich.edu 4995178Sgblack@eecs.umich.edudef makeLinuxX86System(mem_mode, numCPUs = 1, mdesc = None, 5005178Sgblack@eecs.umich.edu Ruby = False): 5015178Sgblack@eecs.umich.edu self = LinuxX86System() 5025178Sgblack@eecs.umich.edu 5035178Sgblack@eecs.umich.edu # Build up the x86 system and then specialize it for Linux 5045178Sgblack@eecs.umich.edu makeX86System(mem_mode, numCPUs, mdesc, self, Ruby) 5055178Sgblack@eecs.umich.edu 5065178Sgblack@eecs.umich.edu # We assume below that there's at least 1MB of memory. We'll require 2 5075178Sgblack@eecs.umich.edu # just to avoid corner cases. 5085178Sgblack@eecs.umich.edu phys_mem_size = sum(map(lambda r: r.size(), self.mem_ranges)) 5095178Sgblack@eecs.umich.edu assert(phys_mem_size >= 0x200000) 5105178Sgblack@eecs.umich.edu assert(len(self.mem_ranges) <= 2) 5115178Sgblack@eecs.umich.edu 5125178Sgblack@eecs.umich.edu entries = \ 5135178Sgblack@eecs.umich.edu [ 5145178Sgblack@eecs.umich.edu # Mark the first megabyte of memory as reserved 5155178Sgblack@eecs.umich.edu X86E820Entry(addr = 0, size = '639kB', range_type = 1), 5164587Sgblack@eecs.umich.edu X86E820Entry(addr = 0x9fc00, size = '385kB', range_type = 2), 5174587Sgblack@eecs.umich.edu # Mark the rest of physical memory as available 518 X86E820Entry(addr = 0x100000, 519 size = '%dB' % (self.mem_ranges[0].size() - 0x100000), 520 range_type = 1), 521 # Reserve the last 16kB of the 32-bit address space for the 522 # m5op interface 523 X86E820Entry(addr=0xFFFF0000, size='64kB', range_type=2), 524 ] 525 526 # In case the physical memory is greater than 3GB, we split it into two 527 # parts and add a separate e820 entry for the second part. This entry 528 # starts at 0x100000000, which is the first address after the space 529 # reserved for devices. 530 if len(self.mem_ranges) == 2: 531 entries.append(X86E820Entry(addr = 0x100000000, 532 size = '%dB' % (self.mem_ranges[1].size()), range_type = 1)) 533 534 self.e820_table.entries = entries 535 536 # Command line 537 self.boot_osflags = 'earlyprintk=ttyS0 console=ttyS0 lpj=7999923 ' + \ 538 'root=/dev/hda1' 539 self.kernel = binary('x86_64-vmlinux-2.6.22.9') 540 return self 541 542 543def makeDualRoot(full_system, testSystem, driveSystem, dumpfile): 544 self = Root(full_system = full_system) 545 self.testsys = testSystem 546 self.drivesys = driveSystem 547 self.etherlink = EtherLink() 548 549 if hasattr(testSystem, 'realview'): 550 self.etherlink.int0 = Parent.testsys.realview.ethernet.interface 551 self.etherlink.int1 = Parent.drivesys.realview.ethernet.interface 552 elif hasattr(testSystem, 'tsunami'): 553 self.etherlink.int0 = Parent.testsys.tsunami.ethernet.interface 554 self.etherlink.int1 = Parent.drivesys.tsunami.ethernet.interface 555 else: 556 fatal("Don't know how to connect these system together") 557 558 if dumpfile: 559 self.etherdump = EtherDump(file=dumpfile) 560 self.etherlink.dump = Parent.etherdump 561 562 return self 563