harness: machines: define custom buildall targets for armv7/armv8 machines
[barrelfish] / tools / harness / machines / gem5.py
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
14 import os, signal, tempfile, subprocess, shutil, time
15 import debug, machines
16 from machines import ARMSimulatorBase, MachineFactory, ARMSimulatorOperations
17
18 GEM5_PATH = '/home/netos/tools/gem5/gem5-stable-1604'
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
25 GEM5_START_TIMEOUT = 1 # in seconds
26
27 class 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         return 25 * 60
44
45 class Gem5MachineBaseOperations(ARMSimulatorOperations):
46
47     def __init__(self, machine):
48         super(Gem5MachineBaseOperations, self).__init__(machine)
49         self.simulator_start_timeout = GEM5_START_TIMEOUT
50         # menu.lst template for gem5 is special
51         # XXX: current template does not work because gem5 coreboot NYI
52         self.menulst_template = "menu.lst.armv7_a15ve_gem5"
53
54     def get_tftp_dir(self):
55         if self.tftp_dir is None:
56             debug.verbose('creating temporary directory for Gem5 files')
57             self.tftp_dir = tempfile.mkdtemp(prefix='harness_gem5_')
58             debug.verbose('Gem5 install directory is %s' % self.tftp_dir)
59         return self.tftp_dir
60
61     def reboot(self):
62         self._kill_child()
63         cmd = self._get_cmdline()
64         debug.verbose('starting "%s" in gem5.py:reboot' % ' '.join(cmd))
65         devnull = open('/dev/null', 'w')
66         # remove ubuntu chroot from environment to make sure gem5 finds the
67         # right shared libraries
68         env = dict(os.environ)
69         if 'LD_LIBRARY_PATH' in env:
70             del env['LD_LIBRARY_PATH']
71         self.child = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=devnull, env=env)
72         time.sleep(GEM5_START_TIMEOUT)
73
74 class Gem5MachineARM(Gem5MachineBase):
75
76     def __init__(self, options, operations, **kwargs):
77         super(Gem5MachineARM, self).__init__(options, operations, **kwargs)
78
79     def get_bootarch(self):
80         return 'armv7'
81
82     def get_platform(self):
83         return 'a15ve'
84
85 class Gem5MachineARMOperations(Gem5MachineBaseOperations):
86
87     def set_bootmodules(self, modules):
88         # write menu.lst in build directory
89         debug.verbose("writing menu.lst in build directory")
90         menulst_fullpath = os.path.join(self._machine.options.builds[0].build_dir,
91                 "platforms", "arm", self.menulst_template)
92         debug.verbose("writing menu.lst in build directory: %s" %
93                 menulst_fullpath)
94         self._machine._write_menu_lst(modules.get_menu_data("/"), menulst_fullpath)
95         debug.verbose("building proper gem5 image")
96         debug.checkcmd(["make", self._machine.imagename],
97                 cwd=self._machine.options.builds[0].build_dir)
98
99
100 # SK: did not test this yet, but should work
101 # @machines.add_machine
102 # class Gem5MachineARMSingleCore(Gem5MachineARM):
103 #     name = 'gem5_arm_1'
104
105 #     def get_ncores(self):
106 #         return 1
107
108 #     def _get_cmdline(self):
109 #         script_path = os.path.join(self.options.sourcedir, 'tools/arm_gem5', 'gem5script.py')
110 #         return (['gem5.fast', script_path, '--kernel=%s'%self.kernel_img, '--n=%s'%self.get_ncores()]
111 #                 + GEM5_CACHES_ENABLE)
112
113
114 class Gem5MachineARMSingleCore(Gem5MachineARM):
115     name = 'armv7_gem5'
116
117     def __init__(self, options, **kwargs):
118         super(Gem5MachineARMSingleCore, self).__init__(options, Gem5MachineARMSingleCoreOperations(self), **kwargs)
119
120
121 class Gem5MachineARMSingleCoreOperations(Gem5MachineARMOperations):
122
123     def _get_cmdline(self):
124         self.get_free_port()
125         script_path = \
126             os.path.join(self._machine.options.sourcedir, 'tools/arm_gem5',
127                          'boot_gem5.sh')
128         return ([script_path, 'VExpress_EMM', self._machine.kernel_img, GEM5_PATH,
129                  str(self.telnet_port)])
130
131 MachineFactory.addMachine(Gem5MachineARMSingleCore.name, Gem5MachineARMSingleCore,
132                           bootarch="armv7",
133                           platform="a15ve")