1########################################################################## 2# Copyright (c) 2012-2016 ETH Zurich. 3# All rights reserved. 4# 5# This file is distributed under the terms in the attached LICENSE file. 6# If you do not find this file, copies can be found by writing to: 7# ETH Zurich D-INFK, Universitaetstr 6, CH-8092 Zurich. Attn: Systems Group. 8########################################################################## 9 10# Quirks: 11# * this is only running in single-core mode, since bootarm=0 is 12# used in above mentioned menu.lst 13 14import os, signal, tempfile, subprocess, shutil, time 15import debug, machines 16from machines import ARMSimulatorBase, MachineFactory, ARMSimulatorOperations 17 18GEM5_PATH = '/home/netos/tools/gem5/gem5-stable-1804' 19# gem5 takes quite a while to come up. If we return right away, 20# telnet will be opened too early and fails to connect 21# 22# SG, 2016-10-07: If this is too high, however, and we have an 23# early-boot bug gem5 will exit before telnet connects, and we do 24# not get the gem5 output at all 25GEM5_START_TIMEOUT = 1 # in seconds 26 27class Gem5MachineBase(ARMSimulatorBase): 28 imagename = "armv7_a15ve_gem5_image" 29 30 def __init__(self, options, operations, **kwargs): 31 super(Gem5MachineBase, self).__init__(options, operations, **kwargs) 32 33 def get_buildall_target(self): 34 return "VExpressEMM-A15" 35 36 def get_boot_timeout(self): 37 # we set this to 10 mins since gem5 is very slow 38 return 600 39 40 def get_test_timeout(self): 41 # give gem5 tests enough time to complete: skb initialization takes 42 # about 10 minutes, so set timeout to 25 minutes. 43 # RH, 2018-08-08 newer version of gem5 is even slower ... 44 # increased to 50 mins 45 return 50 * 60 46 47class Gem5MachineBaseOperations(ARMSimulatorOperations): 48 49 def __init__(self, machine): 50 super(Gem5MachineBaseOperations, self).__init__(machine) 51 self.simulator_start_timeout = GEM5_START_TIMEOUT 52 # menu.lst template for gem5 is special 53 # XXX: current template does not work because gem5 coreboot NYI 54 self.menulst_template = "menu.lst.armv7_a15ve_gem5" 55 56 def get_tftp_dir(self): 57 if self.tftp_dir is None: 58 debug.verbose('creating temporary directory for Gem5 files') 59 self.tftp_dir = tempfile.mkdtemp(prefix='harness_gem5_') 60 debug.verbose('Gem5 install directory is %s' % self.tftp_dir) 61 return self.tftp_dir 62 63 def reboot(self): 64 self._kill_child() 65 cmd = self._get_cmdline() 66 self.telnet_port = 3456 67 debug.verbose('starting "%s" in gem5.py:reboot' % ' '.join(cmd)) 68 devnull = open('/dev/null', 'w') 69 # remove ubuntu chroot from environment to make sure gem5 finds the 70 # right shared libraries 71 env = dict(os.environ) 72 if 'LD_LIBRARY_PATH' in env: 73 del env['LD_LIBRARY_PATH'] 74 75 self.child = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=devnull, env=env) 76 time.sleep(GEM5_START_TIMEOUT) 77 78class Gem5MachineARM(Gem5MachineBase): 79 80 def __init__(self, options, operations, **kwargs): 81 super(Gem5MachineARM, self).__init__(options, operations, **kwargs) 82 83 def get_bootarch(self): 84 return 'armv7' 85 86 def get_platform(self): 87 return 'a15ve' 88 89class Gem5MachineARMOperations(Gem5MachineBaseOperations): 90 91 def set_bootmodules(self, modules): 92 # write menu.lst in build directory 93 debug.verbose("writing menu.lst in build directory") 94 menulst_fullpath = os.path.join(self._machine.options.builds[0].build_dir, 95 "platforms", "arm", self.menulst_template) 96 debug.verbose("writing menu.lst in build directory: %s" % 97 menulst_fullpath) 98 self._machine._write_menu_lst(modules.get_menu_data("/"), menulst_fullpath) 99 debug.verbose("building proper gem5 image") 100 debug.checkcmd(["make", self._machine.imagename], 101 cwd=self._machine.options.builds[0].build_dir) 102 103 104# SK: did not test this yet, but should work 105# @machines.add_machine 106# class Gem5MachineARMSingleCore(Gem5MachineARM): 107# name = 'gem5_arm_1' 108 109# def get_ncores(self): 110# return 1 111 112# def _get_cmdline(self): 113# script_path = os.path.join(self.options.sourcedir, 'tools/arm_gem5', 'gem5script.py') 114# return (['gem5.fast', script_path, '--kernel=%s'%self.kernel_img, '--n=%s'%self.get_ncores()] 115# + GEM5_CACHES_ENABLE) 116 117 118class Gem5MachineARMSingleCore(Gem5MachineARM): 119 name = 'armv7_gem5' 120 121 def __init__(self, options, **kwargs): 122 super(Gem5MachineARMSingleCore, self).__init__(options, Gem5MachineARMSingleCoreOperations(self), **kwargs) 123 124 125class Gem5MachineARMSingleCoreOperations(Gem5MachineARMOperations): 126 127 def _get_cmdline(self): 128 self.get_free_port() 129 script_path = \ 130 os.path.join(self._machine.options.sourcedir, 'tools/arm_gem5', 131 'boot_gem5.sh') 132 return ([script_path, 'VExpress_EMM', self._machine.kernel_img, GEM5_PATH, 133 str(self.telnet_port)]) 134 135MachineFactory.addMachine(Gem5MachineARMSingleCore.name, Gem5MachineARMSingleCore, 136 bootarch="armv7", 137 platform="a15ve") 138