mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-19 12:12:16 +00:00
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>
294 lines
9.9 KiB
Python
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
|