mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-05 05:32:05 +00:00
This patch adds support to configure MBA delay values from scenario xml files just as it is done for CAT mask. This will improve user experience when configuring RDT resource mask values. Tracked-On: #4943 Signed-off-by: Vijay Dhanraj <vijay.dhanraj@intel.com> Acked-by: Victor Sun <victor.sun@intel.com>
224 lines
7.0 KiB
Python
224 lines
7.0 KiB
Python
# Copyright (C) 2020 Intel Corporation. All rights reserved.
|
|
#
|
|
# SPDX-License-Identifier: BSD-3-Clause
|
|
#
|
|
|
|
import os
|
|
import sys
|
|
import common
|
|
import getopt
|
|
import board_cfg_lib
|
|
|
|
|
|
ERR_LIST = {}
|
|
N_Y = ['n', 'y']
|
|
SCHEDULER_TYPE = ['SCHED_NOOP', 'SCHED_IORR', 'SCHED_BVT']
|
|
|
|
RANGE_DB = {
|
|
'LOG_LEVEL':{'min':0,'max':6},
|
|
'LOG_DESTINATION_BITMAP':{'min':0,'max':7},
|
|
'EMULATED_MMIO_REGIONS':{'min':0,'max':128},
|
|
'PT_IRQ_ENTRIES':{'min':0,'max':256},
|
|
'IOAPIC_NUM':{'min':1,'max':10},
|
|
'IOAPIC_LINES':{'min':1,'max':120},
|
|
'PCI_DEV_NUM':{'min':1,'max':1024},
|
|
'MSIX_TABLE_NUM':{'min':1,'max':2048},
|
|
}
|
|
|
|
|
|
def empty_check(val, prime_item, item, sub_item=''):
|
|
if not val or val == None:
|
|
if sub_item:
|
|
key = 'hv,{},{},{}'.format(prime_item, item, sub_item)
|
|
ERR_LIST[key] = "{} should not empty".format(sub_item)
|
|
else:
|
|
key = 'hv,{},{}'.format(prime_item, item)
|
|
ERR_LIST[key] = "{} should not empty".format(item)
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
def is_numeric_check(str_value, prime_item, item):
|
|
|
|
# to skip for strip 0x/0X
|
|
if str_value == '0':
|
|
return True
|
|
str_hex_0x = str_value.lstrip('0x')
|
|
str_hex_0X = str_value.lstrip('0X')
|
|
|
|
if not str_hex_0x.isnumeric() and not str_hex_0X.isnumeric():
|
|
if not isinstance(int(str_hex_0x, 16), int) and not isinstance(int(str_hex_0X, 16), int):
|
|
key = 'hv,{},{}'.format(prime_item, item)
|
|
ERR_LIST[key] = "{} should be a numeric".format(item)
|
|
return False
|
|
return True
|
|
|
|
|
|
def range_check(str_value, prime_item, item, range_val):
|
|
|
|
value = common.num2int(str_value)
|
|
if value < range_val['min'] or value > range_val['max']:
|
|
key = 'hv,{},{}'.format(prime_item, item)
|
|
ERR_LIST[key] = "{} should be in range[{},{}]".format(item, range_val['min'], range_val['max'])
|
|
|
|
|
|
def release_check(sel_str, dbg_opt, rel_str):
|
|
if empty_check(sel_str, dbg_opt, rel_str):
|
|
return
|
|
if sel_str not in N_Y:
|
|
key = 'hv,{},{}'.format(dbg_opt, rel_str)
|
|
ERR_LIST[key] = "{} should be in {}".format(rel_str, N_Y)
|
|
|
|
|
|
def hv_range_check(str_val, branch_tag, item, range_db):
|
|
|
|
if empty_check(str_val, branch_tag, item):
|
|
return
|
|
if not is_numeric_check(str_val, branch_tag, item):
|
|
return
|
|
range_check(str_val, branch_tag, item, range_db)
|
|
|
|
|
|
def hv_size_check(str_val, branch_tag, item):
|
|
|
|
if empty_check(str_val, branch_tag, item):
|
|
return
|
|
if not is_numeric_check(str_val, branch_tag, item):
|
|
return
|
|
|
|
|
|
def ir_entries_check(str_num, cap, cap_ir_entries):
|
|
hv_size_check(str_num, cap, cap_ir_entries)
|
|
val = common.num2int(str_num)
|
|
if val % 2 != 0:
|
|
key = 'hv,{},{}'.format(cap, cap_ir_entries)
|
|
ERR_LIST[key] = "{} should be a value of 2^n".format(cap_ir_entries)
|
|
|
|
|
|
def uefi_load_name_check(str_name, mis, mis_uefi_name):
|
|
|
|
name_len = len(str_name)
|
|
if name_len > 256 or name_len < 0:
|
|
key = 'hv,{},{}'.format(mis, mis_uefi_name)
|
|
ERR_LIST[key] = "{} length should be in range[0, 256]".format(mis_uefi_name)
|
|
|
|
|
|
def ny_support_check(sel_str, feat, feat_item, feat_sub_leaf=''):
|
|
if empty_check(sel_str, feat, feat_item, feat_sub_leaf):
|
|
return
|
|
if sel_str not in N_Y:
|
|
key = 'hv,{},{}'.format(feat, feat_item)
|
|
ERR_LIST[key] = "{} should be in {}".format(feat_item, N_Y)
|
|
|
|
|
|
def scheduler_check(sel_str, feat, feat_scheduler):
|
|
if empty_check(sel_str, feat, feat_scheduler):
|
|
return
|
|
if sel_str not in SCHEDULER_TYPE:
|
|
key = 'hv,{},{}'.format(feat, feat_scheduler)
|
|
ERR_LIST[key] = "{} should be in {}".format(feat_scheduler, SCHEDULER_TYPE)
|
|
|
|
|
|
def get_select_range(branch_tag, range_key):
|
|
|
|
range_list = []
|
|
if range_key not in RANGE_DB.keys():
|
|
key = "hv,{},{}".format(branch_tag, range_key)
|
|
ERR_LIST[key] = "It is invalid for {}.".format(range_key)
|
|
return range_list
|
|
|
|
for range_i in range(RANGE_DB[range_key]['min'], RANGE_DB[range_key]['max'] + 1):
|
|
range_list.append(str(range_i))
|
|
|
|
return range_list
|
|
|
|
|
|
def is_contiguous_bit_set(value):
|
|
|
|
bit_1_cnt = 0
|
|
tmp_val = value
|
|
is_contiguous = False
|
|
|
|
first_p = 0
|
|
last_p = 0
|
|
|
|
while tmp_val > 0:
|
|
tmp_val &= (tmp_val - 1)
|
|
bit_1_cnt += 1
|
|
|
|
for shift_i in range(32):
|
|
mask = (0x1 << shift_i)
|
|
if value & mask:
|
|
if first_p == 0 and last_p == 0:
|
|
first_p = shift_i + 1
|
|
elif first_p != 0:
|
|
last_p = shift_i + 1
|
|
else:
|
|
if first_p == 0 and last_p == 0:
|
|
continue
|
|
break
|
|
|
|
|
|
contiguous_cnt = last_p - first_p + 1
|
|
if bit_1_cnt == contiguous_cnt or bit_1_cnt in (0, 1):
|
|
is_contiguous = True
|
|
|
|
return is_contiguous
|
|
|
|
|
|
def cat_max_mask_check(cat_mask_list, feature, cat_str, max_mask_str):
|
|
|
|
if not board_cfg_lib.is_rdt_supported():
|
|
return
|
|
|
|
(_, rdt_res_clos_max, clos_max_mask_list) = board_cfg_lib.clos_info_parser(common.BOARD_INFO_FILE)
|
|
|
|
clos_max = common.num2int(min(rdt_res_clos_max))
|
|
cat_max_mask_settings_len = len(cat_mask_list)
|
|
if clos_max != cat_max_mask_settings_len:
|
|
key = 'hv,{},{},{}'.format(feature, cat_str, max_mask_str)
|
|
ERR_LIST[key] = "clso max: {} in board xml, should set the same number for CLOS_MASK.".format(clos_max)
|
|
return
|
|
|
|
clos_max_mask_str = clos_max_mask_list[0].strip('"').strip("'")
|
|
clos_max_mask = common.num2int(clos_max_mask_str)
|
|
for val_str in cat_mask_list:
|
|
if empty_check(val_str, feature, cat_str, max_mask_str):
|
|
return
|
|
value = common.num2int(val_str)
|
|
if value < 0 or value > clos_max_mask:
|
|
key = 'hv,{},{},{}'.format(feature, cat_str, max_mask_str)
|
|
ERR_LIST[key] = "{} should be in range[0,{}]".format(max_mask_str, clos_max_mask_str)
|
|
return
|
|
|
|
if not is_contiguous_bit_set(value):
|
|
key = 'hv,{},{},{}'.format(feature, cat_str, max_mask_str)
|
|
ERR_LIST[key] = "CLOS_MASK {} should be contiguous bit set.".format(max_mask_str, clos_max_mask_str)
|
|
return
|
|
|
|
def mba_delay_check(mba_delay_list, feature, mba_str, max_mask_str):
|
|
|
|
if not board_cfg_lib.is_rdt_supported():
|
|
return
|
|
|
|
(_, rdt_res_clos_max, clos_max_mask_list) = board_cfg_lib.clos_info_parser(common.BOARD_INFO_FILE)
|
|
|
|
clos_max = common.num2int(min(rdt_res_clos_max))
|
|
mba_delay_settings_len = len(mba_delay_list)
|
|
if clos_max != mba_delay_settings_len:
|
|
key = 'hv,{},{},{}'.format(feature, mba_str, max_mask_str)
|
|
ERR_LIST[key] = "MBA_DELAY values in scenaio xml should equal to MAX_PLATFORM_CLOS_NUM.".format(clos_max)
|
|
return
|
|
|
|
mba_delay_str = clos_max_mask_list[1].strip('"').strip("'")
|
|
mba_delay = common.num2int(mba_delay_str)
|
|
for val_str in mba_delay_list:
|
|
if empty_check(val_str, feature, mba_str, max_mask_str):
|
|
return
|
|
value = common.num2int(val_str)
|
|
if value > mba_delay:
|
|
key = 'hv,{},{},{}'.format(feature, mba_str, max_mask_str)
|
|
ERR_LIST[key] = "{} should be in range[0,{}]".format(max_mask_str, mba_delay_str)
|
|
return
|