Merge branch 'master' into callcaps
[helenos.git] / tools / ew.py
blob6a9db9afae3528c3352ed659123738d01145716d
1 #!/usr/bin/env python
3 # Copyright (c) 2013 Jakub Jermar
4 # All rights reserved.
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
10 # - Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
12 # - Redistributions in binary form must reproduce the above copyright
13 # notice, this list of conditions and the following disclaimer in the
14 # documentation and/or other materials provided with the distribution.
15 # - The name of the author may not be used to endorse or promote products
16 # derived from this software without specific prior written permission.
18 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 """
32 Emulator wrapper for running HelenOS
33 """
35 import os
36 import sys
37 import subprocess
38 import autotool
39 import platform
40 import thread
41 import time
43 overrides = {}
45 def is_override(str):
46 if str in overrides.keys():
47 return overrides[str]
48 return False
50 def cfg_get(platform, machine, processor):
51 if machine == "" or emulators[platform].has_key("run"):
52 return emulators[platform]
53 elif processor == "" or emulators[platform][machine].has_key("run"):
54 return emulators[platform][machine]
55 else:
56 return emulators[platform][machine][processor]
58 def termemu_detect():
59 for termemu in ['xfce4-terminal', 'xterm']:
60 try:
61 subprocess.check_output('which ' + termemu, shell = True)
62 return termemu
63 except:
64 pass
66 def run_in_console(cmd, title):
67 ecmd = cmd.replace('"', '\\"')
68 cmdline = termemu_detect() + ' -T ' + '"' + title + '"' + ' -e "' + ecmd + '"'
69 print(cmdline)
70 if not is_override('dryrun'):
71 subprocess.call(cmdline, shell = True)
73 def get_host_native_width():
74 return int(platform.architecture()[0].strip('bit'))
76 def pc_options(guest_width):
77 opts = ''
79 # Do not enable KVM if running 64 bits HelenOS
80 # on 32 bits host
81 host_width = get_host_native_width()
82 if guest_width <= host_width and not is_override('nokvm'):
83 opts = opts + ' -enable-kvm'
85 # Remove the leading space
86 return opts[1:]
88 def malta_options():
89 return '-cpu 4Kc'
91 def platform_to_qemu_options(platform, machine, processor):
92 if platform == 'amd64':
93 return 'system-x86_64', pc_options(64)
94 elif platform == 'arm32':
95 return 'system-arm', '-M integratorcp'
96 elif platform == 'ia32':
97 return 'system-i386', pc_options(32)
98 elif platform == 'mips32':
99 if machine == 'lmalta':
100 return 'system-mipsel', malta_options()
101 elif machine == 'bmalta':
102 return 'system-mips', malta_options()
103 elif platform == 'ppc32':
104 return 'system-ppc', '-m 256'
105 elif platform == 'sparc64':
106 if machine != 'generic':
107 raise Exception
108 if processor == 'us':
109 return 'system-sparc64', '-M sun4u --prom-env boot-args="console=devices/\\hw\\pci0\\00:03.0\\com1\\a"'
110 elif processor == 'sun4v':
111 default_path = '/usr/local/opensparc/image/'
112 try:
113 if os.path.exists(default_path):
114 opensparc_bins = default_path
115 elif os.path.exists(os.environ['OPENSPARC_BINARIES']):
116 opensparc_bins = os.environ['OPENSPARC_BINARIES']
117 else:
118 raise Exception
119 except:
120 print("Cannot find OpenSPARC binary images!")
121 print("Either set OPENSPARC_BINARIES environment variable accordingly or place the images in %s." % (default_path))
122 raise Exception
124 return 'system-sparc64', '-M niagara -m 256 -L %s' % (opensparc_bins)
127 def hdisk_mk():
128 if not os.path.exists('hdisk.img'):
129 subprocess.call('tools/mkfat.py 1048576 uspace/dist/data hdisk.img', shell = True)
131 def qemu_bd_options():
132 if is_override('nohdd'):
133 return ''
135 hdisk_mk()
137 return ' -drive file=hdisk.img,index=0,media=disk,format=raw'
139 def qemu_nic_ne2k_options():
140 return ' -device ne2k_isa,irq=5,vlan=0'
142 def qemu_nic_e1k_options():
143 return ' -device e1000,vlan=0'
145 def qemu_nic_rtl8139_options():
146 return ' -device rtl8139,vlan=0'
148 def qemu_net_options():
149 if is_override('nonet'):
150 return ''
152 nic_options = ''
153 if 'net' in overrides.keys():
154 if 'e1k' in overrides['net'].keys():
155 nic_options += qemu_nic_e1k_options()
156 if 'rtl8139' in overrides['net'].keys():
157 nic_options += qemu_nic_rtl8139_options()
158 if 'ne2k' in overrides['net'].keys():
159 nic_options += qemu_nic_ne2k_options()
160 else:
161 # Use the default NIC
162 nic_options += qemu_nic_e1k_options()
164 return nic_options + ' -net user,hostfwd=udp::8080-:8080,hostfwd=udp::8081-:8081,hostfwd=tcp::8080-:8080,hostfwd=tcp::8081-:8081,hostfwd=tcp::2223-:2223'
166 def qemu_usb_options():
167 if is_override('nousb'):
168 return ''
169 return ' -usb'
171 def qemu_audio_options():
172 if is_override('nosnd'):
173 return ''
174 return ' -device intel-hda -device hda-duplex'
176 def qemu_run(platform, machine, processor):
177 cfg = cfg_get(platform, machine, processor)
178 suffix, options = platform_to_qemu_options(platform, machine, processor)
179 cmd = 'qemu-' + suffix
181 cmdline = cmd
182 if options != '':
183 cmdline += ' ' + options
185 cmdline += qemu_bd_options()
187 if (not 'net' in cfg.keys()) or cfg['net']:
188 cmdline += qemu_net_options()
189 if (not 'usb' in cfg.keys()) or cfg['usb']:
190 cmdline += qemu_usb_options()
191 if (not 'audio' in cfg.keys()) or cfg['audio']:
192 cmdline += qemu_audio_options()
194 if cfg['image'] == 'image.iso':
195 cmdline += ' -boot d -cdrom image.iso'
196 elif cfg['image'] == 'image.boot':
197 cmdline += ' -kernel image.boot'
198 else:
199 cmdline += ' ' + cfg['image']
201 if ('console' in cfg.keys()) and not cfg['console']:
202 cmdline += ' -nographic'
204 title = 'HelenOS/' + platform
205 if machine != '':
206 title += ' on ' + machine
207 if 'expect' in cfg.keys():
208 cmdline = 'expect -c \'spawn %s; expect "%s" { send "%s" } timeout exp_continue; interact\'' % (cmdline, cfg['expect']['src'], cfg['expect']['dst'])
209 run_in_console(cmdline, title)
210 else:
211 print(cmdline)
212 if not is_override('dryrun'):
213 subprocess.call(cmdline, shell = True)
215 def ski_run(platform, machine, processor):
216 run_in_console('ski -i contrib/conf/ski.conf', 'HelenOS/ia64 on ski')
218 def msim_run(platform, machine, processor):
219 hdisk_mk()
220 run_in_console('msim -c contrib/conf/msim.conf', 'HelenOS/mips32 on msim')
222 def spike_run(platform, machine, processor):
223 run_in_console('spike -m1073741824:1073741824 image.boot', 'HelenOS/risvc64 on Spike')
225 emulators = {
226 'amd64' : {
227 'run' : qemu_run,
228 'image' : 'image.iso'
230 'arm32' : {
231 'integratorcp' : {
232 'run' : qemu_run,
233 'image' : 'image.boot',
234 'net' : False,
235 'audio' : False
238 'ia32' : {
239 'run' : qemu_run,
240 'image' : 'image.iso'
242 'ia64' : {
243 'ski' : {
244 'run' : ski_run
247 'mips32' : {
248 'msim' : {
249 'run' : msim_run
251 'lmalta' : {
252 'run' : qemu_run,
253 'image' : 'image.boot',
254 'console' : False
256 'bmalta' : {
257 'run' : qemu_run,
258 'image' : 'image.boot',
259 'console' : False
262 'ppc32' : {
263 'run' : qemu_run,
264 'image' : 'image.iso',
265 'audio' : False
267 'riscv64' : {
268 'run' : spike_run,
269 'image' : 'image.boot'
271 'sparc64' : {
272 'generic' : {
273 'us' : {
274 'run' : qemu_run,
275 'image' : 'image.iso',
276 'audio' : False,
277 'console' : False,
279 'sun4v' : {
280 'run' : qemu_run,
281 'image' : '-drive if=pflash,readonly=on,file=image.iso',
282 'audio' : False,
283 'console' : False,
284 'net' : False,
285 'usb' : False,
286 'expect' : {
287 'src' : 'ok ',
288 'dst' : 'boot\n'
295 def usage():
296 print("%s - emulator wrapper for running HelenOS\n" % os.path.basename(sys.argv[0]))
297 print("%s [-d] [-h] [-net e1k|rtl8139|ne2k] [-nohdd] [-nokvm] [-nonet] [-nosnd] [-nousb]\n" %
298 os.path.basename(sys.argv[0]))
299 print("-d\tDry run: do not run the emulation, just print the command line.")
300 print("-h\tPrint the usage information and exit.")
301 print("-nohdd\tDisable hard disk, if applicable.")
302 print("-nokvm\tDisable KVM, if applicable.")
303 print("-nonet\tDisable networking support, if applicable.")
304 print("-nosnd\tDisable sound, if applicable.")
305 print("-nousb\tDisable USB support, if applicable.")
307 def fail(platform, machine):
308 print("Cannot start emulation for the chosen configuration. (%s/%s)" % (platform, machine))
311 def run():
312 expect_nic = False
314 for i in range(1, len(sys.argv)):
316 if expect_nic:
317 expect_nic = False
318 if not 'net' in overrides.keys():
319 overrides['net'] = {}
320 if sys.argv[i] == 'e1k':
321 overrides['net']['e1k'] = True
322 elif sys.argv[i] == 'rtl8139':
323 overrides['net']['rtl8139'] = True
324 elif sys.argv[i] == 'ne2k':
325 overrides['net']['ne2k'] = True
326 else:
327 usage()
328 exit()
330 elif sys.argv[i] == '-h':
331 usage()
332 exit()
333 elif sys.argv[i] == '-d':
334 overrides['dryrun'] = True
335 elif sys.argv[i] == '-net' and i < len(sys.argv) - 1:
336 expect_nic = True
337 elif sys.argv[i] == '-nohdd':
338 overrides['nohdd'] = True
339 elif sys.argv[i] == '-nokvm':
340 overrides['nokvm'] = True
341 elif sys.argv[i] == '-nonet':
342 overrides['nonet'] = True
343 elif sys.argv[i] == '-nosnd':
344 overrides['nosnd'] = True
345 elif sys.argv[i] == '-nousb':
346 overrides['nousb'] = True
347 else:
348 usage()
349 exit()
351 config = {}
352 autotool.read_config(autotool.CONFIG, config)
354 if 'PLATFORM' in config.keys():
355 platform = config['PLATFORM']
356 else:
357 platform = ''
359 if 'MACHINE' in config.keys():
360 mach = config['MACHINE']
361 else:
362 mach = ''
364 if 'PROCESSOR' in config.keys():
365 processor = config['PROCESSOR']
366 else:
367 processor = ''
369 try:
370 emu_run = cfg_get(platform, mach, processor)['run']
371 emu_run(platform, mach, processor)
372 except:
373 fail(platform, mach)
374 return
376 run()