acrn-hypervisor/misc/acrn-config/board_config/misc_cfg_h.py
Wei Liu 5403fd720d acrn-config: re-generate TTYS_INFO in native board
Currently, MMIO PCI BDF of ttyS was indexed by IRQ, but it may found
the wrong BDF when the IRQ was shared and it is not expected. So, the
patch uses the MMIO base to query /proc/iomem to find BDF, the waring
will get if BDF is not present in iomem.

Tracked-On: #4862
Signed-off-by: Wei Liu <weix.w.liu@intel.com>
Acked-by: Victor Sun <victor.sun@intel.com>
2020-06-02 15:15:39 +08:00

294 lines
9.9 KiB
Python

# Copyright (C) 2019 Intel Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
import common
import board_cfg_lib
MISC_CFG_HEADER = """
#ifndef MISC_CFG_H
#define MISC_CFG_H
"""
NATIVE_TTYS_DIC = {}
MISC_CFG_END = """#endif /* MISC_CFG_H */"""
class Vuart:
t_vm_id = {}
t_vuart_id = {}
v_type = {}
v_base = {}
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:
sos_len = len(sos_cmdlines)
i = 0
for sos_cmdline in sos_cmdlines:
if not sos_cmdline:
continue
i += 1
if i == 1:
if sos_len == 1:
print('#define SOS_BOOTARGS_DIFF\t"{}"'.format(sos_cmdline.strip('"')), file=config)
else:
print('#define SOS_BOOTARGS_DIFF\t"{} " \\'.format(sos_cmdline), file=config)
else:
if i < sos_len:
print('\t\t\t\t"{} "\t\\'.format(sos_cmdline), file=config)
else:
print('\t\t\t\t"{}"'.format(sos_cmdline), file=config)
def parse_boot_info():
err_dic = {}
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) = 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) = get_vuart_settings()
return (err_dic, sos_cmdlines, sos_rootfs, vuart0_dic, vuart1_dic)
def find_hi_mmio_window(config):
i_cnt = 0
mmio_min = 0
mmio_max = 0
is_hi_mmio = False
iomem_lines = board_cfg_lib.get_info(common.BOARD_INFO_FILE, "<IOMEM_INFO>", "</IOMEM_INFO>")
for line in iomem_lines:
if "PCI Bus" not in line:
continue
line_start_addr = int(line.split('-')[0], 16)
line_end_addr = int(line.split('-')[1].split()[0], 16)
if line_start_addr < common.SIZE_4G and line_end_addr < common.SIZE_4G:
continue
elif line_start_addr < common.SIZE_4G and line_end_addr >= common.SIZE_4G:
i_cnt += 1
is_hi_mmio = True
mmio_min = common.SIZE_4G
mmio_max = line_end_addr
continue
is_hi_mmio = True
if i_cnt == 0:
mmio_min = line_start_addr
mmio_max = line_end_addr
if mmio_max < line_end_addr:
mmio_max = line_end_addr
i_cnt += 1
print("", file=config)
if is_hi_mmio:
print("#define HI_MMIO_START\t\t0x%xUL" % common.round_down(mmio_min, common.SIZE_G), file=config)
print("#define HI_MMIO_END\t\t0x%xUL" % common.round_up(mmio_max, common.SIZE_G), file=config)
else:
print("#define HI_MMIO_START\t\t~0UL", file=config)
print("#define HI_MMIO_END\t\t0UL", file=config)
def generate_file(config):
"""
Start to generate board.c
:param config: it is a file pointer of board information for writing to
"""
board_cfg_lib.get_valid_irq(common.BOARD_INFO_FILE)
# get cpu processor list
cpu_list = board_cfg_lib.get_processor_info()
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_hv_console()
if err_dic:
return err_dic
# parse sos_bootargs/rootfs/console
(err_dic, sos_cmdlines, sos_rootfs, vuart0_dic, vuart1_dic) = parse_boot_info()
if err_dic:
return err_dic
if vuart0_dic:
# parse to get poart/base of vuart0/vuart1
vuart0_port_base = board_cfg_lib.LEGACY_TTYS[list(vuart0_dic.keys())[0]]
vuart0_irq = vuart0_dic[list(vuart0_dic.keys())[0]]
vuart1_port_base = board_cfg_lib.LEGACY_TTYS[list(vuart1_dic.keys())[0]]
vuart1_irq = vuart1_dic[list(vuart1_dic.keys())[0]]
# parse the setting ttys vuatx dic: {vmid:base/irq}
vuart0_setting = Vuart()
vuart1_setting = Vuart()
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 != '']
# get native rootfs list from board_info.xml
(root_devs, root_dev_num) = board_cfg_lib.get_rootfs(common.BOARD_INFO_FILE)
# start to generate misc_cfg.h
print("{0}".format(board_cfg_lib.HEADER_LICENSE), file=config)
print("{}".format(MISC_CFG_HEADER), file=config)
# define CONFIG_MAX_PCPCU_NUM
print("#define MAX_PCPU_NUM\t{}U".format(max_cpu_num), file=config)
# set macro of max clos number
(_, clos_max, _) = board_cfg_lib.clos_info_parser(common.BOARD_INFO_FILE)
if len(clos_max) != 0:
common_clos_max = min(clos_max)
else:
common_clos_max = 0
print("#define MAX_PLATFORM_CLOS_NUM\t{}U".format(common_clos_max), file=config)
# define rootfs with macro
for i in range(root_dev_num):
print('#define ROOTFS_{}\t\t"root={} "'.format(i, root_devs[i]), file=config)
# sos rootfs and console
print("", file=config)
if "SOS_VM" in common.VM_TYPES.values():
print('#define SOS_ROOTFS\t\t"root={} "'.format(sos_rootfs[0]), file=config)
if ttys_n:
print('#define SOS_CONSOLE\t\t"console={} "'.format(ttys_n), file=config)
else:
print('#define SOS_CONSOLE\t\t" "', file=config)
# sos com base/irq
i_type = 0
for vm_i,vm_type in common.VM_TYPES.items():
if vm_type == "SOS_VM":
i_type = vm_i
break
if "SOS_VM" in common.VM_TYPES.values():
if vuart0_dic:
print("#define SOS_COM1_BASE\t\t{}U".format(vuart0_port_base), file=config)
print("#define SOS_COM1_IRQ\t\t{}U".format(vuart0_irq), file=config)
else:
print("#define SOS_COM1_BASE\t\t0U", file=config)
print("#define SOS_COM1_IRQ\t\t0U", file=config)
if vuart1_setting[i_type]['base'] != "INVALID_COM_BASE":
print("#define SOS_COM2_BASE\t\t{}U".format(vuart1_port_base), file=config)
print("#define SOS_COM2_IRQ\t\t{}U".format(vuart1_irq), file=config)
# sos boot command line
print("", file=config)
if "SOS_VM" in common.VM_TYPES.values():
sos_bootarg_diff(sos_cmdlines, config)
# set macro for HIDDEN PTDEVS
print("", file=config)
if board_cfg_lib.BOARD_NAME in list(board_cfg_lib.KNOWN_HIDDEN_PDEVS_BOARD_DB):
print("#define MAX_HIDDEN_PDEVS_NUM {}U".format(len(board_cfg_lib.KNOWN_HIDDEN_PDEVS_BOARD_DB[board_cfg_lib.BOARD_NAME])), file=config)
else:
print("#define MAX_HIDDEN_PDEVS_NUM 0U", file=config)
# generate HI_MMIO_START/HI_MMIO_END
find_hi_mmio_window(config)
print("", file=config)
print("{}".format(MISC_CFG_END), file=config)
return err_dic