mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-18 19:57:31 +00:00
acrn-config: add ivshmem config in launch setting
Users can add one or more ivshmem shm regions for uos when the shm regions are configured from scenario setting. Tracked-On: #4853 Signed-off-by: Shuang Zheng <shuang.zheng@intel.com> Acked-by: Victor Sun <victor.sun@intel.com>
This commit is contained in:
parent
1ef1ebe4e9
commit
9af694dfbc
@ -440,6 +440,8 @@ $().ready(function(){
|
||||
var id_pre_added = curr_item_id.substr(0, curr_item_id.lastIndexOf('_'));
|
||||
config_item_added.find("button:contains('+')").attr('id', id_pre_added+'_'+id_added);
|
||||
config_item_added.find("button:contains('-')").attr('id', id_pre_added.replace('add_', 'remove_')+'_'+id_added);
|
||||
var curr_err_id = config_item_added.find("p").attr('id');
|
||||
config_item_added.find("p").attr('id', curr_err_id.replace(','+curr_id+'_', ','+id_added+'_'));
|
||||
config_item_added.find("button:contains('-')").prop("disabled", false);
|
||||
config_item_added.find("label:first").text("");
|
||||
config_item_added.find('.bootstrap-select').replaceWith(function() { return $('select', this); });
|
||||
@ -922,7 +924,7 @@ function save_launch(generator=null) {
|
||||
$("select").each(function(){
|
||||
var id = $(this).attr('id');
|
||||
var value = $(this).val();
|
||||
if(id.indexOf('pcpu_id')>=0 || id.indexOf('pci_dev')>=0) {
|
||||
if(id.indexOf('pcpu_id')>=0 || id.indexOf('shm_region')>=0 || id.indexOf('pci_dev')>=0) {
|
||||
if(id in launch_config) {
|
||||
launch_config[id].push(value);
|
||||
} else {
|
||||
|
@ -206,14 +206,19 @@ the launch scripts will be generated into misc/acrn-config/xmls/config-xmls/[boa
|
||||
</div>
|
||||
{% elif elem.getchildren() != [] %}
|
||||
{% if 'multiselect' not in elem.attrib or elem.attrib['multiselect'] != 'true' %}
|
||||
{% set first_child = [] %}
|
||||
{% set first_multi_child = {'block': 0, 'network': 0, 'input': 0} %}
|
||||
{% set first_multi_child = {'block': 0, 'network': 0, 'input': 0, 'pcpu_id': 0, 'shm_region': 0,
|
||||
'passthrough_devices': 0, 'virtio_devices': 0} %}
|
||||
{% for sub_elem in elem.getchildren() %}
|
||||
{% set sub_elem_text = '' if sub_elem.text == None else sub_elem.text %}
|
||||
{% if 'configurable' not in sub_elem.attrib or sub_elem.attrib['configurable'] != '0' %}
|
||||
<div class="form-group">
|
||||
{% if 'id' not in elem.attrib %}
|
||||
{% if not first_child %}
|
||||
{% if elem.tag in first_multi_child.keys() and first_multi_child[elem.tag] == 0 %}
|
||||
<label class="col-sm-1 control-label" data-toggle="tooltip"
|
||||
title="{{sub_elem.attrib['desc'] if 'desc' in sub_elem.attrib else sub_elem.tag}}">
|
||||
{{elem.tag}}</label>
|
||||
{% do first_multi_child.update({elem.tag: first_multi_child[elem.tag]+1}) %}
|
||||
{% elif sub_elem.tag in ['pcpu_id', 'shm_region'] and first_multi_child[sub_elem.tag] == 0 %}
|
||||
<label class="col-sm-1 control-label" data-toggle="tooltip"
|
||||
title="{{sub_elem.attrib['desc'] if 'desc' in sub_elem.attrib else sub_elem.tag}}">
|
||||
{{elem.tag}}</label>
|
||||
@ -228,7 +233,7 @@ the launch scripts will be generated into misc/acrn-config/xmls/config-xmls/[boa
|
||||
{{sub_elem.tag}}</label>
|
||||
|
||||
{% if ','.join(['uos', elem.tag, sub_elem.tag]) not in launch_item_values
|
||||
and elem.tag != 'cpu_affinity'%}
|
||||
and elem.tag != 'cpu_affinity' and elem.tag != 'shm_regions'%}
|
||||
<div class="col-sm-5">
|
||||
{% if 'readonly' in sub_elem.attrib and sub_elem.attrib['readonly'] == 'true' %}
|
||||
<input type="text" class="form-control" readonly
|
||||
@ -254,8 +259,14 @@ the launch scripts will be generated into misc/acrn-config/xmls/config-xmls/[boa
|
||||
{% endif%}
|
||||
|
||||
{% else %}
|
||||
{% set item_key = ','.join(['uos', elem.tag, sub_elem.tag]) if elem.tag != 'cpu_affinity'
|
||||
else ','.join(['uos', elem.tag]) %}
|
||||
|
||||
{% if elem.tag == 'cpu_affinity' %}
|
||||
{% set item_key = ','.join(['uos', elem.tag]) %}
|
||||
{% elif elem.tag == 'shm_regions' %}
|
||||
{% set item_key = ','.join(['uos:id='+vm.attrib['id'], elem.tag, sub_elem.tag]) %}
|
||||
{% else %}
|
||||
{% set item_key = ','.join(['uos', elem.tag, sub_elem.tag]) %}
|
||||
{% endif %}
|
||||
<div class="dropdown col-sm-6">
|
||||
{% if 'readonly' in sub_elem.attrib and sub_elem.attrib['readonly'] == 'true' %}
|
||||
<select class="selectpicker" data-width="auto" disabled
|
||||
@ -273,21 +284,21 @@ the launch scripts will be generated into misc/acrn-config/xmls/config-xmls/[boa
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% if elem.tag == 'cpu_affinity' %}
|
||||
<button type="button" class="btn" id="add_vcpu_{{first_child|length}}">+</button>
|
||||
{% if not first_child %}
|
||||
<button type="button" disabled class="btn" id="remove_vcpu_{{first_child|length}}">-</button>
|
||||
{% if elem.tag in ['cpu_affinity', 'shm_regions'] %}
|
||||
<button type="button" class="btn" id="add_shm_{{first_multi_child[sub_elem.tag]}}">+</button>
|
||||
{% if not first_multi_child[sub_elem.tag] %}
|
||||
<button type="button" disabled class="btn" id="remove_shm_{{first_multi_child[sub_elem.tag]}}">-</button>
|
||||
{% else %}
|
||||
<button type="button" class="btn" id="remove_vcpu_{{first_child|length}}">-</button>
|
||||
<button type="button" class="btn" id="remove_shm_{{first_multi_child[sub_elem.tag]}}">-</button>
|
||||
{% endif %}
|
||||
{% do first_multi_child.update({sub_elem.tag: first_multi_child[sub_elem.tag]+1}) %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% do first_child.append(1) %}
|
||||
<p id="{{'uos:id='+vm.attrib['id']+','+elem.tag+','+sub_elem.tag}}_err" class="col-sm-3"></p>
|
||||
{% else %}
|
||||
{% if not first_child %}
|
||||
{% do first_child.append(1) %}
|
||||
{% if elem.tag in first_multi_child.keys() and first_multi_child[elem.tag] == 0 %}
|
||||
{% do first_multi_child.update({elem.tag: first_multi_child[elem.tag]+1}) %}
|
||||
<label class="col-sm-1 control-label" data-toggle="tooltip"
|
||||
title="{{sub_elem.attrib['desc'] if 'desc' in sub_elem.attrib else sub_elem.tag}}">
|
||||
{{elem.tag+' '+elem.attrib['id']}}</label>
|
||||
|
@ -215,6 +215,7 @@ the source files will be generated into default path and overwirte the previous
|
||||
|
||||
{% if sub_elem.tag in ['RDT', 'IVSHMEM'] %}
|
||||
{% for sub_elem_2 in sub_elem.getchildren() %}
|
||||
{% set sub_elem_2_text = sub_elem_2.text if sub_elem_2.text != None else '' %}
|
||||
{% if ','.join([vm.tag, elem.tag, sub_elem.tag, sub_elem_2.tag]) in scenario_item_values %}
|
||||
<div class="form-group">
|
||||
<label class="col-sm-1 control-label" data-toggle="tooltip"
|
||||
@ -259,10 +260,10 @@ the source files will be generated into default path and overwirte the previous
|
||||
{% if 'readonly' in sub_elem_2.attrib and sub_elem_2.attrib['readonly'] == 'true' %}
|
||||
<input type="text" class="form-control"
|
||||
id="{{vm_type+','+elem.tag+','+sub_elem.tag+','+sub_elem_2.tag}}"
|
||||
readonly vaule="{{sub_elem_2.text}}"></input>
|
||||
readonly vaule="{{sub_elem_2_text}}"></input>
|
||||
{% else %}
|
||||
<input type="text" class="form-control"
|
||||
id="{{vm_type+','+elem.tag+','+sub_elem.tag+','+sub_elem_2.tag}}" value="{{sub_elem_2.text}}"></input>
|
||||
id="{{vm_type+','+elem.tag+','+sub_elem.tag+','+sub_elem_2.tag}}" value="{{sub_elem_2_text}}"></input>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if sub_elem_2.tag in ['IVSHMEM_REGION'] %}
|
||||
@ -277,7 +278,7 @@ the source files will be generated into default path and overwirte the previous
|
||||
{% do first_multi_child.update({sub_elem_2.tag: first_multi_child[sub_elem_2.tag]+1}) %}
|
||||
{% endif%}
|
||||
{% if sub_elem_2.tag in ['IVSHMEM_REGION'] %}
|
||||
<p id="{{vm_type+','+elem.tag+','+sub_elem.tag+','+(first_multi_child[sub_elem_2.tag]-1)|string()}}_err" class="col-sm-3"></p>
|
||||
<p id="{{vm_type+','+elem.tag+','+sub_elem.tag+','+sub_elem_2.tag+','+(first_multi_child[sub_elem_2.tag]-1)|string()}}_err" class="col-sm-3"></p>
|
||||
{% else %}
|
||||
<p id="{{vm_type+','+elem.tag+','+sub_elem.tag+','+sub_elem_2.tag}}_err" class="col-sm-3"></p>
|
||||
{% endif %}
|
||||
|
@ -119,9 +119,20 @@ def launch(launch_name):
|
||||
launch_config.set_curr(launch_name)
|
||||
|
||||
launch_item_values = {}
|
||||
if board_info is not None:
|
||||
scenario_name = launch_config.get_curr_root().attrib['scenario']
|
||||
current_app.config.update(SCENARIO=scenario_name)
|
||||
scenario_name = current_app.config.get('SCENARIO')
|
||||
scenario_file = None
|
||||
if board_info is not None and scenario_name is not None:
|
||||
scenario_file = os.path.join(current_app.config.get('CONFIG_PATH'), board_type, 'user_defined',
|
||||
scenario_name+'.xml')
|
||||
if not os.path.isfile(scenario_file):
|
||||
scenario_file = os.path.join(current_app.config.get('CONFIG_PATH'), board_type,
|
||||
scenario_name + '.xml')
|
||||
if not os.path.isfile(scenario_file):
|
||||
scenario_file = None
|
||||
launch_item_values = get_launch_item_values(
|
||||
os.path.join(os.path.dirname(os.path.abspath(__file__)), 'res', board_info + '.xml'))
|
||||
os.path.join(os.path.dirname(os.path.abspath(__file__)), 'res', board_info + '.xml'), scenario_file)
|
||||
|
||||
scenario_name = None
|
||||
launch_config_root = launch_config.get_curr_root()
|
||||
@ -819,6 +830,8 @@ def get_post_launch_vms():
|
||||
"""
|
||||
data = request.json if request.method == "POST" else request.args
|
||||
scenario_name = data['scenario_name']
|
||||
current_app.config.update(SCENARIO=scenario_name)
|
||||
|
||||
vm_list = get_post_launch_vm_list(scenario_name)
|
||||
|
||||
uos_id_list = []
|
||||
|
@ -483,6 +483,15 @@ def xhci_args_set(dm, vmid, config):
|
||||
launch_cfg_lib.virtual_dev_slot("xhci"), dm['xhci'][vmid]), file=config)
|
||||
|
||||
|
||||
def shm_arg_set(dm, vmid, config):
|
||||
|
||||
if dm['shm_enabled'] == "n":
|
||||
return
|
||||
for shm_region in dm["shm_regions"][vmid]:
|
||||
print(" -s {},ivshmem,{} \\".format(
|
||||
launch_cfg_lib.virtual_dev_slot("shm_region_{}".format(shm_region)), shm_region), file=config)
|
||||
|
||||
|
||||
def virtio_args_set(dm, virt_io, vmid, config):
|
||||
|
||||
# virtio-input set, the value type is a list
|
||||
@ -598,6 +607,9 @@ def dm_arg_set(names, sel, virt_io, dm, vmid, config):
|
||||
# pcpu-list args set
|
||||
pcpu_arg_set(dm, vmid, config)
|
||||
|
||||
# shm regions args set
|
||||
shm_arg_set(dm, vmid, config)
|
||||
|
||||
for value in sel.bdf.values():
|
||||
if value[vmid]:
|
||||
print(" $intr_storm_monitor \\", file=config)
|
||||
|
@ -16,10 +16,11 @@ ACRN_PATH = common.SOURCE_ROOT_DIR
|
||||
ACRN_CONFIG_DEF = ACRN_PATH + '/misc/vm_configs/xmls/config-xmls/'
|
||||
|
||||
|
||||
def get_launch_item_values(board_info):
|
||||
def get_launch_item_values(board_info, scenario_info=None):
|
||||
"""
|
||||
Get items which capable multi select for user
|
||||
:param board_info: it is a file what contains board information for script to read from
|
||||
:param sceanrio_info: it is a file what contains scenario information for script to read from
|
||||
"""
|
||||
common.BOARD_INFO_FILE = board_info
|
||||
launch_item_values = {}
|
||||
@ -51,6 +52,7 @@ def get_launch_item_values(board_info):
|
||||
launch_item_values['uos,vuart0'] = launch_cfg_lib.DM_VUART0
|
||||
launch_item_values['uos,poweroff_channel'] = launch_cfg_lib.PM_CHANNEL
|
||||
launch_item_values["uos,cpu_affinity"] = board_cfg_lib.get_processor_info()
|
||||
launch_cfg_lib.set_shm_regions(launch_item_values, scenario_info)
|
||||
|
||||
return launch_item_values
|
||||
|
||||
@ -62,6 +64,9 @@ def validate_launch_setting(board_info, scenario_info, launch_info):
|
||||
:param scenario_info: it is a file what user have already setting to
|
||||
:return: return a dictionary contain errors
|
||||
"""
|
||||
common.SCENARIO_INFO_FILE = scenario_info
|
||||
common.get_vm_types()
|
||||
|
||||
launch_cfg_lib.ERR_LIST = {}
|
||||
common.BOARD_INFO_FILE = board_info
|
||||
common.SCENARIO_INFO_FILE = scenario_info
|
||||
|
@ -26,6 +26,13 @@ class AcrnDmArgs:
|
||||
self.args["cpu_sharing"] = common.get_hv_item_tag(self.scenario_info, "FEATURES", "SCHEDULER")
|
||||
self.args["pm_channel"] = common.get_leaf_tag_map(self.launch_info, "poweroff_channel")
|
||||
self.args["cpu_affinity"] = common.get_leaf_tag_map(self.launch_info, "cpu_affinity", "pcpu_id")
|
||||
self.args["shm_enabled"] = common.get_hv_item_tag(self.scenario_info, "FEATURES", "IVSHMEM", "IVSHMEM_ENABLED")
|
||||
self.args["shm_regions"] = common.get_leaf_tag_map(self.launch_info, "shm_regions", "shm_region")
|
||||
for vmid, shm_regions in self.args["shm_regions"].items():
|
||||
if self.args["shm_enabled"] == 'y':
|
||||
self.args["shm_regions"][vmid] = [x for x in shm_regions if (x is not None and x.strip != '')]
|
||||
else:
|
||||
self.args["shm_regions"][vmid] = []
|
||||
self.args["xhci"] = common.get_leaf_tag_map(self.launch_info, "usb_xhci")
|
||||
|
||||
def check_item(self):
|
||||
@ -38,6 +45,7 @@ class AcrnDmArgs:
|
||||
cpu_affinity = launch_cfg_lib.uos_cpu_affinity(self.args["cpu_affinity"])
|
||||
err_dic = scenario_cfg_lib.vm_cpu_affinity_check(self.launch_info, cpu_affinity, "pcpu_id")
|
||||
launch_cfg_lib.ERR_LIST.update(err_dic)
|
||||
launch_cfg_lib.check_shm_regions(self.args["shm_regions"], self.scenario_info)
|
||||
|
||||
|
||||
class AvailablePthru():
|
||||
|
@ -20,7 +20,7 @@ PY_CACHES = ["__pycache__", "../board_config/__pycache__", "../scenario_config/_
|
||||
GUEST_FLAG = ["0UL", "GUEST_FLAG_SECURE_WORLD_ENABLED", "GUEST_FLAG_LAPIC_PASSTHROUGH",
|
||||
"GUEST_FLAG_IO_COMPLETION_POLLING", "GUEST_FLAG_HIDE_MTRR", "GUEST_FLAG_RT"]
|
||||
|
||||
MULTI_ITEM = ["guest_flag", "pcpu_id", "vcpu_clos", "input", "block", "network", "pci_dev", "shmem_region"]
|
||||
MULTI_ITEM = ["guest_flag", "pcpu_id", "vcpu_clos", "input", "block", "network", "pci_dev", "shm_region"]
|
||||
|
||||
SIZE_K = 1024
|
||||
SIZE_M = SIZE_K * 1024
|
||||
@ -46,7 +46,7 @@ class MultiItem():
|
||||
self.vir_console = []
|
||||
self.vir_network = []
|
||||
self.pci_dev = []
|
||||
self.shmem_region = []
|
||||
self.shm_region = []
|
||||
|
||||
class TmpItem():
|
||||
|
||||
@ -284,9 +284,9 @@ def get_leaf_value(tmp, tag_str, leaf):
|
||||
if leaf.tag == "pci_dev" and tag_str == "pci_dev":
|
||||
tmp.multi.pci_dev.append(leaf.text)
|
||||
|
||||
# get shmem_region for vm
|
||||
if leaf.tag == "shmem_region" and tag_str == "shmem_region":
|
||||
tmp.multi.shmem_region.append(leaf.text)
|
||||
# get shm_region for vm
|
||||
if leaf.tag == "shm_region" and tag_str == "shm_region":
|
||||
tmp.multi.shm_region.append(leaf.text)
|
||||
|
||||
|
||||
def get_sub_value(tmp, tag_str, vm_id):
|
||||
@ -319,9 +319,9 @@ def get_sub_value(tmp, tag_str, vm_id):
|
||||
if tmp.multi.pci_dev and tag_str == "pci_dev":
|
||||
tmp.tag[vm_id] = tmp.multi.pci_dev
|
||||
|
||||
# append shmem_region for vm
|
||||
if tmp.multi.shmem_region and tag_str == "shmem_region":
|
||||
tmp.tag[vm_id] = tmp.multi.shmem_region
|
||||
# append shm_region for vm
|
||||
if tmp.multi.shm_region and tag_str == "shm_region":
|
||||
tmp.tag[vm_id] = tmp.multi.shm_region
|
||||
|
||||
|
||||
def get_leaf_tag_map(config_file, branch_tag, tag_str=''):
|
||||
|
@ -525,7 +525,7 @@ def uos_cpu_affinity(uosid_cpu_affinity):
|
||||
cpu_affinity = {}
|
||||
sos_vm_id = get_sos_vmid()
|
||||
for uosid,cpu_affinity_list in uosid_cpu_affinity.items():
|
||||
cpu_affinity[uosid + sos_vm_id] = cpu_affinity_list
|
||||
cpu_affinity[int(uosid) + int(sos_vm_id)] = cpu_affinity_list
|
||||
return cpu_affinity
|
||||
|
||||
|
||||
@ -564,3 +564,51 @@ def is_linux_like(uos_type):
|
||||
is_linux = True
|
||||
|
||||
return is_linux
|
||||
|
||||
|
||||
def set_shm_regions(launch_item_values, scenario_info):
|
||||
|
||||
raw_shmem_regions = common.get_hv_item_tag(scenario_info, "FEATURES", "IVSHMEM", "IVSHMEM_REGION")
|
||||
vm_types = common.get_leaf_tag_map(scenario_info, "vm_type")
|
||||
shm_enabled = common.get_hv_item_tag(scenario_info, "FEATURES", "IVSHMEM", "IVSHMEM_ENABLED")
|
||||
|
||||
sos_vm_id = 0
|
||||
for vm_id, vm_type in vm_types.items():
|
||||
if vm_type in ['SOS_VM']:
|
||||
sos_vm_id = vm_id
|
||||
elif vm_type in ['POST_STD_VM', 'POST_RT_VM', 'KATA_VM']:
|
||||
uos_id = vm_id - sos_vm_id
|
||||
shm_region_key = 'uos:id={},shm_regions,shm_region'.format(uos_id)
|
||||
launch_item_values[shm_region_key] = ['']
|
||||
if shm_enabled == 'y':
|
||||
for shmem_region in raw_shmem_regions:
|
||||
if shmem_region is None or shmem_region.strip() == '':
|
||||
continue
|
||||
try:
|
||||
shm_splited = shmem_region.split(',')
|
||||
name = shm_splited[0].strip()
|
||||
size = shm_splited[1].strip()
|
||||
if size.isdecimal():
|
||||
int_size = int(size)
|
||||
else:
|
||||
int_size = int(size, 16)
|
||||
vm_id_list = [x.strip() for x in shm_splited[2].split(':')]
|
||||
if str(vm_id) in vm_id_list:
|
||||
launch_item_values[shm_region_key].append(','.join([name, str(int_size)]))
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
|
||||
def check_shm_regions(launch_shm_regions, scenario_info):
|
||||
launch_item_values = {}
|
||||
set_shm_regions(launch_item_values, scenario_info)
|
||||
|
||||
for uos_id, shm_regions in launch_shm_regions.items():
|
||||
shm_region_key = 'uos:id={},shm_regions,shm_region'.format(uos_id)
|
||||
for shm_region in shm_regions:
|
||||
print(shm_region)
|
||||
print(launch_item_values[shm_region_key])
|
||||
if shm_region_key not in launch_item_values.keys() or shm_region not in launch_item_values[shm_region_key]:
|
||||
ERR_LIST[shm_region_key] = "shm {} should be configured in scenario setting and the size should be decimal" \
|
||||
" and spaces should not exist.".format(shm_region)
|
||||
return
|
||||
|
@ -711,7 +711,7 @@ def share_mem_check(shmem_regions, raw_shmem_regions, vm_type_info, prime_item,
|
||||
break
|
||||
except:
|
||||
index = 0
|
||||
key = "hv,{},{},{}".format(prime_item, item, sub_item, index)
|
||||
key = "hv,{},{},{},{}".format(prime_item, item, sub_item, index)
|
||||
|
||||
shm_str_splited = shm_str.split(',')
|
||||
if len(shm_str_splited) < 3:
|
||||
@ -721,7 +721,7 @@ def share_mem_check(shmem_regions, raw_shmem_regions, vm_type_info, prime_item,
|
||||
try:
|
||||
curr_vm_id = int(shm_i)
|
||||
except:
|
||||
ERR_LIST[key] = "share memory region should be configure with format like this: VM0_VM2,0x20000,0:2"
|
||||
ERR_LIST[key] = "share memory region should be configured with format like this: hv:/shm_region_0, 0x200000, 0:2"
|
||||
return
|
||||
name = shm_str_splited[0].strip()
|
||||
size = shm_str_splited[1].strip()
|
||||
@ -791,7 +791,7 @@ def share_mem_check(shmem_regions, raw_shmem_regions, vm_type_info, prime_item,
|
||||
break
|
||||
except:
|
||||
index = 0
|
||||
key = "hv,{},{},{}".format(prime_item, item, sub_item, index)
|
||||
key = "hv,{},{},{},{}".format(prime_item, item, sub_item, index)
|
||||
if 'IVSHMEM_'+name in board_cfg_lib.PCI_DEV_BAR_DESC.shm_bar_dic.keys():
|
||||
bar_attr_dic = board_cfg_lib.PCI_DEV_BAR_DESC.shm_bar_dic['IVSHMEM_'+name]
|
||||
if (0 in bar_attr_dic.keys() and int(bar_attr_dic[0].addr, 16) < 0x80000000) \
|
||||
|
Loading…
Reference in New Issue
Block a user