harness: machines: define custom buildall targets for armv7/armv8 machines
[barrelfish] / tools / harness / machines / fvp.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 import os, tempfile, subprocess, time
11 import debug
12 from machines import ARMSimulatorBase, MachineFactory, ARMSimulatorOperations
13 import efiimage
14
15 FVP_PATH = '/home/netos/tools/DS-5_v5.26.0/bin'
16
17 # Get the prebuilt binary snapshots (fvp-uefi.zip) from:
18 # https://community.arm.com/docs/DOC-10952
19 FVP_UEFI_BL1="/home/netos/tools/fvp-uefi/bl1.bin"
20 FVP_UEFI_FIP="/home/netos/tools/fvp-uefi/fip.bin"
21 FVP_LICENSE = '8224@sgv-license-01.ethz.ch'
22 FVP_START_TIMEOUT = 2 # in seconds
23
24 class FVPMachineBase(ARMSimulatorBase):
25     imagename = "armv7_a9ve_1_image"
26
27     def __init__(self, options, operations, **kwargs):
28         if operations is None:
29             operations = FVPMachineBaseOperations(self)
30         super(FVPMachineBase, self).__init__(options, operations, **kwargs)
31         self.simulator_start_timeout = FVP_START_TIMEOUT
32
33     def get_buildall_target(self):
34         return "VExpressEMM-A9"
35
36 class FVPMachineBaseOperations(ARMSimulatorOperations):
37
38     def get_tftp_dir(self):
39         if self.tftp_dir is None:
40             debug.verbose('Creating temporary directory for FVP files')
41             self.tftp_dir = tempfile.mkdtemp(prefix='harness_fvp_')
42             debug.verbose('FVP install directory is %s' % self.tftp_dir)
43         return self.tftp_dir
44
45     def reboot(self):
46         self._kill_child()
47         cmd = self._get_cmdline()
48         debug.verbose('starting "%s" in FVP:reboot' % ' '.join(cmd))
49         env = dict(os.environ)
50         env['ARMLMD_LICENSE_FILE'] = FVP_LICENSE
51         self.child = \
52             subprocess.Popen(cmd, stdout=subprocess.PIPE,
53                              stderr=subprocess.STDOUT, env=env)
54         #time.sleep(FVP_START_TIMEOUT)
55
56
57 class FVPMachineARMv7(FVPMachineBase):
58
59     def __init__(self, options, operations, **kwargs):
60         super(FVPMachineARMv7, self).__init__(options, operations, **kwargs)
61
62     def set_bootmodules(self, modules):
63         # write menu.lst in build directory
64         debug.verbose("writing menu.lst in build directory")
65         menulst_fullpath = os.path.join(self.options.builds[0].build_dir,
66                 "platforms", "arm", "menu.lst.armv7_a9ve_1")
67         debug.verbose("writing menu.lst in build directory: %s" %
68                 menulst_fullpath)
69         self._write_menu_lst(modules.get_menu_data("/"), menulst_fullpath)
70         debug.verbose("building proper FVP image")
71         debug.checkcmd(["make", self.imagename],
72                 cwd=self.options.builds[0].build_dir)
73
74 class FVPMachineARMv7NCores(FVPMachineARMv7):
75
76     def __init__(self, options, **kwargs):
77         super(FVPMachineARMv7NCores, self).__init__(options, FVPMachineARMv7NCoresOperations(self), **kwargs)
78
79 class FVPMachineARMv7NCoresOperations(FVPMachineBaseOperations):
80
81     def _get_cmdline(self):
82         self.get_free_port()
83
84         return [os.path.join(FVP_PATH, "FVP_VE_Cortex-A9x" + str(self._machine.get_ncores())),
85                 # Don't try to pop an LCD window up
86                 "-C", "motherboard.vis.disable_visualisation=1",
87                 # Don't start a telnet xterm
88                 "-C", "motherboard.terminal_0.start_telnet=0",
89                 "-C", "motherboard.terminal_0.start_port=%d" % self.telnet_port,
90                 self._machine.kernel_img]
91
92 # Single core machine
93 MachineFactory.addMachine("armv7_fvp", FVPMachineARMv7NCores,
94                           bootarch="armv7",
95                           platform="a9ve")
96
97 # Quad-core machine
98 MachineFactory.addMachine('armv7_fvp_4', FVPMachineARMv7NCores,
99                           bootarch="armv7",
100                           platform="a9ve",
101                           ncores=4)
102
103
104 class FVPMachineEFI(FVPMachineBase):
105     imagename = "armv8_efi"
106
107     def __init__(self, options, simulator=None, **kwargs):
108         super(FVPMachineEFI, self).__init__(options, FVPMachineEFIOperations(self), **kwargs)
109         assert(simulator)
110         self.simulator = simulator
111
112     def set_bootmodules(self, modules):
113         # write menu.lst in build directory
114         debug.verbose("writing menu.lst in build directory")
115         menulst_fullpath = os.path.join(self.options.builds[0].build_dir,
116                 "platforms", "arm", "menu.lst.armv8_base")
117         debug.verbose("writing menu.lst in build directory: %s" %
118                 menulst_fullpath)
119         self._write_menu_lst(modules.get_menu_data("/"), menulst_fullpath)
120
121         debug.checkcmd(["make"] + modules.get_build_targets(), cwd=self.options.builds[0].build_dir)
122
123         debug.verbose("building proper FVP image")
124         efi = efiimage.EFIImage(self.kernel_img, 200)
125         efi.create()
126         for module in modules.get_build_targets():
127             efi.addFile(os.path.join(self.options.builds[0].build_dir, module), module)
128         efi.writeFile("startup.nsh", "Hagfish.efi hagfish.cfg")
129         efi.addFile("/home/netos/tftpboot/Hagfish.efi", "Hagfish.efi")
130         efi.addFile(menulst_fullpath, "hagfish.cfg")
131
132     def get_buildall_target(self):
133         # XXX: this is a misnomer in hake for the a57v platform
134         return "QEMU"
135
136 class FVPMachineEFIOperations(FVPMachineBaseOperations):
137
138
139     def get_output(self):
140         return self.child.stdout
141
142     def _get_cmdline(self):
143         self.get_free_port()
144
145         return [os.path.join(FVP_PATH, self._machine.simulator),
146                 # Don't try to pop an LCD window up
147                 "-C", "bp.vis.disable_visualisation=1",
148                 # Don't start a telnet xterm
149                 "-C", "bp.terminal_0.start_telnet=0",
150                 "-C", "bp.terminal_1.start_telnet=0",
151                 "-C", "bp.secureflashloader.fname=%s" % FVP_UEFI_BL1,
152                 "-C", "bp.flashloader0.fname=%s" % FVP_UEFI_FIP,
153                 "-C", "bp.mmc.p_mmc_file=%s" % self._machine.kernel_img,
154                 "-C", "bp.pl011_uart0.unbuffered_output=1",
155                 # This has to be the last parameter because otherwise the command
156                 # passed to the OS has incorrect parameters. Don't know why
157                 # MH 11/2016
158                 "-C", "bp.pl011_uart0.out_file=-",
159                 ]
160
161 MachineFactory.addMachine('armv8_fvp_base', FVPMachineEFI,
162                           bootarch='armv8',
163                           platform='a57v',
164                           boot_timeout=60,
165                           simulator="FVP_Base_AEMv8A")
166
167 MachineFactory.addMachine('armv8_fvp_a57x1', FVPMachineEFI,
168                           bootarch='armv8',
169                           boot_driver = 'boot_armv8_generic',
170                           platform='a57v',
171                           boot_timeout=60,
172                           simulator="FVP_Base_Cortex-A57x1")
173
174 MachineFactory.addMachine('armv8_fvp_a57x2_a53x4', FVPMachineEFI,
175                           bootarch='armv8',
176                           boot_driver = 'boot_armv8_generic',
177                           platform='a57v',
178                           boot_timeout=60,
179                           simulator="FVP_Base_Cortex-A57x2-A53x4")