acrn-config: generate correct IRQ for VUART1

As VUART is not supported PCI VUART, use native PCI ttySn's IRQ for
VUART1 would cause communication failed, allocate a free IRQ for it.

Tracked-On: #4798
Signed-off-by: Wei Liu <weix.w.liu@intel.com>
Acked-by: Victor Sun <victor.sun@intel.com>
This commit is contained in:
Wei Liu 2020-05-07 13:46:18 +08:00 committed by wenlingz
parent f644b3705b
commit 8b736cc131
7 changed files with 142 additions and 145 deletions

View File

@ -11,6 +11,7 @@ MISC_CFG_HEADER = """
#define MISC_CFG_H
"""
NATIVE_TTYS_DIC = {}
MISC_CFG_END = """#endif /* MISC_CFG_H */"""
@ -23,6 +24,83 @@ class Vuart:
v_irq = {}
def get_valid_ttys_for_vuart(ttys_n):
"""
Get available ttysn list for vuart0/vuart1
:param ttys_n: the serial port was chosen as hv console
"""
vuart0_valid = []
vuart1_valid = ['ttyS0', 'ttyS1', 'ttyS2', 'ttyS3']
ttys_lines = board_cfg_lib.get_info(common.BOARD_INFO_FILE, "<TTYS_INFO>", "</TTYS_INFO>")
if ttys_lines:
vuart0_valid.clear()
for tty_line in ttys_lines:
tmp_dic = {}
#seri:/dev/ttySx type:mmio base:0x91526000 irq:4 bdf:"00:18.0"
#seri:/dev/ttySy type:portio base:0x2f8 irq:5
tty = tty_line.split('/')[2].split()[0]
ttys_irq = tty_line.split()[3].split(':')[1].strip()
ttys_type = tty_line.split()[1].split(':')[1].strip()
tmp_dic['irq'] = int(ttys_irq)
tmp_dic['type'] = ttys_type
NATIVE_TTYS_DIC[tty] = tmp_dic
vuart0_valid.append(tty)
if tty and tty in vuart1_valid:
vuart1_valid.remove(tty)
if not vuart1_valid:
common.print_yel("ttyS are fully used. ttyS0 is used for hv_console, ttyS1 is used for vuart1!", warn=True)
vuart1_valid = ['ttyS0', 'ttyS1', 'ttyS2', 'ttyS3']
if ttys_n in vuart1_valid:
vuart1_valid.remove(ttys_n)
return (vuart0_valid, vuart1_valid)
def get_vuart_settings():
"""
Get vuart setting from scenario setting
:return: vuart0/vuart1 setting dictionary
"""
err_dic = {}
vuart0_setting = {}
vuart1_setting = {}
(err_dic, ttys_n) = board_cfg_lib.parser_hv_console()
if err_dic:
return err_dic
if ttys_n:
(vuart0_valid, vuart1_valid) = get_valid_ttys_for_vuart(ttys_n)
# VUART0 setting
if ttys_n not in list(NATIVE_TTYS_DIC.keys()):
vuart0_setting['ttyS0'] = board_cfg_lib.alloc_irq()
else:
if int(NATIVE_TTYS_DIC[ttys_n]['irq']) >= 16:
vuart0_setting[ttys_n] = board_cfg_lib.alloc_irq()
else:
vuart0_setting[ttys_n] = NATIVE_TTYS_DIC[ttys_n]['irq']
else:
vuart1_valid = ['ttyS1']
# VUART1 setting
# The IRQ of vUART1(COM2) might be hard-coded by SOS ACPI table(i.e. host ACPI),
# so we had better follow native COM2 IRQ assignment for vUART1 if COM2 is a legacy ttyS,
# otherwise function of vUART1 would be failed. If host COM2 does not exist or it is a PCI ttyS,
# then we could allocate a free IRQ for vUART1.
if 'ttyS1' in NATIVE_TTYS_DIC.keys() \
and NATIVE_TTYS_DIC['ttyS1']['type'] == "portio" \
and 'irq' in list(NATIVE_TTYS_DIC['ttyS1'].keys()) \
and NATIVE_TTYS_DIC['ttyS1']['irq'] < 16:
vuart1_setting['ttyS1'] = NATIVE_TTYS_DIC['ttyS1']['irq']
else:
vuart1_setting[vuart1_valid[0]] = board_cfg_lib.alloc_irq()
return (err_dic, vuart0_setting, vuart1_setting)
def sos_bootarg_diff(sos_cmdlines, config):
if sos_cmdlines:
@ -52,12 +130,12 @@ def parse_boot_info():
if 'SOS_VM' in common.VM_TYPES.values():
sos_cmdlines = list(common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "board_private", "bootargs").values())
sos_rootfs = list(common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "board_private", "rootfs").values())
(err_dic, vuart0_dic, vuart1_dic) = board_cfg_lib.get_board_private_vuart("board_private", "console")
(err_dic, vuart0_dic, vuart1_dic) = get_vuart_settings()
else:
sos_cmdlines = list(common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "os_config", "bootargs").values())
sos_rootfs = list(common.get_leaf_tag_map(common.SCENARIO_INFO_FILE, "os_config", "rootfs").values())
(err_dic, vuart0_dic, vuart1_dic) = board_cfg_lib.get_board_private_vuart("os_config", "console")
(err_dic, vuart0_dic, vuart1_dic) = get_vuart_settings()
return (err_dic, sos_cmdlines, sos_rootfs, vuart0_dic, vuart1_dic)
@ -115,7 +193,7 @@ def generate_file(config):
max_cpu_num = len(cpu_list)
# get the vuart0/vuart1 which user chosed from scenario.xml of board_private section
(err_dic, ttys_n) = board_cfg_lib.parser_vuart_console()
(err_dic, ttys_n) = board_cfg_lib.parser_hv_console()
if err_dic:
return err_dic
@ -135,8 +213,8 @@ def generate_file(config):
# parse the setting ttys vuatx dic: {vmid:base/irq}
vuart0_setting = Vuart()
vuart1_setting = Vuart()
vuart0_setting = board_cfg_lib.get_vuart_info_id(common.SCENARIO_INFO_FILE, 0)
vuart1_setting = board_cfg_lib.get_vuart_info_id(common.SCENARIO_INFO_FILE, 1)
vuart0_setting = common.get_vuart_info_id(common.SCENARIO_INFO_FILE, 0)
vuart1_setting = common.get_vuart_info_id(common.SCENARIO_INFO_FILE, 1)
# sos command lines information
sos_cmdlines = [i for i in sos_cmdlines[0].split() if i != '']

