1d002ce55SAlexander Richardson#!/usr/bin/env python3 2d002ce55SAlexander Richardson# ===----------------------------------------------------------------------===## 3d002ce55SAlexander Richardson# 4d002ce55SAlexander Richardson# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5d002ce55SAlexander Richardson# See https://llvm.org/LICENSE.txt for license information. 6d002ce55SAlexander Richardson# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7d002ce55SAlexander Richardson# 8d002ce55SAlexander Richardson# ===----------------------------------------------------------------------===## 9d002ce55SAlexander Richardson 10d002ce55SAlexander Richardson"""qemu_baremetal.py is a utility for running a program with QEMU's system mode. 11d002ce55SAlexander Richardson 12d002ce55SAlexander RichardsonIt is able to pass command line arguments to the program and forward input and 13d002ce55SAlexander Richardsonoutput (if the underlying baremetal enviroment supports QEMU semihosting). 14d002ce55SAlexander Richardson""" 15d002ce55SAlexander Richardson 16d002ce55SAlexander Richardsonimport argparse 17d002ce55SAlexander Richardsonimport os 18d002ce55SAlexander Richardsonimport sys 19*acbb491aSDavid Spickettimport shutil 20d002ce55SAlexander Richardson 21d002ce55SAlexander Richardson 22d002ce55SAlexander Richardsondef main(): 23d002ce55SAlexander Richardson parser = argparse.ArgumentParser() 24d002ce55SAlexander Richardson parser.add_argument("--qemu", type=str, required=True) 25d002ce55SAlexander Richardson parser.add_argument("--cpu", type=str, required=False) 26d002ce55SAlexander Richardson parser.add_argument("--machine", type=str, default="virt") 27d002ce55SAlexander Richardson parser.add_argument( 28d002ce55SAlexander Richardson "--qemu-arg", dest="qemu_args", type=str, action="append", default=[] 29d002ce55SAlexander Richardson ) 30d002ce55SAlexander Richardson parser.add_argument("--semihosting", action="store_true", default=True) 31d002ce55SAlexander Richardson parser.add_argument("--no-semihosting", dest="semihosting", action="store_false") 32d002ce55SAlexander Richardson parser.add_argument("--execdir", type=str, required=True) 33d002ce55SAlexander Richardson parser.add_argument("test_binary") 34d002ce55SAlexander Richardson parser.add_argument("test_args", nargs=argparse.ZERO_OR_MORE, default=[]) 35d002ce55SAlexander Richardson args = parser.parse_args() 36*acbb491aSDavid Spickett 37*acbb491aSDavid Spickett if not shutil.which(args.qemu): 38*acbb491aSDavid Spickett sys.exit(f"Failed to find QEMU binary from --qemu value: '{args.qemu}'") 39*acbb491aSDavid Spickett 40d002ce55SAlexander Richardson if not os.path.exists(args.test_binary): 41d002ce55SAlexander Richardson sys.exit(f"Expected argument to be a test executable: '{args.test_binary}'") 42*acbb491aSDavid Spickett 43d002ce55SAlexander Richardson qemu_commandline = [ 44d002ce55SAlexander Richardson args.qemu, 45d002ce55SAlexander Richardson "-chardev", 46d002ce55SAlexander Richardson "stdio,mux=on,id=stdio0", 47d002ce55SAlexander Richardson "-monitor", 48d002ce55SAlexander Richardson "none", 49d002ce55SAlexander Richardson "-serial", 50d002ce55SAlexander Richardson "none", 51d002ce55SAlexander Richardson "-machine", 52d002ce55SAlexander Richardson f"{args.machine},accel=tcg", 53d002ce55SAlexander Richardson "-device", 54d002ce55SAlexander Richardson f"loader,file={args.test_binary},cpu-num=0", 55d002ce55SAlexander Richardson "-nographic", 56d002ce55SAlexander Richardson *args.qemu_args, 57d002ce55SAlexander Richardson ] 58d002ce55SAlexander Richardson if args.cpu: 59d002ce55SAlexander Richardson qemu_commandline += ["-cpu", args.cpu] 60d002ce55SAlexander Richardson 61d002ce55SAlexander Richardson if args.semihosting: 62d002ce55SAlexander Richardson # Use QEMU's semihosting support to pass argv (supported by picolibc) 63d002ce55SAlexander Richardson semihosting_config = f"enable=on,chardev=stdio0,arg={args.test_binary}" 64d002ce55SAlexander Richardson for arg in args.test_args: 65d002ce55SAlexander Richardson semihosting_config += f",arg={arg}" 66d002ce55SAlexander Richardson qemu_commandline += ["-semihosting-config", semihosting_config] 67d002ce55SAlexander Richardson elif args.test_args: 68d002ce55SAlexander Richardson sys.exit( 69d002ce55SAlexander Richardson "Got non-empty test arguments but do no know how to pass them to " 70d002ce55SAlexander Richardson "QEMU without semihosting support" 71d002ce55SAlexander Richardson ) 72d002ce55SAlexander Richardson os.execvp(qemu_commandline[0], qemu_commandline) 73d002ce55SAlexander Richardson 74d002ce55SAlexander Richardson 75d002ce55SAlexander Richardsonif __name__ == "__main__": 76d002ce55SAlexander Richardson exit(main()) 77