1#!/usr/bin/env python3
2#
3# Copyright (C) 2022 Intel Corporation.
4#
5# SPDX-License-Identifier: BSD-3-Clause
6#
7
8import sys, os
9sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'library'))
10import acrn_config_utilities
11import rdt
12import re
13from collections import defaultdict
14from itertools import combinations
15from collections import namedtuple
16from acrn_config_utilities import get_node
17
18def create_clos_node(scenario_etree, vm_id, index_list):
19    allocation_vm_node = get_node(f"/acrn-config/vm[@id = '{vm_id}']", scenario_etree)
20    if allocation_vm_node is None:
21        allocation_vm_node = acrn_config_utilities.append_node("/acrn-config/vm", None, scenario_etree, id = vm_id)
22    if get_node("./clos", allocation_vm_node) is None:
23        clos_node = acrn_config_utilities.append_node("./clos", None, allocation_vm_node)
24        for index in index_list:
25            acrn_config_utilities.append_node(f"./vcpu_clos", str(index), clos_node)
26
27def get_clos_id(rdt_list, policy_owner):
28    for index,rdt in enumerate(rdt_list):
29        if rdt.find_policy_owner(policy_owner):
30            return index
31    return 0
32
33def alloc_clos_index(board_etree, scenario_etree, allocation_etree, mask_list):
34    vm_node_list = scenario_etree.xpath("//vm")
35    for vm_node in vm_node_list:
36        vm_name = get_node("./name/text()", vm_node)
37        vcpu_list = scenario_etree.xpath(f"//POLICY[VM = '{vm_name}']/VCPU/text()")
38        index_list = []
39        for vcpu in sorted([int(x) for x in set(vcpu_list)]):
40            if rdt.cdp_enable(scenario_etree):
41                index = get_clos_id(mask_list, rdt.policy_owner(vm_name, vcpu, "Data")) // 2
42            else:
43                index = get_clos_id(mask_list, rdt.policy_owner(vm_name, vcpu, "Unified"))
44            index_list.append(index)
45        create_clos_node(allocation_etree, get_node("./@id", vm_node), index_list)
46
47def create_mask_list_node(board_etree, scenario_etree, allocation_etree, rdt_policy_list):
48    allocation_hv_node = get_node(f"//hv", allocation_etree)
49    if allocation_hv_node is None:
50        allocation_hv_node = acrn_config_utilities.append_node(f"/acrn-config/hv", None, allocation_etree)
51
52    if get_node("./clos_mask[@id = l3]", allocation_hv_node) is None:
53        clos_mask = acrn_config_utilities.append_node("./clos_mask", None, allocation_hv_node, id="l3")
54        length = get_node(f"//cache[@level='3']/capability/capacity_mask_length/text()", board_etree)
55        if length is not None:
56            default_l3_value = hex((1 << int(length)) - 1)
57        else:
58            default_l3_value = "0xffff"
59        for i in range(0, len(rdt_policy_list)):
60            if rdt_policy_list[i].l3policy.get_clos_mask() is not None:
61                value = str(rdt_policy_list[i].l3policy.get_clos_mask())
62            else:
63                value = default_l3_value
64            acrn_config_utilities.append_node(f"./clos", value, clos_mask)
65        for index,cache2 in enumerate(rdt.L2Policy.cache2_id_list):
66            length = get_node(f"//cache[@level='2' and @id = '{cache2}']/capability/capacity_mask_length/text()", board_etree)
67            if length is not None:
68                default_l2_value = hex((1 << int(length)) - 1)
69            else:
70                default_l2_value = "0xffff"
71
72            if get_node("./clos_mask[@id = '{cache2}']", allocation_hv_node) is None:
73                clos_mask = acrn_config_utilities.append_node("./clos_mask", None, allocation_hv_node, id=cache2)
74            for i in range(0, len(rdt_policy_list)):
75                if rdt_policy_list[i].l2policy.get_clos_mask(index) is not None:
76                    value = str(rdt_policy_list[i].l2policy.get_clos_mask(index))
77                else:
78                    value = default_l2_value
79                acrn_config_utilities.append_node(f"./clos", value, clos_mask)
80
81def fn(board_etree, scenario_etree, allocation_etree):
82    policy_list = rdt.get_policy_list(scenario_etree)
83    create_mask_list_node(board_etree, scenario_etree, allocation_etree, policy_list)
84    alloc_clos_index(board_etree, scenario_etree, allocation_etree, policy_list)
85