View File

@ -88,7 +88,7 @@ def get_serial_type():
ttys_lines = board_cfg_lib.get_info(common.BOARD_INFO_FILE, "<TTYS_INFO>", "</TTYS_INFO>")
# Get ttySx from scenario config file which selected by user
(err_dic, ttyn) = board_cfg_lib.parser_vuart_console()
(err_dic, ttyn) = board_cfg_lib.parser_hv_console()
if err_dic:
hv_cfg_lib.ERR_LIST.update(err_dic)

View File

@ -19,7 +19,6 @@ LEGACY_TTYS = {
'ttyS3':'0x2E8',
}
NATIVE_CONSOLE_DIC = {}
VALID_LEGACY_IRQ = []
ERR_LIST = {}
@ -196,45 +195,7 @@ def alloc_irq():
return irq_val
def get_valid_console():
""" Get valid console with mapping {ttyS:irq} returned """
used_console_lines = get_info(common.BOARD_INFO_FILE, "<TTYS_INFO>", "</TTYS_INFO>")
vuart0_valid_console = []
vuart1_valid_console = ['ttyS0', 'ttyS1', 'ttyS2', 'ttyS3', 'ttyS4', 'ttyS5', 'ttyS6', 'ttyS7']
if used_console_lines:
vuart0_valid_console.clear()
for console in used_console_lines:
#seri:/dev/ttySx type:mmio base:0x91526000 irq:4 bdf:"00:18.0"
#seri:/dev/ttySy type:portio base:0x2f8 irq:5
tty = console.split('/')[2].split()[0]
ttys_irq = console.split()[3].split(':')[1].strip()
NATIVE_CONSOLE_DIC[tty] = ttys_irq
vuart0_valid_console.append(tty)
if tty:
vuart1_valid_console.remove(tty)
return (vuart0_valid_console, vuart1_valid_console)
def console_to_show(board_info):
"""
This is get available console from board info file
:param board_info: it is a file what contains board information for script to read from
:return: available console
"""
show_vuart1 = False
(vuart0_valid_console, vuart1_valid_console) = get_valid_console()
if not vuart1_valid_console:
print_yel("Console are full used, sos_console/vuart1 have to chose one:", warn=True)
vuart0_valid_console = ['ttyS0', 'ttyS1', 'ttyS2', 'ttyS3']
vuart1_valid_console = ['ttyS0', 'ttyS1', 'ttyS2', 'ttyS3']
show_vuart1 = True
return (vuart0_valid_console, vuart1_valid_console, show_vuart1)
def parser_vuart_console():
def parser_hv_console():
"""
There may be 3 types in the console item
1. BDF:(00:18.2) seri:/dev/ttyS2
@ -256,98 +217,6 @@ def parser_vuart_console():
return (err_dic, ttys_n)
def get_board_private_vuart(branch_tag, tag_console):
"""
Get vuart_console from board setting
:param tag_console: TTYS_INFO
:return: vuart0/vuart1 console dictionary
"""
err_dic = {}
vuart0_console_dic = {}
vuart1_console_dic = {}
(err_dic, ttys_n) = parser_vuart_console()
if err_dic:
return err_dic
if ttys_n:
(vuart0_valid_console, vuart1_valid_console, show_vuart1) = console_to_show(common.BOARD_INFO_FILE)
# VUART0
if ttys_n not in list(NATIVE_CONSOLE_DIC.keys()):
vuart0_console_dic[ttys_n] = alloc_irq()
else:
if int(NATIVE_CONSOLE_DIC[ttys_n]) >= 16:
vuart0_console_dic[ttys_n] = alloc_irq()
else:
vuart0_console_dic[ttys_n] = NATIVE_CONSOLE_DIC[ttys_n]
else:
vuart1_valid_console = ['ttyS1']
# VUART1
if len(NATIVE_CONSOLE_DIC) >= 2 and 'ttyS1' in NATIVE_CONSOLE_DIC.keys():
# There are more than 1 serial port in native, we need to use native ttyS1 info for vuart1 which include
# base ioport and irq number.
vuart1_console_dic['ttyS1'] = NATIVE_CONSOLE_DIC['ttyS1']
else:
# There is only one native serial port. We hardcode base ioport for vuart1 and allocate a irq which is
# free in native env and use it for vuart1 irq number
vuart1_console_dic[vuart1_valid_console[0]] = alloc_irq()
return (err_dic, vuart0_console_dic, vuart1_console_dic)
def get_vuart_id(tmp_vuart, leaf_tag, leaf_text):
"""
Get all vuart id member of class
:param tmp_vuart: a dictionary to store member:value
:param leaf_tag: key pattern of item tag
:param leaf_text: key pattern of item tag's value
:return: a dictionary to which stored member:value
"""
if leaf_tag == "type":
tmp_vuart['type'] = leaf_text
if leaf_tag == "base":
tmp_vuart['base'] = leaf_text
if leaf_tag == "irq":
tmp_vuart['irq'] = leaf_text
if leaf_tag == "target_vm_id":
tmp_vuart['target_vm_id'] = leaf_text
if leaf_tag == "target_uart_id":
tmp_vuart['target_uart_id'] = leaf_text
return tmp_vuart
def get_vuart_info_id(config_file, idx):
"""
Get vuart information by vuart id indexx
:param config_file: it is a file what contains information for script to read from
:param idx: vuart index in range: [0,1]
:return: dictionary which stored the vuart-id
"""
tmp_tag = {}
vm_id = 0
root = common.get_config_root(config_file)
for item in root:
if item.tag == "vm":
vm_id = int(item.attrib['id'])
for sub in item:
tmp_vuart = {}
for leaf in sub:
if sub.tag == "vuart" and int(sub.attrib['id']) == idx:
tmp_vuart = get_vuart_id(tmp_vuart, leaf.tag, leaf.text)
# append vuart for each vm
if tmp_vuart and sub.tag == "vuart":
tmp_tag[vm_id] = tmp_vuart
return tmp_tag
def get_processor_info():
"""
Get cpu processor list
@ -375,11 +244,11 @@ def get_processor_info():
return tmp_list
def get_ttys_info(board_info):
def get_native_ttys_info(board_info):
"""
Get ttySn from board info
:param board_info: it is a file what contains board information for script to read from
:return: serial console list
:return: serial port list
"""
ttys_list = []
ttys_info = get_info(board_info, "<TTYS_INFO>", "</TTYS_INFO>")

