1#!/usr/bin/env python3
2#
3# Copyright (C) 2021-2022 Intel Corporation.
4#
5# SPDX-License-Identifier: BSD-3-Clause
6#
7import sys, os
8sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'library'))
9
10import argparse
11from defusedxml.lxml import parse
12import acrn_config_utilities
13from acrn_config_utilities import get_node
14
15#vuart devices name is configured to start from /dev/ttyS8
16START_VUART_DEV_NAME_NO = 8
17VUART_DEV_NAME_NUM = 8
18stadard_uart_port = {'0x3F8', '0x2F8', '0x3E8', '0x2E8'}
19UART_IRQ_BAUD = " irq 0 uart 16550A baud_base 115200"
20
21def find_non_standard_uart(vm, scenario_etree, allocation_etree):
22    uart_list = []
23    vmname = get_node("./name/text()", vm)
24
25    connection_list0 = scenario_etree.xpath(f"//vuart_connection[endpoint/vm_name = '{vmname}']")
26    connection_list1 = allocation_etree.xpath(f"//vuart_connection[endpoint/vm_name = '{vmname}']")
27    for connection in (connection_list0 + connection_list1):
28        type = get_node(f"./type/text()", connection)
29
30        if (type != "legacy") :
31            continue
32        port = get_node(f".//endpoint[vm_name = '{vmname}']/io_port/text()", connection)
33        if port not in stadard_uart_port:
34            target_vm_name = get_node(f".//endpoint[vm_name != '{vmname}']/vm_name/text()", connection)
35            target_vm_id = get_node(f"//vm[name = '{target_vm_name}']/@id", scenario_etree)
36            uart_list.append({"io_port" : port, "target_vm_id" : target_vm_id})
37    return uart_list
38
39def main(args):
40    """
41    Generate serial configuration file for service VM
42    :param args: command line args
43    """
44    scenario_etree = parse(args.scenario)
45    allocation_etree = parse(args.allocation)
46    vuart_target_vmid = {}
47
48    vm_list = scenario_etree.xpath("//vm[load_order = 'SERVICE_VM']")
49    for vm in vm_list:
50        vuart_list = find_non_standard_uart(vm, scenario_etree, allocation_etree)
51        vmname = get_node("./name/text()", vm)
52        if len(vuart_list) != 0:
53            with open(args.out, "w+") as config_f:
54                for uart_start_num, vuart in enumerate(vuart_list, start=START_VUART_DEV_NAME_NO):
55                    base = " port " + vuart["io_port"]
56                    vm_id_note = "# User_VM_id: " + str(vuart["target_vm_id"])+ '\n'
57                    config_f.write(vm_id_note)
58                    conf = "/dev/ttyS" + str(uart_start_num) + base + UART_IRQ_BAUD + '\n'
59                    config_f.write(conf)
60
61if __name__ == '__main__':
62    parser = argparse.ArgumentParser()
63    parser.add_argument("--allocation", help="the XML file summarizing resource allocated by config tool")
64    parser.add_argument("--scenario", help="the XML file specifying the scenario to be set up")
65    parser.add_argument("--out", help="location of the output serial configuration file")
66    args = parser.parse_args()
67    main(args)
68