diff --git a/misc/acrn-config/launch_config/com.py b/misc/acrn-config/launch_config/com.py new file mode 100644 index 000000000..5b5cf1143 --- /dev/null +++ b/misc/acrn-config/launch_config/com.py @@ -0,0 +1,549 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +import launch_cfg_lib +import pt + + +def is_nuc_clr(names, vmid): + uos_type = names['uos_types'][vmid] + board_name = names['board_name'] + + if uos_type == "CLEARLINUX" and 'nuc' in board_name: + return True + + return False + + +def tap_uos_net(names, vmid, config): + uos_type = names['uos_types'][vmid] + board_name = names['board_name'] + + if uos_type in ("CLEARLINUX", "ANDROID", "ALIOS"): + if board_name in ("apl-mrb", "apl-up2"): + print('if [ ! -f "/data/$5/$5.img" ]; then', file=config) + print(' echo "no /data/$5/$5.img, exit"', file=config) + print(" exit", file=config) + print("fi", file=config) + print("", file=config) + print("#vm-name used to generate uos-mac address", file=config) + print("mac=$(cat /sys/class/net/e*/address)", file=config) + print("vm_name=vm$1", file=config) + print("mac_seed=${mac:9:8}-${vm_name}", file=config) + print("", file=config) + + if uos_type in ("VXWORKS", "ZEPHYR", "WINDOWS"): + print("vm_name={}_vm$1".format(uos_type), file=config) + + if uos_type in ("CLEARLINUX", "ANDROID", "ALIOS"): + if board_name in ("apl-mrb", "apl-up2"): + print("# create a unique tap device for each VM", file=config) + print("tap=tap_$6", file=config) + print('tap_exist=$(ip a | grep "$tap" | awk \'{print $1}\')', file=config) + print('if [ "$tap_exist"x != "x" ]; then', file=config) + print(' echo "tap device existed, reuse $tap"', file=config) + print("else", file=config) + print(" ip tuntap add dev $tap mode tap", file=config) + print("fi", file=config) + print("", file=config) + print("# if acrn-br0 exists, add VM's unique tap device under it", file=config) + print("br_exist=$(ip a | grep acrn-br0 | awk '{print $1}')", file=config) + print('if [ "$br_exist"x != "x" -a "$tap_exist"x = "x" ]; then', file=config) + print(' echo "acrn-br0 bridge aleady exists, adding new tap device to it..."', file=config) + print(' ip link set "$tap" master acrn-br0', file=config) + print(' ip link set dev "$tap" down', file=config) + print(' ip link set dev "$tap" up', file=config) + print("fi", file=config) + print("", file=config) + print("#check if the vm is running or not", file=config) + print("vm_ps=$(pgrep -a -f acrn-dm)", file=config) + print('result=$(echo $vm_ps | grep -w "${vm_name}")', file=config) + print('if [[ "$result" != "" ]]; then', file=config) + print(' echo "$vm_name is running, can\'t create twice!"', file=config) + print(" exit", file=config) + print("fi", file=config) + print("", file=config) + + +def delay_use_usb_storage(uos_type, config): + if uos_type == "CLEARLINUX": + print("echo 100 > /sys/bus/usb/drivers/usb-storage/module/parameters/delay_use", file=config) + + +def off_line_cpus(uos_type, config): + + print('offline_path="/sys/class/vhm/acrn_vhm"', file=config) + print("", file=config) + + if uos_type in ("ANDROID", "CLEARLINUX", "ALIOS"): + print("# Check the device file of /dev/acrn_hsm to determine the offline_path", file=config) + print('if [ -e "/dev/acrn_hsm" ]; then', file=config) + print('offline_path="/sys/class/acrn/acrn_hsm"', file=config) + print('fi', file=config) + print("", file=config) + print("# offline SOS CPUs except BSP before launch UOS", file=config) + print("for i in `ls -d /sys/devices/system/cpu/cpu[1-99]`; do", file=config) + print(" online=`cat $i/online`", file=config) + print(' idx=`echo $i | tr -cd "[1-99]"`', file=config) + print(" echo cpu$idx online=$online", file=config) + print(' if [ "$online" = "1" ]; then', file=config) + print(" echo 0 > $i/online", file=config) + + if uos_type in ("ANDROID", "CLEARLINUX", "ALIOS"): + print(" online=`cat $i/online`", file=config) + print(" # during boot time, cpu hotplug may be disabled by pci_device_probe during a pci module insmod", file=config) + if uos_type != "PREEMPT-RT LINUX": + print(' while [ "$online" = "1" ]; do', file=config) + print(" sleep 1", file=config) + print(" echo 0 > $i/online", file=config) + print(" online=`cat $i/online`", file=config) + print(" done", file=config) + print(" echo $idx > ${offline_path}/offline_cpu", file=config) + print(" fi", file=config) + print("done", file=config) + print("", file=config) + + +def run_container(board_name, config): + if board_name != "apl-mrb": + return + + print("function run_container()", file=config) + print("{", file=config) + print("vm_name=vm1", file=config) + print('config_src="/usr/share/acrn/samples/apl-mrb/runC.json"', file=config) + print('shell="/usr/share/acrn/conf/add/$vm_name.sh"', file=config) + print('arg_file="/usr/share/acrn/conf/add/$vm_name.args"', file=config) + print('runc_bundle="/usr/share/acrn/conf/add/runc/$vm_name"', file=config) + print('rootfs_dir="/usr/share/acrn/conf/add/runc/rootfs"', file=config) + print('config_dst="$runc_bundle/config.json"', file=config) + print("", file=config) + print("", file=config) + print("input=$(runc list -f table | awk '{print $1}''{print $3}')", file=config) + print("arr=(${input// / })", file=config) + print("", file=config) + print("for((i=0;i<${#arr[@]};i++))", file=config) + print("do", file=config) + print(' if [ "$vm_name" = "${arr[$i]}" ]; then', file=config) + print(' if [ "running" = "${arr[$i+1]}" ]; then', file=config) + print(' echo "runC instance ${arr[$i]} is running"', file=config) + print(" exit", file=config) + print(" else", file=config) + print(" runc kill ${arr[$i]}", file=config) + print(" runc delete ${arr[$i]}", file=config) + print(" fi", file=config) + print(" fi", file=config) + print("done", file=config) + print("vmsts=$(acrnctl list)", file=config) + print("vms=(${vmsts// / })", file=config) + print("for((i=0;i<${#vms[@]};i++))", file=config) + print("do", file=config) + print(' if [ "$vm_name" = "${vms[$i]}" ]; then', file=config) + print(' if [ "stopped" != "${vms[$i+1]}" ]; then', file=config) + print(' echo "Uos ${vms[$i]} ${vms[$i+1]}"', file=config) + print(" acrnctl stop ${vms[$i]}", file=config) + print(" fi", file=config) + print(" fi", file=config) + print("done", file=config) + + +def boot_image_type(args, vmid, config): + + if not args['vbootloader'][vmid] or (args['vbootloader'][vmid] and args['vbootloader'][vmid] != "vsbl"): + return + + print('boot_dev_flag=",b"', file=config) + print("if [ $7 == 1 ];then", file=config) + print(' boot_image_option="--vsbl /usr/share/acrn/bios/VSBL_debug.bin"', file=config) + print("else", file=config) + print(' boot_image_option="--vsbl /usr/share/acrn/bios/VSBL.bin"', file=config) + print("fi", file=config) + print("", file=config) + + +def interrupt_storm(names, vmid, config): + uos_type = names['uos_types'][vmid] + + if uos_type not in ("CLEARLINUX", "ANDROID", "ALIOS") or is_nuc_clr(names, vmid): + return + + print("#interrupt storm monitor for pass-through devices, params order:", file=config) + print("#threshold/s,probe-period(s),intr-inject-delay-time(ms),delay-duration(ms)", file=config) + print('intr_storm_monitor="--intr_monitor 10000,10,1,100"', file=config) + print("", file=config) + + +def gvt_arg_set(uos_type, config): + + if uos_type not in ('CLEARLINUX', 'ANDROID', 'ALIOS'): + return + print("GVT_args=$3", file=config) + print('boot_GVT_option=" -s 0:2:0,pci-gvt -G "', file=config) + print("", file=config) + + +def log_level_set(uos_type, config): + + if uos_type not in ('CLEARLINUX', 'ANDROID', 'ALIOS'): + return + print("#logger_setting, format: logger_name,level; like following", file=config) + print('logger_setting="--logger_setting console,level=4;kmsg,level=3;disk,level=5"', file=config) + print("", file=config) + + +def launch_begin(uos_type, config): + launch_uos = '_'.join(uos_type.lower().split()) + print("function launch_{}()".format(launch_uos), file=config) + print("{", file=config) + + +def wa_usage(uos_type, config): + if uos_type in ("ANDROID", "ALIOS"): + print("# WA for USB role switch hang issue, disable runtime PM of xHCI device", file=config) + print("echo on > /sys/devices/pci0000:00/0000:00:15.0/power/control", file=config) + print("", file=config) + +def mem_size_set(names, args, vmid, config): + + uos_type = names['uos_types'][vmid] + #board_name = names['board_name'] + mem_size = args['mem_size'][vmid] + + if uos_type not in ("CLEARLINUX", "ANDROID", "ALIOS") or is_nuc_clr(names, vmid): + print("mem_size={}M".format(mem_size), file=config) + return + + print("#for memsize setting, total 8GB(>7.5GB) uos->6GB, 4GB(>3.5GB) uos->2GB", file=config) + print("memsize=`cat /proc/meminfo|head -n 1|awk '{print $2}'`", file=config) + print("if [ $memsize -gt 7500000 ];then", file=config) + print(" mem_size=6G", file=config) + print("elif [ $memsize -gt 3500000 ];then", file=config) + print(" mem_size=2G", file=config) + print("else", file=config) + print(" mem_size=1750M", file=config) + print("fi", file=config) + print("", file=config) + print('if [ "$setup_mem" != "" ];then', file=config) + print(" mem_size=$setup_mem", file=config) + print("fi", file=config) + print("", file=config) + + +def function_help(config): + print("function help()", file=config) + print("{", file=config) + print('echo "Use luanch_uos.sh like that ./launch_uos.sh -V <#>"', file=config) + print('echo "The option -V means the UOSs group to be launched by vsbl as below"', file=config) + print('echo "-V 1 means just launching 1 clearlinux UOS"', file=config) + print('echo "-V 2 means just launching 1 android UOS"', file=config) + print('echo "-V 4 means launching 2 clearlinux UOSs"', file=config) + print('echo "-V 5 means just launching 1 alios UOS"', file=config) + print('echo "-V 6 means auto check android/linux/alios UOS; if exist, launch it"', file=config) + print("}", file=config) + print("", file=config) + + +def uos_launch(names, args, vmid, config): + gvt_args = args['gvt_args'][vmid] + cpu_num = int(args['cpu_num'][vmid]) + uos_type = names['uos_types'][vmid] + launch_uos = '_'.join(uos_type.lower().split()) + + if uos_type in ("CLEARLINUX", "ANDROID", "ALIOS") and not is_nuc_clr(names, vmid): + + print("", file=config) + print("case $launch_type in", file=config) + print(' 1) echo "Launch clearlinux UOS"', file=config) + print(' launch_clearlinux 1 {} "{}" 0x070F00 clearlinux "LaaG" $debug'.format(cpu_num, gvt_args), file=config) + print(" ;;", file=config) + print(' 2) echo "Launch android UOS"', file=config) + print(' launch_android 1 {} "{}" 0x070F00 android "AaaG" $debug'.format(cpu_num, gvt_args), file=config) + print(" ;;", file=config) + print(' 4) echo "Launch two clearlinux UOSs"', file=config) + print(' launch_clearlinux 1 {} "{}" 0x00000C clearlinux "L1aaG" $debug &'.format(cpu_num, gvt_args), file=config) + print(" sleep 5", file=config) + print(' launch_clearlinux 2 {} "{}" 0x070F00 clearlinux_dup "L2aaG" $debug'.format(cpu_num, gvt_args), file=config) + print(" ;;", file=config) + print(' 5) echo "Launch alios UOS"', file=config) + print(' launch_alios 1 {} "{}" 0x070F00 alios "AliaaG" $debug'.format(cpu_num, gvt_args), file=config) + print(" ;;", file=config) + print("esac", file=config) + print("", file=config) + print("umount /data", file=config) + + if uos_type not in ("CLEARLINUX", "ANDROID", "ALIOS"): + if uos_type == "VXWORKS": + print("launch_{} 1 {}".format(launch_uos, cpu_num), file=config) + if uos_type == "PREEMPT-RT LINUX": + print("launch_{} {}".format(launch_uos, cpu_num), file=config) + if uos_type == "WINDOWS": + print('launch_{} 1 {} "{}"'.format(launch_uos, cpu_num, gvt_args), file=config) + if uos_type == "ZEPHYR": + print("launch_{} 1 {}".format(launch_uos, cpu_num), file=config) + + if is_nuc_clr(names, vmid): + print('if [ "$1" = "-C" ];then', file=config) + print(' echo "runc_container"', file=config) + print(" run_container", file=config) + print("else", file=config) + print(' launch_{} 1 {} "{}" 0x070F00'.format(launch_uos, cpu_num, gvt_args), file=config) + print("fi", file=config) + + +def launch_type(names, args, vmid, config): + + uos_type = names['uos_types'][vmid] + #board_name = names['board_name'] + mem_size = args["mem_size"][vmid] + + if uos_type in ("ANDROID", "ALIOS") and not is_nuc_clr(names, vmid): + function_help(config) + + if uos_type in ("CLEARLINUX", "ANDROID", "ALIOS") and not is_nuc_clr(names, vmid): + print("launch_type=1", file=config) + print("debug=0", file=config) + print("", file=config) + print('while getopts "V:M:hd" opt', file=config) + print("do", file=config) + print(" case $opt in", file=config) + print(" V) launch_type=$[$OPTARG]", file=config) + print(" ;;", file=config) + + if not mem_size: + print(" M) setup_mem=$OPTARG", file=config) + else: + print(" M) setup_mem={}M".format(mem_size), file=config) + print(" ;;", file=config) + print(" d) debug=1", file=config) + print(" ;;", file=config) + print(" h) help", file=config) + print(" exit 1", file=config) + print(" ;;", file=config) + print(" ?) help", file=config) + print(" exit 1", file=config) + print(" ;;", file=config) + print(" esac", file=config) + print("done", file=config) + print("", file=config) + + if uos_type in ("CLEARLINUX", "ANDROID", "ALIOS") and not is_nuc_clr(names, vmid): + root_fs = args['rootfs_dev'][vmid] + + print('if [ ! -b "{}" ]; then'.format(root_fs), file=config) + print(' echo "no {} data partition, exit"'.format(root_fs), file=config) + print(" exit", file=config) + print("fi", file=config) + print("", file=config) + print("mkdir -p /data", file=config) + print("mount {} /data".format(root_fs), file=config) + print("", file=config) + print("if [ $launch_type == 6 ]; then", file=config) + print(' if [ -f "/data/android/android.img" ]; then', file=config) + print(" launch_type=2;", file=config) + print(' elif [ -f "/data/alios/alios.img" ]; then', file=config) + print(" launch_type=5;", file=config) + print(" else", file=config) + print(" launch_type=1;", file=config) + print(" fi", file=config) + print("fi", file=config) + print("", file=config) + + off_line_cpus(uos_type, config) + + uos_launch(names, args, vmid, config) + + +def launch_end(names, args, vmid, config): + #uos_type = names['uos_types'] + launch_type(names, args, vmid, config) + + +def set_dm_pt(names, sel, vmid, config): + + #cap_pt = launch_cfg_lib.get_board_pt_dev(names, vmid) + uos_type = names['uos_types'][vmid] + + if sel.bdf['usb_xdci'][vmid] and sel.slot['usb_xdci'][vmid]: + print(' -s {},passthru,{}/{}/{} \\'.format(sel.slot["usb_xdci"][vmid], sel.bdf["usb_xdci"][vmid][0:2],\ + sel.bdf["usb_xdci"][vmid][3:5], sel.bdf["usb_xdci"][vmid][6:7]), file=config) + + if uos_type in ("ANDROID", "ALIOS"): + print(" $boot_audio_option \\", file=config) + if uos_type == "WINDOWS": + if sel.bdf['audio'][vmid] and sel.slot['audio'][vmid]: + print(" -s {},passthru,{}/{}/{} \\".format( + launch_cfg_lib.virtual_dev_slot("win_audio"), + sel.bdf['audio'][vmid][0:2], sel.bdf['audio'][vmid][3:5], + sel.bdf['audio'][vmid][6:7]), file=config) + + if sel.bdf['cse'][vmid] and sel.slot['cse'][vmid]: + print(" $boot_cse_option \\", file=config) + + if sel.bdf["sd_card"][vmid] and sel.slot['sd_card'][vmid]: + print(' -s {},passthru,{}/{}/{} \\'.format(sel.slot["sd_card"][vmid], sel.bdf["sd_card"][vmid][0:2], \ + sel.bdf["sd_card"][vmid][3:5], sel.bdf["sd_card"][vmid][6:7]), file=config) + + if sel.bdf['bluetooth'][vmid] and sel.slot['bluetooth'][vmid]: + print(' -s {},passthru,{}/{}/{} \\'.format(sel.slot["bluetooth"][vmid], sel.bdf["bluetooth"][vmid][0:2], \ + sel.bdf["bluetooth"][vmid][3:5], sel.bdf["bluetooth"][vmid][6:7]), file=config) + + if sel.bdf['wifi'][vmid] and sel.slot['wifi'][vmid]: + print(" -s {},passthru,{}/{}/{},keep_gsi \\".format(sel.slot["wifi"][vmid], sel.bdf["wifi"][vmid][0:2], \ + sel.bdf["wifi"][vmid][3:5], sel.bdf["wifi"][vmid][6:7]), file=config) + + if sel.bdf['ipu'][vmid] or sel.bdf['ipu_i2c'][vmid]: + print(" $boot_ipu_option \\", file=config) + + if sel.bdf['ethernet'][vmid] and sel.slot['ethernet'][vmid]: + print(" -s {},passthru,{}/{}/{} \\".format(sel.slot["ethernet"][vmid], sel.bdf["ethernet"][vmid][0:2], \ + sel.bdf["ethernet"][vmid][3:5], sel.bdf["ethernet"][vmid][6:7]), file=config) + + if sel.bdf['sata'] and sel.slot["sata"][vmid]: + print(" -s {},passthru,{}/{}/{} \\".format(sel.slot["sata"][vmid], sel.bdf["sata"][vmid][0:2], \ + sel.bdf["sata"][vmid][3:5], sel.bdf["sata"][vmid][6:7]), file=config) + + if sel.bdf['nvme'] and sel.slot["nvme"][vmid]: + print(" -s {},passthru,{}/{}/{} \\".format(sel.slot["nvme"][vmid], sel.bdf["nvme"][vmid][0:2], \ + sel.bdf["nvme"][vmid][3:5], sel.bdf["nvme"][vmid][6:7]), file=config) + + +def dm_arg_set(names, sel, dm, vmid, config): + + uos_type = names['uos_types'][vmid] + board_name = names['board_name'] + + # vbootlaoder for vsbl + boot_image_type(dm, vmid, config) + + # uuid get + scenario_uuid = launch_cfg_lib.get_scenario_uuid() + + # clearlinux/android/alios + dm_str = 'acrn-dm -A -m $mem_size $boot_GVT_option"$GVT_args" -s 0:0,hostbridge -s 1:0,lpc -U {}'.format(scenario_uuid[vmid]) + if uos_type in ("CLEARLINUX", "ANDROID", "ALIOS"): + if uos_type == "CLEARLINUX": + print("{} \\".format(dm_str), file=config) + else: + print('{} $npk_virt \\'.format(dm_str), file=config) + + if board_name == "apl-up2" or is_nuc_clr(names, vmid): + print(" $logger_setting \\", file=config) + + if uos_type in ("ANDROID", "ALIOS"): + print(" -s {},virtio-rpmb \\".format(launch_cfg_lib.virtual_dev_slot("virtio-rpmb")), file=config) + if board_name == "apl-up2": + print(" --pm_notify_channel power_button \\", file=config) + if board_name == "apl-mrb": + print(" --pm_notify_channel ioc \\", file=config) + + if is_nuc_clr(names, vmid): + print(" --pm_notify_channel uart \\", file=config) + print(' --pm_by_vuart pty,/run/acrn/life_mngr_$vm_name \\', file=config) + print(' -s 1:0,lpc -l com2,/run/acrn/life_mngr_$vm_name \\', file=config) + + # mac_seed + if uos_type in ("CLEARLINUX", "ANDROID", "ALIOS"): + print(" --mac_seed $mac_seed \\", file=config) + + # hard rt os + if uos_type == "PREEMPT-RT LINUX": + print("acrn-dm -A -m $mem_size -s 0:0,hostbridge -U {} \\".format(scenario_uuid[vmid]), file=config) + #print(" -k /usr/lib/kernel/default-iot-lts2018-preempt-rt \\", file=config) + print(" -k /usr/lib/kernel/default-iot-lts2018-preempt-rt \\", file=config) + print(" --lapic_pt \\", file=config) + print(" --rtvm \\", file=config) + print(" -s {},virtio-net,tap0 \\".format(launch_cfg_lib.virtual_dev_slot("virtio-net")), file=config) + print(" --virtio_poll 1000000 \\", file=config) + print(" --pm_notify_channel uart --pm_by_vuart tty,/dev/ttyS1 \\", file=config) + + # vxworks + if uos_type == "VXWORKS": + print("acrn-dm -A -m $mem_size -s 0:0,hostbridge -U {} \\".format(scenario_uuid[vmid]), file=config) + print(" -s {},virtio-blk,./VxWorks.img \\".format(launch_cfg_lib.virtual_dev_slot("virtio-blk")), file=config) + print(" --virtio_poll 1000000 \\", file=config) + print(" --lapic_pt \\", file=config) + + # zephyr + if uos_type == "ZEPHYR": + print("acrn-dm -A -m $mem_size -s 0:0,hostbridge -s 1:0,lpc -l -U {} \\".format(scenario_uuid[vmid]), file=config) + print(" -s {},virtio-blk,./zephyr.img \\".format(launch_cfg_lib.virtual_dev_slot("virtio-blk")), file=config) + + # windows + if uos_type == "WINDOWS": + print("acrn-dm -A -m $mem_size -s 0:0,hostbridge -s 1:0,lpc -U {} \\".format(scenario_uuid[vmid]), file=config) + print(' -s 2,pci-gvt -G "$3" \\', file=config) + print(" -s {},virtio-blk,./win10-ltsc.img \\".format(launch_cfg_lib.virtual_dev_slot("virtio-blk")), file=config) + print(" -s {},virtio-net,tap0 \\".format(launch_cfg_lib.virtual_dev_slot("virtio-net")), file=config) + + # vbootloader of ovmf + #if uos_type != "PREEMPT-RT LINUX" and dm['vbootloader'][vmid] == "ovmf": + if dm['vbootloader'][vmid] == "ovmf": + print(" --ovmf ./OVMF.fd \\", file=config) + + # redirect console + if dm['console_type'][vmid] == "com1(ttyS0)": + print(" -l com1,stdio \\", file=config) + print(" -s {},{} \\".format(launch_cfg_lib.virtual_dev_slot("com1(ttyS0)"), + launch_cfg_lib.RE_CONSOLE_MAP['com1(ttyS0)']), file=config) + else: + print(" -s {},{} \\".format( + launch_cfg_lib.virtual_dev_slot("virtio-console(hvc0)"), + launch_cfg_lib.RE_CONSOLE_MAP['virtio-console(hvc0)']), file=config) + + if uos_type in ("CLEARLINUX", "ANDROID", "ALIOS"): + print(" -s {},virtio-net,$tap \\".format(launch_cfg_lib.virtual_dev_slot("virtio-net")), file=config) + + if uos_type in ("CLEARLINUX", "ANDROID", "ALIOS"): + print(" -s {},virtio-hyper_dmabuf \\".format(launch_cfg_lib.virtual_dev_slot("virtio-hyper_dmabuf")), file=config) + if board_name == "apl-mrb": + print(" -i /run/acrn/ioc_$vm_name,0x20 \\", file=config) + print(" -l com2,/run/acrn/ioc_$vm_name \\", file=config) + + if not is_nuc_clr(names, vmid): + print(" -s {},wdt-i6300esb \\".format(launch_cfg_lib.virtual_dev_slot("wdt-i6300esb")), file=config) + print(" $intr_storm_monitor \\", file=config) + if dm['vbootloader'][vmid] == "vsbl": + print(" $boot_image_option \\",file=config) + print(" -s {},virtio-blk$boot_dev_flag,/data/$5/$5.img \\".format(launch_cfg_lib.virtual_dev_slot("virtio-blk")), file=config) + print(" -s {},xhci,1-1:1-2:1-3:2-1:2-2:2-3:cap=apl \\".format(launch_cfg_lib.virtual_dev_slot("xhci")), file=config) + else: + print(" -s {},virtio-blk,/home/clear/uos/uos.img \\".format(launch_cfg_lib.virtual_dev_slot("virtio-blk")), file=config) + + if uos_type in ("ANDROID", "ALIOS"): + print(" --enable_trusty \\", file=config) + + set_dm_pt(names, sel, vmid, config) + if uos_type != "PREEMPT-RT LINUX": + print(" $vm_name", file=config) + else: + print(" hard_rtvm", file=config) + print("}", file=config) + + +def gen(names, pt_sel, dm, vmid, config): + + uos_type = names['uos_types'][vmid] + + # passthrough bdf/vpid dictionay + pt.gen_pt_head(names, pt_sel, vmid, config) + + # gen launch header + launch_begin(uos_type, config) + tap_uos_net(names, vmid, config) + + # passthrough device + pt.gen_pt(names, pt_sel, vmid, config) + wa_usage(uos_type, config) + delay_use_usb_storage(uos_type, config) + mem_size_set(names, dm, vmid, config) + interrupt_storm(names, vmid, config) + gvt_arg_set(uos_type, config) + log_level_set(uos_type, config) + + # gen acrn-dm args + dm_arg_set(names, pt_sel, dm, vmid, config) + + # gen launch end + launch_end(names, dm, vmid, config) diff --git a/misc/acrn-config/launch_config/launch_cfg_gen.py b/misc/acrn-config/launch_config/launch_cfg_gen.py new file mode 100644 index 000000000..5d9918ca1 --- /dev/null +++ b/misc/acrn-config/launch_config/launch_cfg_gen.py @@ -0,0 +1,233 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +import os +import sys +sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'library')) +from launch_item import AvailablePthru, PthruSelected, AcrnDmArgs +import launch_cfg_lib +import com + +ACRN_PATH = launch_cfg_lib.SOURCE_ROOT_DIR +XML_PATH = ACRN_PATH + '/misc/acrn-config/xmls/config-xmls/' + + +def get_launch_item_values(board_info): + """ + Get items which capable multi select for user + :param board_info: it is a file what contains board information for script to read from + """ + launch_item_values = {} + + pthru = AvailablePthru(board_info) + pthru.get_pci_dev() + pthru.insert_nun() + + # pre passthrough device for ui + launch_item_values["uos,passthrough_devices,usb_xdci"] = pthru.avl["usb_xdci"] + launch_item_values["uos,passthrough_devices,ipu"] = pthru.avl["ipu"] + launch_item_values["uos,passthrough_devices,ipu_i2c"] = pthru.avl["ipu_i2c"] + launch_item_values["uos,passthrough_devices,cse"] = pthru.avl["cse"] + launch_item_values["uos,passthrough_devices,audio"] = pthru.avl["audio"] + launch_item_values["uos,passthrough_devices,audio_codec"] = pthru.avl["audio_codec"] + launch_item_values["uos,passthrough_devices,sd_card"] = pthru.avl["sd_card"] + launch_item_values["uos,passthrough_devices,wifi"] = pthru.avl["wifi"] + launch_item_values["uos,passthrough_devices,ethernet"] = pthru.avl["ethernet"] + launch_item_values["uos,passthrough_devices,sata"] = pthru.avl["sata"] + launch_item_values["uos,passthrough_devices,nvme"] = pthru.avl["nvme"] + launch_item_values["uos,passthrough_devices,bluetooth"] = pthru.avl["bluetooth"] + + # acrn dm available optargs + launch_item_values['uos,uos_type'] = launch_cfg_lib.UOS_TYPES + launch_item_values["uos,rtos_type"] = launch_cfg_lib.RTOS_TYPE + launch_item_values["uos,rootfs_dev"] = launch_cfg_lib.get_rootdev_info(board_info) + + launch_item_values["uos,vbootloader"] = launch_cfg_lib.BOOT_TYPE + launch_item_values['uos,console_type'] = launch_cfg_lib.REDIRECT_CONSOLE + launch_item_values['uos,gvt_args'] = launch_cfg_lib.GVT_ARGS + + return launch_item_values + + +def validate_launch_setting(board_info, scenario_info, launch_info): + """ + This is validate the data setting from scenario xml + :param board_info: it is a file what contains board information for script to read from + :param scenario_info: it is a file what user have already setting to + :return: return a dictionary contain errors + """ + launch_cfg_lib.ERR_LIST = {} + launch_cfg_lib.BOARD_INFO_FILE = board_info + launch_cfg_lib.SCENARIO_INFO_FILE = scenario_info + launch_cfg_lib.LAUNCH_INFO_FILE = launch_info + + # init available pt devices and get selected pt devices + pt_avl = AvailablePthru(board_info) + pt_sel = PthruSelected(launch_info, pt_avl.bdf_desc_map, pt_avl.bdf_vpid_map) + dm = AcrnDmArgs(board_info, scenario_info, launch_info) + + # get bdf/vpid list from config xml + pt_sel.get_bdf() + pt_sel.get_vpid() + pt_sel.get_slot() + dm.get_args() + + # check items in config xml + pt_sel.check_item() + dm.check_item() + + return (launch_cfg_lib.ERR_LIST, pt_sel, dm) + + +def ui_entry_api(board_info, scenario_info, launch_info): + + err_dic = {} + arg_list = ['board_cfg_gen.py', '--board', board_info, '--scenario', scenario_info, '--launch', launch_info, '--uosid', '0'] + + err_dic = launch_cfg_lib.prepare() + if err_dic: + return err_dic + + err_dic = main(arg_list) + return err_dic + + +def get_names(): + + names = {} + + # get uos name + uos_types = launch_cfg_lib.get_uos_type() + names['uos_types'] = uos_types + + # get board name + (err_dic, board_name) = launch_cfg_lib.get_board_name() + if err_dic: + return (err_dic, names) + names['board_name'] = board_name + + # get scenario name + (err_dic, scenario_name) = launch_cfg_lib.get_scenario_name() + if err_dic: + return (err_dic, names) + names['scenario_name'] = scenario_name + + return (err_dic, names) + + +def generate_script_file(names, pt_sel, dm, vmid, config): + + uos_type = names['uos_types'][vmid] + board_name = names['board_name'] + scenario_name = names['scenario_name'] + + header_info = "#!/bin/bash\n" +\ + "# board: {}, scenario: {}, uos: {}".format( + board_name.upper(), scenario_name.upper(), uos_type.upper()) + + print("{}".format(header_info), file=config) + com.gen(names, pt_sel, dm, vmid, config) + + +def main(args): + """ + This is main function to start generate launch script + :param args: it is a command line args for the script + """ + config_srcs = [] + + # get parameters + (err_dic, board_info_file, scenario_info_file, launch_info_file, vm_th) = launch_cfg_lib.get_param(args) + if err_dic: + return err_dic + # vm_th =[0..post_vm_max] + # 0: generate all launch script for all post vm launch script + # 1: generate launch script for 1st post vm launch script + # 2: generate launch script for 2nd post vm launch script + + launch_cfg_lib.BOARD_INFO_FILE = board_info_file + launch_cfg_lib.SCENARIO_INFO_FILE = scenario_info_file + launch_cfg_lib.LAUNCH_INFO_FILE = launch_info_file + + # get post vm dic + post_num_list = launch_cfg_lib.get_post_num_list() + + # get toatl post vm number and total vm in launch config file + (launch_vm_count, post_vm_count) = launch_cfg_lib.get_post_vm_cnt() + if vm_th < 0 or vm_th > post_vm_count: + err_dic['uosid err:'] = "--uosid shoudl be positive and less than total post vm count in scenario" + if vm_th and vm_th not in post_num_list: + err_dic['uosid err:'] = "--uosid generate the {} post vm, but this vm's config not in launch xml".format(vm_th) + if launch_vm_count > post_vm_count: + err_dic['xm config err:'] = "too many vms config than scenario" + + for post_num in post_num_list: + if post_num > post_vm_count: + err_dic['xm config err:'] = "launch xml uos id config is bigger than scenario post vm count" + + if err_dic: + return err_dic + + # validate launch config file + (err_dic, pt_sel, dm) = validate_launch_setting(board_info_file, scenario_info_file, launch_info_file) + if err_dic: + return err_dic + + # check if this is the scenario config which matched board info + (err_dic, status) = launch_cfg_lib.is_config_file_match() + if not status: + return err_dic + + (err_dic, names) = get_names() + if err_dic: + return err_dic + + # create output directory + board_name = names['board_name'] + output = XML_PATH + '/' + board_name + '/output/' + if not os.path.exists(output): + os.makedirs(output) + + # generate launch script + if vm_th: + script_name = "launch_uos_id{}.sh".format(vm_th) + commit_msg = script_name + launch_script_file = output + script_name + config_srcs.append(launch_script_file) + with open(launch_script_file, mode = 'w', newline=None, encoding='utf-8') as config: + generate_script_file(names, pt_sel, dm.args, vm_th, config) + else: + for post_vm_i in post_num_list: + script_name = "launch_uos_id{}.sh".format(post_vm_i) + launch_script_file = output + script_name + config_srcs.append(launch_script_file) + with open(launch_script_file, mode = 'w', newline='\n', encoding='utf-8') as config: + generate_script_file(names, pt_sel, dm.args, post_vm_i, config) + + commit_msg = "launch_uos_id{}.sh".format(launch_vm_count) + + # move changes to patch, and apply to the source code + err_dic = launch_cfg_lib.gen_patch(config_srcs, commit_msg) + if not err_dic: + print("Config patch for {} is committed successfully!".format(commit_msg)) + else: + print("Config patch for {} is failed".format(commit_msg)) + + return err_dic + + +if __name__ == '__main__': + + err_dic = launch_cfg_lib.prepare() + if err_dic: + for err_k, err_v in err_dic.items(): + launch_cfg_lib.print_red("{}: {}".format(err_k, err_v), err=True) + sys.exit(1) + + ARGS = sys.argv + err_dic = main(ARGS) + if err_dic: + for err_k, err_v in err_dic.items(): + launch_cfg_lib.print_red("{}: {}".format(err_k, err_v), err=True) diff --git a/misc/acrn-config/launch_config/launch_item.py b/misc/acrn-config/launch_config/launch_item.py new file mode 100644 index 000000000..e2a97a6e7 --- /dev/null +++ b/misc/acrn-config/launch_config/launch_item.py @@ -0,0 +1,142 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +import launch_cfg_lib + +class AcrnDmArgs: + args = {} + + def __init__(self, board_info, scenario_info, launch_info): + self.board_info = board_info + self.scenario_info = scenario_info + self.launch_info = launch_info + + def get_args(self): + self.args["uos_type"] = launch_cfg_lib.get_sub_tree_tag(self.launch_info, "uos_type") + self.args["rtos_type"] = launch_cfg_lib.get_sub_tree_tag(self.launch_info, "rtos_type") + self.args["cpu_num"] = launch_cfg_lib.get_sub_tree_tag(self.launch_info, "cpu_num") + self.args["mem_size"] = launch_cfg_lib.get_sub_tree_tag(self.launch_info, "mem_size") + self.args["gvt_args"] = launch_cfg_lib.get_sub_tree_tag(self.launch_info, "gvt_args") + self.args["rootfs_dev"] = launch_cfg_lib.get_sub_tree_tag(self.launch_info, "rootfs_dev") + self.args["vbootloader"] = launch_cfg_lib.get_sub_tree_tag(self.launch_info, "vbootloader") + self.args["console_type"] = launch_cfg_lib.get_sub_tree_tag(self.launch_info, "console_type") + + def check_item(self): + rootfs = launch_cfg_lib.get_rootdev_info(self.board_info) + launch_cfg_lib.args_aval_check(self.args["uos_type"], "uos_type", launch_cfg_lib.UOS_TYPES) + launch_cfg_lib.args_aval_check(self.args["rtos_type"], "rtos_type", launch_cfg_lib.RTOS_TYPE) + launch_cfg_lib.args_aval_check(self.args["gvt_args"], "gvt_args", launch_cfg_lib.GVT_ARGS) + launch_cfg_lib.args_aval_check(self.args["vbootloader"], "vbootloader", launch_cfg_lib.BOOT_TYPE) + launch_cfg_lib.args_aval_check(self.args["console_type"], "console_type", launch_cfg_lib.REDIRECT_CONSOLE) + launch_cfg_lib.args_aval_check(self.args["rootfs_dev"], "rootfs_dev", rootfs) + + +class AvailablePthru(): + + avl = {} + + def __init__(self, board_info): + self.board_info = board_info + (self.bdf_desc_map, self.bdf_vpid_map) = launch_cfg_lib.get_pci_info(board_info) + + def get_bdf_vpid_map(self): + return self.bdf_vpid_map + + def get_pci_dev(self): + self.avl["usb_xdci"] = launch_cfg_lib.get_avl_dev_info(self.bdf_desc_map, launch_cfg_lib.PT_SUB_PCI['usb_xdci']) + self.avl["ipu"] = launch_cfg_lib.get_avl_dev_info(self.bdf_desc_map, launch_cfg_lib.PT_SUB_PCI['ipu']) + self.avl["ipu_i2c"] = launch_cfg_lib.get_avl_dev_info(self.bdf_desc_map, launch_cfg_lib.PT_SUB_PCI['ipu_i2c']) + self.avl["cse"] = launch_cfg_lib.get_avl_dev_info(self.bdf_desc_map, launch_cfg_lib.PT_SUB_PCI['cse']) + self.avl["audio"] = launch_cfg_lib.get_avl_dev_info(self.bdf_desc_map, launch_cfg_lib.PT_SUB_PCI['audio']) + self.avl["audio_codec"] = launch_cfg_lib.get_avl_dev_info(self.bdf_desc_map, launch_cfg_lib.PT_SUB_PCI['audio_codec']) + self.avl["sd_card"] = launch_cfg_lib.get_avl_dev_info(self.bdf_desc_map, launch_cfg_lib.PT_SUB_PCI['sd_card']) + self.avl["wifi"] = launch_cfg_lib.get_avl_dev_info(self.bdf_desc_map, launch_cfg_lib.PT_SUB_PCI['wifi']) + self.avl["ethernet"] = launch_cfg_lib.get_avl_dev_info(self.bdf_desc_map, launch_cfg_lib.PT_SUB_PCI['ethernet']) + self.avl["sata"] = launch_cfg_lib.get_avl_dev_info(self.bdf_desc_map, launch_cfg_lib.PT_SUB_PCI['sata']) + self.avl["nvme"] = launch_cfg_lib.get_avl_dev_info(self.bdf_desc_map, launch_cfg_lib.PT_SUB_PCI['nvme']) + self.avl["bluetooth"] = launch_cfg_lib.get_avl_dev_info(self.bdf_desc_map, launch_cfg_lib.PT_SUB_PCI['bluetooth']) + + def insert_nun(self): + self.avl["usb_xdci"].insert(0, '') + self.avl["ipu"].insert(0, '') + self.avl["ipu_i2c"].insert(0, '') + self.avl["cse"].insert(0, '') + self.avl["ethernet"].insert(0, '') + self.avl["sd_card"].insert(0, '') + self.avl["audio"].insert(0, '') + self.avl["audio_codec"].insert(0, '') + self.avl["wifi"].insert(0, '') + self.avl["sata"].insert(0, '') + self.avl["nvme"].insert(0, '') + self.avl["bluetooth"].insert(0, '') + + +class PthruSelected(): + + bdf = {} + vpid = {} + slot = {} + + def __init__(self, launch_info, bdf_desc_map, bdf_vpid_map): + self.launch_info = launch_info + self.bdf_desc_map = bdf_desc_map + self.bdf_vpid_map = bdf_vpid_map + + def get_bdf(self): + self.bdf["usb_xdci"] = launch_cfg_lib.get_bdf_from_tag(self.launch_info, "passthrough_devices", "usb_xdci") + self.bdf["ipu"] = launch_cfg_lib.get_bdf_from_tag(self.launch_info, "passthrough_devices", "ipu") + self.bdf["ipu_i2c"] = launch_cfg_lib.get_bdf_from_tag(self.launch_info, "passthrough_devices", "ipu_i2c") + self.bdf["cse"] = launch_cfg_lib.get_bdf_from_tag(self.launch_info, "passthrough_devices", "cse") + self.bdf["ethernet"] = launch_cfg_lib.get_bdf_from_tag(self.launch_info, "passthrough_devices", "ethernet") + self.bdf["sd_card"] = launch_cfg_lib.get_bdf_from_tag(self.launch_info, "passthrough_devices", "sd_card") + self.bdf["sata"] = launch_cfg_lib.get_bdf_from_tag(self.launch_info, "passthrough_devices", "sata") + self.bdf["nvme"] = launch_cfg_lib.get_bdf_from_tag(self.launch_info, "passthrough_devices", "nvme") + self.bdf["audio"] = launch_cfg_lib.get_bdf_from_tag(self.launch_info, "passthrough_devices", "audio") + self.bdf["audio_codec"] = launch_cfg_lib.get_bdf_from_tag(self.launch_info, "passthrough_devices", "audio_codec") + self.bdf["wifi"] = launch_cfg_lib.get_bdf_from_tag(self.launch_info, "passthrough_devices", "wifi") + self.bdf["bluetooth"] = launch_cfg_lib.get_bdf_from_tag(self.launch_info, "passthrough_devices", "bluetooth") + + def get_vpid(self): + self.vpid["usb_xdci"] = launch_cfg_lib.get_vpid_from_bdf(self.bdf_vpid_map, self.bdf["usb_xdci"]) + self.vpid["ipu"] = launch_cfg_lib.get_vpid_from_bdf(self.bdf_vpid_map, self.bdf["ipu"]) + self.vpid["ipu_i2c"] = launch_cfg_lib.get_vpid_from_bdf(self.bdf_vpid_map, self.bdf["ipu_i2c"]) + self.vpid["cse"] = launch_cfg_lib.get_vpid_from_bdf(self.bdf_vpid_map, self.bdf["cse"]) + self.vpid["ethernet"] = launch_cfg_lib.get_vpid_from_bdf(self.bdf_vpid_map, self.bdf["ethernet"]) + self.vpid["sd_card"] = launch_cfg_lib.get_vpid_from_bdf(self.bdf_vpid_map, self.bdf["sd_card"]) + self.vpid["sata"] = launch_cfg_lib.get_vpid_from_bdf(self.bdf_vpid_map, self.bdf["sata"]) + self.vpid["nvme"] = launch_cfg_lib.get_vpid_from_bdf(self.bdf_vpid_map, self.bdf["nvme"]) + self.vpid["audio"] = launch_cfg_lib.get_vpid_from_bdf(self.bdf_vpid_map, self.bdf["audio"]) + self.vpid["audio_codec"] = launch_cfg_lib.get_vpid_from_bdf(self.bdf_vpid_map, self.bdf["audio_codec"]) + self.vpid["wifi"] = launch_cfg_lib.get_vpid_from_bdf(self.bdf_vpid_map, self.bdf["wifi"]) + self.vpid["bluetooth"] = launch_cfg_lib.get_vpid_from_bdf(self.bdf_vpid_map, self.bdf["bluetooth"]) + + + def get_slot(self): + self.slot["usb_xdci"] = launch_cfg_lib.get_slot(self.bdf["usb_xdci"], "usb_xdci") + self.slot["ipu"] = launch_cfg_lib.get_slot(self.bdf["ipu"], "ipu") + self.slot["ipu_i2c"] = launch_cfg_lib.get_slot(self.bdf["ipu_i2c"], "ipu_i2c") + self.slot["cse"] = launch_cfg_lib.get_slot(self.bdf["cse"], "cse") + self.slot["ethernet"] = launch_cfg_lib.get_slot(self.bdf["ethernet"], "ethernet") + self.slot["sd_card"] = launch_cfg_lib.get_slot(self.bdf["sd_card"], "sd_card") + self.slot["sata"] = launch_cfg_lib.get_slot(self.bdf["sata"], "sata") + self.slot["nvme"] = launch_cfg_lib.get_slot(self.bdf["nvme"], "nvme") + self.slot["audio"] = launch_cfg_lib.get_slot(self.bdf["audio"], "audio") + self.slot["audio_codec"] = launch_cfg_lib.get_slot(self.bdf["audio_codec"], "audio_codec") + self.slot["wifi"] = launch_cfg_lib.get_slot(self.bdf["wifi"], "wifi") + self.slot["bluetooth"] = launch_cfg_lib.get_slot(self.bdf["bluetooth"], "bluetooth") + + def check_item(self): + launch_cfg_lib.pt_devs_check(self.bdf["usb_xdci"], self.vpid["usb_xdci"], "usb_xdci") + launch_cfg_lib.pt_devs_check(self.bdf["ipu"], self.vpid["ipu"], "ipu") + launch_cfg_lib.pt_devs_check(self.bdf["ipu_i2c"], self.vpid["ipu_i2c"], "ipu_i2c") + launch_cfg_lib.pt_devs_check(self.bdf["cse"], self.vpid["cse"], "cse") + launch_cfg_lib.pt_devs_check(self.bdf["ethernet"], self.vpid["ethernet"], "ethernet") + launch_cfg_lib.pt_devs_check(self.bdf["sd_card"], self.vpid["sd_card"], "sd_card") + launch_cfg_lib.pt_devs_check(self.bdf["sata"], self.vpid["sata"], "sata") + launch_cfg_lib.pt_devs_check(self.bdf["nvme"], self.vpid["nvme"], "nvme") + launch_cfg_lib.pt_devs_check(self.bdf["audio"], self.vpid["audio"], "audio") + launch_cfg_lib.pt_devs_check(self.bdf["audio_codec"], self.vpid["audio_codec"], "audio_codec") + launch_cfg_lib.pt_devs_check(self.bdf["wifi"], self.vpid["wifi"], "wifi") + launch_cfg_lib.pt_devs_check(self.bdf["bluetooth"], self.vpid["bluetooth"], "bluetooth") diff --git a/misc/acrn-config/launch_config/pt.py b/misc/acrn-config/launch_config/pt.py new file mode 100644 index 000000000..27e415388 --- /dev/null +++ b/misc/acrn-config/launch_config/pt.py @@ -0,0 +1,247 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +import launch_cfg_lib + +MEDIA_DEV = ['ipu', 'ipu_i2c', 'cse', 'audio', 'audio_codec'] + + +def pass_through_dev(sel, pt_dev, vmid, config): + + bdf = sel.bdf[pt_dev][vmid] + if not bdf: + return + + print("# Passthrough {}".format(pt_dev.upper()), file=config) + print('echo ${passthru_vpid["%s"]} > /sys/bus/pci/drivers/pci-stub/new_id'%pt_dev, file=config) + print('echo ${passthru_bdf["%s"]} > /sys/bus/pci/devices/${passthru_bdf["%s"]}/driver/unbind'%(pt_dev, pt_dev), file=config) + print('echo ${passthru_bdf["%s"]} > /sys/bus/pci/drivers/pci-stub/bind'%pt_dev, file=config) + print("", file=config) + + +def ipu_pt(sel, cap_pt, vmid, config): + + if not sel.bdf['ipu'][vmid] and not sel.bdf['ipu_i2c'][vmid]: + return + + bdf_ipu = sel.bdf['ipu'][vmid] + if bdf_ipu: + bus = bdf_ipu[0:2] + dev = bdf_ipu[3:5] + fun = bdf_ipu[6:7] + slot_ipu = sel.slot['ipu'][vmid] + + bdf_ipu_i2c = sel.bdf['ipu_i2c'][vmid] + if bdf_ipu_i2c: + bus_i2c = bdf_ipu_i2c[0:2] + dev_i2c = bdf_ipu_i2c[3:5] + fun_i2c = bdf_ipu_i2c[6:7] + slot_ipu_i2c = sel.slot['ipu_i2c'][vmid] + + if "ipu" in cap_pt or "ipu_i2c" in cap_pt: + if bdf_ipu or bdf_ipu_i2c: + print("ipu_passthrough=0", file=config) + print("", file=config) + print("# Check the device file of /dev/vbs_ipu to determine the IPU mode", file=config) + print('if [ ! -e "/dev/vbs_ipu" ]; then', file=config) + print("ipu_passthrough=1", file=config) + print("fi", file=config) + print('boot_ipu_option=""', file=config) + print("if [ $ipu_passthrough == 1 ];then", file=config) + + if bdf_ipu: + print(" # for ipu passthrough - ipu device", file=config) + print(' if [ -d "/sys/bus/pci/devices/${passthru_bdf["ipu"]}" ]; then', file=config) + print(' echo ${passthru_vpid["ipu"]} > /sys/bus/pci/drivers/pci-stub/new_id', file=config) + print(' echo ${passthru_bdf["ipu"]} > /sys/bus/pci/devices/${passthru_bdf["ipu"]}/driver/unbind', file=config) + print(' echo ${passthru_bdf["ipu"]} > /sys/bus/pci/drivers/pci-stub/bind', file=config) + print(' boot_ipu_option="$boot_ipu_option"" -s {},passthru,{}/{}/{} "'.format( + slot_ipu, bus, dev, fun), file=config) + print(" fi", file=config) + print("", file=config) + + if bdf_ipu_i2c: + print(" # for ipu passthrough - ipu related i2c", file=config) + print(" # please use virtual slot for i2c to make sure that the i2c controller", file=config) + print(" # could get the same virtaul BDF as physical BDF", file=config) + print(' if [ -d "/sys/bus/pci/devices/${passthru_bdf["ipu_i2c"]}" ]; then', file=config) + print(' echo ${passthru_vpid["ipu_i2c"]} > /sys/bus/pci/drivers/pci-stub/new_id', file=config) + print(' echo ${passthru_bdf["ipu_i2c"]} > /sys/bus/pci/devices/${passthru_bdf["ipu_i2c"]}/driver/unbind', file=config) + print(' echo ${passthru_bdf["ipu_i2c"]} > /sys/bus/pci/drivers/pci-stub/bind', file=config) + print(' boot_ipu_option="$boot_ipu_option"" -s {},passthru,{}/{}/{} "'.format( + slot_ipu_i2c, bus_i2c, dev_i2c, fun_i2c), file=config) + print(" fi", file=config) + + if bdf_ipu or bdf_ipu_i2c: + print("else", file=config) + print(' boot_ipu_option="$boot_ipu_option"" -s {},virtio-ipu "'.format(launch_cfg_lib.virtual_dev_slot("virtio-ipu")), file=config) + print("fi", file=config) + print("", file=config) + + +def cse_pt(sel, cap_pt, vmid, config): + + if not sel.bdf['cse'][vmid]: + return + + bdf = sel.bdf['cse'][vmid] + if bdf: + bus = bdf[0:2] + dev = bdf[3:5] + fun = bdf[6:7] + slot = sel.slot['cse'][vmid] + + if "cse" in cap_pt: + if bdf: + print("cse_passthrough=0", file=config) + print("hbm_ver=`cat /sys/class/mei/mei0/hbm_ver`", file=config) + print("major_ver=`echo $hbm_ver | cut -d '.' -f1`", file=config) + print("minor_ver=`echo $hbm_ver | cut -d '.' -f2`", file=config) + print('if [[ "$major_ver" -lt "2" ]] || \\', file=config) + print(' [[ "$major_ver" == "2" && "$minor_ver" -lt "2" ]]; then', file=config) + print(" cse_passthrough=1", file=config) + print("fi", file=config) + print('boot_cse_option=""', file=config) + print("if [ $cse_passthrough == 1 ]; then", file=config) + print(' echo ${passthru_vpid["cse"]} > /sys/bus/pci/drivers/pci-stub/new_id', file=config) + print(' echo ${passthru_bdf["cse"]} > /sys/bus/pci/devices/${passthru_bdf["cse"]}/driver/unbind', file=config) + print(' echo ${passthru_bdf["cse"]} > /sys/bus/pci/drivers/pci-stub/bind', file=config) + print(' boot_cse_option="$boot_cse_option"" -s {},passthru,{}/{}/{} "'.format( + slot, bus, dev, fun), file=config) + print("else", file=config) + print(' boot_cse_option="$boot_cse_option"" -s {},virtio-heci,{}/{}/{} "'.format( + slot, bus, dev, fun), file=config) + print("fi", file=config) + print("", file=config) + + +def audio_pt(uos_type, sel, cap_pt, vmid, config): + + if not sel.bdf['audio'][vmid] and not sel.bdf['audio_codec'][vmid]: + return + + bdf_audio = sel.bdf['audio'][vmid] + if bdf_audio: + bus = bdf_audio[0:2] + dev = bdf_audio[3:5] + fun = bdf_audio[6:7] + slot_audio = sel.slot['audio'][vmid] + + bdf_codec = sel.bdf['audio_codec'][vmid] + if bdf_codec: + bus_codec = bdf_codec[0:2] + dev_codec = bdf_codec[3:5] + fun_codec = bdf_codec[6:7] + slot_codec = sel.slot['audio_codec'][vmid] + + if uos_type == "WINDOWS": + print(' echo ${passthru_vpid["audio"]} > /sys/bus/pci/drivers/pci-stub/new_id', file=config) + print(' echo ${passthru_bdf["audio"]} > /sys/bus/pci/devices/${passthru_bdf["audio"]}/driver/unbind', file=config) + print(' echo ${passthru_bdf["audio"]} > /sys/bus/pci/drivers/pci-stub/bind', file=config) + return + + if "audio" in cap_pt or "audio_codec" in cap_pt: + if bdf_audio: + print("kernel_version=$(uname -r)", file=config) + print('audio_module="/usr/lib/modules/$kernel_version/kernel/sound/soc/intel/boards/snd-soc-sst_bxt_sos_tdf8532.ko"', file=config) + print("", file=config) + print("# use the modprobe to force loading snd-soc-skl/sst_bxt_bdf8532", file=config) + print("if [ ! -e $audio_module ]; then", file=config) + print("modprobe -q snd-soc-skl", file=config) + print("modprobe -q snd-soc-sst_bxt_tdf8532", file=config) + print("else", file=config) + print("", file=config) + print("modprobe -q snd_soc_skl", file=config) + print("modprobe -q snd_soc_tdf8532", file=config) + print("modprobe -q snd_soc_sst_bxt_sos_tdf8532", file=config) + print("modprobe -q snd_soc_skl_virtio_be", file=config) + print("fi", file=config) + print("audio_passthrough=0", file=config) + print("", file=config) + print("# Check the device file of /dev/vbs_k_audio to determine the audio mode", file=config) + print('if [ ! -e "/dev/vbs_k_audio" ]; then', file=config) + print("audio_passthrough=1", file=config) + print("fi", file=config) + print('boot_audio_option=""', file=config) + print("if [ $audio_passthrough == 1 ]; then", file=config) + print(" # for audio device", file=config) + print(' echo ${passthru_vpid["audio"]} > /sys/bus/pci/drivers/pci-stub/new_id', file=config) + print(' echo ${passthru_bdf["audio"]} > /sys/bus/pci/devices/${passthru_bdf["audio"]}/driver/unbind', file=config) + print(' echo ${passthru_bdf["audio"]} > /sys/bus/pci/drivers/pci-stub/bind', file=config) + print("", file=config) + + print(" # for audio codec", file=config) + print(' echo ${passthru_vpid["audio_codec"]} > /sys/bus/pci/drivers/pci-stub/new_id', file=config) + print(' echo ${passthru_bdf["audio_codec"]} > /sys/bus/pci/devices/${passthru_bdf["audio_codec"]}/driver/unbind', file=config) + print(' echo ${passthru_bdf["audio_codec"]} > /sys/bus/pci/drivers/pci-stub/bind', file=config) + print("", file=config) + + print(' boot_audio_option="-s {},passthru,{}/{}/{},'.format( + slot_audio, bus, dev, fun), end="", file=config) + print('keep_gsi -s {},passthru,{}/{}/{}"'.format( + slot_codec, bus_codec, dev_codec, fun_codec), file=config) + print("else", file=config) + print(' boot_audio_option="-s {},virtio-audio"'.format(slot_audio), file=config) + print("fi", file=config) + + +def media_pt(uos_type, sel, cap_pt, vmid, config): + ipu_pt(sel, cap_pt, vmid, config) + cse_pt(sel, cap_pt, vmid, config) + audio_pt(uos_type, sel, cap_pt, vmid, config) + + +def gen_pt(names, sel, vmid, config): + + pt_none = True + cap_pt = launch_cfg_lib.get_board_pt_dev(names, vmid) + uos_type = names['uos_types'][vmid] + for pt_dev in cap_pt: + if sel.bdf[pt_dev][vmid]: + pt_none = False + if pt_none: + return + + print("modprobe pci_stub", file=config) + for pt_dev in cap_pt: + if pt_dev not in MEDIA_DEV: + pass_through_dev(sel, pt_dev, vmid, config) + continue + + media_pt(uos_type, sel, cap_pt, vmid, config) + +def gen_pt_head(names, sel, vmid, config): + + # get passthrough device for specify board and uos + cap_pt = launch_cfg_lib.get_board_pt_dev(names, vmid) + uos_type = names['uos_types'][vmid] + pt_none = True + + for pt_dev in cap_pt: + if sel.bdf[pt_dev][vmid]: + pt_none = False + if pt_none: + return + + print("# pci devices for passthru", file=config) + print("declare -A passthru_vpid", file=config) + print("declare -A passthru_bdf", file=config) + print("", file=config) + + print("passthru_vpid=(", file=config) + for pt_dev in cap_pt: + if not sel.vpid[pt_dev] or not sel.vpid[pt_dev][vmid]: + continue + print('["{}"]="{}"'.format(pt_dev, sel.vpid[pt_dev][vmid]), file=config) + print(')', file=config) + + print("passthru_bdf=(", file=config) + for pt_dev in cap_pt: + if not sel.bdf[pt_dev] or not sel.bdf[pt_dev][vmid]: + continue + print('["{}"]="0000:{}"'.format(pt_dev, sel.bdf[pt_dev][vmid]), file=config) + print(')', file=config) + + print("", file=config) diff --git a/misc/acrn-config/library/common.py b/misc/acrn-config/library/common.py index 762d82717..17506c872 100644 --- a/misc/acrn-config/library/common.py +++ b/misc/acrn-config/library/common.py @@ -274,7 +274,7 @@ def get_vm_count(config_file): return vm_count -def get_post_vm_count(config_file): +def launch_vm_cnt(config_file): """ Get post vm number :param config_file: it is a file what contains information for script to read from @@ -291,6 +291,23 @@ def get_post_vm_count(config_file): return post_vm_count +def get_post_num_list(config_file): + """ + Get post vm number list + :param config_file: it is a file what contains information for script to read from + :return: total post dic: {launch_id:scenario_id} in launch file + """ + post_vm_list = [] + + # get post vm number + root = get_config_root(config_file) + for item in root: + if item.tag == "uos": + post_vm_list.append(int(item.attrib['id'])) + + return post_vm_list + + def get_tree_tag_val(config_file, tag_str): """ This is get tag value by tag_str from config file @@ -306,25 +323,6 @@ def get_tree_tag_val(config_file, tag_str): return False -#def get_spec_branch_tag(config_file, tag_str, p_id): -# """ -# This is get tag value by tag_str from config file -# :param config_file: it is a file what contains information for script to read from -# :param tag_str: it is key of pattern to config file item -# :return: value of tag_str item list -# """ -# tmp_tag = '' -# root = get_config_root(config_file) -# for item in root: -# if item.tag != 'vm' and item.attrib['id'] != str(p_id): -# continue -# for sub in item: -# if sub.tag == tag_str: -# tmp_tag = sub.text -# -# return tmp_tag - - def get_branch_tag_val(config_file, tag_str): """ This is get tag value by tag_str from config file @@ -342,21 +340,23 @@ def get_branch_tag_val(config_file, tag_str): return tmp_tag -def get_spec_branch_tag_val(config_file, tag_str, uos_id): +def get_spec_branch_tag_val(config_file, tag_str): """ This is get tag value by tag_str from config file :param config_file: it is a file what contains information for script to read from :param tag_str: it is key of pattern to config file item :return: value of tag_str item list """ - tmp_tag = '' + tmp_tag = {} root = get_config_root(config_file) for item in root: - if item.attrib['id'] != uos_id: - continue + id_i = int(item.attrib['id']) for sub in item: if sub.tag == tag_str: - tmp_tag = sub.text + if sub.text == None or not sub.text: + tmp_tag[id_i] = '' + else: + tmp_tag[id_i] = sub.text return tmp_tag @@ -369,31 +369,33 @@ def get_branch_tag_map(config_file, tag_str): :return: value of tag_str item dictionary """ tmp_tag = {} - vm_id = 0 root = get_config_root(config_file) for item in root: + vm_id = int(item.attrib['id']) for sub in item: if sub.tag == tag_str: tmp_tag[vm_id] = sub.text - if item.tag == "vm": - vm_id += 1 + #if item.tag == "vm": + # vm_id += 1 return tmp_tag -def get_spec_leaf_tag_val(config_file, branch_tag, tag_str, uos_id): - tmp_tag = '' +def get_spec_leaf_tag_val(config_file, branch_tag, tag_str): + tmp_tag = {} root = get_config_root(config_file) for item in root: - if item.attrib['id'] != uos_id: - continue + id_i = int(item.attrib['id']) for sub in item: if sub.tag == branch_tag: for leaf in sub: if leaf.tag == tag_str and tag_str != "guest_flag" and tag_str != "pcpu_id" and\ sub.tag != "vuart": - tmp_tag = leaf.text + if leaf.text == None or not leaf.text: + tmp_tag[id_i] = '' + else: + tmp_tag[id_i] = leaf.text continue return tmp_tag @@ -569,6 +571,22 @@ def vm_pre_launch_cnt(config_file): return pre_launch_cnt +def post_vm_cnt(config_file): + """ + Calculate the pre launched vm number + :param config_file: it is a file what contains information for script to read from + :return: number of post launched vm + """ + post_launch_cnt = 0 + load_type_list = get_branch_tag_val(config_file, "load_order") + + for vm_type in load_type_list: + if vm_type == "POST_LAUNCHED_VM": + post_launch_cnt += 1 + + return post_launch_cnt + + def handle_root_dev(line): """Handle if it match root device information pattern :param line: one line of information which had decoded to 'ASCII' diff --git a/misc/acrn-config/library/launch_cfg_lib.py b/misc/acrn-config/library/launch_cfg_lib.py new file mode 100644 index 000000000..31b5a2b0f --- /dev/null +++ b/misc/acrn-config/library/launch_cfg_lib.py @@ -0,0 +1,532 @@ +# Copyright (C) 2019 Intel Corporation. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +import os +import getopt +import common + +SOURCE_ROOT_DIR = common.SOURCE_PATH +BOARD_INFO_FILE = "board_info.txt" +SCENARIO_INFO_FILE = "" +LAUNCH_INFO_FILE = "" + +ERR_LIST = {} +BOOT_TYPE = ['no', 'vsbl', 'ovmf'] +RTOS_TYPE = ['no', 'Soft RT', 'Hard RT'] +REDIRECT_CONSOLE = ['com1(ttyS0)', 'virtio-console(hvc0)'] +UOS_TYPES = ['CLEARLINUX', 'ANDROID', 'ALIOS', 'PREEMPT-RT LINUX', 'VXWORKS', 'WINDOWS', 'ZEPHYR', 'GENERIC LINUX'] +GVT_ARGS = ['64 448 8'] + +RE_CONSOLE_MAP = { + "com1(ttyS0)":"virtio-console,@pty:pty_port", + "virtio-console(hvc0)":"virtio-console,@stdio:stdio_port" +} + +PT_SUB_PCI = {} +PT_SUB_PCI['usb_xdci'] = ['USB controller'] +PT_SUB_PCI['ipu'] = ['Multimedia controller'] +PT_SUB_PCI['ipu_i2c'] = ['Signal processing controller'] +PT_SUB_PCI['cse'] = ['Communication controller'] +PT_SUB_PCI['audio'] = ['Audio device', 'Multimedia audio controller'] +PT_SUB_PCI['audio_codec'] = ['Signal processing controller'] +PT_SUB_PCI['sd_card'] = ['SD Host controller'] +PT_SUB_PCI['wifi'] = ['Ethernet controller'] +PT_SUB_PCI['bluetooth'] = ['Signal processing controller'] +PT_SUB_PCI['ethernet'] = ['Ethernet controller'] +PT_SUB_PCI['sata'] = ['SATA controller'] +PT_SUB_PCI['nvme'] = ['Non-Volatile memory controller'] + +# passthrough device of board and uos sepcify +NUC_RT_PASSTHRU = ['ethernet', 'nvme', 'sata'] +NUC_WIN_PASSTHRU = ['audio', 'audio_codec'] +NUC_CLR_PASSTHRU = ['usb_xdci', 'ipu', 'ipu_i2c', 'cse', 'audio', 'audio_codec', 'sd_card', 'ethernet', 'bluetooth'] +UP2_CLR_PASSTHRU = ['usb_xdci', 'ipu', 'ipu_i2c', 'cse'] +UP2_ADR_PASSTHRU = ['usb_xdci', 'audio', 'audio_codec'] +MRB_CLR_PASSTHRU = ['usb_xdci', 'ipu', 'ipu_i2c', 'cse', 'sd_card'] +MRB_ADR_PASSTHRU = ['usb_xdci', 'audio', 'audio_codec', 'sd_card', 'wifi', 'bluetooth'] +GENERIC_PASSTHRU = ['usb_xdci', 'ipu', 'ipu_i2c', 'cse', 'audio', 'sata', 'nvme', 'audio_codec', 'sd_card', 'ethernet', 'wifi', 'bluetooth'] + +PT_SLOT = { + "hostbridge":0, + "lpc":1, + "pci-gvt":2, + "virtio-blk":3, + "audio_codec":24 + } + + +POST_UUID_DIC = {} + + +def prepare(): + """ Check environment """ + return common.check_env() + + +def print_yel(msg, warn=False): + """ + Print the message with color of yellow + :param msg: the stings which will be output to STDOUT + :param warn: the condition if needs to be output the color of yellow with 'Warning' + """ + common.print_if_yel(msg, warn) + + +def print_red(msg, err=False): + """ + Print the message with color of red + :param msg: the stings which will be output to STDOUT + :param err: the condition if needs to be output the color of red with 'Error' + """ + common.print_if_red(msg, err) + + +def usage(file_name): + """ This is usage for how to use this tool """ + print("usage= {} [h]".format(file_name), end="") + print("--board --scenario --launch --uosid ") + print('board_info_file : file name of the board info') + print('scenario_info_file : file name of the scenario info') + print('launch_info_file : file name of the launch info') + print('uosid : the vm id which to launch:[0..max uosid id]') + + +def get_param(args): + """ + Get the script parameters from command line + :param args: this the command line of string for the script without script name + """ + vm_th = '0' + err_dic = {} + board_info_file = False + scenario_info_file = False + launch_info_file = False + + if '--board' not in args or '--scenario' not in args or '--launch' not in args or '--uosid' not in args: + usage(args[0]) + err_dic['common error: get wrong parameter'] = "wrong usage" + return (err_dic, board_info_file, scenario_info_file, launch_info_file, int(vm_th)) + + args_list = args[1:] + (optlist, args_list) = getopt.getopt(args_list, '', ['board=', 'scenario=', 'launch=', 'uosid=']) + for arg_k, arg_v in optlist: + if arg_k == '--board': + board_info_file = arg_v + if arg_k == '--scenario': + scenario_info_file = arg_v + if arg_k == '--launch': + launch_info_file = arg_v + if '--uosid' in args: + if arg_k == '--uosid': + vm_th = arg_v + if not vm_th.isnumeric(): + err_dic['common error: get wrong parameter'] = "--uosid should be a number" + return (err_dic, board_info_file, scenario_info_file, launch_info_file, int(vm_th)) + + if not board_info_file or not scenario_info_file or not launch_info_file: + usage(args[0]) + err_dic['common error: get wrong parameter'] = "wrong usage" + return (err_dic, board_info_file, scenario_info_file, launch_info_file, int(vm_th)) + + if not os.path.exists(board_info_file): + err_dic['common error: get wrong parameter'] = "{} is not exist!".format(board_info_file) + return (err_dic, board_info_file, scenario_info_file, launch_info_file, int(vm_th)) + + if not os.path.exists(scenario_info_file): + err_dic['common error: get wrong parameter'] = "{} is not exist!".format(scenario_info_file) + return (err_dic, board_info_file, scenario_info_file, launch_info_file, int(vm_th)) + + if not os.path.exists(launch_info_file): + err_dic['common error: get wrong parameter'] = "{} is not exist!".format(launch_info_file) + return (err_dic, board_info_file, scenario_info_file, launch_info_file, int(vm_th)) + + return (err_dic, board_info_file, scenario_info_file, launch_info_file, int(vm_th)) + + +def get_scenario_uuid(): + # {id_num:uuid} (id_num:0~max) + scenario_uuid_dic = {} + scenario_uuid_dic = common.get_branch_tag_map(SCENARIO_INFO_FILE, 'uuid') + return scenario_uuid_dic + + +def get_post_num_list(): + """ + Get board name from launch.xml at fist line + :param scenario_file: it is a file what contains scenario information for script to read from + """ + post_num_list = common.get_post_num_list(LAUNCH_INFO_FILE) + # {launch_id:scenario_id} + return post_num_list + + +def get_post_vm_cnt(): + """ + Get board name from launch.xml at fist line + :param scenario_file: it is a file what contains scenario information for script to read from + """ + launch_vm_count = common.launch_vm_cnt(LAUNCH_INFO_FILE) + post_vm_count = common.post_vm_cnt(SCENARIO_INFO_FILE) + return (launch_vm_count, post_vm_count) + + +def get_pci_info(board_info): + pci_bdf_vpid = {} + pci_vid_start = False + pci_vid_end = False + pci_desc = {} + pci_start = False + pci_end = False + + with open(board_info, 'r') as f: + while True: + line = f.readline() + if not line: + break + + s = " " + if s.join(line.split()[0:2]) == "": + pci_start = True + pci_end = False + continue + + if s.join(line.split()[0:2]) == "": + pci_start = False + pci_end = True + continue + + # all pci device wiht description + if pci_start and not pci_end: + if "Region" in line and "Memory at" in line: + continue + bdf = line.split()[0] + pci_desc[bdf] = line + + if s.join(line.split()[0:2]) == "": + pci_vid_start = True + pci_vid_end = False + continue + + if s.join(line.split()[0:2]) == "": + pci_vid_start = False + pci_vid_end = True + continue + + # all pci device with vid/pid and bdf + if pci_vid_start and not pci_vid_end: + bdf_str = line.split()[0] + vid_pid = line.split()[2] + pci_bdf_vpid[bdf_str] = vid_pid + + return (pci_desc, pci_bdf_vpid) + + +def get_avl_dev_info(bdf_desc_map, pci_sub_class): + + tmp_pci_desc = [] + for sub_class in pci_sub_class: + for pci_desc_value in bdf_desc_map.values(): + pci_desc_sub_class = ' '.join(pci_desc_value.strip().split(':')[1].split()[1:]) + if sub_class == pci_desc_sub_class: + tmp_pci_desc.append(pci_desc_value.strip()) + + return tmp_pci_desc + + +def get_info(board_info, msg_s, msg_e): + """ + Get information which specify by argument + :param board_info: it is a file what contains board information for script to read from + :param msg_s: it is a pattern of key stings what start to match from board information + :param msg_e: it is a pattern of key stings what end to match from board information + """ + info_lines = common.get_board_info(board_info, msg_s, msg_e) + return info_lines + + +def get_rootdev_info(board_info): + """ + Get root devices from board info + :param board_info: it is a file what contains board information for script to read from + :return: root devices list + """ + rootdev_list = [] + rootdev_info = get_info(board_info, "", "") + + if rootdev_info == None: + return rootdev_list + + for rootdev_line in rootdev_info: + if not rootdev_line: + break + + if not common.handle_root_dev(rootdev_line): + continue + + root_dev = rootdev_line.strip().split(':')[0] + rootdev_list.append(root_dev) + + return rootdev_list + + +def get_scenario_name(): + """ + Get board name from scenario.xml at fist line + :param scenario_file: it is a file what contains scenario information for script to read from + """ + (err_dic, scenario) = common.get_xml_attrib(SCENARIO_INFO_FILE, "scenario") + + return (err_dic, scenario) + + +def get_board_name(): + """ + Get board name from board.xml at fist line + :param board_info: it is a file what contains board information for script to read from + """ + (err_dic, board) = common.get_xml_attrib(BOARD_INFO_FILE, "board") + return (err_dic, board) + + +def is_config_file_match(): + + match = True + # check if the board config match scenario config + (err_dic, scenario_for_board) = common.get_xml_attrib(SCENARIO_INFO_FILE, "board") + (err_dic, board_name) = common.get_xml_attrib(BOARD_INFO_FILE, "board") + if scenario_for_board != board_name: + err_dic['scenario config: Not match'] = "The board xml and scenario xml should be matched!" + match = False + + # check if the board config match launch config + (err_dic, launch_for_board) = common.get_xml_attrib(LAUNCH_INFO_FILE, "board") + if launch_for_board != board_name: + err_dic['launch config: Not match'] = "The board xml and launch xml should be matched!" + match = False + + return (err_dic, match) + + +def get_sos_vmid(config_file, tag_str): + + load_list = common.get_branch_tag_val(config_file, tag_str) + + sos_id = 0 + for load_order in load_list: + if load_order == "SOS_VM": + break + + sos_id += 1 + + return sos_id + + +def get_sub_tree_tag(config_file, tag_str): + """ + This is get tag value by tag_str from config file + :param config_file: it is a file what contains information for script to read from + :param tag_str: it is key of pattern to config file item + :return: value of tag_str item + """ + arg = common.get_spec_branch_tag_val(config_file, tag_str) + + return arg + + +def get_bdf_from_tag(config_file, branch_tag, tag_str): + bdf_list = {} + bdf_list = common.get_spec_leaf_tag_val(config_file, branch_tag, tag_str) + + # split b:d:f from pci description + for idx, bdf_v in bdf_list.items(): + if bdf_v: + bdf_list[idx] = bdf_v.split()[0] + + return bdf_list + + +def get_vpid_from_bdf(bdf_vpid_map, bdf_list): + vpid_list = {} + post_vm_list = get_post_num_list() + for p_id in post_vm_list: + for bdf_k, vpid_v in bdf_vpid_map.items(): + if bdf_k == bdf_list[p_id]: + # print("k:{}, v{}".format(bdf_k, bdf_list[p_id])) + # convert "808x:0xxx" to "808x 0xxx" + tmp_vpid = " ".join(vpid_v.split(':')) + vpid_list[p_id] = tmp_vpid + elif not bdf_list[p_id]: + vpid_list[p_id] = '' + + return vpid_list + + +def gen_patch(srcs_list, launch_name): + """ + Generate patch and apply to local source code + :param srcs_list: it is a list what contains source files + :param scenario_name: scenario name + """ + err_dic = common.add_to_patch(srcs_list, launch_name) + return err_dic + + +def get_uos_type(): + """ + Get uos name from launch.xml at fist line + """ + uos_types = get_sub_tree_tag(LAUNCH_INFO_FILE, "uos_type") + + return uos_types + + +def is_bdf_format(bdf_str): + bdf_len = 7 + status = True + if not bdf_str: + return status + + bdf_str_len = len(bdf_str) + if ':' in bdf_str and '.' in bdf_str and bdf_len == bdf_str_len: + status = True + else: + status = False + + return status + + +def is_vpid_format(vpid_str): + status = True + if not vpid_str: + return status + + vpid_len = 9 + vpid_str_len = len(vpid_str) + + if ' ' in vpid_str and vpid_len == vpid_str_len: + status = True + else: + status = False + + return status + + +def pt_devs_check(bdf_list, vpid_list, item): + i_cnt = 1 + + # check bdf + for bdf_str in bdf_list.values(): + if is_bdf_format(bdf_str): + continue + else: + key = "uos,id={},passthrough_devices,{}".format(i_cnt, item) + ERR_LIST[key] = "Unkonw the BDF format of {} device".format(item) + i_cnt += 1 + + # check vpid + i_cnt = 1 + for vpid_str in vpid_list.values(): + if is_vpid_format(vpid_str): + continue + else: + key = "uos,id={},passthrough_devices,{}".format(i_cnt, item) + ERR_LIST[key] = "Unkonw the Vendor:Product ID format of {} device".format(item) + + i_cnt += 1 + + +def args_aval_check(arg_list, item, avl_list): + + # allow args of dm is empty in launch xml + return + err_dic = {} + i_cnt = 1 + for arg_str in arg_list.values(): + if arg_str == None or not arg_str: + key = "uos,id={},{}".format(i_cnt, item) + err_dic[key] = "The parameter should not be empty" + + if arg_str not in avl_list: + key = "uos,id={},{}".format(i_cnt, item) + ERR_LIST[key] = "The {} is invalidate".format(item) + if err_dic: + ERR_LIST.update(err_dic) + i_cnt += 1 + + +def virtual_dev_slot(dev): + max_slot = 31 + base_slot = 3 + + #slot_used_len = len(list(PT_SLOT.values())) + + # get devices slot which already stored + if dev in list(PT_SLOT.keys()): + return PT_SLOT[dev] + + # alloc a new slot for device + for slot_num in range(base_slot, max_slot): + if slot_num not in list(PT_SLOT.values()): + + if (slot_num == 6 and 14 in list(PT_SLOT.values())) or (slot_num == 14 and 6 in list(PT_SLOT.values())): + continue + if (slot_num == 7 and 15 in list(PT_SLOT.values())) or (slot_num == 15 and 7 in list(PT_SLOT.values())): + continue + + PT_SLOT[dev] = slot_num + break + + return slot_num + + +def get_slot(bdf_list, dev): + + slot_list = {} + post_vm_list = get_post_num_list() + for p_id in post_vm_list: + if not bdf_list[p_id]: + slot_list[p_id] = '' + else: + slot = int(bdf_list[p_id][3:5], 16) + # re-allocate virtual slot while slot is 0 + if slot == 0: + slot = virtual_dev_slot(dev) + slot_list[p_id] = slot + PT_SLOT[dev] = slot + + return slot_list + + +def get_board_pt_dev(names, vmid): + + board_name = names['board_name'] + uos_type = names['uos_types'][vmid] + cap_pt = [] + + if 'mrb' in board_name: + if uos_type == "CLEARLINUX": + cap_pt = MRB_CLR_PASSTHRU + if uos_type == "ANDROID": + cap_pt = MRB_ADR_PASSTHRU + elif 'up2' in board_name: + if uos_type == "CLEARLINUX": + cap_pt = UP2_CLR_PASSTHRU + if uos_type == "ANDROID": + cap_pt = UP2_ADR_PASSTHRU + elif 'nuc' in board_name: + if uos_type == "CLEARLINUX": + cap_pt = NUC_CLR_PASSTHRU + elif uos_type == "PREEMPT-RT LINUX": + cap_pt = NUC_RT_PASSTHRU + elif uos_type == "WINDOWS": + cap_pt = NUC_WIN_PASSTHRU + else: + # zephyr/vxworks have no passthroug device + cap_pt = [] + else: + # new board passthrough the generic device + cap_pt = GENERIC_PASSTHRU + + return cap_pt