View File

@ -356,6 +356,56 @@ def get_leaf_tag_map(config_file, branch_tag, tag_str=''):
return dict(sorted(tmp.tag.items()))
def get_vuart_id(tmp_vuart, leaf_tag, leaf_text):
"""
Get all vuart id member of class
:param tmp_vuart: a dictionary to store member:value
:param leaf_tag: key pattern of item tag
:param leaf_text: key pattern of item tag's value
:return: a dictionary to which stored member:value
"""
if leaf_tag == "type":
tmp_vuart['type'] = leaf_text
if leaf_tag == "base":
tmp_vuart['base'] = leaf_text
if leaf_tag == "irq":
tmp_vuart['irq'] = leaf_text
if leaf_tag == "target_vm_id":
tmp_vuart['target_vm_id'] = leaf_text
if leaf_tag == "target_uart_id":
tmp_vuart['target_uart_id'] = leaf_text
return tmp_vuart
def get_vuart_info_id(config_file, idx):
"""
Get vuart information by vuart id indexx
:param config_file: it is a file what contains information for script to read from
:param idx: vuart index in range: [0,1]
:return: dictionary which stored the vuart-id
"""
tmp_tag = {}
vm_id = 0
root = get_config_root(config_file)
for item in root:
if item.tag == "vm":
vm_id = int(item.attrib['id'])
for sub in item:
tmp_vuart = {}
for leaf in sub:
if sub.tag == "vuart" and int(sub.attrib['id']) == idx:
tmp_vuart = get_vuart_id(tmp_vuart, leaf.tag, leaf.text)
# append vuart for each vm
if tmp_vuart and sub.tag == "vuart":
tmp_tag[vm_id] = tmp_vuart
return tmp_tag
def get_hv_item_tag(config_file, branch_tag, tag_str=''):
tmp = ''

View File

@ -443,7 +443,7 @@ def get_pt_dev():
def get_vuart1_from_scenario(vmid):
"""Get the vmid's vuart1 base"""
vuart1 = board_cfg_lib.get_vuart_info_id(common.SCENARIO_INFO_FILE, 1)
vuart1 = common.get_vuart_info_id(common.SCENARIO_INFO_FILE, 1)
return vuart1[vmid]['base']

View File

@ -61,7 +61,7 @@ def get_scenario_item_values(board_info, scenario_info):
scenario_item_values["hv,DEBUG_OPTIONS,NPK_LOGLEVEL"] = hv_cfg_lib.get_select_range("DEBUG_OPTIONS", "LOG_LEVEL")
scenario_item_values["hv,DEBUG_OPTIONS,MEM_LOGLEVEL"] = hv_cfg_lib.get_select_range("DEBUG_OPTIONS", "LOG_LEVEL")
scenario_item_values["hv,DEBUG_OPTIONS,CONSOLE_LOGLEVEL"] = hv_cfg_lib.get_select_range("DEBUG_OPTIONS", "LOG_LEVEL")
scenario_item_values["hv,DEBUG_OPTIONS,SERIAL_CONSOLE"] = board_cfg_lib.get_ttys_info(board_info)
scenario_item_values["hv,DEBUG_OPTIONS,SERIAL_CONSOLE"] = board_cfg_lib.get_native_ttys_info(board_info)
scenario_item_values["hv,DEBUG_OPTIONS,LOG_DESTINATION"] = hv_cfg_lib.get_select_range("DEBUG_OPTIONS", "LOG_DESTINATION_BITMAP")
scenario_item_values["hv,CAPACITIES,MAX_IOAPIC_NUM"] = hv_cfg_lib.get_select_range("CAPACITIES", "IOAPIC_NUM")

View File

@ -39,7 +39,7 @@ class HwInfo:
Get ttySn from board info
:return: serial console list
"""
self.ttys_val = board_cfg_lib.get_ttys_info(self.board_info)
self.ttys_val = board_cfg_lib.get_native_ttys_info(self.board_info)
return self.ttys_val
def get_clos_val(self):
@ -140,8 +140,8 @@ class VuartInfo:
Get all items which belong to this class
:return: None
"""
self.v0_vuart = board_cfg_lib.get_vuart_info_id(self.scenario_info, 0)
self.v1_vuart = board_cfg_lib.get_vuart_info_id(self.scenario_info, 1)
self.v0_vuart = common.get_vuart_info_id(self.scenario_info, 0)
self.v1_vuart = common.get_vuart_info_id(self.scenario_info, 1)
def check_item(self):
"""